summaryrefslogtreecommitdiff
path: root/src/libs/cplusplus
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/cplusplus')
-rw-r--r--src/libs/cplusplus/BackwardsScanner.cpp108
-rw-r--r--src/libs/cplusplus/BackwardsScanner.h10
-rw-r--r--src/libs/cplusplus/SimpleLexer.cpp36
-rw-r--r--src/libs/cplusplus/SimpleLexer.h42
4 files changed, 166 insertions, 30 deletions
diff --git a/src/libs/cplusplus/BackwardsScanner.cpp b/src/libs/cplusplus/BackwardsScanner.cpp
index b0b71ffecd..eb0e5c2803 100644
--- a/src/libs/cplusplus/BackwardsScanner.cpp
+++ b/src/libs/cplusplus/BackwardsScanner.cpp
@@ -38,6 +38,7 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, const QString &suf
, _block(cursor.block())
, _maxBlockCount(maxBlockCount)
{
+ _tokenize.setQtMocRunEnabled(true);
_tokenize.setSkipComments(true);
_text = _block.text().left(cursor.position() - cursor.block().position());
@@ -52,13 +53,10 @@ BackwardsScanner::BackwardsScanner(const QTextCursor &cursor, const QString &suf
int BackwardsScanner::state() const
{ return _tokenize.state(); }
-const QList<SimpleToken> &BackwardsScanner::tokens() const
-{ return _tokens; }
-
-const SimpleToken &BackwardsScanner::LA(int index) const
+SimpleToken BackwardsScanner::LA(int index) const
{ return const_cast<BackwardsScanner *>(this)->fetchToken(_startToken - index); }
-const SimpleToken &BackwardsScanner::operator[](int index) const
+SimpleToken BackwardsScanner::operator[](int index) const
{ return const_cast<BackwardsScanner *>(this)->fetchToken(index); }
const SimpleToken &BackwardsScanner::fetchToken(int i)
@@ -72,16 +70,27 @@ const SimpleToken &BackwardsScanner::fetchToken(int i)
} else {
++_blocksTokenized;
- QString blockText = _block.text();
+ const QString blockText = _block.text();
_text.prepend(blockText);
+
QList<SimpleToken> adaptedTokens;
for (int i = 0; i < _tokens.size(); ++i) {
- const SimpleToken &t = _tokens.at(i);
- const int position = t.position() + blockText.length();
- adaptedTokens.append(SimpleToken(t.kind(),
- position,
- t.length(),
- _text.midRef(position, t.length())));
+ SimpleToken t = _tokens.at(i);
+ if (i == 0) {
+ Q_ASSERT(t.followsNewline());
+ }
+ t.setPosition(t.position() + blockText.length());
+ t.setText(_text.midRef(t.position(), t.length()));
+
+ if (i == 0) {
+ Q_ASSERT(t.followsNewline());
+ }
+
+ adaptedTokens.append(t);
+
+ if (i == 0) {
+ Q_ASSERT(adaptedTokens.last().followsNewline());
+ }
}
_tokens = _tokenize(blockText, previousBlockState(_block));
@@ -156,6 +165,17 @@ int BackwardsScanner::startOfMatchingBrace(int index) const
--count;
--i;
} while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
+ } else if (tk[index - 1].is(T_RBRACE)) {
+ int i = index - 1;
+ int count = 0;
+ do {
+ if (tk[i].is(T_LBRACE)) {
+ if (! ++count)
+ return i;
+ } else if (tk[i].is(T_RBRACE))
+ --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;
@@ -167,7 +187,71 @@ int BackwardsScanner::startOfMatchingBrace(int index) const
--count;
--i;
} while (count != 0 && tk[i].isNot(T_EOF_SYMBOL));
+ } else {
+ Q_ASSERT(0);
+ }
+
+ return index;
+}
+
+int BackwardsScanner::startOfLine(int index) const
+{
+ const BackwardsScanner tk(*this);
+
+ forever {
+ const SimpleToken &tok = tk[index - 1];
+
+ if (tok.is(T_EOF_SYMBOL))
+ break;
+ else if (tok.followsNewline())
+ return index - 1;
+
+ --index;
}
return index;
}
+
+int BackwardsScanner::startOfBlock(int index) const
+{
+ const BackwardsScanner tk(*this);
+
+ const int start = index;
+
+ forever {
+ SimpleToken token = tk[index - 1];
+
+ if (token.is(T_EOF_SYMBOL)) {
+ break;
+
+ } else if (token.is(T_GREATER)) {
+ const int matchingBrace = startOfMatchingBrace(index);
+
+ if (matchingBrace != index && tk[matchingBrace - 1].is(T_TEMPLATE))
+ index = matchingBrace;
+
+ } else if (token.is(T_RPAREN) || token.is(T_RBRACKET) || token.is(T_RBRACE)) {
+ const int matchingBrace = startOfMatchingBrace(index);
+
+ if (matchingBrace != index)
+ index = matchingBrace;
+
+ } else if (token.is(T_LPAREN) || token.is(T_LBRACKET)) {
+ break; // unmatched brace
+
+ } else if (token.is(T_LBRACE)) {
+ return index - 1;
+
+ }
+
+ --index;
+ }
+
+ return start;
+}
+
+int BackwardsScanner::indentation(int index) const
+{
+ SimpleToken newline = operator[](startOfLine(index + 1));
+ return newline.position();
+}
diff --git a/src/libs/cplusplus/BackwardsScanner.h b/src/libs/cplusplus/BackwardsScanner.h
index 68d1f04787..1ce6d3f85c 100644
--- a/src/libs/cplusplus/BackwardsScanner.h
+++ b/src/libs/cplusplus/BackwardsScanner.h
@@ -55,17 +55,21 @@ public:
QStringRef textRef(int begin, int end) const;
// 1-based
- const SimpleToken &LA(int index) const;
+ SimpleToken LA(int index) const;
// n-la token is [startToken - n]
- const SimpleToken &operator[](int index) const; // ### deprecate
+ SimpleToken operator[](int index) const; // ### deprecate
+ int indentation(int index) const;
+
+ int startOfLine(int index) const;
int startOfMatchingBrace(int index) const;
+ int startOfBlock(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/SimpleLexer.cpp b/src/libs/cplusplus/SimpleLexer.cpp
index 7e60f76115..8c023d8603 100644
--- a/src/libs/cplusplus/SimpleLexer.cpp
+++ b/src/libs/cplusplus/SimpleLexer.cpp
@@ -35,6 +35,17 @@
using namespace CPlusPlus;
+SimpleToken::SimpleToken(const Token &token, const QStringRef &text)
+ : _kind(token.f.kind)
+ , _flags(0)
+ , _position(token.begin())
+ , _length(token.f.length)
+ , _text(text)
+{
+ f._whitespace = token.f.whitespace;
+ f._newline = token.f.newline;
+}
+
bool SimpleToken::isLiteral() const
{
return _kind >= T_FIRST_LITERAL && _kind <= T_LAST_LITERAL;
@@ -60,6 +71,11 @@ bool SimpleToken::isObjCAtKeyword() const
return _kind >= T_FIRST_OBJC_AT_KEYWORD && _kind <= T_LAST_OBJC_AT_KEYWORD;
}
+const char *SimpleToken::name() const
+{
+ return Token::name(_kind);
+}
+
SimpleLexer::SimpleLexer()
: _lastState(0),
_skipComments(false),
@@ -113,6 +129,7 @@ QList<SimpleToken> SimpleLexer::operator()(const QString &text, int state)
Lexer lex(firstChar, lastChar);
lex.setQtMocRunEnabled(_qtMocRunEnabled);
lex.setObjCEnabled(_objCEnabled);
+ lex.setStartWithNewline(true);
if (! _skipComments)
lex.setScanCommentTokens(true);
@@ -122,17 +139,26 @@ QList<SimpleToken> SimpleLexer::operator()(const QString &text, int state)
bool inPreproc = false;
+ bool first = true;
+
for (;;) {
Token tk;
lex(&tk);
if (tk.is(T_EOF_SYMBOL))
break;
- SimpleToken simpleTk;
- simpleTk._kind = int(tk.f.kind);
- simpleTk._position = int(lex.tokenOffset());
- simpleTk._length = int(lex.tokenLength());
- simpleTk._text = text.midRef(simpleTk._position, simpleTk._length);
+ Q_ASSERT(lex.tokenOffset() == tk.begin());
+ Q_ASSERT(lex.tokenLength() == tk.f.length);
+
+ QStringRef spell = text.midRef(lex.tokenOffset(), lex.tokenLength());
+ SimpleToken simpleTk(tk, spell);
+
+ if (first) {
+ first = false;
+
+ Q_ASSERT(tk.f.newline);
+ Q_ASSERT(simpleTk.followsNewline());
+ }
lex.setScanAngleStringLiteralTokens(false);
diff --git a/src/libs/cplusplus/SimpleLexer.h b/src/libs/cplusplus/SimpleLexer.h
index 3f15193ee0..0775eccb1c 100644
--- a/src/libs/cplusplus/SimpleLexer.h
+++ b/src/libs/cplusplus/SimpleLexer.h
@@ -37,21 +37,18 @@
namespace CPlusPlus {
class SimpleLexer;
+class Token;
class CPLUSPLUS_EXPORT SimpleToken
{
public:
- SimpleToken(int kind, int position, int length, const QStringRef &text)
- : _kind(kind)
- , _position(position)
- , _length(length)
- , _text(text)
- { }
+ SimpleToken(const Token &token, const QStringRef &text);
SimpleToken()
- : _kind(0),
- _position(0),
- _length(0)
+ : _kind(0)
+ , _flags(0)
+ , _position(0)
+ , _length(0)
{ }
inline int kind() const
@@ -72,6 +69,12 @@ public:
inline QStringRef text() const
{ return _text; }
+ inline bool followsNewline() const
+ { return f._newline; }
+
+ inline bool followsWhitespace() const
+ { return f._whitespace; }
+
inline bool is(int k) const { return _kind == k; }
inline bool isNot(int k) const { return _kind != k; }
@@ -81,8 +84,27 @@ public:
bool isComment() const;
bool isObjCAtKeyword() const;
+ const char *name() const;
+
+ // internal
+ inline void setPosition(int position)
+ { _position = position; }
+
+ // internal
+ inline void setText(const QStringRef &text)
+ { _text = text; }
+
public:
- int _kind;
+ short _kind;
+ union {
+ short _flags;
+
+ struct {
+ short _newline: 1;
+ short _whitespace: 1;
+ } f;
+ };
+
int _position;
int _length;
QStringRef _text;