diff options
author | David Schulz <david.schulz@theqtcompany.com> | 2016-04-15 09:35:20 +0200 |
---|---|---|
committer | David Schulz <david.schulz@theqtcompany.com> | 2016-05-20 12:35:10 +0000 |
commit | b482a6158c91b4f7dd89d2e4adcae60e922df08c (patch) | |
tree | fbb08495e7c2cdfaea743119931544049008d7be /src/libs/cplusplus/MatchingText.cpp | |
parent | 61be2397955fe29e328b9fc4ac1783390604d6e4 (diff) | |
download | qt-creator-b482a6158c91b4f7dd89d2e4adcae60e922df08c.tar.gz |
Remove duplicated code from c++ and glsl completer.
Change-Id: Ibda04771fceffef6344f6a6128d77dd8192379ca
Reviewed-by: Nikolai Kosjar <nikolai.kosjar@qt.io>
Diffstat (limited to 'src/libs/cplusplus/MatchingText.cpp')
-rw-r--r-- | src/libs/cplusplus/MatchingText.cpp | 118 |
1 files changed, 110 insertions, 8 deletions
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp index 16264894d9..787d98b99f 100644 --- a/src/libs/cplusplus/MatchingText.cpp +++ b/src/libs/cplusplus/MatchingText.cpp @@ -125,10 +125,52 @@ static int countSkippedChars(const QString blockText, const QString &textToProce return skippedChars; } -bool MatchingText::shouldInsertMatchingText(const QTextCursor &tc) +static const Token tokenAtPosition(const Tokens &tokens, const unsigned pos) { - QTextDocument *doc = tc.document(); - return shouldInsertMatchingText(doc->characterAt(tc.selectionEnd())); + for (int i = tokens.size() - 1; i >= 0; --i) { + const Token tk = tokens.at(i); + if (pos >= tk.utf16charsBegin() && pos < tk.utf16charsEnd()) + return tk; + } + return Token(); +} + +bool MatchingText::contextAllowsAutoParentheses(const QTextCursor &cursor, + const QString &textToInsert) +{ + QChar ch; + + if (!textToInsert.isEmpty()) + ch = textToInsert.at(0); + + if (!shouldInsertMatchingText(cursor) && ch != QLatin1Char('\'') && ch != QLatin1Char('"')) + return false; + else if (isInCommentHelper(cursor)) + return false; + + return true; +} + +bool MatchingText::contextAllowsElectricCharacters(const QTextCursor &cursor) +{ + Token token; + + if (isInCommentHelper(cursor, &token)) + return false; + + if (token.isStringLiteral() || token.isCharLiteral()) { + const unsigned pos = cursor.selectionEnd() - cursor.block().position(); + if (pos <= token.utf16charsEnd()) + return false; + } + + return true; +} + +bool MatchingText::shouldInsertMatchingText(const QTextCursor &cursor) +{ + QTextDocument *doc = cursor.document(); + return shouldInsertMatchingText(doc->characterAt(cursor.selectionEnd())); } bool MatchingText::shouldInsertMatchingText(QChar lookAhead) @@ -147,6 +189,66 @@ bool MatchingText::shouldInsertMatchingText(QChar lookAhead) } // switch } +static Tokens getTokens(const QTextCursor &cursor, int &prevState) +{ + LanguageFeatures features; + features.qtEnabled = false; + features.qtKeywordsEnabled = false; + features.qtMocRunEnabled = false; + features.cxx11Enabled = true; + features.c99Enabled = true; + + SimpleLexer tokenize; + tokenize.setLanguageFeatures(features); + + prevState = BackwardsScanner::previousBlockState(cursor.block()) & 0xFF; + return tokenize(cursor.block().text(), prevState); +} + +bool MatchingText::isInCommentHelper(const QTextCursor &cursor, Token *retToken) +{ + int prevState = 0; + const Tokens tokens = getTokens(cursor, prevState); + + const unsigned pos = cursor.selectionEnd() - cursor.block().position(); + + if (tokens.isEmpty() || pos < tokens.first().utf16charsBegin()) + return prevState > 0; + + if (pos >= tokens.last().utf16charsEnd()) { + const Token tk = tokens.last(); + if (retToken) + *retToken = tk; + 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 MatchingText::isInStringHelper(const QTextCursor &cursor) +{ + int prevState = 0; + const Tokens tokens = getTokens(cursor, 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); + return tk.isStringLiteral() && pos > tk.utf16charsBegin(); +} + QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QString &textToProcess, QChar la, int *skippedChars) { @@ -211,15 +313,15 @@ static bool shouldInsertNewline(const QTextCursor &tc) return newlines <= 1 && doc->characterAt(pos) != QLatin1Char('}'); } -QString MatchingText::insertParagraphSeparator(const QTextCursor &tc) +QString MatchingText::insertParagraphSeparator(const QTextCursor &cursor) { - BackwardsScanner tk(tc, LanguageFeatures::defaultFeatures(), MAX_NUM_LINES); + BackwardsScanner tk(cursor, LanguageFeatures::defaultFeatures(), MAX_NUM_LINES); int index = tk.startToken(); if (tk[index - 1].isNot(T_LBRACE)) return QString(); // nothing to do. - const QString textBlock = tc.block().text().mid(tc.positionInBlock()).trimmed(); + const QString textBlock = cursor.block().text().mid(cursor.positionInBlock()).trimmed(); if (! textBlock.isEmpty()) return QString(); @@ -244,7 +346,7 @@ QString MatchingText::insertParagraphSeparator(const QTextCursor &tc) // found a class key. QString str = QLatin1String("};"); - if (shouldInsertNewline(tc)) + if (shouldInsertNewline(cursor)) str += QLatin1Char('\n'); return str; @@ -310,7 +412,7 @@ QString MatchingText::insertParagraphSeparator(const QTextCursor &tc) // if we reached this point there is a good chance that we are parsing a function definition QString str = QLatin1String("}"); - if (shouldInsertNewline(tc)) + if (shouldInsertNewline(cursor)) str += QLatin1Char('\n'); return str; |