From e984691fe69c12f06922267666d062df9ea659b2 Mon Sep 17 00:00:00 2001
From: Christian Kamm <christian.d.kamm@nokia.com>
Date: Thu, 4 Feb 2010 09:44:43 +0100
Subject: [PATCH] Fix prototype reference resolution for Qml objects.

---
 src/libs/qmljs/qmljsbind.cpp        |  3 ++-
 src/libs/qmljs/qmljsinterpreter.cpp | 20 +++++++++++---------
 src/libs/qmljs/qmljsinterpreter.h   | 12 +++++++-----
 src/libs/qmljs/qmljslink.cpp        |  7 +++----
 src/libs/qmljs/qmljslink.h          |  1 -
 5 files changed, 23 insertions(+), 20 deletions(-)

diff --git a/src/libs/qmljs/qmljsbind.cpp b/src/libs/qmljs/qmljsbind.cpp
index 0c7ab0e9e00..7a580d18ce6 100644
--- a/src/libs/qmljs/qmljsbind.cpp
+++ b/src/libs/qmljs/qmljsbind.cpp
@@ -140,7 +140,8 @@ ObjectValue *Bind::bindObject(UiQualifiedId *qualifiedTypeNameId, UiObjectInitia
 
     // normal component instance
     ASTObjectValue *objectValue = new ASTObjectValue(qualifiedTypeNameId, initializer, &_interp);
-    QmlPrototypeReference *prototypeReference = new QmlPrototypeReference(qualifiedTypeNameId, &_interp);
+    QmlPrototypeReference *prototypeReference =
+            new QmlPrototypeReference(qualifiedTypeNameId, _doc, &_interp);
     objectValue->setPrototype(prototypeReference);
 
     parentObjectValue = switchObjectValue(objectValue);
diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index f6d2066b695..c9e0c15f539 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -708,14 +708,14 @@ void Context::setLookupMode(LookupMode lookupMode)
     _lookupMode = lookupMode;
 }
 
-const ObjectValue *Context::typeEnvironment() const
+const ObjectValue *Context::typeEnvironment(const Document *doc) const
 {
-    return _typeEnvironment;
+    return _typeEnvironments.value(doc, 0);
 }
 
-void Context::setTypeEnvironment(const ObjectValue *typeEnvironment)
+void Context::setTypeEnvironment(const Document *doc, const ObjectValue *typeEnvironment)
 {
-    _typeEnvironment = typeEnvironment;
+    _typeEnvironments[doc] = typeEnvironment;
 }
 
 void Context::pushScope(const ObjectValue *object)
@@ -743,9 +743,9 @@ const Value *Context::lookup(const QString &name)
     return _engine->undefinedValue();
 }
 
-const ObjectValue *Context::lookupType(UiQualifiedId *qmlTypeName)
+const ObjectValue *Context::lookupType(const Document *doc, UiQualifiedId *qmlTypeName)
 {
-    const ObjectValue *objectValue = _typeEnvironment;
+    const ObjectValue *objectValue = typeEnvironment(doc);
 
     for (UiQualifiedId *iter = qmlTypeName; objectValue && iter; iter = iter->next) {
         if (! iter->name)
@@ -1992,9 +1992,11 @@ bool ASTFunctionValue::isVariadic() const
     return true;
 }
 
-QmlPrototypeReference::QmlPrototypeReference(UiQualifiedId *qmlTypeName, Engine *engine)
+QmlPrototypeReference::QmlPrototypeReference(UiQualifiedId *qmlTypeName, const Document *doc,
+                                             Engine *engine)
     : Reference(engine),
-      _qmlTypeName(qmlTypeName)
+      _qmlTypeName(qmlTypeName),
+      _doc(doc)
 {
 }
 
@@ -2009,6 +2011,6 @@ UiQualifiedId *QmlPrototypeReference::qmlTypeName() const
 
 const Value *QmlPrototypeReference::value(Context *context) const
 {
-    return context->lookupType(_qmlTypeName);
+    return context->lookupType(_doc, _qmlTypeName);
 }
 
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 8144c9950df..feaf95e33f0 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -42,6 +42,7 @@
 namespace QmlJS {
 
 class NameId;
+class Document;
 
 namespace Interpreter {
 
@@ -229,14 +230,14 @@ public:
     LookupMode lookupMode() const;
     void setLookupMode(LookupMode lookupMode);
 
-    const ObjectValue *typeEnvironment() const;
-    void setTypeEnvironment(const ObjectValue *typeEnvironment);
+    const ObjectValue *typeEnvironment(const Document *doc) const;
+    void setTypeEnvironment(const Document *doc, const ObjectValue *typeEnvironment);
 
     void pushScope(const ObjectValue *object);
     void popScope();
 
     const Value *lookup(const QString &name);
-    const ObjectValue *lookupType(AST::UiQualifiedId *qmlTypeName);
+    const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName);
 
     const Value *property(const ObjectValue *object, const QString &name) const;
     void setProperty(const ObjectValue *object, const QString &name, const Value *value);
@@ -246,9 +247,9 @@ private:
 
     Engine *_engine;
     LookupMode _lookupMode;
-    const ObjectValue *_typeEnvironment;
     QHash<const ObjectValue *, Properties> _properties;
     ScopeChain _scopeChain;
+    QHash<const Document *, const ObjectValue *> _typeEnvironments;
 };
 
 class QMLJS_EXPORT Reference: public Value
@@ -626,7 +627,7 @@ private:
 class QMLJS_EXPORT QmlPrototypeReference: public Reference
 {
 public:
-    QmlPrototypeReference(AST::UiQualifiedId *qmlTypeName, Engine *engine);
+    QmlPrototypeReference(AST::UiQualifiedId *qmlTypeName, const Document *doc, Engine *engine);
     virtual ~QmlPrototypeReference();
 
     AST::UiQualifiedId *qmlTypeName() const;
@@ -635,6 +636,7 @@ public:
 
 private:
     AST::UiQualifiedId *_qmlTypeName;
+    const Document *_doc;
 };
 
 class QMLJS_EXPORT ASTObjectValue: public ObjectValue
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index 666c8a56ca3..50cfc515432 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -80,20 +80,19 @@ void Link::scopeChainAt(Document::Ptr doc, Node *currentObject)
     if (bind->_idEnvironment)
         _context.pushScope(bind->_idEnvironment);
 
-    if (const ObjectValue *typeEnvironment = _typeEnvironments.value(doc.data())) {
+    if (const ObjectValue *typeEnvironment = _context.typeEnvironment(doc.data()))
         _context.pushScope(typeEnvironment);
-        _context.setTypeEnvironment(typeEnvironment);
-    }
 }
 
 void Link::linkImports()
 {
     foreach (Document::Ptr doc, _docs) {
         ObjectValue *typeEnv = engine()->newObject(/*prototype =*/0); // ### FIXME
-        _typeEnvironments.insert(doc.data(), typeEnv);
 
         // Populate the _typeEnvironment with imports.
         populateImportedTypes(typeEnv, doc);
+
+        _context.setTypeEnvironment(doc.data(), typeEnv);
     }
 }
 
diff --git a/src/libs/qmljs/qmljslink.h b/src/libs/qmljs/qmljslink.h
index 0a481598c24..fd92fd06149 100644
--- a/src/libs/qmljs/qmljslink.h
+++ b/src/libs/qmljs/qmljslink.h
@@ -46,7 +46,6 @@ private:
     Snapshot _snapshot;
     Interpreter::Context _context;
     QList<Document::Ptr> _docs;
-    QHash<Document *, Interpreter::ObjectValue *> _typeEnvironments;
 };
 
 } // namespace QmlJS
-- 
GitLab