From a7f4e5fab5f46ec392345770c017de2106f9615a Mon Sep 17 00:00:00 2001
From: Christian Kamm <christian.d.kamm@nokia.com>
Date: Fri, 27 May 2011 10:43:06 +0200
Subject: [PATCH] QmlJS: Separate imported types and imported JS scopes.

Task-number: QTCREATORBUG-4981
Change-Id: I06d3e428ca4928296a3d5977aeff29fc3217c37c
Reviewed-on: http://codereview.qt.nokia.com/175
Reviewed-by: Fawzi Mohamed <fawzi.mohamed@nokia.com>
---
 src/libs/qmljs/qmljsinterpreter.cpp           | 132 +++++++++++++-----
 src/libs/qmljs/qmljsinterpreter.h             |  71 +++++++---
 src/libs/qmljs/qmljslink.cpp                  |  48 ++++---
 src/libs/qmljs/qmljslink.h                    |  12 +-
 src/libs/qmljs/qmljsscopebuilder.cpp          |   5 +-
 .../designercore/model/texttomodelmerger.cpp  |   4 +-
 src/plugins/qmljseditor/qmljshoverhandler.cpp |   6 +-
 7 files changed, 190 insertions(+), 88 deletions(-)

diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp
index 3e316c23c28..1530e307f05 100644
--- a/src/libs/qmljs/qmljsinterpreter.cpp
+++ b/src/libs/qmljs/qmljsinterpreter.cpp
@@ -1308,6 +1308,7 @@ void StringValue::accept(ValueVisitor *visitor) const
 ScopeChain::ScopeChain()
     : globalScope(0)
     , qmlTypes(0)
+    , jsImports(0)
 {
 }
 
@@ -1369,7 +1370,8 @@ void ScopeChain::update()
         _all += ids;
     if (qmlTypes)
         _all += qmlTypes;
-    // qmlTypes are not added on purpose
+    if (jsImports)
+        _all += jsImports;
     _all += jsScopes;
 }
 
@@ -1412,18 +1414,18 @@ ScopeChain &Context::scopeChain()
     return _scopeChain;
 }
 
-const TypeEnvironment *Context::typeEnvironment(const QmlJS::Document *doc) const
+const Imports *Context::imports(const QmlJS::Document *doc) const
 {
     if (!doc)
         return 0;
-    return _typeEnvironments.value(doc, 0);
+    return _imports.value(doc).data();
 }
 
-void Context::setTypeEnvironment(const QmlJS::Document *doc, const TypeEnvironment *typeEnvironment)
+void Context::setImports(const QmlJS::Document *doc, const Imports *imports)
 {
     if (!doc)
         return;
-    _typeEnvironments[doc] = typeEnvironment;
+    _imports[doc] = QSharedPointer<const Imports>(imports);
 }
 
 const Value *Context::lookup(const QString &name, const ObjectValue **foundInScope) const
@@ -1446,7 +1448,10 @@ const Value *Context::lookup(const QString &name, const ObjectValue **foundInSco
 
 const ObjectValue *Context::lookupType(const QmlJS::Document *doc, UiQualifiedId *qmlTypeName) const
 {
-    const ObjectValue *objectValue = typeEnvironment(doc);
+    const Imports *importsObj = imports(doc);
+    if (!importsObj)
+        return 0;
+    const ObjectValue *objectValue = importsObj->typeScope();
     if (!objectValue)
         return 0;
 
@@ -1466,7 +1471,12 @@ const ObjectValue *Context::lookupType(const QmlJS::Document *doc, UiQualifiedId
 
 const ObjectValue *Context::lookupType(const QmlJS::Document *doc, const QStringList &qmlTypeName) const
 {
-    const ObjectValue *objectValue = typeEnvironment(doc);
+    const Imports *importsObj = imports(doc);
+    if (!importsObj)
+        return 0;
+    const ObjectValue *objectValue = importsObj->typeScope();
+    if (!objectValue)
+        return 0;
 
     foreach (const QString &name, qmlTypeName) {
         if (!objectValue)
@@ -3398,25 +3408,30 @@ UiImport *ImportInfo::ast() const
     return _ast;
 }
 
-TypeEnvironment::Import::Import()
+Import::Import()
     : object(0)
 {}
 
-TypeEnvironment::TypeEnvironment(Engine *engine)
+TypeScope::TypeScope(const Imports *imports, Engine *engine)
     : ObjectValue(engine)
+    , _imports(imports)
 {
 }
 
-const Value *TypeEnvironment::lookupMember(const QString &name, const Context *context,
+const Value *TypeScope::lookupMember(const QString &name, const Context *context,
                                            const ObjectValue **foundInObject, bool) const
 {
-    QListIterator<Import> it(_imports);
+    QListIterator<Import> it(_imports->all());
     it.toBack();
     while (it.hasPrevious()) {
         const Import &i = it.previous();
         const ObjectValue *import = i.object;
         const ImportInfo &info = i.info;
 
+        // JS import has no types
+        if (info.type() == ImportInfo::FileImport)
+            continue;
+
         if (!info.id().isEmpty()) {
             if (info.id() == name) {
                 if (foundInObject)
@@ -3426,48 +3441,91 @@ const Value *TypeEnvironment::lookupMember(const QString &name, const Context *c
             continue;
         }
 
-        if (info.type() == ImportInfo::FileImport) {
-            if (import->className() == name) {
-                if (foundInObject)
-                    *foundInObject = this;
-                return import;
-            }
-        } else {
-            if (const Value *v = import->lookupMember(name, context, foundInObject))
-                return v;
-        }
+        if (const Value *v = import->lookupMember(name, context, foundInObject))
+            return v;
     }
     if (foundInObject)
         *foundInObject = 0;
     return 0;
 }
 
-void TypeEnvironment::processMembers(MemberProcessor *processor) const
+void TypeScope::processMembers(MemberProcessor *processor) const
 {
-    QListIterator<Import> it(_imports);
+    QListIterator<Import> it(_imports->all());
     it.toBack();
     while (it.hasPrevious()) {
         const Import &i = it.previous();
         const ObjectValue *import = i.object;
         const ImportInfo &info = i.info;
 
+        // JS import has no types
+        if (info.type() == ImportInfo::FileImport)
+            continue;
+
         if (!info.id().isEmpty()) {
             processor->processProperty(info.id(), import);
         } else {
-            if (info.type() == ImportInfo::FileImport)
-                processor->processProperty(import->className(), import);
-            else
-                import->processMembers(processor);
+            import->processMembers(processor);
         }
     }
 }
 
-void TypeEnvironment::addImport(const Import &import)
+JSImportScope::JSImportScope(const Imports *imports, Engine *engine)
+    : ObjectValue(engine)
+    , _imports(imports)
+{
+}
+
+const Value *JSImportScope::lookupMember(const QString &name, const Context *,
+                                         const ObjectValue **foundInObject, bool) const
+{
+    QListIterator<Import> it(_imports->all());
+    it.toBack();
+    while (it.hasPrevious()) {
+        const Import &i = it.previous();
+        const ObjectValue *import = i.object;
+        const ImportInfo &info = i.info;
+
+        // JS imports are always: import "somefile.js" as Foo
+        if (info.type() != ImportInfo::FileImport)
+            continue;
+
+        if (info.id() == name) {
+            if (foundInObject)
+                *foundInObject = this;
+            return import;
+        }
+    }
+    if (foundInObject)
+        *foundInObject = 0;
+    return 0;
+}
+
+void JSImportScope::processMembers(MemberProcessor *processor) const
+{
+    QListIterator<Import> it(_imports->all());
+    it.toBack();
+    while (it.hasPrevious()) {
+        const Import &i = it.previous();
+        const ObjectValue *import = i.object;
+        const ImportInfo &info = i.info;
+
+        if (info.type() == ImportInfo::FileImport)
+            processor->processProperty(info.id(), import);
+    }
+}
+
+Imports::Imports(Engine *engine)
+    : _typeScope(new TypeScope(this, engine))
+    , _jsImportScope(new JSImportScope(this, engine))
+{}
+
+void Imports::append(const Import &import)
 {
     _imports.append(import);
 }
 
-ImportInfo TypeEnvironment::importInfo(const QString &name, const Context *context) const
+ImportInfo Imports::info(const QString &name, const Context *context) const
 {
     QString firstId = name;
     int dotIdx = firstId.indexOf(QLatin1Char('.'));
@@ -3498,11 +3556,21 @@ ImportInfo TypeEnvironment::importInfo(const QString &name, const Context *conte
     return ImportInfo();
 }
 
-QList<TypeEnvironment::Import> TypeEnvironment::imports() const
+QList<Import> Imports::all() const
 {
     return _imports;
 }
 
+const TypeScope *Imports::typeScope() const
+{
+    return _typeScope;
+}
+
+const JSImportScope *Imports::jsImportScope() const
+{
+    return _jsImportScope;
+}
+
 #ifdef QT_DEBUG
 
 class MemberDumper: public MemberProcessor
@@ -3541,9 +3609,9 @@ public:
     }
 };
 
-void TypeEnvironment::dump() const
+void Imports::dump() const
 {
-    qDebug() << "Type environment contents, in search order:";
+    qDebug() << "Imports contents, in search order:";
     QListIterator<Import> it(_imports);
     it.toBack();
     while (it.hasPrevious()) {
diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h
index 8af4981c60b..5c68ca493df 100644
--- a/src/libs/qmljs/qmljsinterpreter.h
+++ b/src/libs/qmljs/qmljsinterpreter.h
@@ -71,8 +71,9 @@ class FunctionValue;
 class Reference;
 class ColorValue;
 class AnchorLineValue;
-class TypeEnvironment;
-class AttachedTypeEnvironment;
+class Imports;
+class TypeScope;
+class JSImportScope;
 
 typedef QList<const Value *> ValueList;
 
@@ -303,7 +304,8 @@ public:
     const ObjectValue *globalScope;
     QSharedPointer<const QmlComponentChain> qmlComponentScope;
     QList<const ObjectValue *> qmlScopeObjects;
-    const TypeEnvironment *qmlTypes;
+    const TypeScope *qmlTypes;
+    const JSImportScope *jsImports;
     QList<const ObjectValue *> jsScopes;
 
     // rebuilds the flat list of all scopes
@@ -326,8 +328,8 @@ public:
     const ScopeChain &scopeChain() const;
     ScopeChain &scopeChain();
 
-    const TypeEnvironment *typeEnvironment(const Document *doc) const;
-    void setTypeEnvironment(const Document *doc, const TypeEnvironment *typeEnvironment);
+    const Imports *imports(const Document *doc) const;
+    void setImports(const Document *doc, const Imports *imports);
 
     const Value *lookup(const QString &name, const ObjectValue **foundInScope = 0) const;
     const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName) const;
@@ -345,7 +347,7 @@ private:
     Snapshot _snapshot;
     QSharedPointer<Engine> _engine;
     QHash<const ObjectValue *, Properties> _properties;
-    QHash<const Document *, const TypeEnvironment *> _typeEnvironments;
+    QHash<const Document *, QSharedPointer<const Imports> > _imports;
     ScopeChain _scopeChain;
     int _qmlScopeObjectIndex;
     bool _qmlScopeObjectSet;
@@ -1030,32 +1032,59 @@ private:
     AST::UiImport *_ast;
 };
 
-class QMLJS_EXPORT TypeEnvironment: public ObjectValue
+class QMLJS_EXPORT Import {
+public:
+    Import();
+
+    // const!
+    ObjectValue *object;
+    ImportInfo info;
+    // uri imports: path to library, else empty
+    QString libraryPath;
+};
+
+class Imports;
+
+class QMLJS_EXPORT TypeScope: public ObjectValue
 {
 public:
-    class Import {
-    public:
-        Import();
+    TypeScope(const Imports *imports, Engine *engine);
 
-        // const!
-        ObjectValue *object;
-        ImportInfo info;
-        // uri imports: path to library, else empty
-        QString libraryPath;
-    };
+    virtual const Value *lookupMember(const QString &name, const Context *context,
+                                      const ObjectValue **foundInObject = 0,
+                                      bool examinePrototypes = true) const;
+    virtual void processMembers(MemberProcessor *processor) const;
 
+private:
+    const Imports *_imports;
+};
+
+class QMLJS_EXPORT JSImportScope: public ObjectValue
+{
 public:
-    TypeEnvironment(Engine *engine);
+    JSImportScope(const Imports *imports, Engine *engine);
 
     virtual const Value *lookupMember(const QString &name, const Context *context,
                                       const ObjectValue **foundInObject = 0,
                                       bool examinePrototypes = true) const;
     virtual void processMembers(MemberProcessor *processor) const;
 
-    void addImport(const Import &import);
+private:
+    const Imports *_imports;
+};
+
+class QMLJS_EXPORT Imports
+{
+public:
+    Imports(Engine *engine);
+
+    void append(const Import &import);
+
+    ImportInfo info(const QString &name, const Context *context) const;
+    QList<Import> all() const;
 
-    ImportInfo importInfo(const QString &name, const Context *context) const;
-    QList<Import> imports() const;
+    const TypeScope *typeScope() const;
+    const JSImportScope *jsImportScope() const;
 
 #ifdef QT_DEBUG
     void dump() const;
@@ -1065,6 +1094,8 @@ private:
     // holds imports in the order they appeared,
     // lookup order is back to front
     QList<Import> _imports;
+    TypeScope *_typeScope;
+    JSImportScope *_jsImportScope;
 };
 
 } } // namespace QmlJS::Interpreter
diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp
index e18d10444d9..d5c883dacc9 100644
--- a/src/libs/qmljs/qmljslink.cpp
+++ b/src/libs/qmljs/qmljslink.cpp
@@ -89,7 +89,7 @@ public:
     Interpreter::Context *context;
     QStringList importPaths;
 
-    QHash<ImportCacheKey, TypeEnvironment::Import> importCache;
+    QHash<ImportCacheKey, Import> importCache;
 
     Document::Ptr doc;
     QList<DiagnosticMessage> *diagnosticMessages;
@@ -161,22 +161,22 @@ void Link::linkImports()
 
     if (d->doc) {
         // do it on d->doc first, to make sure import errors are shown
-        TypeEnvironment *typeEnv = new TypeEnvironment(engine());
-        populateImportedTypes(typeEnv, d->doc);
-        d->context->setTypeEnvironment(d->doc.data(), typeEnv);
+        Imports *imports = new Imports(engine());
+        populateImportedTypes(imports, d->doc);
+        d->context->setImports(d->doc.data(), imports);
     }
 
     foreach (Document::Ptr doc, d->snapshot) {
         if (doc == d->doc)
             continue;
 
-        TypeEnvironment *typeEnv = new TypeEnvironment(engine());
-        populateImportedTypes(typeEnv, doc);
-        d->context->setTypeEnvironment(doc.data(), typeEnv);
+        Imports *imports = new Imports(engine());
+        populateImportedTypes(imports, doc);
+        d->context->setImports(doc.data(), imports);
     }
 }
 
-void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
+void Link::populateImportedTypes(Imports *imports, Document::Ptr doc)
 {
     Q_D(Link);
 
@@ -184,15 +184,15 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
         return;
 
     // implicit imports: the <default> package is always available
-    loadImplicitDefaultImports(typeEnv);
+    loadImplicitDefaultImports(imports);
 
     // implicit imports:
     // qml files in the same directory are available without explicit imports
-    loadImplicitDirectoryImports(typeEnv, doc);
+    loadImplicitDirectoryImports(imports, doc);
 
     // explicit imports, whether directories, files or libraries
     foreach (const ImportInfo &info, doc->bind()->imports()) {
-        TypeEnvironment::Import import = d->importCache.value(ImportCacheKey(info));
+        Import import = d->importCache.value(ImportCacheKey(info));
 
         if (!import.object) {
             switch (info.type()) {
@@ -210,7 +210,7 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
                 d->importCache.insert(ImportCacheKey(info), import);
         }
         if (import.object)
-            typeEnv->addImport(import);
+            imports->append(import);
     }
 }
 
@@ -221,12 +221,14 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
     import "content" 4.6 as Xxx
 
     import "http://www.ovi.com/" as Ovi
+
+    import "file.js" as Foo
 */
-TypeEnvironment::Import Link::importFileOrDirectory(Document::Ptr doc, const ImportInfo &importInfo)
+Import Link::importFileOrDirectory(Document::Ptr doc, const ImportInfo &importInfo)
 {
     Q_D(Link);
 
-    TypeEnvironment::Import import;
+    Import import;
     import.info = importInfo;
     import.object = 0;
 
@@ -259,11 +261,11 @@ TypeEnvironment::Import Link::importFileOrDirectory(Document::Ptr doc, const Imp
   import Qt 4.6 as Xxx
   (import com.nokia.qt is the same as the ones above)
 */
-TypeEnvironment::Import Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo)
+Import Link::importNonFile(Document::Ptr doc, const ImportInfo &importInfo)
 {
     Q_D(Link);
 
-    TypeEnvironment::Import import;
+    Import import;
     import.info = importInfo;
     import.object = new ObjectValue(engine());
 
@@ -305,7 +307,7 @@ TypeEnvironment::Import Link::importNonFile(Document::Ptr doc, const ImportInfo
 
 bool Link::importLibrary(Document::Ptr doc,
                          const QString &libraryPath,
-                         TypeEnvironment::Import *import,
+                         Import *import,
                          const QString &importPath)
 {
     Q_D(Link);
@@ -435,32 +437,32 @@ void Link::loadQmldirComponents(Interpreter::ObjectValue *import, ComponentVersi
     }
 }
 
-void Link::loadImplicitDirectoryImports(TypeEnvironment *typeEnv, Document::Ptr doc)
+void Link::loadImplicitDirectoryImports(Imports *imports, Document::Ptr doc)
 {
     Q_D(Link);
 
     ImportInfo implcitDirectoryImportInfo(
                 ImportInfo::ImplicitDirectoryImport, doc->path());
 
-    TypeEnvironment::Import directoryImport = d->importCache.value(ImportCacheKey(implcitDirectoryImportInfo));
+    Import directoryImport = d->importCache.value(ImportCacheKey(implcitDirectoryImportInfo));
     if (!directoryImport.object) {
         directoryImport = importFileOrDirectory(doc, implcitDirectoryImportInfo);
         if (directoryImport.object)
             d->importCache.insert(ImportCacheKey(implcitDirectoryImportInfo), directoryImport);
     }
     if (directoryImport.object) {
-        typeEnv->addImport(directoryImport);
+        imports->append(directoryImport);
     }
 }
 
-void Link::loadImplicitDefaultImports(TypeEnvironment *typeEnv)
+void Link::loadImplicitDefaultImports(Imports *imports)
 {
     Q_D(Link);
 
     const QString defaultPackage = CppQmlTypes::defaultPackage;
     if (engine()->cppQmlTypes().hasPackage(defaultPackage)) {
         ImportInfo info(ImportInfo::LibraryImport, defaultPackage);
-        TypeEnvironment::Import import = d->importCache.value(ImportCacheKey(info));
+        Import import = d->importCache.value(ImportCacheKey(info));
         if (!import.object) {
             import.info = info;
             import.object = new ObjectValue(engine());
@@ -470,6 +472,6 @@ void Link::loadImplicitDefaultImports(TypeEnvironment *typeEnv)
             }
             d->importCache.insert(ImportCacheKey(info), import);
         }
-        typeEnv->addImport(import);
+        imports->append(import);
     }
 }
diff --git a/src/libs/qmljs/qmljslink.h b/src/libs/qmljs/qmljslink.h
index 338dd11d226..20b8272057e 100644
--- a/src/libs/qmljs/qmljslink.h
+++ b/src/libs/qmljs/qmljslink.h
@@ -73,25 +73,25 @@ private:
 
     void linkImports();
 
-    void populateImportedTypes(Interpreter::TypeEnvironment *typeEnv, Document::Ptr doc);
-    Interpreter::TypeEnvironment::Import importFileOrDirectory(
+    void populateImportedTypes(Interpreter::Imports *imports, Document::Ptr doc);
+    Interpreter::Import importFileOrDirectory(
         Document::Ptr doc,
         const Interpreter::ImportInfo &importInfo);
-    Interpreter::TypeEnvironment::Import importNonFile(
+    Interpreter::Import importNonFile(
         Document::Ptr doc,
         const Interpreter::ImportInfo &importInfo);
     void importObject(Bind *bind, const QString &name, Interpreter::ObjectValue *object, NameId *targetNamespace);
 
     bool importLibrary(Document::Ptr doc,
                        const QString &libraryPath,
-                       Interpreter::TypeEnvironment::Import *import,
+                       Interpreter::Import *import,
                        const QString &importPath = QString());
     void loadQmldirComponents(Interpreter::ObjectValue *import,
                               LanguageUtils::ComponentVersion version,
                               const LibraryInfo &libraryInfo,
                               const QString &libraryPath);
-    void loadImplicitDirectoryImports(Interpreter::TypeEnvironment *typeEnv, Document::Ptr doc);
-    void loadImplicitDefaultImports(Interpreter::TypeEnvironment *typeEnv);
+    void loadImplicitDirectoryImports(Interpreter::Imports *imports, Document::Ptr doc);
+    void loadImplicitDefaultImports(Interpreter::Imports *imports);
 
     void error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);
     void warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);
diff --git a/src/libs/qmljs/qmljsscopebuilder.cpp b/src/libs/qmljs/qmljsscopebuilder.cpp
index 62f43c1e5c2..5fb853aa0a2 100644
--- a/src/libs/qmljs/qmljsscopebuilder.cpp
+++ b/src/libs/qmljs/qmljsscopebuilder.cpp
@@ -127,8 +127,9 @@ void ScopeBuilder::initializeRootScope()
         componentScopes.insert(_doc.data(), chain);
         makeComponentChain(_doc, snapshot, chain, &componentScopes);
 
-        if (const TypeEnvironment *typeEnvironment = _context->typeEnvironment(_doc.data())) {
-            scopeChain.qmlTypes = typeEnvironment;
+        if (const Imports *imports = _context->imports(_doc.data())) {
+            scopeChain.qmlTypes = imports->typeScope();
+            scopeChain.jsImports = imports->jsImportScope();
         }
     } else {
         // add scope chains for all components that import this file
diff --git a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
index ebdaf7b5ed2..a5367d49ffd 100644
--- a/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
+++ b/src/plugins/qmldesigner/designercore/model/texttomodelmerger.cpp
@@ -358,8 +358,8 @@ public:
             majorVersion = ComponentVersion::NoVersion;
             minorVersion = ComponentVersion::NoVersion;
 
-            const Interpreter::TypeEnvironment *typeEnv = m_lookupContext->context()->typeEnvironment(m_lookupContext->document().data());
-            Interpreter::ImportInfo importInfo = typeEnv->importInfo(fullTypeName, m_context);
+            const Interpreter::Imports *imports = m_lookupContext->context()->imports(m_lookupContext->document().data());
+            Interpreter::ImportInfo importInfo = imports->info(fullTypeName, m_context);
             if (importInfo.isValid() && importInfo.type() == Interpreter::ImportInfo::LibraryImport) {
                 QString name = importInfo.name().replace("\\", ".");
                 majorVersion = importInfo.version().majorVersion();
diff --git a/src/plugins/qmljseditor/qmljshoverhandler.cpp b/src/plugins/qmljseditor/qmljshoverhandler.cpp
index c7b07a30f8e..aee2154618e 100644
--- a/src/plugins/qmljseditor/qmljshoverhandler.cpp
+++ b/src/plugins/qmljseditor/qmljshoverhandler.cpp
@@ -219,11 +219,11 @@ void HoverHandler::handleOrdinaryMatch(const LookupContext::Ptr &lookupContext,
 
 void HoverHandler::handleImport(const LookupContext::Ptr &lookupContext, AST::UiImport *node)
 {
-    const Interpreter::TypeEnvironment *typeEnv = lookupContext->context()->typeEnvironment(lookupContext->document().data());
-    if (!typeEnv)
+    const Interpreter::Imports *imports = lookupContext->context()->imports(lookupContext->document().data());
+    if (!imports)
         return;
 
-    foreach (const Interpreter::TypeEnvironment::Import &import, typeEnv->imports()) {
+    foreach (const Interpreter::Import &import, imports->all()) {
         if (import.info.ast() == node) {
             if (import.info.type() == Interpreter::ImportInfo::LibraryImport
                     && !import.libraryPath.isEmpty()) {
-- 
GitLab