Commit 313d3065 authored by Christian Kamm's avatar Christian Kamm
Browse files

QmlJS: Avoid infinite recursion when encountering property loops.

Such as
property int foo: bar
property int bar: foo.

Task-number: QTCREATORBUG-1389
Reviewed-by: Roberto Raggi
parent 181cecbb
......@@ -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();
......
......@@ -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;
......
......@@ -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;
};
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment