summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus
diff options
context:
space:
mode:
authorRoberto Raggi <roberto.raggi@nokia.com>2009-09-17 17:57:17 +0200
committerRoberto Raggi <roberto.raggi@nokia.com>2009-09-17 17:58:00 +0200
commit82b80b9e3946083ec0a9f2cb8415b32503790136 (patch)
treef0bad94a1185408c70e7f8a039855d15edf7996d /src/libs/cplusplus
parent245dfe51c622a77b69ee9f39e2b30d03443f3117 (diff)
downloadqt-creator-82b80b9e3946083ec0a9f2cb8415b32503790136.tar.gz
Automagically insert matching characters.
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r--src/libs/cplusplus/BackwardsScanner.cpp6
-rw-r--r--src/libs/cplusplus/BackwardsScanner.h4
-rw-r--r--src/libs/cplusplus/ExpressionUnderCursor.cpp4
-rw-r--r--src/libs/cplusplus/ExpressionUnderCursor.h2
-rw-r--r--src/libs/cplusplus/MatchingText.cpp109
-rw-r--r--src/libs/cplusplus/MatchingText.h1
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;
};