forked from qt-creator/qt-creator
Improved completion of JavaScript expressions.
This commit is contained in:
@@ -129,7 +129,7 @@ void Document::setDocumentRevision(int revision)
|
||||
_documentRevision = revision;
|
||||
}
|
||||
|
||||
bool Document::parseQml()
|
||||
bool Document::parse_helper(int startToken)
|
||||
{
|
||||
Q_ASSERT(! _engine);
|
||||
Q_ASSERT(! _pool);
|
||||
@@ -144,8 +144,21 @@ bool Document::parseQml()
|
||||
|
||||
lexer.setCode(_source, /*line = */ 1);
|
||||
|
||||
switch (startToken) {
|
||||
case QmlJSGrammar::T_FEED_UI_PROGRAM:
|
||||
_parsedCorrectly = parser.parse();
|
||||
_ast = parser.ast();
|
||||
break;
|
||||
case QmlJSGrammar::T_FEED_JS_PROGRAM:
|
||||
_parsedCorrectly = parser.parseProgram();
|
||||
break;
|
||||
case QmlJSGrammar::T_FEED_JS_EXPRESSION:
|
||||
_parsedCorrectly = parser.parseExpression();
|
||||
break;
|
||||
default:
|
||||
Q_ASSERT(0);
|
||||
}
|
||||
|
||||
_ast = parser.rootNode();
|
||||
_diagnosticMessages = parser.diagnosticMessages();
|
||||
|
||||
_bind = new Bind(this);
|
||||
@@ -153,51 +166,19 @@ bool Document::parseQml()
|
||||
return _parsedCorrectly;
|
||||
}
|
||||
|
||||
bool Document::parseQml()
|
||||
{
|
||||
return parse_helper(QmlJSGrammar::T_FEED_UI_PROGRAM);
|
||||
}
|
||||
|
||||
bool Document::parseJavaScript()
|
||||
{
|
||||
Q_ASSERT(! _engine);
|
||||
Q_ASSERT(! _pool);
|
||||
Q_ASSERT(! _ast);
|
||||
Q_ASSERT(! _bind);
|
||||
|
||||
_engine = new Engine();
|
||||
_pool = new NodePool(_fileName, _engine);
|
||||
|
||||
Lexer lexer(_engine);
|
||||
Parser parser(_engine);
|
||||
|
||||
lexer.setCode(_source, /*line = */ 1);
|
||||
|
||||
_parsedCorrectly = parser.parseProgram();
|
||||
_ast = cast<Program*>(parser.rootNode());
|
||||
_diagnosticMessages = parser.diagnosticMessages();
|
||||
|
||||
_bind = new Bind(this);
|
||||
|
||||
return _parsedCorrectly;
|
||||
return parse_helper(QmlJSGrammar::T_FEED_JS_PROGRAM);
|
||||
}
|
||||
|
||||
bool Document::parseExpression()
|
||||
{
|
||||
Q_ASSERT(! _engine);
|
||||
Q_ASSERT(! _pool);
|
||||
Q_ASSERT(! _ast);
|
||||
|
||||
_engine = new Engine();
|
||||
_pool = new NodePool(_fileName, _engine);
|
||||
|
||||
Lexer lexer(_engine);
|
||||
Parser parser(_engine);
|
||||
|
||||
lexer.setCode(_source, /*line = */ 1);
|
||||
|
||||
_parsedCorrectly = parser.parseExpression();
|
||||
_ast = parser.rootNode();
|
||||
if (_ast)
|
||||
_ast = _ast->expressionCast();
|
||||
_diagnosticMessages = parser.diagnosticMessages();
|
||||
|
||||
return _parsedCorrectly;
|
||||
return parse_helper(QmlJSGrammar::T_FEED_JS_EXPRESSION);
|
||||
}
|
||||
|
||||
Bind *Document::bind() const
|
||||
|
||||
@@ -81,6 +81,9 @@ public:
|
||||
QString path() const { return _path; }
|
||||
QString componentName() const { return _componentName; }
|
||||
|
||||
private:
|
||||
bool parse_helper(int kind);
|
||||
|
||||
private:
|
||||
QmlJS::Engine *_engine;
|
||||
NodePool *_pool;
|
||||
|
||||
@@ -45,17 +45,31 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject)
|
||||
|
||||
// ### FIXME: May want to link to instantiating components from here.
|
||||
|
||||
if (bind->_rootObjectValue)
|
||||
_context->pushScope(bind->_rootObjectValue);
|
||||
qDebug() << "**** here" << currentObject;
|
||||
|
||||
ObjectValue *scopeObject = 0;
|
||||
if (UiObjectDefinition *definition = cast<UiObjectDefinition *>(currentObject))
|
||||
scopeObject = bind->_qmlObjects.value(definition);
|
||||
else if (UiObjectBinding *binding = cast<UiObjectBinding *>(currentObject))
|
||||
scopeObject = bind->_qmlObjects.value(binding);
|
||||
else if (FunctionDeclaration *fun = cast<FunctionDeclaration *>(currentObject)) {
|
||||
_context->pushScope(bind->_rootObjectValue);
|
||||
|
||||
if (scopeObject && scopeObject != bind->_rootObjectValue)
|
||||
ObjectValue *activation = engine()->newObject(/*prototype = */ 0);
|
||||
for (FormalParameterList *it = fun->formals; it; it = it->next) {
|
||||
if (it->name)
|
||||
activation->setProperty(it->name->asString(), engine()->undefinedValue());
|
||||
}
|
||||
_context->pushScope(activation);
|
||||
}
|
||||
|
||||
if (scopeObject) {
|
||||
if (bind->_rootObjectValue)
|
||||
_context->pushScope(bind->_rootObjectValue);
|
||||
|
||||
if (scopeObject != bind->_rootObjectValue)
|
||||
_context->pushScope(scopeObject);
|
||||
}
|
||||
|
||||
const QStringList &includedScripts = bind->includedScripts();
|
||||
for (int index = includedScripts.size() - 1; index != -1; --index) {
|
||||
|
||||
@@ -654,6 +654,7 @@ int QmlCodeCompletion::startCompletion(TextEditor::ITextEditable *editor)
|
||||
|
||||
// Set up the current scope chain.
|
||||
AST::Node *declaringMember = semanticInfo.declaringMember(editor->position());
|
||||
qDebug() << "*** declaring member:" << declaringMember;
|
||||
context.build(declaringMember, document, snapshot);
|
||||
|
||||
// Search for the operator that triggered the completion.
|
||||
|
||||
@@ -387,8 +387,8 @@ public:
|
||||
{
|
||||
_textDocument = textDocument;
|
||||
_ranges.clear();
|
||||
if (doc && doc->qmlProgram() != 0)
|
||||
doc->qmlProgram()->accept(this);
|
||||
if (doc && doc->ast() != 0)
|
||||
doc->ast()->accept(this);
|
||||
return _ranges;
|
||||
}
|
||||
|
||||
@@ -409,7 +409,6 @@ protected:
|
||||
return true;
|
||||
}
|
||||
|
||||
#if 0 // ### create ranges for function declarations.
|
||||
virtual bool visit(AST::FunctionExpression *ast)
|
||||
{
|
||||
_ranges.append(createRange(ast));
|
||||
@@ -421,7 +420,6 @@ protected:
|
||||
_ranges.append(createRange(ast));
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
Range createRange(AST::UiObjectMember *member, AST::UiObjectInitializer *ast)
|
||||
{
|
||||
@@ -448,6 +446,7 @@ protected:
|
||||
|
||||
range.end = QTextCursor(_textDocument);
|
||||
range.end.setPosition(ast->rbraceToken.end());
|
||||
|
||||
return range;
|
||||
}
|
||||
|
||||
@@ -649,8 +648,9 @@ void QmlJSTextEditor::updateDocumentNow()
|
||||
|
||||
void QmlJSTextEditor::onDocumentUpdated(QmlJS::Document::Ptr doc)
|
||||
{
|
||||
if (file()->fileName() != doc->fileName())
|
||||
if (file()->fileName() != doc->fileName()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (doc->documentRevision() != document()->revision()) {
|
||||
// got an outdated document.
|
||||
|
||||
Reference in New Issue
Block a user