aboutsummaryrefslogtreecommitdiffstats
path: root/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/qmljs/qmljsmodelmanagerinterface.cpp')
-rw-r--r--src/libs/qmljs/qmljsmodelmanagerinterface.cpp100
1 files changed, 76 insertions, 24 deletions
diff --git a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
index 4417ddb240..dc4c855c26 100644
--- a/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
+++ b/src/libs/qmljs/qmljsmodelmanagerinterface.cpp
@@ -38,6 +38,7 @@
#include <utils/algorithm.h>
#include <utils/hostosinfo.h>
#include <utils/runextensions.h>
+#include <utils/stringutils.h>
#include <QDir>
#include <QDirIterator>
@@ -90,7 +91,7 @@ static QStringList environmentImportPaths()
QStringList paths;
const QStringList importPaths = QString::fromLocal8Bit(qgetenv("QML_IMPORT_PATH")).split(
- Utils::HostOsInfo::pathListSeparator(), QString::SkipEmptyParts);
+ Utils::HostOsInfo::pathListSeparator(), Utils::SkipEmptyParts);
for (const QString &path : importPaths) {
const QString canonicalPath = QDir(path).canonicalPath();
@@ -267,8 +268,10 @@ void ModelManagerInterface::loadQmlTypeDescriptionsInternal(const QString &resou
}
// load the fallbacks for libraries
- CppQmlTypesLoader::defaultLibraryObjects.unite(
- CppQmlTypesLoader::loadQmlTypes(qmlTypesFiles, &errors, &warnings));
+ const CppQmlTypesLoader::BuiltinObjects objs =
+ CppQmlTypesLoader::loadQmlTypes(qmlTypesFiles, &errors, &warnings);
+ for (auto it = objs.cbegin(); it != objs.cend(); ++it)
+ CppQmlTypesLoader::defaultLibraryObjects.insert(it.key(), it.value());
for (const QString &error : qAsConst(errors))
writeMessageInternal(error);
@@ -306,6 +309,7 @@ void ModelManagerInterface::updateSourceFiles(const QStringList &files,
void ModelManagerInterface::cleanupFutures()
{
+ QMutexLocker lock(&m_futuresMutex);
const int maxFutures = 10;
if (m_futures.size() > maxFutures) {
const QList<QFuture<void>> futures = m_futures;
@@ -327,8 +331,7 @@ QFuture<void> ModelManagerInterface::refreshSourceFiles(const QStringList &sourc
workingCopyInternal(), sourceFiles,
this, Dialect(Dialect::Qml),
emitDocumentOnDiskChanged);
- cleanupFutures();
- m_futures.append(result);
+ addFuture(result);
if (sourceFiles.count() > 1)
addTaskInternal(result, tr("Parsing QML Files"), Constants::TASK_INDEX);
@@ -561,11 +564,12 @@ void ModelManagerInterface::updateProjectInfo(const ProjectInfo &pinfo, ProjectE
// parse any files not yet in the snapshot
QStringList newFiles;
for (const QString &file : qAsConst(pinfo.sourceFiles)) {
+ if (!m_fileToProject.contains(file, p))
+ m_fileToProject.insert(file, p);
if (!snapshot.document(file))
newFiles += file;
}
- for (const QString &newFile : qAsConst(newFiles))
- m_fileToProject.insert(newFile, p);
+
updateSourceFiles(newFiles, false);
// update qrc cache
@@ -636,7 +640,6 @@ QList<ModelManagerInterface::ProjectInfo> ModelManagerInterface::allProjectInfos
infos.append(info);
}
std::sort(infos.begin(), infos.end(), &pInfoLessThanImports);
- infos.append(m_defaultProjectInfo);
return infos;
}
@@ -1133,13 +1136,11 @@ void ModelManagerInterface::maybeScan(const PathsAndLanguages &importPaths)
pathToScan.maybeInsert(importPath);
}
- if (pathToScan.length() > 1) {
+ if (pathToScan.length() >= 1) {
QFuture<void> result = Utils::runAsync(&ModelManagerInterface::importScan,
workingCopyInternal(), pathToScan,
this, true, true, false);
- cleanupFutures();
- m_futures.append(result);
-
+ addFuture(result);
addTaskInternal(result, tr("Scanning QML Imports"), Constants::TASK_IMPORT_SCAN);
}
}
@@ -1401,7 +1402,7 @@ ModelManagerInterface::CppDataHash ModelManagerInterface::cppData() const
LibraryInfo ModelManagerInterface::builtins(const Document::Ptr &doc) const
{
const ProjectInfo info = projectInfoForPath(doc->fileName());
- if (!info.project.isNull() && !info.qtQmlPath.isEmpty())
+ if (!info.qtQmlPath.isEmpty())
return m_validSnapshot.libraryInfo(info.qtQmlPath);
return LibraryInfo();
}
@@ -1409,6 +1410,13 @@ LibraryInfo ModelManagerInterface::builtins(const Document::Ptr &doc) const
ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
const Document::Ptr &doc) const
{
+ return getVContext(vCtx, doc, false);
+}
+
+ViewerContext ModelManagerInterface::getVContext(const ViewerContext &vCtx,
+ const Document::Ptr &doc,
+ bool limitToProject) const
+{
ViewerContext res = vCtx;
if (!doc.isNull()
@@ -1446,20 +1454,27 @@ ViewerContext ModelManagerInterface::completeVContext(const ViewerContext &vCtx,
{
if (res.language == Dialect::QmlQtQuick2 || res.language == Dialect::QmlQtQuick2Ui)
maybeAddPath(res, info.qtQmlPath);
- QList<ProjectInfo> allProjects;
- {
- QMutexLocker locker(&m_mutex);
- allProjects = m_projects.values();
- }
- std::sort(allProjects.begin(), allProjects.end(), &pInfoLessThanImports);
+
QList<Dialect> languages = res.language.companionLanguages();
- for (const ProjectInfo &pInfo : qAsConst(allProjects)) {
- for (const auto &importPath : pInfo.importPaths) {
+ auto addPathsOnLanguageMatch = [&](const PathsAndLanguages &importPaths) {
+ for (const auto &importPath : importPaths) {
if (languages.contains(importPath.language())
|| importPath.language().companionLanguages().contains(res.language)) {
maybeAddPath(res, importPath.path().toString());
}
}
+ };
+ if (limitToProject) {
+ addPathsOnLanguageMatch(info.importPaths);
+ } else {
+ QList<ProjectInfo> allProjects;
+ {
+ QMutexLocker locker(&m_mutex);
+ allProjects = m_projects.values();
+ }
+ std::sort(allProjects.begin(), allProjects.end(), &pInfoLessThanImports);
+ for (const ProjectInfo &pInfo : qAsConst(allProjects))
+ addPathsOnLanguageMatch(pInfo.importPaths);
}
const auto environmentPaths = environmentImportPaths();
for (const QString &path : environmentPaths)
@@ -1518,6 +1533,13 @@ ViewerContext ModelManagerInterface::defaultVContext(Dialect language,
return autoComplete ? completeVContext(defaultCtx, doc) : defaultCtx;
}
+ViewerContext ModelManagerInterface::projectVContext(Dialect language, const Document::Ptr &doc) const
+{
+ // Returns context limited to the project the file belongs to
+ ViewerContext defaultCtx = defaultVContext(language, doc, false);
+ return getVContext(defaultCtx, doc, true);
+}
+
ModelManagerInterface::ProjectInfo ModelManagerInterface::defaultProjectInfo() const
{
QMutexLocker l(mutex());
@@ -1536,13 +1558,43 @@ void ModelManagerInterface::setDefaultVContext(const ViewerContext &vContext)
m_defaultVContexts[vContext.language] = vContext;
}
-void ModelManagerInterface::joinAllThreads()
+void ModelManagerInterface::test_joinAllThreads()
{
- for (QFuture<void> &future : m_futures)
- future.waitForFinished();
+ // Loop since futures can spawn more futures as they finish.
+ while (true) {
+ QFuture<void> f;
+ // get one future
+ {
+ QMutexLocker lock(&m_futuresMutex);
+ for (QFuture<void> &future : m_futures) {
+ if (!future.isFinished() && !future.isCanceled()) {
+ f = future;
+ break;
+ }
+ }
+ }
+ if (!f.isFinished() && !f.isCanceled()) {
+ f.waitForFinished();
+
+ // Some futures trigger more futures from connected signals
+ // and in tests, we care about finishing all of these too.
+ QEventLoop().processEvents();
+ } else {
+ break;
+ }
+ }
m_futures.clear();
}
+void ModelManagerInterface::addFuture(const QFuture<void> &future)
+{
+ {
+ QMutexLocker lock(&m_futuresMutex);
+ m_futures.append(future);
+ }
+ cleanupFutures();
+}
+
Document::Ptr ModelManagerInterface::ensuredGetDocumentForPath(const QString &filePath)
{
QmlJS::Document::Ptr document = newestSnapshot().document(filePath);