From 7b2110de7ea69ffa3914d3289ac42cbb69d9a414 Mon Sep 17 00:00:00 2001 From: Christian Kamm <christian.d.kamm@nokia.com> Date: Mon, 12 Sep 2011 11:48:33 +0200 Subject: [PATCH] QmlJS: Fix reference lookup cycles. Since several reference lookups involve Evaluate which may cause further reference lookups, we need to be able to pass the existing ReferenceContext to avoid cycles. Change-Id: I2f1eeaad4d6b6ff094413d51077b03c985f6fab4 Reviewed-on: http://codereview.qt-project.org/4653 Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com> --- src/libs/qmljs/qmljsevaluate.cpp | 11 ++++++++--- src/libs/qmljs/qmljsevaluate.h | 3 ++- src/libs/qmljs/qmljsinterpreter.cpp | 14 +++++++------- src/libs/qmljs/qmljsinterpreter.h | 10 +++++----- 4 files changed, 22 insertions(+), 16 deletions(-) diff --git a/src/libs/qmljs/qmljsevaluate.cpp b/src/libs/qmljs/qmljsevaluate.cpp index 5c3ecfa1d45..80680d7b2ed 100644 --- a/src/libs/qmljs/qmljsevaluate.cpp +++ b/src/libs/qmljs/qmljsevaluate.cpp @@ -39,9 +39,10 @@ using namespace QmlJS; -Evaluate::Evaluate(const ScopeChain *scopeChain) +Evaluate::Evaluate(const ScopeChain *scopeChain, ReferenceContext *referenceContext) : _valueOwner(scopeChain->context()->valueOwner()), _context(scopeChain->context()), + _referenceContext(referenceContext), _scopeChain(scopeChain), _scope(_valueOwner->globalObject()), _result(0) @@ -61,8 +62,12 @@ const Value *Evaluate::value(AST::Node *ast) { const Value *result = reference(ast); - if (const Reference *ref = value_cast<const Reference *>(result)) - result = _context->lookupReference(ref); + if (const Reference *ref = value_cast<const Reference *>(result)) { + if (_referenceContext) + result = _referenceContext->lookupReference(ref); + else + result = _context->lookupReference(ref); + } if (! result) result = _valueOwner->undefinedValue(); diff --git a/src/libs/qmljs/qmljsevaluate.h b/src/libs/qmljs/qmljsevaluate.h index a3289465608..62271459687 100644 --- a/src/libs/qmljs/qmljsevaluate.h +++ b/src/libs/qmljs/qmljsevaluate.h @@ -48,7 +48,7 @@ class FunctionValue; class QMLJS_EXPORT Evaluate: protected AST::Visitor { public: - Evaluate(const ScopeChain *scopeChain); + Evaluate(const ScopeChain *scopeChain, ReferenceContext *referenceContext = 0); virtual ~Evaluate(); // same as value() @@ -164,6 +164,7 @@ private: QmlJS::Document::Ptr _doc; ValueOwner *_valueOwner; ContextPtr _context; + ReferenceContext *_referenceContext; const ScopeChain *_scopeChain; const ObjectValue *_scope; const Value *_result; diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index a8cfb6e9748..f288c36ed2b 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -727,7 +727,7 @@ void Reference::accept(ValueVisitor *visitor) const visitor->visit(this); } -const Value *Reference::value(const ReferenceContext *) const +const Value *Reference::value(ReferenceContext *) const { return _valueOwner->undefinedValue(); } @@ -1745,7 +1745,7 @@ ASTVariableReference::~ASTVariableReference() { } -const Value *ASTVariableReference::value(const ReferenceContext *referenceContext) const +const Value *ASTVariableReference::value(ReferenceContext *referenceContext) const { if (!_ast->expression) return valueOwner()->undefinedValue(); @@ -1755,7 +1755,7 @@ const Value *ASTVariableReference::value(const ReferenceContext *referenceContex ScopeBuilder builder(&scopeChain); builder.push(ScopeAstPath(doc)(_ast->expression->firstSourceLocation().begin())); - Evaluate evaluator(&scopeChain); + Evaluate evaluator(&scopeChain, referenceContext); return evaluator(_ast->expression); } @@ -1832,7 +1832,7 @@ UiQualifiedId *QmlPrototypeReference::qmlTypeName() const return _qmlTypeName; } -const Value *QmlPrototypeReference::value(const ReferenceContext *referenceContext) const +const Value *QmlPrototypeReference::value(ReferenceContext *referenceContext) const { return referenceContext->context()->lookupType(_doc, _qmlTypeName); } @@ -1859,7 +1859,7 @@ bool ASTPropertyReference::getSourceLocation(QString *fileName, int *line, int * return true; } -const Value *ASTPropertyReference::value(const ReferenceContext *referenceContext) const +const Value *ASTPropertyReference::value(ReferenceContext *referenceContext) const { if (_ast->statement && (!_ast->memberType || _ast->memberType->asString() == QLatin1String("variant") @@ -1875,7 +1875,7 @@ const Value *ASTPropertyReference::value(const ReferenceContext *referenceContex int offset = _ast->statement->firstSourceLocation().begin(); builder.push(ScopeAstPath(doc)(offset)); - Evaluate evaluator(&scopeChain); + Evaluate evaluator(&scopeChain, referenceContext); return evaluator(_ast->statement); } @@ -1906,7 +1906,7 @@ bool ASTSignalReference::getSourceLocation(QString *fileName, int *line, int *co return true; } -const Value *ASTSignalReference::value(const ReferenceContext *) const +const Value *ASTSignalReference::value(ReferenceContext *) const { return valueOwner()->undefinedValue(); } diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index cc7999739b9..2fad1f43a0d 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -296,7 +296,7 @@ public: virtual void accept(ValueVisitor *) const; private: - virtual const Value *value(const ReferenceContext *referenceContext) const; + virtual const Value *value(ReferenceContext *referenceContext) const; ValueOwner *_valueOwner; friend class ReferenceContext; @@ -699,7 +699,7 @@ public: AST::UiQualifiedId *qmlTypeName() const; private: - virtual const Value *value(const ReferenceContext *referenceContext) const; + virtual const Value *value(ReferenceContext *referenceContext) const; AST::UiQualifiedId *_qmlTypeName; const Document *_doc; @@ -715,7 +715,7 @@ public: virtual ~ASTVariableReference(); private: - virtual const Value *value(const ReferenceContext *referenceContext) const; + virtual const Value *value(ReferenceContext *referenceContext) const; }; class QMLJS_EXPORT ASTFunctionValue: public FunctionValue @@ -755,7 +755,7 @@ public: virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; private: - virtual const Value *value(const ReferenceContext *referenceContext) const; + virtual const Value *value(ReferenceContext *referenceContext) const; }; class QMLJS_EXPORT ASTSignalReference: public Reference @@ -774,7 +774,7 @@ public: virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; private: - virtual const Value *value(const ReferenceContext *referenceContext) const; + virtual const Value *value(ReferenceContext *referenceContext) const; }; class QMLJS_EXPORT ASTObjectValue: public ObjectValue -- GitLab