QmlJS: Fix resolution of "alias" directives in qrc files

Previously qrc paths of QML/JS documents were not considered for
implicit imports. Only the path of the document in the file system
was considered. The QML engine, however, doesn't know the original
path at all and only uses the qrc paths for import resolution. This
created a mismatch between what the QML engine could recognize and
what the code model suggested.

Without alias directives, any files imported from a qrc file would
have to reside in the same directory as the one implicitly importing
them, so this arrangement happened to work, most of the time.

In order to support aliases we have to search the files in the same
qrc path to figure out the imports. To do that, we keep a reverse
map of qrc paths to files in the QrcParser and iterate that when
resolving imports.

Change-Id: I84baae6cbfbe96ddd5322c81494c1e4a3f473f3f
Reviewed-by: Eike Ziller <eike.ziller@theqtcompany.com>
Reviewed-by: Tobias Hunger <tobias.hunger@theqtcompany.com>
This commit is contained in:
Ulf Hermann
2016-03-18 17:43:33 +01:00
parent 9af85186e6
commit 35bafd3952
7 changed files with 114 additions and 57 deletions

View File

@@ -575,16 +575,23 @@ void LinkPrivate::loadQmldirComponents(ObjectValue *import, ComponentVersion ver
void LinkPrivate::loadImplicitDirectoryImports(Imports *imports, Document::Ptr doc)
{
ImportInfo implcitDirectoryImportInfo = ImportInfo::implicitDirectoryImport(doc->path());
Import directoryImport = importCache.value(ImportCacheKey(implcitDirectoryImportInfo));
if (!directoryImport.object) {
directoryImport = importFileOrDirectory(doc, implcitDirectoryImportInfo);
auto processImport = [this, imports, doc](const ImportInfo &importInfo){
Import directoryImport = importCache.value(ImportCacheKey(importInfo));
if (!directoryImport.object) {
directoryImport = importFileOrDirectory(doc, importInfo);
if (directoryImport.object)
importCache.insert(ImportCacheKey(importInfo), directoryImport);
}
if (directoryImport.object)
importCache.insert(ImportCacheKey(implcitDirectoryImportInfo), directoryImport);
imports->append(directoryImport);
};
processImport(ImportInfo::implicitDirectoryImport(doc->path()));
foreach (const QString &path,
ModelManagerInterface::instance()->qrcPathsForFile(doc->fileName())) {
processImport(ImportInfo::qrcDirectoryImport(
QrcParser::qrcDirectoryPathForQrcFilePath(path)));
}
if (directoryImport.object)
imports->append(directoryImport);
}
void LinkPrivate::loadImplicitDefaultImports(Imports *imports)