diff --git a/src/libs/qmljs/qmljsdocument.cpp b/src/libs/qmljs/qmljsdocument.cpp index fc3fb9ec88343287c7f675e0303b4703733aa86f..3ba72a4bee614bd477946bae8c88f57f19e50198 100644 --- a/src/libs/qmljs/qmljsdocument.cpp +++ b/src/libs/qmljs/qmljsdocument.cpp @@ -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); - _parsedCorrectly = parser.parse(); - _ast = parser.ast(); + switch (startToken) { + case QmlJSGrammar::T_FEED_UI_PROGRAM: + _parsedCorrectly = parser.parse(); + 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::parseJavaScript() +bool Document::parseQml() { - 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 parse_helper(QmlJSGrammar::T_FEED_UI_PROGRAM); +} - return _parsedCorrectly; +bool Document::parseJavaScript() +{ + 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 diff --git a/src/libs/qmljs/qmljsdocument.h b/src/libs/qmljs/qmljsdocument.h index 5cc07ccf6bbf9c7988b1f7093e79e39f4545e4e1..767ca281235012a8ec5cc8b3d37f1bab07c48ee8 100644 --- a/src/libs/qmljs/qmljsdocument.h +++ b/src/libs/qmljs/qmljsdocument.h @@ -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; diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index f39b91c04e3ce2d2ab2fbd773672033bf5bedcd7..e2f9316df33adef2ec78629263837623c31b7d97 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -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) - _context->pushScope(scopeObject); + 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) { diff --git a/src/plugins/qmljseditor/qmlcodecompletion.cpp b/src/plugins/qmljseditor/qmlcodecompletion.cpp index 6d1bb3f064f375095cd3000d9e8900baf222779b..e063819295dad7459e2e5ae36e9b4559a36a8d23 100644 --- a/src/plugins/qmljseditor/qmlcodecompletion.cpp +++ b/src/plugins/qmljseditor/qmlcodecompletion.cpp @@ -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. diff --git a/src/plugins/qmljseditor/qmljseditor.cpp b/src/plugins/qmljseditor/qmljseditor.cpp index 786d6e76418fb78ac1bdaca8b7230d2f384fb56e..65ddfe75489bcf25d6dede3b5635fa4a9ad81b36 100644 --- a/src/plugins/qmljseditor/qmljseditor.cpp +++ b/src/plugins/qmljseditor/qmljseditor.cpp @@ -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.