static bool isInStringHelper(const QTextCursor &cursor, Token *retToken = 0) { LanguageFeatures features; features.qtEnabled = false; features.qtKeywordsEnabled = false; features.qtMocRunEnabled = false; features.cxx11Enabled = true; features.c99Enabled = true; SimpleLexer tokenize; tokenize.setLanguageFeatures(features); const int prevState = BackwardsScanner::previousBlockState(cursor.block()) & 0xFF; const Tokens tokens = tokenize(cursor.block().text(), prevState); const unsigned pos = cursor.selectionEnd() - cursor.block().position(); if (tokens.isEmpty() || pos <= tokens.first().utf16charsBegin()) return false; if (pos >= tokens.last().utf16charsEnd()) { const Token tk = tokens.last(); return tk.isStringLiteral() && prevState > 0; } Token tk = tokenAtPosition(tokens, pos); if (retToken) *retToken = tk; return tk.isStringLiteral() && pos > tk.utf16charsBegin(); }
bool CppAutoCompleter::isInCommentHelper(const QTextCursor &cursor, Token *retToken) const { SimpleLexer tokenize; tokenize.setQtMocRunEnabled(false); tokenize.setObjCEnabled(false); tokenize.setCxx0xEnabled(true); const int prevState = BackwardsScanner::previousBlockState(cursor.block()) & 0xFF; const QList<Token> tokens = tokenize(cursor.block().text(), prevState); const unsigned pos = cursor.selectionEnd() - cursor.block().position(); if (tokens.isEmpty() || pos < tokens.first().begin()) return prevState > 0; if (pos >= tokens.last().end()) { const Token tk = tokens.last(); if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT)) return true; return tk.isComment() && (cursor.block().userState() & 0xFF); } Token tk = tokenAtPosition(tokens, pos); if (retToken) *retToken = tk; return tk.isComment(); }
bool LuaAutoCompleter::isInCommentHelper(const QTextCursor &cursor, Token *retToken) const { LanguageFeatures features; features.qtEnabled = false; features.qtKeywordsEnabled = false; features.qtMocRunEnabled = false; features.cxx11Enabled = true; SimpleLexer tokenize; tokenize.setLanguageFeatures(features); const int prevState = BackwardsScanner::previousBlockState(cursor.block()) & 0xFF; const QList<Token> tokens = tokenize(cursor.block().text(), prevState); const unsigned pos = cursor.selectionEnd() - cursor.block().position(); if (tokens.isEmpty() || pos < tokens.first().begin()) return prevState > 0; if (pos >= tokens.last().end()) { const Token tk = tokens.last(); if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT)) return true; return tk.isComment() && (cursor.block().userState() & 0xFF); } Token tk = tokenAtPosition(tokens, pos); if (retToken) *retToken = tk; return tk.isComment(); }
QString ExpressionUnderCursor::operator()(const QTextCursor &cursor) { enum { MAX_BLOCK_COUNT = 5 }; QTextBlock block = cursor.block(); QTextBlock initialBlock = block; for (int i = 0; i < MAX_BLOCK_COUNT; ++i) { if (! initialBlock.previous().isValid()) break; initialBlock = initialBlock.previous(); } QString text; QTextBlock it = initialBlock; for (; it.isValid(); it = it.next()) { QString textBlock = it.text(); if (it == block) textBlock = textBlock.left(cursor.position() - cursor.block().position()); text += textBlock; if (it == block) break; text += QLatin1Char('\n'); } SimpleLexer tokenize; tokenize.setSkipComments(true); QList<SimpleToken> tokens = tokenize(text, previousBlockState(initialBlock)); tokens.prepend(SimpleToken()); // sentinel _jumpedComma = false; const int i = startOfExpression(tokens, tokens.size()); if (i == tokens.size()) return QString(); return text.mid(tokens.at(i).position(), tokens.last().position() + tokens.last().length() - tokens.at(i).position()); }
QFuture<TextEditor::HighlightingResult> CppHighlightingSupportInternal::highlightingFuture( const Document::Ptr &doc, const Snapshot &snapshot) const { typedef TextEditor::HighlightingResult Result; QList<Result> macroUses; // Get macro definitions foreach (const CPlusPlus::Macro& macro, doc->definedMacros()) { int line, column; editor()->convertPosition(macro.offset(), &line, &column); ++column; //Highlighting starts at (column-1) --> compensate here Result use(line, column, macro.name().size(), MacroUse); macroUses.append(use); } // Get macro uses foreach (const Document::MacroUse ¯o, doc->macroUses()) { const QString name = QString::fromUtf8(macro.macro().name()); //Filter out QtKeywords if (isQtKeyword(QStringRef(&name))) continue; //Filter out C++ keywords SimpleLexer tokenize; tokenize.setQtMocRunEnabled(false); tokenize.setObjCEnabled(false); tokenize.setCxx0xEnabled(true); const QList<Token> tokens = tokenize(name); if (tokens.length() && (tokens.at(0).isKeyword() || tokens.at(0).isObjCAtKeyword())) continue; int line, column; editor()->convertPosition(macro.begin(), &line, &column); ++column; //Highlighting starts at (column-1) --> compensate here Result use(line, column, name.size(), MacroUse); macroUses.append(use); } LookupContext context(doc, snapshot); return CheckSymbols::go(doc, context, macroUses); }
bool GolangTextLexer::fetchFunctionArgs(const QString &str, int &argnr, int &parcount) { LanguageFeatures features; features.golangEnable = true; argnr = 0; parcount = 0; SimpleLexer tokenize; tokenize.setLanguageFeatures(features); QList<Token> tokens = tokenize(str); for (int i = 0; i < tokens.count(); ++i) { const Token &tk = tokens.at(i); if (tk.is(T_LPAREN)) ++parcount; else if (tk.is(T_RPAREN)) --parcount; else if (! parcount && tk.is(T_COMMA)) ++argnr; } return true; }
bool GolangTextLexer::isInCommentHelper(const QTextCursor &cursor, Token *retToken) const { LanguageFeatures features; features.golangEnable = true; SimpleLexer tokenize; tokenize.setLanguageFeatures(features); const int prevState = BackwardsScanner::previousBlockState(cursor.block()) & 0xFF; const QList<Token> tokens = tokenize(cursor.block().text(), prevState); const unsigned pos = cursor.selectionEnd() - cursor.block().position(); if (tokens.isEmpty() || pos < tokens.first().begin()) return prevState > 0; if (pos >= tokens.last().end()) { const Token tk = tokens.last(); if (tk.is(T_CPP_COMMENT) || tk.is(T_CPP_DOXY_COMMENT)) return true; if (tk.is(T_RAW_STRING_LITERAL) && (cursor.block().userState() & 0xFF) ) { if (retToken) *retToken = tk; return false; } if (tk.isStringLiteral() || tk.isCharLiteral()) { if (retToken) *retToken = tk; return false; } return tk.isComment() && (cursor.block().userState() & 0xFF); } Token tk = tokenAtPosition(tokens, pos); if (retToken) *retToken = tk; return tk.isComment(); }
SimpleToken TokenUnderCursor::operator()(const QTextCursor &cursor, QTextBlock *b) { SimpleLexer tokenize; tokenize.setObjCEnabled(true); tokenize.setSkipComments(false); QTextBlock block = cursor.block(); int column = cursor.position() - cursor.block().position(); _text = block.text(); _tokens = tokenize(_text, BackwardsScanner::previousBlockState(block)); for (int index = _tokens.size() - 1; index != -1; --index) { const SimpleToken &tk = _tokens.at(index); if (tk.position() < column) { if (b) *b = block; return tk; } } return SimpleToken(); }
{ const int previousBlockState_ = previousBlockState(); int lexerState = 0, initialBraceDepth = 0; if (previousBlockState_ != -1) { lexerState = previousBlockState_ & 0xff; initialBraceDepth = previousBlockState_ >> 8; } int braceDepth = initialBraceDepth; // FIXME: Check defaults or get from document. LanguageFeatures features; features.cxx11Enabled = true; features.c99Enabled = true; SimpleLexer tokenize; tokenize.setLanguageFeatures(features); int initialLexerState = lexerState; const QList<Token> tokens = tokenize(text, initialLexerState); lexerState = tokenize.state(); // refresh lexer state initialLexerState &= ~0x80; // discard newline expected bit int foldingIndent = initialBraceDepth; if (TextBlockUserData *userData = BaseTextDocumentLayout::testUserData(currentBlock())) { userData->setFoldingIndent(0); userData->setFoldingStartIncluded(false); userData->setFoldingEndIncluded(false); } if (tokens.isEmpty()) {
void CppCompletionAssistProcessor::startOfOperator(QTextDocument *textDocument, int positionInDocument, unsigned *kind, int &start, const CPlusPlus::LanguageFeatures &languageFeatures, bool adjustForQt5SignalSlotCompletion, DotAtIncludeCompletionHandler dotAtIncludeCompletionHandler) { if (start != positionInDocument) { QTextCursor tc(textDocument); tc.setPosition(positionInDocument); // Include completion: make sure the quote character is the first one on the line if (*kind == T_STRING_LITERAL) { QTextCursor s = tc; s.movePosition(QTextCursor::StartOfLine, QTextCursor::KeepAnchor); QString sel = s.selectedText(); if (sel.indexOf(QLatin1Char('"')) < sel.length() - 1) { *kind = T_EOF_SYMBOL; start = positionInDocument; } } if (*kind == T_COMMA) { ExpressionUnderCursor expressionUnderCursor(languageFeatures); if (expressionUnderCursor.startOfFunctionCall(tc) == -1) { *kind = T_EOF_SYMBOL; start = positionInDocument; } } SimpleLexer tokenize; tokenize.setLanguageFeatures(languageFeatures); tokenize.setSkipComments(false); const Tokens &tokens = tokenize(tc.block().text(), BackwardsScanner::previousBlockState(tc.block())); const int tokenIdx = SimpleLexer::tokenBefore(tokens, qMax(0, tc.positionInBlock() - 1)); // get the token at the left of the cursor const Token tk = (tokenIdx == -1) ? Token() : tokens.at(tokenIdx); const QChar characterBeforePositionInDocument = textDocument->characterAt(positionInDocument - 1); if (adjustForQt5SignalSlotCompletion && *kind == T_AMPER && tokenIdx > 0) { const Token &previousToken = tokens.at(tokenIdx - 1); if (previousToken.kind() == T_COMMA) start = positionInDocument - (tk.utf16charOffset - previousToken.utf16charOffset) - 1; } else if (*kind == T_DOXY_COMMENT && !(tk.is(T_DOXY_COMMENT) || tk.is(T_CPP_DOXY_COMMENT))) { *kind = T_EOF_SYMBOL; start = positionInDocument; // Do not complete in comments, except in doxygen comments for doxygen commands. // Do not complete in strings, except it is for include completion. } else if (tk.is(T_COMMENT) || tk.is(T_CPP_COMMENT) || ((tk.is(T_CPP_DOXY_COMMENT) || tk.is(T_DOXY_COMMENT)) && !isDoxygenTagCompletionCharacter(characterBeforePositionInDocument)) || (tk.isLiteral() && (*kind != T_STRING_LITERAL && *kind != T_ANGLE_STRING_LITERAL && *kind != T_SLASH && *kind != T_DOT))) { *kind = T_EOF_SYMBOL; start = positionInDocument; // Include completion: can be triggered by slash, but only in a string } else if (*kind == T_SLASH && (tk.isNot(T_STRING_LITERAL) && tk.isNot(T_ANGLE_STRING_LITERAL))) { *kind = T_EOF_SYMBOL; start = positionInDocument; } else if (*kind == T_LPAREN) { if (tokenIdx > 0) { const Token &previousToken = tokens.at(tokenIdx - 1); // look at the token at the left of T_LPAREN switch (previousToken.kind()) { case T_IDENTIFIER: case T_GREATER: case T_SIGNAL: case T_SLOT: break; // good default: // that's a bad token :) *kind = T_EOF_SYMBOL; start = positionInDocument; } } } // Check for include preprocessor directive else if (*kind == T_STRING_LITERAL || *kind == T_ANGLE_STRING_LITERAL || *kind == T_SLASH || (*kind == T_DOT && (tk.is(T_STRING_LITERAL) || tk.is(T_ANGLE_STRING_LITERAL)))) { bool include = false; if (tokens.size() >= 3) { if (tokens.at(0).is(T_POUND) && tokens.at(1).is(T_IDENTIFIER) && (tokens.at(2).is(T_STRING_LITERAL) || tokens.at(2).is(T_ANGLE_STRING_LITERAL))) { const Token &directiveToken = tokens.at(1); QString directive = tc.block().text().mid(directiveToken.utf16charsBegin(), directiveToken.utf16chars()); if (directive == QLatin1String("include") || directive == QLatin1String("include_next") || directive == QLatin1String("import")) { include = true; } } } if (!include) { *kind = T_EOF_SYMBOL; start = positionInDocument; } else if (*kind == T_DOT && dotAtIncludeCompletionHandler){ dotAtIncludeCompletionHandler(start, kind); } } } }
TextEditor::SyntaxHighlighter(document) { } void CppHighlighter::highlightBlock(const QString &text) { const int previousState = previousBlockState(); int state = 0, initialBraceDepth = 0; if (previousState != -1) { state = previousState & 0xff; initialBraceDepth = previousState >> 8; } int braceDepth = initialBraceDepth; SimpleLexer tokenize; tokenize.setQtMocRunEnabled(false); tokenize.setObjCEnabled(false); tokenize.setCxx0xEnabled(true); int initialState = state; const QList<Token> tokens = tokenize(text, initialState); state = tokenize.state(); // refresh the state int foldingIndent = initialBraceDepth; if (TextBlockUserData *userData = BaseTextDocumentLayout::testUserData(currentBlock())) { userData->setFoldingIndent(0); userData->setFoldingStartIncluded(false); userData->setFoldingEndIncluded(false); }