forked from qt-creator/qt-creator
Simplified the algorithm used to compute the expression under cursor.
This commit is contained in:
@@ -39,89 +39,83 @@
|
|||||||
using namespace QmlJS;
|
using namespace QmlJS;
|
||||||
using namespace QmlJS::AST;
|
using namespace QmlJS::AST;
|
||||||
|
|
||||||
namespace QmlJSEditor {
|
namespace {
|
||||||
namespace Internal {
|
|
||||||
|
|
||||||
class ExpressionUnderCursor
|
class ExpressionUnderCursor
|
||||||
{
|
{
|
||||||
QTextCursor _cursor;
|
QTextCursor _cursor;
|
||||||
Scanner scanner;
|
Scanner scanner;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ExpressionUnderCursor()
|
ExpressionUnderCursor()
|
||||||
: start(0), end(0)
|
: start(0), end(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
int start, end;
|
int start, end;
|
||||||
|
|
||||||
|
int startState(const QTextBlock &block) const
|
||||||
|
{
|
||||||
|
int state = block.previous().userState();
|
||||||
|
if (state == -1)
|
||||||
|
return 0;
|
||||||
|
return state & 0xff;
|
||||||
|
}
|
||||||
|
|
||||||
QString operator()(const QTextCursor &cursor)
|
QString operator()(const QTextCursor &cursor)
|
||||||
|
{
|
||||||
|
return process(cursor);
|
||||||
|
}
|
||||||
|
|
||||||
|
int startOfExpression(const QList<Token> &tokens) const
|
||||||
|
{
|
||||||
|
return startOfExpression(tokens, tokens.size() - 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int startOfExpression(const QList<Token> &tokens, int index) const
|
||||||
|
{
|
||||||
|
if (index != -1) {
|
||||||
|
const Token &tk = tokens.at(index);
|
||||||
|
|
||||||
|
if (tk.is(Token::Identifier)) {
|
||||||
|
if (index > 0 && tokens.at(index - 1).is(Token::Dot))
|
||||||
|
index = startOfExpression(tokens, index - 2);
|
||||||
|
|
||||||
|
} else if (tk.is(Token::RightParenthesis)) {
|
||||||
|
do { --index; }
|
||||||
|
while (index != -1 && tokens.at(index).isNot(Token::LeftParenthesis));
|
||||||
|
if (index > 0 && tokens.at(index - 1).is(Token::Identifier))
|
||||||
|
index = startOfExpression(tokens, index - 1);
|
||||||
|
|
||||||
|
} else if (tk.is(Token::RightBracket)) {
|
||||||
|
do { --index; }
|
||||||
|
while (index != -1 && tokens.at(index).isNot(Token::LeftBracket));
|
||||||
|
if (index > 0 && tokens.at(index - 1).is(Token::Identifier))
|
||||||
|
index = startOfExpression(tokens, index - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString process(const QTextCursor &cursor)
|
||||||
{
|
{
|
||||||
_cursor = cursor;
|
_cursor = cursor;
|
||||||
|
|
||||||
QTextBlock block = _cursor.block();
|
QTextBlock block = _cursor.block();
|
||||||
const QString blockText = block.text().left(cursor.columnNumber());
|
const QString blockText = block.text().left(cursor.columnNumber());
|
||||||
//qDebug() << "block text:" << blockText;
|
|
||||||
|
|
||||||
int startState = block.previous().userState();
|
scanner.setScanComments(false);
|
||||||
if (startState == -1)
|
const QList<Token> tokens = scanner(blockText, startState(block));
|
||||||
startState = 0;
|
int start = startOfExpression(tokens);
|
||||||
else
|
if (start == -1)
|
||||||
startState = startState & 0xff;
|
|
||||||
|
|
||||||
const QList<Token> originalTokens = scanner(blockText, startState);
|
|
||||||
QList<Token> tokens;
|
|
||||||
int skipping = 0;
|
|
||||||
for (int index = originalTokens.size() - 1; index != -1; --index) {
|
|
||||||
const Token &tk = originalTokens.at(index);
|
|
||||||
|
|
||||||
if (tk.is(Token::Comment) || tk.is(Token::String) || tk.is(Token::Number))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (! skipping) {
|
|
||||||
tokens.append(tk);
|
|
||||||
|
|
||||||
if (tk.is(Token::Identifier)) {
|
|
||||||
if (index > 0 && originalTokens.at(index - 1).isNot(Token::Dot))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
//qDebug() << "skip:" << blockText.mid(tk.offset, tk.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tk.is(Token::RightParenthesis) || tk.is(Token::RightBracket))
|
|
||||||
++skipping;
|
|
||||||
|
|
||||||
else if (tk.is(Token::LeftParenthesis) || tk.is(Token::LeftBracket)) {
|
|
||||||
--skipping;
|
|
||||||
|
|
||||||
if (! skipping)
|
|
||||||
tokens.append(tk);
|
|
||||||
|
|
||||||
if (index > 0 && originalTokens.at(index - 1).isNot(Token::Identifier))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (! tokens.isEmpty()) {
|
|
||||||
QString expr;
|
|
||||||
for (int index = tokens.size() - 1; index >= 0; --index) {
|
|
||||||
Token tk = tokens.at(index);
|
|
||||||
expr.append(QLatin1Char(' '));
|
|
||||||
expr.append(blockText.midRef(tk.offset, tk.length));
|
|
||||||
|
|
||||||
}
|
|
||||||
start = tokens.first().begin();
|
|
||||||
end = tokens.first().end();
|
|
||||||
//qDebug() << "expression under cursor:" << expr;
|
|
||||||
return expr;
|
|
||||||
}
|
|
||||||
|
|
||||||
//qDebug() << "no expression";
|
|
||||||
return QString();
|
return QString();
|
||||||
|
|
||||||
|
const Token &tk = tokens.at(start);
|
||||||
|
return blockText.mid(tk.begin(), tokens.last().end() - tk.begin());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
|
||||||
}
|
} // enf of anonymous namespace
|
||||||
|
|
||||||
using namespace QmlJSEditor;
|
using namespace QmlJSEditor;
|
||||||
using namespace QmlJSEditor::Internal;
|
using namespace QmlJSEditor::Internal;
|
||||||
|
|||||||
@@ -627,6 +627,16 @@ bool CodeCompletion::isDelimiter(const QChar &ch) const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool isLiteral(AST::Node *ast)
|
||||||
|
{
|
||||||
|
if (AST::cast<AST::StringLiteral *>(ast))
|
||||||
|
return true;
|
||||||
|
else if (AST::cast<AST::NumericLiteral *>(ast))
|
||||||
|
return true;
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
|
int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
|
||||||
{
|
{
|
||||||
m_editor = editor;
|
m_editor = editor;
|
||||||
@@ -691,9 +701,8 @@ int CodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
|
|||||||
|
|
||||||
QmlExpressionUnderCursor expressionUnderCursor;
|
QmlExpressionUnderCursor expressionUnderCursor;
|
||||||
QmlJS::AST::ExpressionNode *expression = expressionUnderCursor(tc);
|
QmlJS::AST::ExpressionNode *expression = expressionUnderCursor(tc);
|
||||||
//qDebug() << "expression:" << expression;
|
|
||||||
|
|
||||||
if (expression != 0) {
|
if (expression != 0 && ! isLiteral(expression)) {
|
||||||
Evaluate evaluate(&context);
|
Evaluate evaluate(&context);
|
||||||
|
|
||||||
// Evaluate the expression under cursor.
|
// Evaluate the expression under cursor.
|
||||||
|
|||||||
Reference in New Issue
Block a user