diff --git a/src/libs/qmljs/qmljsevaluate.cpp b/src/libs/qmljs/qmljsevaluate.cpp index d7a7129216a245d4bfe4d35b209e094f643be911..2b6821e755b482d61952ffb9c8e56c9d2051fa9a 100644 --- a/src/libs/qmljs/qmljsevaluate.cpp +++ b/src/libs/qmljs/qmljsevaluate.cpp @@ -53,7 +53,7 @@ const Interpreter::Value *Evaluate::operator()(AST::Node *ast) const Value *result = reference(ast); if (const Reference *ref = value_cast<const Reference *>(result)) - result = ref->value(_context); + result = _context->lookupReference(ref); if (! result) result = _engine->undefinedValue(); diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index a32cd10c9fc4309d0940e80458261d72868f84e2..a83f24141d9215efb70a524ce6e36ac0bd326041 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -1483,6 +1483,18 @@ const ObjectValue *Context::lookupType(const QmlJS::Document *doc, const QString return objectValue; } +const Value *Context::lookupReference(const Reference *reference) +{ + if (_referenceStack.contains(reference)) + return 0; + + _referenceStack.append(reference); + const Value *v = reference->value(this); + _referenceStack.removeLast(); + + return v; +} + const Value *Context::property(const ObjectValue *object, const QString &name) const { const Properties properties = _properties.value(object); @@ -1632,7 +1644,7 @@ const ObjectValue *ObjectValue::prototype(Context *context) const const ObjectValue *prototypeObject = value_cast<const ObjectValue *>(_prototype); if (! prototypeObject) { if (const Reference *prototypeReference = value_cast<const Reference *>(_prototype)) { - prototypeObject = value_cast<const ObjectValue *>(prototypeReference->value(context)); + prototypeObject = value_cast<const ObjectValue *>(context->lookupReference(prototypeReference)); } } return prototypeObject; diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index 50254fda99c696047ba60641cec1b50df3fb899b..7ce3fcffba62c6decb2bd46fd73e0ad4bae6ee37 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -293,6 +293,7 @@ public: const Value *lookup(const QString &name); const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName); const ObjectValue *lookupType(const Document *doc, const QStringList &qmlTypeName); + const Value *lookupReference(const Reference *reference); const Value *property(const ObjectValue *object, const QString &name) const; void setProperty(const ObjectValue *object, const QString &name, const Value *value); @@ -313,6 +314,7 @@ private: ScopeChain _scopeChain; int _qmlScopeObjectIndex; bool _qmlScopeObjectSet; + QList<const Reference *> _referenceStack; }; class QMLJS_EXPORT Reference: public Value @@ -322,14 +324,16 @@ public: virtual ~Reference(); Engine *engine() const; - virtual const Value *value(Context *context) const; // Value interface virtual const Reference *asReference() const; virtual void accept(ValueVisitor *) const; private: + virtual const Value *value(Context *context) const; + Engine *_engine; + friend class Context; }; class QMLJS_EXPORT ColorValue: public Value @@ -742,9 +746,9 @@ public: AST::UiQualifiedId *qmlTypeName() const; +private: virtual const Value *value(Context *context) const; -private: AST::UiQualifiedId *_qmlTypeName; const Document *_doc; }; @@ -757,6 +761,7 @@ public: ASTVariableReference(AST::VariableDeclaration *ast, Engine *engine); virtual ~ASTVariableReference(); +private: virtual const Value *value(Context *context) const; }; @@ -792,6 +797,8 @@ public: QString onChangedSlotName() const { return _onChangedSlotName; } virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; + +private: virtual const Value *value(Context *context) const; }; @@ -809,6 +816,8 @@ public: QString slotName() const { return _slotName; } virtual bool getSourceLocation(QString *fileName, int *line, int *column) const; + +private: virtual const Value *value(Context *context) const; };