summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r--src/libs/cplusplus/BackwardsScanner.cpp67
-rw-r--r--src/libs/cplusplus/BackwardsScanner.h18
-rw-r--r--src/libs/cplusplus/ExpressionUnderCursor.cpp54
-rw-r--r--src/libs/cplusplus/ExpressionUnderCursor.h1
-rw-r--r--src/libs/cplusplus/MatchingText.cpp131
-rw-r--r--src/libs/cplusplus/MatchingText.h49
-rw-r--r--src/libs/cplusplus/cplusplus-lib.pri2
7 files changed, 266 insertions, 56 deletions
diff --git a/src/libs/cplusplus/BackwardsScanner.cpp b/src/libs/cplusplus/BackwardsScanner.cpp
index df2916a6d7..251fa9bd19 100644
--- a/src/libs/cplusplus/BackwardsScanner.cpp
+++ b/src/libs/cplusplus/BackwardsScanner.cpp
@@ -27,6 +27,7 @@
**
**************************************************************************/
#include "BackwardsScanner.h"
+#include <Token.h>
#include <QtGui/QTextCursor>
using namespace CPlusPlus;
@@ -42,10 +43,16 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, int maxBlockCount)
_tokens.append(_tokenize(_text, previousBlockState(_block)));
}
-QList<SimpleToken> BackwardsScanner::tokens() const
+int BackwardsScanner::state() const
+{ return _tokenize.state(); }
+
+const QList<SimpleToken> &BackwardsScanner::tokens() const
{ return _tokens; }
-const SimpleToken &BackwardsScanner::operator[](int i)
+const SimpleToken &BackwardsScanner::operator[](int i) const
+{ return const_cast<BackwardsScanner *>(this)->fetchToken(i); }
+
+const SimpleToken &BackwardsScanner::fetchToken(int i)
{
while (_offset + i < 0) {
_block = _block.previous();
@@ -77,10 +84,13 @@ const SimpleToken &BackwardsScanner::operator[](int i)
return _tokens.at(_offset + i);
}
+int BackwardsScanner::startToken() const
+{ return _tokens.size(); }
+
int BackwardsScanner::startPosition() const
{ return _block.position(); }
-const QString &BackwardsScanner::text() const
+QString BackwardsScanner::text() const
{ return _text; }
QString BackwardsScanner::text(int begin, int end) const
@@ -90,7 +100,14 @@ QString BackwardsScanner::text(int begin, int end) const
return _text.mid(firstToken.begin(), lastToken.end() - firstToken.begin());
}
-int BackwardsScanner::previousBlockState(const QTextBlock &block)
+QStringRef BackwardsScanner::textRef(int begin, int end) const
+{
+ const SimpleToken &firstToken = _tokens.at(begin + _offset);
+ const SimpleToken &lastToken = _tokens.at(end + _offset - 1);
+ return _text.midRef(firstToken.begin(), lastToken.end() - firstToken.begin());
+}
+
+int BackwardsScanner::previousBlockState(const QTextBlock &block) const
{
const QTextBlock prevBlock = block.previous();
@@ -103,3 +120,45 @@ int BackwardsScanner::previousBlockState(const QTextBlock &block)
return 0;
}
+
+int BackwardsScanner::startOfMatchingBrace(int index) const
+{
+ const BackwardsScanner &tk = *this;
+
+ if (tk[index - 1].is(T_RPAREN)) {
+ int i = index - 1;
+ int count = 0;
+ do {
+ if (tk[i].is(T_LPAREN)) {
+ if (! ++count)
+ return i;
+ } else if (tk[i].is(T_RPAREN))
+ --count;
+ --i;
+ } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
+ } else if (tk[index - 1].is(T_RBRACKET)) {
+ int i = index - 1;
+ int count = 0;
+ do {
+ if (tk[i].is(T_LBRACKET)) {
+ if (! ++count)
+ return i;
+ } else if (tk[i].is(T_RBRACKET))
+ --count;
+ --i;
+ } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
+ } else if (tk[index - 1].is(T_GREATER)) {
+ int i = index - 1;
+ int count = 0;
+ do {
+ if (tk[i].is(T_LESS)) {
+ if (! ++count)
+ return i;
+ } else if (tk[i].is(T_GREATER))
+ --count;
+ --i;
+ } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
+ }
+
+ return index;
+}
diff --git a/src/libs/cplusplus/BackwardsScanner.h b/src/libs/cplusplus/BackwardsScanner.h
index c38060040b..925527cbcf 100644
--- a/src/libs/cplusplus/BackwardsScanner.h
+++ b/src/libs/cplusplus/BackwardsScanner.h
@@ -43,13 +43,23 @@ class CPLUSPLUS_EXPORT BackwardsScanner
public:
BackwardsScanner(const QTextCursor &cursor, int maxBlockCount = MAX_BLOCK_COUNT);
- QList<SimpleToken> tokens() const;
+ int state() const;
+ int startToken() const;
+
int startPosition() const;
- const QString &text() const;
- const SimpleToken &operator[](int i);
+ QString text() const;
QString text(int begin, int end) const;
- int previousBlockState(const QTextBlock &block);
+ QStringRef textRef(int begin, int end) const;
+
+ const SimpleToken &operator[](int i) const;
+
+ int startOfMatchingBrace(int index) const;
+ int previousBlockState(const QTextBlock &block) const;
+
+private:
+ const SimpleToken &fetchToken(int i);
+ const QList<SimpleToken> &tokens() const;
private:
QList<SimpleToken> _tokens;
diff --git a/src/libs/cplusplus/ExpressionUnderCursor.cpp b/src/libs/cplusplus/ExpressionUnderCursor.cpp
index 1cc546de22..622b420048 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.cpp
+++ b/src/libs/cplusplus/ExpressionUnderCursor.cpp
@@ -43,46 +43,6 @@ ExpressionUnderCursor::ExpressionUnderCursor()
ExpressionUnderCursor::~ExpressionUnderCursor()
{ }
-int ExpressionUnderCursor::startOfMatchingBrace(BackwardsScanner &tk, int index)
-{
- if (tk[index - 1].is(T_RPAREN)) {
- int i = index - 1;
- int count = 0;
- do {
- if (tk[i].is(T_LPAREN)) {
- if (! ++count)
- return i;
- } else if (tk[i].is(T_RPAREN))
- --count;
- --i;
- } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
- } else if (tk[index - 1].is(T_RBRACKET)) {
- int i = index - 1;
- int count = 0;
- do {
- if (tk[i].is(T_LBRACKET)) {
- if (! ++count)
- return i;
- } else if (tk[i].is(T_RBRACKET))
- --count;
- --i;
- } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
- } else if (tk[index - 1].is(T_GREATER)) {
- int i = index - 1;
- int count = 0;
- do {
- if (tk[i].is(T_LESS)) {
- if (! ++count)
- return i;
- } else if (tk[i].is(T_GREATER))
- --count;
- --i;
- } while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
- }
-
- return index;
-}
-
int ExpressionUnderCursor::startOfExpression(BackwardsScanner &tk, int index)
{
// tk is a reference to a const QList. So, don't worry about [] access.
@@ -122,10 +82,10 @@ int ExpressionUnderCursor::startOfExpression(BackwardsScanner &tk, int index)
}
return index - 1;
} else if (tk[index - 1].is(T_RPAREN)) {
- int rparenIndex = startOfMatchingBrace(tk, index);
+ int rparenIndex = tk.startOfMatchingBrace(index);
if (rparenIndex != index) {
if (tk[rparenIndex - 1].is(T_GREATER)) {
- int lessIndex = startOfMatchingBrace(tk, rparenIndex);
+ int lessIndex = tk.startOfMatchingBrace(rparenIndex);
if (lessIndex != rparenIndex - 1) {
if (tk[lessIndex - 1].is(T_DYNAMIC_CAST) ||
tk[lessIndex - 1].is(T_STATIC_CAST) ||
@@ -144,13 +104,13 @@ int ExpressionUnderCursor::startOfExpression(BackwardsScanner &tk, int index)
}
return index;
} else if (tk[index - 1].is(T_RBRACKET)) {
- int rbracketIndex = startOfMatchingBrace(tk, index);
+ int rbracketIndex = tk.startOfMatchingBrace(index);
if (rbracketIndex != index)
return startOfExpression(tk, rbracketIndex);
return index;
} else if (tk[index - 1].is(T_COLON_COLON)) {
if (tk[index - 2].is(T_GREATER)) { // ### not exactly
- int lessIndex = startOfMatchingBrace(tk, index - 1);
+ int lessIndex = tk.startOfMatchingBrace(index - 1);
if (lessIndex != index - 1)
return startOfExpression(tk, lessIndex);
return index - 1;
@@ -185,7 +145,7 @@ QString ExpressionUnderCursor::operator()(const QTextCursor &cursor)
_jumpedComma = false;
- const int initialSize = scanner.tokens().size();
+ const int initialSize = scanner.startToken();
const int i = startOfExpression(scanner, initialSize);
if (i == initialSize)
return QString();
@@ -199,7 +159,7 @@ int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor)
BackwardsScanner scanner(cursor);
- int index = scanner.tokens().size();
+ int index = scanner.startToken();
forever {
const SimpleToken &tk = scanner[index - 1];
@@ -209,7 +169,7 @@ int ExpressionUnderCursor::startOfFunctionCall(const QTextCursor &cursor)
else if (tk.is(T_LPAREN))
return scanner.startPosition() + tk.position();
else if (tk.is(T_RPAREN)) {
- int matchingBrace = startOfMatchingBrace(scanner, index);
+ int matchingBrace = scanner.startOfMatchingBrace(index);
if (matchingBrace == index) // If no matching brace found
return -1;
diff --git a/src/libs/cplusplus/ExpressionUnderCursor.h b/src/libs/cplusplus/ExpressionUnderCursor.h
index 50404d2d5d..2c5ca12bcb 100644
--- a/src/libs/cplusplus/ExpressionUnderCursor.h
+++ b/src/libs/cplusplus/ExpressionUnderCursor.h
@@ -54,7 +54,6 @@ public:
int startOfFunctionCall(const QTextCursor &cursor);
private:
- int startOfMatchingBrace(BackwardsScanner &tk, int index);
int startOfExpression(BackwardsScanner &tk, int index);
int previousBlockState(const QTextBlock &block);
bool isAccessToken(const SimpleToken &tk);
diff --git a/src/libs/cplusplus/MatchingText.cpp b/src/libs/cplusplus/MatchingText.cpp
new file mode 100644
index 0000000000..14449584d1
--- /dev/null
+++ b/src/libs/cplusplus/MatchingText.cpp
@@ -0,0 +1,131 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+#include "MatchingText.h"
+#include "BackwardsScanner.h"
+
+#include <Token.h>
+#include <QtDebug>
+
+using namespace CPlusPlus;
+
+MatchingText::MatchingText()
+{ }
+
+QString MatchingText::insertParagraphSeparator(const QTextCursor &tc) const
+{
+ BackwardsScanner tk(tc, 400);
+ int index = tk.startToken();
+
+ if (tk[index - 1].isNot(T_LBRACE))
+ return QString(); // nothing to do.
+
+ --index; // consume the `{'
+
+ const SimpleToken &token = tk[index - 1];
+
+ if (token.is(T_STRING_LITERAL) && tk[index - 2].is(T_EXTERN)) {
+ // recognized extern "C"
+ return QLatin1String("}");
+
+ } else if (token.is(T_IDENTIFIER)) {
+ int i = index - 1;
+
+ forever {
+ const SimpleToken &current = tk[i - 1];
+
+ if (current.is(T_EOF_SYMBOL))
+ break;
+
+ else if (current.is(T_CLASS) || current.is(T_STRUCT) || current.is(T_UNION))
+ return QLatin1String("};"); // found a class key.
+
+ else if (current.is(T_NAMESPACE))
+ return QLatin1String("}"); // found a namespace declaration
+
+ else if (current.is(T_SEMICOLON))
+ break; // found the `;' sync token
+
+ else if (current.is(T_LBRACE) || current.is(T_RBRACE))
+ break; // braces are considered sync tokens
+
+ else if (current.is(T_LPAREN) || current.is(T_RPAREN))
+ break; // sync token
+
+ else if (current.is(T_LBRACKET) || current.is(T_RBRACKET))
+ break; // sync token
+
+ --i;
+ }
+ }
+
+ if (token.is(T_NAMESPACE)) {
+ // anonymous namespace
+ return QLatin1String("}");
+
+ } else if (token.is(T_CLASS) || token.is(T_STRUCT) || token.is(T_UNION)) {
+ if (tk[index - 2].is(T_TYPEDEF)) {
+ // recognized:
+ // typedef struct {
+ //
+ // in this case we don't want to insert the extra semicolon+newline.
+ return QLatin1String("}");
+ }
+
+ // anonymous class
+ return QLatin1String("};");
+
+ } else if (token.is(T_RPAREN)) {
+ // search the matching brace.
+ const int lparenIndex = tk.startOfMatchingBrace(index);
+
+ if (lparenIndex == index) {
+ // found an unmatched brace. We don't really know to do in this case.
+ return QString();
+ }
+
+ // look at the token before the matched brace
+ const SimpleToken &tokenBeforeBrace = tk[lparenIndex - 1];
+
+ if (tokenBeforeBrace.is(T_IF)) {
+ // recognized an if statement
+ return QLatin1String("}");
+
+ } else if (tokenBeforeBrace.is(T_FOR) || tokenBeforeBrace.is(T_WHILE)) {
+ // recognized a for-like statement
+ return QLatin1String("}");
+
+ }
+
+ // if we reached this point there is a good chance that we are parsing a function definition
+ return QLatin1String("}");
+ }
+
+ // match the block
+ return QLatin1String("}");
+}
diff --git a/src/libs/cplusplus/MatchingText.h b/src/libs/cplusplus/MatchingText.h
new file mode 100644
index 0000000000..3f7ef2cebf
--- /dev/null
+++ b/src/libs/cplusplus/MatchingText.h
@@ -0,0 +1,49 @@
+/**************************************************************************
+**
+** This file is part of Qt Creator
+**
+** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
+**
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** Commercial Usage
+**
+** Licensees holding valid Qt Commercial licenses may use this file in
+** accordance with the Qt Commercial License Agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and Nokia.
+**
+** GNU Lesser General Public License Usage
+**
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file. Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** If you are unsure which license is appropriate for your use, please
+** contact the sales department at http://qt.nokia.com/contact.
+**
+**************************************************************************/
+#ifndef MATCHINGTEXT_H
+#define MATCHINGTEXT_H
+
+#include <CPlusPlusForwardDeclarations.h>
+#include <QtGui/QTextCursor>
+
+namespace CPlusPlus {
+
+class BackwardsScanner;
+
+class CPLUSPLUS_EXPORT MatchingText
+{
+public:
+ MatchingText();
+
+ QString insertParagraphSeparator(const QTextCursor &tc) const;
+};
+
+} // end of namespace CPlusPlus
+
+#endif // MATCHINGTEXT_H
diff --git a/src/libs/cplusplus/cplusplus-lib.pri b/src/libs/cplusplus/cplusplus-lib.pri
index 1cc2bd08e1..34caa520a8 100644
--- a/src/libs/cplusplus/cplusplus-lib.pri
+++ b/src/libs/cplusplus/cplusplus-lib.pri
@@ -9,6 +9,7 @@ HEADERS += \
$$PWD/ExpressionUnderCursor.h \
$$PWD/TokenUnderCursor.h \
$$PWD/BackwardsScanner.h \
+ $$PWD/MatchingText.h \
$$PWD/OverviewModel.h
SOURCES += \
@@ -16,6 +17,7 @@ SOURCES += \
$$PWD/ExpressionUnderCursor.cpp \
$$PWD/TokenUnderCursor.cpp \
$$PWD/BackwardsScanner.cpp \
+ $$PWD/MatchingText.cpp \
$$PWD/OverviewModel.cpp
}