diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp index 3942a240541..be82659d505 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp @@ -38,7 +38,6 @@ #include #include #include -#include #include #include @@ -50,7 +49,7 @@ #include #include #include -#include +#include #include @@ -371,32 +370,6 @@ bool pInfoLessThanAll(const ModelManagerInterface::ProjectInfo &p1, const ModelM } return false; } - -bool pInfoLessThanImports(const ModelManagerInterface::ProjectInfo &p1, const ModelManagerInterface::ProjectInfo &p2) -{ - if (p1.qtQmlPath < p2.qtQmlPath) - return true; - if (p1.qtQmlPath > p2.qtQmlPath) - return false; - if (p1.qtImportsPath < p2.qtImportsPath) - return true; - if (p1.qtImportsPath > p2.qtImportsPath) - return false; - QStringList s1 = p1.importPaths; - QStringList s2 = p2.importPaths; - if (s1.size() < s2.size()) - return true; - if (s1.size() > s2.size()) - return false; - for (int i = 0; i < s1.size(); ++i) { - if (s1.at(i) < s2.at(i)) - return true; - else if (s1.at(i) > s2.at(i)) - return false; - } - return false; -} - } QStringList ModelManagerInterface::filesAtQrcPath(const QString &path, const QLocale *locale, @@ -566,32 +539,14 @@ void ModelManagerInterface::removeProjectInfo(ProjectExplorer::Project *project) } } -ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfoForPath(QString path) const +ModelManagerInterface::ProjectInfo ModelManagerInterface::projectInfoForPath(QString path) { - QList projects; - { - QMutexLocker locker(&m_mutex); - projects = m_fileToProject.values(path); - } - QList infos; - foreach (ProjectExplorer::Project *project, projects) { - ProjectInfo info = projectInfo(project); - if (info.isValid()) - infos.append(info); - } - std::sort(infos.begin(), infos.end(), &pInfoLessThanImports); + QMutexLocker locker(&m_mutex); - ProjectInfo res; - foreach (const ProjectInfo &pInfo, infos) { - if (res.qtImportsPath.isEmpty()) - res.qtImportsPath = pInfo.qtImportsPath; - if (res.qtQmlPath.isEmpty()) - res.qtQmlPath = pInfo.qtQmlPath; - foreach (const QString &path, pInfo.importPaths) - if (res.importPaths.contains(path)) - res.importPaths.append(path); - } - return res; + foreach (const ProjectInfo &p, m_projects) + if (p.sourceFiles.contains(path)) + return p; + return ProjectInfo(); } void ModelManagerInterface::emitDocumentChangedOnDisk(Document::Ptr doc) @@ -1056,26 +1011,21 @@ void ModelManagerInterface::updateImportPaths() QStringList allImportPaths; QmlLanguageBundles activeBundles; QmlLanguageBundles extendedBundles; - QMapIterator pInfoIter(m_projects); - QHashIterator vCtxsIter = m_defaultVContexts; - while (pInfoIter.hasNext()) { - pInfoIter.next(); - foreach (const QString &path, pInfoIter.value().importPaths) { + QMapIterator it(m_projects); + while (it.hasNext()) { + it.next(); + foreach (const QString &path, it.value().importPaths) { const QString canonicalPath = QFileInfo(path).canonicalFilePath(); if (!canonicalPath.isEmpty()) allImportPaths += canonicalPath; } } - while (vCtxsIter.hasNext()) { - vCtxsIter.next(); - allImportPaths << vCtxsIter.value().paths; - } - pInfoIter.toFront(); - while (pInfoIter.hasNext()) { - pInfoIter.next(); - activeBundles.mergeLanguageBundles(pInfoIter.value().activeBundle); - foreach (Language::Enum l, pInfoIter.value().activeBundle.languages()) { - foreach (const QString &path, pInfoIter.value().activeBundle.bundleForLanguage(l) + it.toFront(); + while (it.hasNext()) { + it.next(); + activeBundles.mergeLanguageBundles(it.value().activeBundle); + foreach (Language::Enum l, it.value().activeBundle.languages()) { + foreach (const QString &path, it.value().activeBundle.bundleForLanguage(l) .searchPaths().stringList()) { const QString canonicalPath = QFileInfo(path).canonicalFilePath(); if (!canonicalPath.isEmpty()) @@ -1083,33 +1033,18 @@ void ModelManagerInterface::updateImportPaths() } } } - pInfoIter.toFront(); - while (pInfoIter.hasNext()) { - pInfoIter.next(); - QString pathAtt = pInfoIter.value().qtQmlPath; - if (!pathAtt.isEmpty() && allImportPaths.size() > 0 - && allImportPaths.value(allImportPaths.size()) != pathAtt) - allImportPaths.append(pathAtt); - } - { - QString pathAtt = defaultProjectInfo().qtQmlPath; - if (!pathAtt.isEmpty() && allImportPaths.size() > 0 - && allImportPaths.value(allImportPaths.size()) != pathAtt) - allImportPaths.append(pathAtt); - } - pInfoIter.toFront(); - while (pInfoIter.hasNext()) { - pInfoIter.next(); - QString pathAtt = pInfoIter.value().qtImportsPath; - if (!pathAtt.isEmpty() && allImportPaths.size() > 0 - && allImportPaths.value(allImportPaths.size()) != pathAtt) - allImportPaths.append(pathAtt); - } - { - QString pathAtt = defaultProjectInfo().qtImportsPath; - if (!pathAtt.isEmpty() && allImportPaths.size() > 0 - && allImportPaths.value(allImportPaths.size()) != pathAtt) - allImportPaths.append(pathAtt); + it.toFront(); + while (it.hasNext()) { + it.next(); + extendedBundles.mergeLanguageBundles(it.value().extendedBundle); + foreach (Language::Enum l, it.value().extendedBundle.languages()) { + foreach (const QString &path, it.value().extendedBundle.bundleForLanguage(l) + .searchPaths().stringList()) { + const QString canonicalPath = QFileInfo(path).canonicalFilePath(); + if (!canonicalPath.isEmpty()) + allImportPaths += canonicalPath; + } + } } allImportPaths += m_defaultImportPaths; allImportPaths.removeDuplicates(); @@ -1137,6 +1072,13 @@ void ModelManagerInterface::updateImportPaths() maybeScan(allImportPaths, Language::Qml); } +ModelManagerInterface::ProjectInfo ModelManagerInterface::defaultProjectInfo() const +{ + if (m_projects.isEmpty()) + return ProjectInfo(); + return m_projects.begin().value(); +} + void ModelManagerInterface::loadPluginTypes(const QString &libraryPath, const QString &importPath, const QString &importUri, const QString &importVersion) { @@ -1251,124 +1193,54 @@ ModelManagerInterface::CppDataHash ModelManagerInterface::cppData() const LibraryInfo ModelManagerInterface::builtins(const Document::Ptr &doc) const { - ProjectInfo info = projectInfoForPath(doc->path()); + QList projects = m_fileToProject.values(doc->fileName()); + + ProjectExplorer::Project *project = 0; + foreach (ProjectExplorer::Project *p, projects) { + if (p) { + project = p; + break; + } + } + + if (!project) + return LibraryInfo(); + + QMutexLocker locker(&m_mutex); + ProjectInfo info = m_projects.value(project); if (!info.isValid()) return LibraryInfo(); + return m_validSnapshot.libraryInfo(info.qtImportsPath); } ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx, - const Document::Ptr &doc) const + const Document::Ptr &doc) const { + Q_UNUSED(doc); ViewerContext res = vCtx; - - if (vCtx.language == Language::Qml && !doc.isNull() && - (doc->language() == Language::QmlQtQuick1 || doc->language() == Language::QmlQtQuick2)) - res.language = doc->language(); - ProjectInfo info; - if (!doc.isNull()) - info = projectInfoForPath(doc->path()); - ViewerContext defaultVCtx = defaultVContext(res.language, Document::Ptr(0), false); - ProjectInfo defaultInfo = defaultProjectInfo(); - if (info.qtImportsPath.isEmpty()) - info.qtImportsPath = defaultInfo.qtImportsPath; - if (info.qtQmlPath.isEmpty()) - info.qtQmlPath = defaultInfo.qtQmlPath; switch (res.flags) { case ViewerContext::Complete: break; - case ViewerContext::AddAllPathsAndDefaultSelectors: - res.selectors.append(defaultVCtx.selectors); - // fallthrough + case ViewerContext::AddQtPath: case ViewerContext::AddAllPaths: - { - foreach (const QString &path, defaultVCtx.paths) - res.maybeAddPath(path); - switch (res.language) { - case Language::Unknown: - case Language::Qml: - res.maybeAddPath(info.qtQmlPath); - // fallthrough - case Language::QmlQtQuick1: - res.maybeAddPath(info.qtImportsPath); - // fallthrough - case Language::QmlQtQuick2: - { - if (res.language == Language::QmlQtQuick2) - res.maybeAddPath(info.qtQmlPath); - QList allProjects; - { - QMutexLocker locker(&m_mutex); - allProjects = m_projects.values(); - } - std::sort(allProjects.begin(), allProjects.end(), &pInfoLessThanImports); - foreach (const ProjectInfo &pInfo, allProjects) { - foreach (const QString &path, pInfo.importPaths) - res.maybeAddPath(path); - } - break; - } - case Language::JavaScript: - case Language::QmlTypeInfo: - case Language::Json: - case Language::QmlQbs: - case Language::QmlProject: - break; - } - break; - } - case ViewerContext::AddDefaultPathsAndSelectors: - res.selectors.append(defaultVCtx.selectors); - // fallthrough - case ViewerContext::AddDefaultPaths: - foreach (const QString &path, defaultVCtx.paths) - res.maybeAddPath(path); - if (res.language == Language::Unknown || res.language == Language::Qml - || res.language == Language::QmlQtQuick2) - res.maybeAddPath(info.qtImportsPath); - if (res.language == Language::Unknown || res.language == Language::Qml - || res.language == Language::QmlQtQuick1) - res.maybeAddPath(info.qtQmlPath); - break; + res.paths << importPaths(); } res.flags = ViewerContext::Complete; return res; } -ViewerContext ModelManagerInterface::defaultVContext(Language::Enum language, - const Document::Ptr &doc, - bool autoComplete) const +ViewerContext ModelManagerInterface::defaultVContext(bool autoComplete, const Document::Ptr &doc) const { - if (!doc.isNull()) { - if (language == Language::Unknown) - language = doc->language(); - else if (language == Language::Qml && - (doc->language() == Language::QmlQtQuick1 || doc->language() == Language::QmlQtQuick2)) - language = doc->language(); - } - ViewerContext defaultCtx; - { - QMutexLocker locker(&m_mutex); - defaultCtx = m_defaultVContexts.value(language); - } if (autoComplete) - return completeVContext(defaultCtx, doc); + return completeVContext(m_vContext, doc); else - return defaultCtx; -} - -ModelManagerInterface::ProjectInfo ModelManagerInterface::defaultProjectInfo() const -{ - ProjectInfo res; - res.qtImportsPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); - res.qtQmlPath = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath); - return res; + return m_vContext; } void ModelManagerInterface::setDefaultVContext(const ViewerContext &vContext) { - QMutexLocker locker(&m_mutex); - m_defaultVContexts[vContext.language] = vContext; + m_vContext = vContext; } void ModelManagerInterface::joinAllThreads() diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.h b/src/libs/qmljs/qmljsmodelmanagerinterface.h index 425f7bc2eb1..fd28b27a883 100644 --- a/src/libs/qmljs/qmljsmodelmanagerinterface.h +++ b/src/libs/qmljs/qmljsmodelmanagerinterface.h @@ -178,7 +178,7 @@ public: void updateLibraryInfo(const QString &path, const QmlJS::LibraryInfo &info); void emitDocumentChangedOnDisk(QmlJS::Document::Ptr doc); void updateQrcFile(const QString &path); - ProjectInfo projectInfoForPath(QString path) const; + ProjectInfo projectInfoForPath(QString path); QStringList importPaths() const; QmlJS::QmlLanguageBundles activeBundles() const; @@ -189,16 +189,17 @@ public: CppDataHash cppData() const; LibraryInfo builtins(const Document::Ptr &doc) const; - ViewerContext completeVContext(const ViewerContext &vCtx, - const Document::Ptr &doc = Document::Ptr(0)) const; - ViewerContext defaultVContext(Language::Enum language = Language::Qml, - const Document::Ptr &doc = Document::Ptr(0), - bool autoComplete = true) const; - void setDefaultVContext(const ViewerContext &vContext); - virtual ProjectInfo defaultProjectInfo() const; + virtual ViewerContext completeVContext(const ViewerContext &vCtx, + const Document::Ptr &doc = Document::Ptr(0)) const; + virtual ViewerContext defaultVContext(bool autoComplete = true, + const Document::Ptr &doc = Document::Ptr(0)) const; + virtual void setDefaultVContext(const ViewerContext &vContext); // Blocks until all parsing threads are done. Used for testing. void joinAllThreads(); + + virtual ModelManagerInterface::ProjectInfo defaultProjectInfo() const; + public slots: virtual void resetCodeModel(); void removeProjectInfo(ProjectExplorer::Project *project); @@ -256,7 +257,7 @@ private: QStringList m_defaultImportPaths; QmlJS::QmlLanguageBundles m_activeBundles; QmlJS::QmlLanguageBundles m_extendedBundles; - QHash m_defaultVContexts; + QmlJS::ViewerContext m_vContext; bool m_shouldScanImports; QSet m_scannedPaths; diff --git a/src/libs/qmljs/qmljsviewercontext.cpp b/src/libs/qmljs/qmljsviewercontext.cpp index 4750c23f53e..3a7e7c945e5 100644 --- a/src/libs/qmljs/qmljsviewercontext.cpp +++ b/src/libs/qmljs/qmljsviewercontext.cpp @@ -76,10 +76,4 @@ bool ViewerContext::languageIsCompatible(Language::Enum l) const return true; } -void ViewerContext::maybeAddPath(const QString &path) -{ - if (!path.isEmpty() && !paths.contains(path)) - paths.append(path); -} - } // namespace QmlJS diff --git a/src/libs/qmljs/qmljsviewercontext.h b/src/libs/qmljs/qmljsviewercontext.h index f4b36392268..32a93e9c959 100644 --- a/src/libs/qmljs/qmljsviewercontext.h +++ b/src/libs/qmljs/qmljsviewercontext.h @@ -42,10 +42,8 @@ class QMLJS_EXPORT ViewerContext public: enum Flags { Complete, - AddAllPathsAndDefaultSelectors, AddAllPaths, - AddDefaultPaths, - AddDefaultPathsAndSelectors + AddQtPath }; ViewerContext(); @@ -54,7 +52,6 @@ public: Flags flags = AddAllPaths); bool languageIsCompatible(Language::Enum l) const; - void maybeAddPath(const QString &path); QStringList selectors; QStringList paths; diff --git a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp index 3fd8985324e..2b1723f164e 100644 --- a/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp +++ b/src/plugins/qmldesigner/designercore/metainfo/subcomponentmanager.cpp @@ -103,7 +103,7 @@ static inline bool checkIfDerivedFromItem(const QString &fileName) snapshot.insert(document); - QmlJS::Link link(snapshot, modelManager->defaultVContext(document->language(), document), QmlJS::ModelManagerInterface::instance()->builtins(document)); + QmlJS::Link link(snapshot, modelManager->defaultVContext(), QmlJS::ModelManagerInterface::instance()->builtins(document)); QList diagnosticLinkMessages; QmlJS::ContextPtr context = link(document, &diagnosticLinkMessages); diff --git a/src/plugins/qmljseditor/qmljsfindreferences.cpp b/src/plugins/qmljseditor/qmljsfindreferences.cpp index 4258a14719d..b92341637da 100644 --- a/src/plugins/qmljseditor/qmljsfindreferences.cpp +++ b/src/plugins/qmljseditor/qmljsfindreferences.cpp @@ -831,7 +831,7 @@ static void find_helper(QFutureInterface &future, QmlJS::ModelManagerInterface *modelManager = QmlJS::ModelManagerInterface::instance(); - Link link(snapshot, modelManager->defaultVContext(doc->language(), doc), modelManager->builtins(doc)); + Link link(snapshot, modelManager->defaultVContext(), modelManager->builtins(doc)); ContextPtr context = link(); ScopeChain scopeChain(doc, context); diff --git a/src/plugins/qmljseditor/qmljssemanticinfoupdater.cpp b/src/plugins/qmljseditor/qmljssemanticinfoupdater.cpp index 84d280aa242..64b44e49786 100644 --- a/src/plugins/qmljseditor/qmljssemanticinfoupdater.cpp +++ b/src/plugins/qmljseditor/qmljssemanticinfoupdater.cpp @@ -122,7 +122,7 @@ QmlJSTools::SemanticInfo SemanticInfoUpdater::makeNewSemanticInfo(const QmlJS::D ModelManagerInterface *modelManager = ModelManagerInterface::instance(); - Link link(semanticInfo.snapshot, modelManager->defaultVContext(doc->language(), doc), modelManager->builtins(doc)); + Link link(semanticInfo.snapshot, modelManager->defaultVContext(), modelManager->builtins(doc)); semanticInfo.context = link(doc, &semanticInfo.semanticMessages); ScopeChain *scopeChain = new ScopeChain(doc, semanticInfo.context); diff --git a/src/plugins/qmljseditor/qmltaskmanager.cpp b/src/plugins/qmljseditor/qmltaskmanager.cpp index 0b54640fdce..496720e15a9 100644 --- a/src/plugins/qmljseditor/qmltaskmanager.cpp +++ b/src/plugins/qmljseditor/qmltaskmanager.cpp @@ -161,7 +161,7 @@ void QmlTaskManager::updateMessagesNow(bool updateSemantic) QFuture future = QtConcurrent::run( &collectMessages, modelManager->newestSnapshot(), modelManager->projectInfos(), - modelManager->defaultVContext(Language::Unknown), updateSemantic); + modelManager->defaultVContext(), updateSemantic); m_messageCollector.setFuture(future); } diff --git a/src/plugins/qmljstools/qmljsmodelmanager.cpp b/src/plugins/qmljstools/qmljsmodelmanager.cpp index d0abc0beace..51144b8dbc9 100644 --- a/src/plugins/qmljstools/qmljsmodelmanager.cpp +++ b/src/plugins/qmljstools/qmljsmodelmanager.cpp @@ -61,8 +61,6 @@ #include #include #include -#include -#include #include @@ -89,8 +87,8 @@ ModelManagerInterface::ProjectInfo QmlJSTools::defaultProjectInfoForProject( globs.append(MimeGlobPattern(QLatin1String("*.qmltypes"))); globs.append(MimeGlobPattern(QLatin1String("*.qmlproject"))); } - foreach (const QString &filePath, - project->files(ProjectExplorer::Project::ExcludeGeneratedFiles)) + foreach (const QString &filePath + , project->files(ProjectExplorer::Project::ExcludeGeneratedFiles)) foreach (const MimeGlobPattern &glob, globs) if (glob.matches(filePath)) projectInfo.sourceFiles << filePath; @@ -119,10 +117,6 @@ ModelManagerInterface::ProjectInfo QmlJSTools::defaultProjectInfoForProject( projectInfo.qtQmlPath = qtVersion->qmakeProperty("QT_INSTALL_QML"); projectInfo.qtImportsPath = qtVersion->qmakeProperty("QT_INSTALL_IMPORTS"); projectInfo.qtVersionString = qtVersion->qtVersionString(); - } else { - projectInfo.qtQmlPath = QLibraryInfo::location(QLibraryInfo::Qml2ImportsPath); - projectInfo.qtImportsPath = QLibraryInfo::location(QLibraryInfo::ImportsPath); - projectInfo.qtVersionString = QLatin1String(qVersion()); } if (projectInfo.tryQmlDump) { @@ -257,9 +251,11 @@ ModelManagerInterface::WorkingCopy ModelManager::workingCopyInternal() const ModelManagerInterface::ProjectInfo ModelManager::defaultProjectInfo() const { - // needs to be performed in the ui therad (change?) - ProjectExplorer::Project *currentProject = ProjectExplorer::ProjectExplorerPlugin::currentProject(); - return defaultProjectInfoForProject(currentProject); + ProjectExplorer::Project *activeProject = ProjectExplorer::SessionManager::startupProject(); + if (!activeProject) + return ModelManagerInterface::ProjectInfo(); + + return projectInfo(activeProject); } // Check whether fileMimeType is the same or extends knownMimeType @@ -283,3 +279,4 @@ void ModelManager::addTaskInternal(QFuture result, const QString &msg, con { ProgressManager::addTask(result, msg, taskId); } +