From 05831a8ea5169e407cca6de1f207225e1a710ff1 Mon Sep 17 00:00:00 2001 From: Christian Kamm <christian.d.kamm@nokia.com> Date: Wed, 24 Nov 2010 14:42:10 +0100 Subject: [PATCH] QmlJS: Fix binding and scoping function expressions. Reviewed-by: Erik Verbruggen --- src/libs/qmljs/qmljsbind.cpp | 7 +++---- src/libs/qmljs/qmljsscopebuilder.cpp | 10 ++++++---- src/plugins/qmljseditor/qmljsfindreferences.cpp | 17 +++++++++++++++-- 3 files changed, 24 insertions(+), 10 deletions(-) diff --git a/src/libs/qmljs/qmljsbind.cpp b/src/libs/qmljs/qmljsbind.cpp index 4bc2f193e71..802957f7d4d 100644 --- a/src/libs/qmljs/qmljsbind.cpp +++ b/src/libs/qmljs/qmljsbind.cpp @@ -346,19 +346,18 @@ bool Bind::visit(VariableDeclaration *ast) ASTVariableReference *ref = new ASTVariableReference(ast, &_engine); _currentObjectValue->setProperty(ast->name->asString(), ref); - return false; + return true; } bool Bind::visit(FunctionExpression *ast) { - if (!ast->name) - return false; // ### FIXME: the first declaration counts //if (_currentObjectValue->property(ast->name->asString(), 0)) // return false; ASTFunctionValue *function = new ASTFunctionValue(ast, _doc, &_engine); - _currentObjectValue->setProperty(ast->name->asString(), function); + if (ast->name && cast<FunctionDeclaration *>(ast)) + _currentObjectValue->setProperty(ast->name->asString(), function); // build function scope ObjectValue *functionScope = _engine.newObject(/*prototype=*/0); diff --git a/src/libs/qmljs/qmljsscopebuilder.cpp b/src/libs/qmljs/qmljsscopebuilder.cpp index 77b6dcc5cbf..bd27cebab92 100644 --- a/src/libs/qmljs/qmljsscopebuilder.cpp +++ b/src/libs/qmljs/qmljsscopebuilder.cpp @@ -61,8 +61,8 @@ void ScopeBuilder::push(AST::Node *node) if (qmlObject) setQmlScopeObject(qmlObject); - // JS scopes - if (FunctionDeclaration *fun = cast<FunctionDeclaration *>(node)) { + // JS scopes (catch both, FunctionExpression and FunctionDeclaration) + if (FunctionExpression *fun = dynamic_cast<FunctionExpression *>(node)) { ObjectValue *functionScope = _doc->bind()->findFunctionScope(fun); if (functionScope) _context->scopeChain().jsScopes += functionScope; @@ -83,8 +83,10 @@ void ScopeBuilder::pop() _nodes.removeLast(); // JS scopes - if (cast<FunctionDeclaration *>(toRemove)) - _context->scopeChain().jsScopes.removeLast(); + if (FunctionExpression *fun = dynamic_cast<FunctionExpression *>(toRemove)) { + if (_doc->bind()->findFunctionScope(fun)) + _context->scopeChain().jsScopes.removeLast(); + } // QML scope object if (! _nodes.isEmpty() diff --git a/src/plugins/qmljseditor/qmljsfindreferences.cpp b/src/plugins/qmljseditor/qmljsfindreferences.cpp index 9771ea5280c..debbbac5ef1 100644 --- a/src/plugins/qmljseditor/qmljsfindreferences.cpp +++ b/src/plugins/qmljseditor/qmljsfindreferences.cpp @@ -201,6 +201,11 @@ protected: } virtual bool visit(AST::FunctionDeclaration *node) + { + return visit(static_cast<FunctionExpression *>(node)); + } + + virtual bool visit(AST::FunctionExpression *node) { if (node->name && node->name->asString() == _name) { if (checkLookup()) @@ -328,6 +333,11 @@ protected: } virtual bool visit(AST::FunctionDeclaration *node) + { + return visit(static_cast<FunctionExpression *>(node)); + } + + virtual bool visit(AST::FunctionExpression *node) { Node::accept(node->formals, this); _result.append(node); @@ -422,9 +432,12 @@ protected: return true; } - // ### Misses function declaration, var declaration - virtual bool visit(FunctionDeclaration *node) + { + return visit(static_cast<FunctionExpression *>(node)); + } + + virtual bool visit(FunctionExpression *node) { if (containsOffset(node->identifierToken)) { _result.second = node->name->asString(); -- GitLab