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>
This commit is contained in:
Christian Kamm
2011-05-27 10:43:06 +02:00
parent ca1eaca136
commit a7f4e5fab5
7 changed files with 194 additions and 92 deletions

View File

@@ -1308,6 +1308,7 @@ void StringValue::accept(ValueVisitor *visitor) const
ScopeChain::ScopeChain() ScopeChain::ScopeChain()
: globalScope(0) : globalScope(0)
, qmlTypes(0) , qmlTypes(0)
, jsImports(0)
{ {
} }
@@ -1369,7 +1370,8 @@ void ScopeChain::update()
_all += ids; _all += ids;
if (qmlTypes) if (qmlTypes)
_all += qmlTypes; _all += qmlTypes;
// qmlTypes are not added on purpose if (jsImports)
_all += jsImports;
_all += jsScopes; _all += jsScopes;
} }
@@ -1412,18 +1414,18 @@ ScopeChain &Context::scopeChain()
return _scopeChain; return _scopeChain;
} }
const TypeEnvironment *Context::typeEnvironment(const QmlJS::Document *doc) const const Imports *Context::imports(const QmlJS::Document *doc) const
{ {
if (!doc) if (!doc)
return 0; 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) if (!doc)
return; return;
_typeEnvironments[doc] = typeEnvironment; _imports[doc] = QSharedPointer<const Imports>(imports);
} }
const Value *Context::lookup(const QString &name, const ObjectValue **foundInScope) const 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 *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) if (!objectValue)
return 0; 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 *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) { foreach (const QString &name, qmlTypeName) {
if (!objectValue) if (!objectValue)
@@ -3398,25 +3408,30 @@ UiImport *ImportInfo::ast() const
return _ast; return _ast;
} }
TypeEnvironment::Import::Import() Import::Import()
: object(0) : object(0)
{} {}
TypeEnvironment::TypeEnvironment(Engine *engine) TypeScope::TypeScope(const Imports *imports, Engine *engine)
: ObjectValue(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 const ObjectValue **foundInObject, bool) const
{ {
QListIterator<Import> it(_imports); QListIterator<Import> it(_imports->all());
it.toBack(); it.toBack();
while (it.hasPrevious()) { while (it.hasPrevious()) {
const Import &i = it.previous(); const Import &i = it.previous();
const ObjectValue *import = i.object; const ObjectValue *import = i.object;
const ImportInfo &info = i.info; const ImportInfo &info = i.info;
// JS import has no types
if (info.type() == ImportInfo::FileImport)
continue;
if (!info.id().isEmpty()) { if (!info.id().isEmpty()) {
if (info.id() == name) { if (info.id() == name) {
if (foundInObject) if (foundInObject)
@@ -3426,48 +3441,91 @@ const Value *TypeEnvironment::lookupMember(const QString &name, const Context *c
continue; continue;
} }
if (info.type() == ImportInfo::FileImport) { if (const Value *v = import->lookupMember(name, context, foundInObject))
if (import->className() == name) { return v;
}
if (foundInObject)
*foundInObject = 0;
return 0;
}
void TypeScope::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;
// JS import has no types
if (info.type() == ImportInfo::FileImport)
continue;
if (!info.id().isEmpty()) {
processor->processProperty(info.id(), import);
} else {
import->processMembers(processor);
}
}
}
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) if (foundInObject)
*foundInObject = this; *foundInObject = this;
return import; return import;
} }
} else {
if (const Value *v = import->lookupMember(name, context, foundInObject))
return v;
}
} }
if (foundInObject) if (foundInObject)
*foundInObject = 0; *foundInObject = 0;
return 0; return 0;
} }
void TypeEnvironment::processMembers(MemberProcessor *processor) const void JSImportScope::processMembers(MemberProcessor *processor) const
{ {
QListIterator<Import> it(_imports); QListIterator<Import> it(_imports->all());
it.toBack(); it.toBack();
while (it.hasPrevious()) { while (it.hasPrevious()) {
const Import &i = it.previous(); const Import &i = it.previous();
const ObjectValue *import = i.object; const ObjectValue *import = i.object;
const ImportInfo &info = i.info; const ImportInfo &info = i.info;
if (!info.id().isEmpty()) {
processor->processProperty(info.id(), import);
} else {
if (info.type() == ImportInfo::FileImport) if (info.type() == ImportInfo::FileImport)
processor->processProperty(import->className(), import); processor->processProperty(info.id(), import);
else
import->processMembers(processor);
}
} }
} }
void TypeEnvironment::addImport(const Import &import) Imports::Imports(Engine *engine)
: _typeScope(new TypeScope(this, engine))
, _jsImportScope(new JSImportScope(this, engine))
{}
void Imports::append(const Import &import)
{ {
_imports.append(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; QString firstId = name;
int dotIdx = firstId.indexOf(QLatin1Char('.')); int dotIdx = firstId.indexOf(QLatin1Char('.'));
@@ -3498,11 +3556,21 @@ ImportInfo TypeEnvironment::importInfo(const QString &name, const Context *conte
return ImportInfo(); return ImportInfo();
} }
QList<TypeEnvironment::Import> TypeEnvironment::imports() const QList<Import> Imports::all() const
{ {
return _imports; return _imports;
} }
const TypeScope *Imports::typeScope() const
{
return _typeScope;
}
const JSImportScope *Imports::jsImportScope() const
{
return _jsImportScope;
}
#ifdef QT_DEBUG #ifdef QT_DEBUG
class MemberDumper: public MemberProcessor 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); QListIterator<Import> it(_imports);
it.toBack(); it.toBack();
while (it.hasPrevious()) { while (it.hasPrevious()) {

View File

@@ -71,8 +71,9 @@ class FunctionValue;
class Reference; class Reference;
class ColorValue; class ColorValue;
class AnchorLineValue; class AnchorLineValue;
class TypeEnvironment; class Imports;
class AttachedTypeEnvironment; class TypeScope;
class JSImportScope;
typedef QList<const Value *> ValueList; typedef QList<const Value *> ValueList;
@@ -303,7 +304,8 @@ public:
const ObjectValue *globalScope; const ObjectValue *globalScope;
QSharedPointer<const QmlComponentChain> qmlComponentScope; QSharedPointer<const QmlComponentChain> qmlComponentScope;
QList<const ObjectValue *> qmlScopeObjects; QList<const ObjectValue *> qmlScopeObjects;
const TypeEnvironment *qmlTypes; const TypeScope *qmlTypes;
const JSImportScope *jsImports;
QList<const ObjectValue *> jsScopes; QList<const ObjectValue *> jsScopes;
// rebuilds the flat list of all scopes // rebuilds the flat list of all scopes
@@ -326,8 +328,8 @@ public:
const ScopeChain &scopeChain() const; const ScopeChain &scopeChain() const;
ScopeChain &scopeChain(); ScopeChain &scopeChain();
const TypeEnvironment *typeEnvironment(const Document *doc) const; const Imports *imports(const Document *doc) const;
void setTypeEnvironment(const Document *doc, const TypeEnvironment *typeEnvironment); void setImports(const Document *doc, const Imports *imports);
const Value *lookup(const QString &name, const ObjectValue **foundInScope = 0) const; const Value *lookup(const QString &name, const ObjectValue **foundInScope = 0) const;
const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName) const; const ObjectValue *lookupType(const Document *doc, AST::UiQualifiedId *qmlTypeName) const;
@@ -345,7 +347,7 @@ private:
Snapshot _snapshot; Snapshot _snapshot;
QSharedPointer<Engine> _engine; QSharedPointer<Engine> _engine;
QHash<const ObjectValue *, Properties> _properties; QHash<const ObjectValue *, Properties> _properties;
QHash<const Document *, const TypeEnvironment *> _typeEnvironments; QHash<const Document *, QSharedPointer<const Imports> > _imports;
ScopeChain _scopeChain; ScopeChain _scopeChain;
int _qmlScopeObjectIndex; int _qmlScopeObjectIndex;
bool _qmlScopeObjectSet; bool _qmlScopeObjectSet;
@@ -1030,10 +1032,7 @@ private:
AST::UiImport *_ast; AST::UiImport *_ast;
}; };
class QMLJS_EXPORT TypeEnvironment: public ObjectValue class QMLJS_EXPORT Import {
{
public:
class Import {
public: public:
Import(); Import();
@@ -1044,18 +1043,48 @@ public:
QString libraryPath; QString libraryPath;
}; };
class Imports;
class QMLJS_EXPORT TypeScope: public ObjectValue
{
public: public:
TypeEnvironment(Engine *engine); TypeScope(const Imports *imports, Engine *engine);
virtual const Value *lookupMember(const QString &name, const Context *context, virtual const Value *lookupMember(const QString &name, const Context *context,
const ObjectValue **foundInObject = 0, const ObjectValue **foundInObject = 0,
bool examinePrototypes = true) const; bool examinePrototypes = true) const;
virtual void processMembers(MemberProcessor *processor) const; virtual void processMembers(MemberProcessor *processor) const;
void addImport(const Import &import); private:
const Imports *_imports;
};
ImportInfo importInfo(const QString &name, const Context *context) const; class QMLJS_EXPORT JSImportScope: public ObjectValue
QList<Import> imports() const; {
public:
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;
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;
const TypeScope *typeScope() const;
const JSImportScope *jsImportScope() const;
#ifdef QT_DEBUG #ifdef QT_DEBUG
void dump() const; void dump() const;
@@ -1065,6 +1094,8 @@ private:
// holds imports in the order they appeared, // holds imports in the order they appeared,
// lookup order is back to front // lookup order is back to front
QList<Import> _imports; QList<Import> _imports;
TypeScope *_typeScope;
JSImportScope *_jsImportScope;
}; };
} } // namespace QmlJS::Interpreter } } // namespace QmlJS::Interpreter

View File

@@ -89,7 +89,7 @@ public:
Interpreter::Context *context; Interpreter::Context *context;
QStringList importPaths; QStringList importPaths;
QHash<ImportCacheKey, TypeEnvironment::Import> importCache; QHash<ImportCacheKey, Import> importCache;
Document::Ptr doc; Document::Ptr doc;
QList<DiagnosticMessage> *diagnosticMessages; QList<DiagnosticMessage> *diagnosticMessages;
@@ -161,22 +161,22 @@ void Link::linkImports()
if (d->doc) { if (d->doc) {
// do it on d->doc first, to make sure import errors are shown // do it on d->doc first, to make sure import errors are shown
TypeEnvironment *typeEnv = new TypeEnvironment(engine()); Imports *imports = new Imports(engine());
populateImportedTypes(typeEnv, d->doc); populateImportedTypes(imports, d->doc);
d->context->setTypeEnvironment(d->doc.data(), typeEnv); d->context->setImports(d->doc.data(), imports);
} }
foreach (Document::Ptr doc, d->snapshot) { foreach (Document::Ptr doc, d->snapshot) {
if (doc == d->doc) if (doc == d->doc)
continue; continue;
TypeEnvironment *typeEnv = new TypeEnvironment(engine()); Imports *imports = new Imports(engine());
populateImportedTypes(typeEnv, doc); populateImportedTypes(imports, doc);
d->context->setTypeEnvironment(doc.data(), typeEnv); 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); Q_D(Link);
@@ -184,15 +184,15 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
return; return;
// implicit imports: the <default> package is always available // implicit imports: the <default> package is always available
loadImplicitDefaultImports(typeEnv); loadImplicitDefaultImports(imports);
// implicit imports: // implicit imports:
// qml files in the same directory are available without explicit 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 // explicit imports, whether directories, files or libraries
foreach (const ImportInfo &info, doc->bind()->imports()) { 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) { if (!import.object) {
switch (info.type()) { switch (info.type()) {
@@ -210,7 +210,7 @@ void Link::populateImportedTypes(TypeEnvironment *typeEnv, Document::Ptr doc)
d->importCache.insert(ImportCacheKey(info), import); d->importCache.insert(ImportCacheKey(info), import);
} }
if (import.object) 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 "content" 4.6 as Xxx
import "http://www.ovi.com/" as Ovi 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); Q_D(Link);
TypeEnvironment::Import import; Import import;
import.info = importInfo; import.info = importInfo;
import.object = 0; import.object = 0;
@@ -259,11 +261,11 @@ TypeEnvironment::Import Link::importFileOrDirectory(Document::Ptr doc, const Imp
import Qt 4.6 as Xxx import Qt 4.6 as Xxx
(import com.nokia.qt is the same as the ones above) (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); Q_D(Link);
TypeEnvironment::Import import; Import import;
import.info = importInfo; import.info = importInfo;
import.object = new ObjectValue(engine()); import.object = new ObjectValue(engine());
@@ -305,7 +307,7 @@ TypeEnvironment::Import Link::importNonFile(Document::Ptr doc, const ImportInfo
bool Link::importLibrary(Document::Ptr doc, bool Link::importLibrary(Document::Ptr doc,
const QString &libraryPath, const QString &libraryPath,
TypeEnvironment::Import *import, Import *import,
const QString &importPath) const QString &importPath)
{ {
Q_D(Link); 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); Q_D(Link);
ImportInfo implcitDirectoryImportInfo( ImportInfo implcitDirectoryImportInfo(
ImportInfo::ImplicitDirectoryImport, doc->path()); ImportInfo::ImplicitDirectoryImport, doc->path());
TypeEnvironment::Import directoryImport = d->importCache.value(ImportCacheKey(implcitDirectoryImportInfo)); Import directoryImport = d->importCache.value(ImportCacheKey(implcitDirectoryImportInfo));
if (!directoryImport.object) { if (!directoryImport.object) {
directoryImport = importFileOrDirectory(doc, implcitDirectoryImportInfo); directoryImport = importFileOrDirectory(doc, implcitDirectoryImportInfo);
if (directoryImport.object) if (directoryImport.object)
d->importCache.insert(ImportCacheKey(implcitDirectoryImportInfo), directoryImport); d->importCache.insert(ImportCacheKey(implcitDirectoryImportInfo), directoryImport);
} }
if (directoryImport.object) { if (directoryImport.object) {
typeEnv->addImport(directoryImport); imports->append(directoryImport);
} }
} }
void Link::loadImplicitDefaultImports(TypeEnvironment *typeEnv) void Link::loadImplicitDefaultImports(Imports *imports)
{ {
Q_D(Link); Q_D(Link);
const QString defaultPackage = CppQmlTypes::defaultPackage; const QString defaultPackage = CppQmlTypes::defaultPackage;
if (engine()->cppQmlTypes().hasPackage(defaultPackage)) { if (engine()->cppQmlTypes().hasPackage(defaultPackage)) {
ImportInfo info(ImportInfo::LibraryImport, defaultPackage); ImportInfo info(ImportInfo::LibraryImport, defaultPackage);
TypeEnvironment::Import import = d->importCache.value(ImportCacheKey(info)); Import import = d->importCache.value(ImportCacheKey(info));
if (!import.object) { if (!import.object) {
import.info = info; import.info = info;
import.object = new ObjectValue(engine()); import.object = new ObjectValue(engine());
@@ -470,6 +472,6 @@ void Link::loadImplicitDefaultImports(TypeEnvironment *typeEnv)
} }
d->importCache.insert(ImportCacheKey(info), import); d->importCache.insert(ImportCacheKey(info), import);
} }
typeEnv->addImport(import); imports->append(import);
} }
} }

View File

@@ -73,25 +73,25 @@ private:
void linkImports(); void linkImports();
void populateImportedTypes(Interpreter::TypeEnvironment *typeEnv, Document::Ptr doc); void populateImportedTypes(Interpreter::Imports *imports, Document::Ptr doc);
Interpreter::TypeEnvironment::Import importFileOrDirectory( Interpreter::Import importFileOrDirectory(
Document::Ptr doc, Document::Ptr doc,
const Interpreter::ImportInfo &importInfo); const Interpreter::ImportInfo &importInfo);
Interpreter::TypeEnvironment::Import importNonFile( Interpreter::Import importNonFile(
Document::Ptr doc, Document::Ptr doc,
const Interpreter::ImportInfo &importInfo); const Interpreter::ImportInfo &importInfo);
void importObject(Bind *bind, const QString &name, Interpreter::ObjectValue *object, NameId *targetNamespace); void importObject(Bind *bind, const QString &name, Interpreter::ObjectValue *object, NameId *targetNamespace);
bool importLibrary(Document::Ptr doc, bool importLibrary(Document::Ptr doc,
const QString &libraryPath, const QString &libraryPath,
Interpreter::TypeEnvironment::Import *import, Interpreter::Import *import,
const QString &importPath = QString()); const QString &importPath = QString());
void loadQmldirComponents(Interpreter::ObjectValue *import, void loadQmldirComponents(Interpreter::ObjectValue *import,
LanguageUtils::ComponentVersion version, LanguageUtils::ComponentVersion version,
const LibraryInfo &libraryInfo, const LibraryInfo &libraryInfo,
const QString &libraryPath); const QString &libraryPath);
void loadImplicitDirectoryImports(Interpreter::TypeEnvironment *typeEnv, Document::Ptr doc); void loadImplicitDirectoryImports(Interpreter::Imports *imports, Document::Ptr doc);
void loadImplicitDefaultImports(Interpreter::TypeEnvironment *typeEnv); void loadImplicitDefaultImports(Interpreter::Imports *imports);
void error(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message); 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); void warning(const Document::Ptr &doc, const AST::SourceLocation &loc, const QString &message);

View File

@@ -127,8 +127,9 @@ void ScopeBuilder::initializeRootScope()
componentScopes.insert(_doc.data(), chain); componentScopes.insert(_doc.data(), chain);
makeComponentChain(_doc, snapshot, chain, &componentScopes); makeComponentChain(_doc, snapshot, chain, &componentScopes);
if (const TypeEnvironment *typeEnvironment = _context->typeEnvironment(_doc.data())) { if (const Imports *imports = _context->imports(_doc.data())) {
scopeChain.qmlTypes = typeEnvironment; scopeChain.qmlTypes = imports->typeScope();
scopeChain.jsImports = imports->jsImportScope();
} }
} else { } else {
// add scope chains for all components that import this file // add scope chains for all components that import this file

View File

@@ -358,8 +358,8 @@ public:
majorVersion = ComponentVersion::NoVersion; majorVersion = ComponentVersion::NoVersion;
minorVersion = ComponentVersion::NoVersion; minorVersion = ComponentVersion::NoVersion;
const Interpreter::TypeEnvironment *typeEnv = m_lookupContext->context()->typeEnvironment(m_lookupContext->document().data()); const Interpreter::Imports *imports = m_lookupContext->context()->imports(m_lookupContext->document().data());
Interpreter::ImportInfo importInfo = typeEnv->importInfo(fullTypeName, m_context); Interpreter::ImportInfo importInfo = imports->info(fullTypeName, m_context);
if (importInfo.isValid() && importInfo.type() == Interpreter::ImportInfo::LibraryImport) { if (importInfo.isValid() && importInfo.type() == Interpreter::ImportInfo::LibraryImport) {
QString name = importInfo.name().replace("\\", "."); QString name = importInfo.name().replace("\\", ".");
majorVersion = importInfo.version().majorVersion(); majorVersion = importInfo.version().majorVersion();

View File

@@ -219,11 +219,11 @@ void HoverHandler::handleOrdinaryMatch(const LookupContext::Ptr &lookupContext,
void HoverHandler::handleImport(const LookupContext::Ptr &lookupContext, AST::UiImport *node) void HoverHandler::handleImport(const LookupContext::Ptr &lookupContext, AST::UiImport *node)
{ {
const Interpreter::TypeEnvironment *typeEnv = lookupContext->context()->typeEnvironment(lookupContext->document().data()); const Interpreter::Imports *imports = lookupContext->context()->imports(lookupContext->document().data());
if (!typeEnv) if (!imports)
return; return;
foreach (const Interpreter::TypeEnvironment::Import &import, typeEnv->imports()) { foreach (const Interpreter::Import &import, imports->all()) {
if (import.info.ast() == node) { if (import.info.ast() == node) {
if (import.info.type() == Interpreter::ImportInfo::LibraryImport if (import.info.type() == Interpreter::ImportInfo::LibraryImport
&& !import.libraryPath.isEmpty()) { && !import.libraryPath.isEmpty()) {