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 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(); }
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(); }
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); } } } }