diff options
author | Roberto Raggi <roberto.raggi@nokia.com> | 2009-09-17 17:57:17 +0200 |
---|---|---|
committer | Roberto Raggi <roberto.raggi@nokia.com> | 2009-09-17 17:58:00 +0200 |
commit | 82b80b9e3946083ec0a9f2cb8415b32503790136 (patch) | |
tree | f0bad94a1185408c70e7f8a039855d15edf7996d /src/libs/cplusplus | |
parent | 245dfe51c622a77b69ee9f39e2b30d03443f3117 (diff) | |
download | qt-creator-82b80b9e3946083ec0a9f2cb8415b32503790136.tar.gz |
Automagically insert matching characters.
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r-- | src/libs/cplusplus/BackwardsScanner.cpp | 6 | ||||
-rw-r--r-- | src/libs/cplusplus/BackwardsScanner.h | 4 | ||||
-rw-r--r-- | src/libs/cplusplus/ExpressionUnderCursor.cpp | 4 | ||||
-rw-r--r-- | src/libs/cplusplus/ExpressionUnderCursor.h | 2 | ||||
-rw-r--r-- | src/libs/cplusplus/MatchingText.cpp | 109 | ||||
-rw-r--r-- | src/libs/cplusplus/MatchingText.h | 1 |
6 files changed, 119 insertions, 7 deletions
diff --git a/src/libs/cplusplus/BackwardsScanner.cpp b/src/libs/cplusplus/BackwardsScanner.cpp index 251fa9bd19..07c4688757 100644 --- a/src/libs/cplusplus/BackwardsScanner.cpp +++ b/src/libs/cplusplus/BackwardsScanner.cpp @@ -32,7 +32,7 @@ using namespace CPlusPlus; -BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, int maxBlockCount) +BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, const QString &suffix, int maxBlockCount) : _offset(0) , _blocksTokenized(0) , _block(cursor.block()) @@ -40,6 +40,10 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, int maxBlockCount) { _tokenize.setSkipComments(true); _text = _block.text().left(cursor.position() - cursor.block().position()); + + if (! suffix.isEmpty()) + _text += suffix; + _tokens.append(_tokenize(_text, previousBlockState(_block))); } diff --git a/src/libs/cplusplus/BackwardsScanner.h b/src/libs/cplusplus/BackwardsScanner.h index 925527cbcf..7b8e3b6e71 100644 --- a/src/libs/cplusplus/BackwardsScanner.h +++ b/src/libs/cplusplus/BackwardsScanner.h @@ -41,7 +41,9 @@ class CPLUSPLUS_EXPORT BackwardsScanner enum { MAX_BLOCK_COUNT = 10 }; public: - BackwardsScanner(const QTextCursor &cursor, int maxBlockCount = MAX_BLOCK_COUNT); + BackwardsScanner(const QTextCursor &cursor, + const QString &suffix = QString(), + int maxBlockCount = MAX_BLOCK_COUNT); int state() const; int startToken() const; diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp index 622b420048..106e3040b1 100644 --- a/src/libs/cplusplus/ExpressionUnderCursor.cpp +++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp @@ -153,10 +153,8 @@ QString ExpressionUnderCursor::operator()(const QTextCursor &cursor) return scanner.text(i, initialSize); } -int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor) +int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor) const { - QString text; - BackwardsScanner scanner(cursor); int index = scanner.startToken(); diff --git a/src/libs/cplusplus/ExpressionUnderCursor.h b/src/libs/cplusplus/ExpressionUnderCursor.h index 2c5ca12bcb..35be67214d 100644 --- a/src/libs/cplusplus/ExpressionUnderCursor.h +++ b/src/libs/cplusplus/ExpressionUnderCursor.h @@ -51,7 +51,7 @@ public: ~ExpressionUnderCursor(); QString operator()(const QTextCursor &cursor); - int startOfFunctionCall(const QTextCursor &cursor); + int startOfFunctionCall(const QTextCursor &cursor) const; private: int startOfExpression(BackwardsScanner &tk, int index); diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp index 14449584d1..86a31fc9ec 100644 --- a/src/libs/cplusplus/MatchingText.cpp +++ b/src/libs/cplusplus/MatchingText.cpp @@ -34,17 +34,124 @@ using namespace CPlusPlus; +enum { MAX_NUM_LINES = 400 }; + +static bool maybeOverrideChar(const QChar &ch) +{ + if (ch == QLatin1Char(')')) return true; + else if (ch == QLatin1Char(']')) return true; + else if (ch == QLatin1Char('"')) return true; + else if (ch == QLatin1Char('\'')) return true; + else return false; +} + +static bool isCompleteStringLiteral(const BackwardsScanner &tk, int index, int startToken) +{ + const QStringRef text = tk.textRef(index, startToken); + + if (text.length() < 2) + return false; + + else if (text.at(text.length() - 1) == QLatin1Char('"')) + return text.at(text.length() - 2) != QLatin1Char('\\'); // ### not exactly. + + return false; +} + +static bool isCompleteCharLiteral(const BackwardsScanner &tk, int index, int startToken) +{ + const QStringRef text = tk.textRef(index, startToken); + + if (text.length() < 2) + return false; + + else if (text.at(text.length() - 1) == QLatin1Char('\'')) + return text.at(text.length() - 2) != QLatin1Char('\\'); // ### not exactly. + + return false; +} + MatchingText::MatchingText() { } +QString MatchingText::insertMatchingBrace(const QTextCursor &cursor, const QString &textToProcess, int *skippedChars) const +{ + *skippedChars = 0; + + QTextCursor tc = cursor; + QString text = textToProcess; + + const QString blockText = tc.block().text().mid(tc.columnNumber()); + const int length = qMin(blockText.length(), textToProcess.length()); + + for (int i = 0; i < length; ++i) { + const QChar ch1 = blockText.at(i); + const QChar ch2 = textToProcess.at(i); + + if (ch1 != ch2) + break; + else if (! maybeOverrideChar(ch1)) + break; + + ++*skippedChars; + } + + if (*skippedChars != 0) { + tc.movePosition(QTextCursor::NextCharacter, QTextCursor::MoveAnchor, *skippedChars); + text = textToProcess.mid(*skippedChars); + } + + if (text.isEmpty()) + return QString(); + + BackwardsScanner tk(tc, textToProcess.left(*skippedChars), MAX_NUM_LINES); + const int startToken = tk.startToken(); + int index = startToken; + + const SimpleToken &token = tk[index - 1]; + + if (text.at(0) == QLatin1Char('"') && (token.is(T_STRING_LITERAL) || token.is(T_WIDE_STRING_LITERAL))) { + if (text.length() != 1) + qWarning() << Q_FUNC_INFO << "handle event compression"; + + if (isCompleteStringLiteral(tk, index - 1, startToken)) + return QLatin1String("\""); + + return QString(); + } else if (text.at(0) == QLatin1Char('\'') && (token.is(T_CHAR_LITERAL) || token.is(T_WIDE_CHAR_LITERAL))) { + if (text.length() != 1) + qWarning() << Q_FUNC_INFO << "handle event compression"; + + if (isCompleteCharLiteral(tk, index - 1, startToken)) + return QLatin1String("'"); + + return QString(); + } + + QString result; + + foreach (const QChar &ch, text) { + if (ch == QLatin1Char('(')) result += ')'; + else if (ch == QLatin1Char('[')) result += ']'; + else if (ch == QLatin1Char('"')) result += '"'; + else if (ch == QLatin1Char('\'')) result += '\''; + } + + return result; +} + QString MatchingText::insertParagraphSeparator(const QTextCursor &tc) const { - BackwardsScanner tk(tc, 400); + BackwardsScanner tk(tc, QString(), 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.columnNumber()).trimmed(); + if (! textBlock.isEmpty()) + return QString(); + --index; // consume the `{' const SimpleToken &token = tk[index - 1]; diff --git a/src/libs/cplusplus/MatchingText.h b/src/libs/cplusplus/MatchingText.h index 3f7ef2cebf..f964c42454 100644 --- a/src/libs/cplusplus/MatchingText.h +++ b/src/libs/cplusplus/MatchingText.h @@ -41,6 +41,7 @@ class CPLUSPLUS_EXPORT MatchingText public: MatchingText(); + QString insertMatchingBrace(const QTextCursor &tc, const QString &text, int *skippedChars) const; QString insertParagraphSeparator(const QTextCursor &tc) const; }; |