diff --git a/src/libs/qmljs/qmljsinterpreter.cpp b/src/libs/qmljs/qmljsinterpreter.cpp index 00959abc307..078ee96ad8c 100644 --- a/src/libs/qmljs/qmljsinterpreter.cpp +++ b/src/libs/qmljs/qmljsinterpreter.cpp @@ -2277,6 +2277,14 @@ ImportInfo ImportInfo::implicitDirectoryImport(const QString &directory) return info; } +ImportInfo ImportInfo::qrcDirectoryImport(const QString &directory) +{ + ImportInfo info; + info.m_type = ImportType::QrcDirectory; + info.m_path = directory; + return info; +} + bool ImportInfo::isValid() const { return m_type != ImportType::Invalid; diff --git a/src/libs/qmljs/qmljsinterpreter.h b/src/libs/qmljs/qmljsinterpreter.h index 4ceece5e3da..02e22e2f4cb 100644 --- a/src/libs/qmljs/qmljsinterpreter.h +++ b/src/libs/qmljs/qmljsinterpreter.h @@ -1002,6 +1002,7 @@ public: const QString &as, AST::UiImport *ast = 0); static ImportInfo invalidImport(AST::UiImport *ast = 0); static ImportInfo implicitDirectoryImport(const QString &directory); + static ImportInfo qrcDirectoryImport(const QString &directory); bool isValid() const; ImportType::Enum type() const; diff --git a/src/libs/qmljs/qmljslink.cpp b/src/libs/qmljs/qmljslink.cpp index 1f3045a675a..f46b228547b 100644 --- a/src/libs/qmljs/qmljslink.cpp +++ b/src/libs/qmljs/qmljslink.cpp @@ -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) diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp index de0ad9d61a5..75cea106844 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp @@ -427,46 +427,10 @@ bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1, const Mo } -QStringList ModelManagerInterface::filesAtQrcPath(const QString &path, const QLocale *locale, - ProjectExplorer::Project *project, - QrcResourceSelector resources) +void ModelManagerInterface::iterateQrcFiles(ProjectExplorer::Project *project, + QrcResourceSelector resources, + std::function callback) { - QString normPath = QrcParser::normalizedQrcFilePath(path); - QList pInfos; - if (project) - pInfos.append(projectInfo(project)); - else - pInfos = projectInfos(); - - QStringList res; - QSet pathsChecked; - foreach (const ModelManagerInterface::ProjectInfo &pInfo, pInfos) { - QStringList qrcFilePaths; - if (resources == ActiveQrcResources) - qrcFilePaths = pInfo.activeResourceFiles; - else - qrcFilePaths = pInfo.allResourceFiles; - foreach (const QString &qrcFilePath, qrcFilePaths) { - if (pathsChecked.contains(qrcFilePath)) - continue; - pathsChecked.insert(qrcFilePath); - QrcParser::ConstPtr qrcFile = m_qrcCache.parsedPath(qrcFilePath); - if (qrcFile.isNull()) - continue; - qrcFile->collectFilesAtPath(normPath, &res, locale); - } - } - res.sort(); // make the result predictable - return res; -} - -QMap ModelManagerInterface::filesInQrcPath(const QString &path, - const QLocale *locale, - ProjectExplorer::Project *project, - bool addDirs, - QrcResourceSelector resources) -{ - QString normPath = QrcParser::normalizedQrcDirectoryPath(path); QList pInfos; if (project) { pInfos.append(projectInfo(project)); @@ -477,7 +441,7 @@ QMap ModelManagerInterface::filesInQrcPath(const QString & else qSort(pInfos.begin(), pInfos.end(), &pInfoLessThanAll); } - QMap res; + QSet pathsChecked; foreach (const ModelManagerInterface::ProjectInfo &pInfo, pInfos) { QStringList qrcFilePaths; @@ -490,12 +454,47 @@ QMap ModelManagerInterface::filesInQrcPath(const QString & continue; pathsChecked.insert(qrcFilePath); QrcParser::ConstPtr qrcFile = m_qrcCache.parsedPath(qrcFilePath); - if (qrcFile.isNull()) continue; - qrcFile->collectFilesInPath(normPath, &res, addDirs, locale); + callback(qrcFile); } } +} + +QStringList ModelManagerInterface::qrcPathsForFile(const QString &file, const QLocale *locale, + ProjectExplorer::Project *project, + QrcResourceSelector resources) +{ + QStringList res; + iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) { + qrcFile->collectResourceFilesForSourceFile(file, &res, locale); + }); + return res; +} + +QStringList ModelManagerInterface::filesAtQrcPath(const QString &path, const QLocale *locale, + ProjectExplorer::Project *project, + QrcResourceSelector resources) +{ + QString normPath = QrcParser::normalizedQrcFilePath(path); + QStringList res; + iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) { + qrcFile->collectFilesAtPath(normPath, &res, locale); + }); + return res; +} + +QMap ModelManagerInterface::filesInQrcPath(const QString &path, + const QLocale *locale, + ProjectExplorer::Project *project, + bool addDirs, + QrcResourceSelector resources) +{ + QString normPath = QrcParser::normalizedQrcDirectoryPath(path); + QMap res; + iterateQrcFiles(project, resources, [&](QrcParser::ConstPtr qrcFile) { + qrcFile->collectFilesInPath(normPath, &res, addDirs, locale); + }); return res; } diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h index 690b178ec8a..ceeacc94f22 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.h +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h @@ -153,6 +153,9 @@ public: bool emitDocumentOnDiskChanged); void fileChangedOnDisk(const QString &path); void removeFiles(const QStringList &files); + QStringList qrcPathsForFile(const QString &file, const QLocale *locale = 0, + ProjectExplorer::Project *project = 0, + QrcResourceSelector resources = AllQrcResources); QStringList filesAtQrcPath(const QString &path, const QLocale *locale = 0, ProjectExplorer::Project *project = 0, QrcResourceSelector resources = AllQrcResources); @@ -250,6 +253,9 @@ protected: private: void cleanupFutures(); + void iterateQrcFiles(ProjectExplorer::Project *project, + QrcResourceSelector resources, + std::function callback); mutable QMutex m_mutex; QmlJS::Snapshot m_validSnapshot; diff --git a/src/libs/qmljs/qmljsqrcparser.cpp b/src/libs/qmljs/qmljsqrcparser.cpp index 7439343f71a..6b07fc1d135 100644 --- a/src/libs/qmljs/qmljsqrcparser.cpp +++ b/src/libs/qmljs/qmljsqrcparser.cpp @@ -74,6 +74,9 @@ public: bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const; void collectFilesInPath(const QString &path, QMap *res, bool addDirs = false, const QLocale *locale = 0) const; + void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *res, + const QLocale *locale = 0) const; + QStringList errorMessages() const; QStringList languages() const; private: @@ -81,6 +84,7 @@ private: QStringList allUiLanguages(const QLocale *locale) const; SMap m_resources; + SMap m_files; QStringList m_languages; QStringList m_errorMessages; }; @@ -130,6 +134,11 @@ QString QrcParser::normalizedQrcDirectoryPath(const QString &path) { return normPath; } +QString QrcParser::qrcDirectoryPathForQrcFilePath(const QString &file) +{ + return file.left(file.lastIndexOf(QLatin1Char('/'))); +} + QrcParser::QrcParser() { d = new Internal::QrcParserPrivate(this); @@ -181,6 +190,12 @@ void QrcParser::collectFilesInPath(const QString &path, QMapcollectFilesInPath(path, res, addDirs, locale); } +void QrcParser::collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *res, + const QLocale *locale) const +{ + d->collectResourceFilesForSourceFile(sourceFile, res, locale); +} + /*! \brief returns the errors found while parsing */ QStringList QrcParser::errorMessages() const @@ -297,13 +312,12 @@ bool QrcParserPrivate::parseFile(const QString &path) accessPath = language + prefix + alias; else accessPath = language + prefix + fileName; - if (m_resources.contains(accessPath)) { - QStringList &val = m_resources[accessPath]; - if (!val.contains(filePath)) - val.append(filePath); - } else { - m_resources.insert(accessPath, QStringList(filePath)); - } + QStringList &resources = m_resources[accessPath]; + if (!resources.contains(filePath)) + resources.append(filePath); + QStringList &files = m_files[filePath]; + if (!files.contains(accessPath)) + files.append(accessPath); } } return true; @@ -388,6 +402,24 @@ void QrcParserPrivate::collectFilesInPath(const QString &path, QMapcontains(resource)) + results->append(resource); + } + } +} + QStringList QrcParserPrivate::errorMessages() const { return m_errorMessages; diff --git a/src/libs/qmljs/qmljsqrcparser.h b/src/libs/qmljs/qmljsqrcparser.h index 19bd4d0f78c..653cf4c0cf3 100644 --- a/src/libs/qmljs/qmljsqrcparser.h +++ b/src/libs/qmljs/qmljsqrcparser.h @@ -53,6 +53,9 @@ public: bool hasDirAtPath(const QString &path, const QLocale *locale = 0) const; void collectFilesInPath(const QString &path, QMap *res, bool addDirs = false, const QLocale *locale = 0) const; + void collectResourceFilesForSourceFile(const QString &sourceFile, QStringList *results, + const QLocale *locale = 0) const; + QStringList errorMessages() const; QStringList languages() const; bool isValid() const; @@ -60,6 +63,7 @@ public: static Ptr parseQrcFile(const QString &path); static QString normalizedQrcFilePath(const QString &path); static QString normalizedQrcDirectoryPath(const QString &path); + static QString qrcDirectoryPathForQrcFilePath(const QString &file); private: QrcParser(); QrcParser(const QrcParser &);