Beispiel #1
0
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 &macro, 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;
}
Beispiel #7
0
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);
            }
        }
    }
}
Beispiel #11
0
    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);
    }