diff --git a/src/plugins/appmanager/project/appmanagerproject.cpp b/src/plugins/appmanager/project/appmanagerproject.cpp index 9f79be2e63f..d0ea2824d41 100644 --- a/src/plugins/appmanager/project/appmanagerproject.cpp +++ b/src/plugins/appmanager/project/appmanagerproject.cpp @@ -129,6 +129,8 @@ void AppManagerProject::populateProject() foreach (ProjectExplorer::Target *target, targets()) targetUpdateDeployableFiles(target, files); } + + emit parsingFinished(); } void AppManagerProject::recursiveScanDirectory(const QDir &dir, QSet &container) diff --git a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp index b66b37c1067..d07d3552343 100644 --- a/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp +++ b/src/plugins/autotoolsprojectmanager/autotoolsproject.cpp @@ -231,6 +231,8 @@ void AutotoolsProject::makefileParsingFinished() m_makefileParserThread->deleteLater(); m_makefileParserThread = 0; + + emit parsingFinished(); } void AutotoolsProject::onFileChanged(const QString &file) diff --git a/src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp b/src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp index 462e26fe836..e6ae1404be2 100644 --- a/src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp +++ b/src/plugins/clangstaticanalyzer/clangstaticanalyzerpreconfiguredsessiontests.cpp @@ -29,7 +29,6 @@ #include "clangstaticanalyzertool.h" #include "clangstaticanalyzerutils.h" -#include #include #include #include @@ -44,6 +43,7 @@ #include #include #include +#include #include @@ -66,6 +66,35 @@ static bool processEventsUntil(const std::function condition, int timeOu } } +class WaitForParsedProjects : public QObject +{ +public: + WaitForParsedProjects(ProjectExplorer::SessionManager &sessionManager, + const QStringList &projects) + : m_sessionManager(sessionManager) + , m_projectsToWaitFor(projects) + { + connect(&m_sessionManager, &ProjectExplorer::SessionManager::projectFinishedParsing, + this, &WaitForParsedProjects::onProjectFinishedParsing); + } + + void onProjectFinishedParsing(ProjectExplorer::Project *project) + { + m_projectsToWaitFor.removeOne(project->projectFilePath().toString()); + } + + bool wait() + { + return processEventsUntil([this]() { + return m_projectsToWaitFor.isEmpty(); + }); + } + +private: + ProjectExplorer::SessionManager &m_sessionManager; + QStringList m_projectsToWaitFor; +}; + namespace ClangStaticAnalyzer { namespace Internal { @@ -84,16 +113,14 @@ void ClangStaticAnalyzerPreconfiguredSessionTests::initTestCase() if (!m_sessionManager.sessions().contains(preconfiguredSessionName)) QSKIP("Manually preconfigured session 'ClangStaticAnalyzerPreconfiguredSession' needed."); - // Load session - if (m_sessionManager.activeSession() != preconfiguredSessionName) - QVERIFY(m_sessionManager.loadSession(preconfiguredSessionName)); + if (m_sessionManager.activeSession() == preconfiguredSessionName) + QSKIP("Session must not be already active."); - // Wait until all projects are loaded. - const int sessionManagerProjects = m_sessionManager.projects().size(); - const auto allProjectsLoaded = [sessionManagerProjects]() { - return CppModelManager::instance()->projectInfos().size() == sessionManagerProjects; - }; - QVERIFY(processEventsUntil(allProjectsLoaded)); + // Load session + const QStringList projects = m_sessionManager.projectsForSessionName(preconfiguredSessionName); + WaitForParsedProjects waitForParsedProjects(m_sessionManager, projects); + QVERIFY(m_sessionManager.loadSession(preconfiguredSessionName)); + QVERIFY(waitForParsedProjects.wait()); } void ClangStaticAnalyzerPreconfiguredSessionTests::testPreconfiguredSession() @@ -201,15 +228,15 @@ bool ClangStaticAnalyzerPreconfiguredSessionTests::switchToProjectAndTarget(Proj m_sessionManager.setStartupProject(project); if (target != project->activeTarget()) { - QSignalSpy waitUntilProjectUpdated(CppModelManager::instance(), - &CppModelManager::projectPartsUpdated); + QSignalSpy spyFinishedParsing(ProjectExplorer::SessionManager::instance(), + &ProjectExplorer::SessionManager::projectFinishedParsing); m_sessionManager.setActiveTarget(project, target, ProjectExplorer::SetActive::NoCascade); + QTC_ASSERT(spyFinishedParsing.wait(30000), return false); - const bool waitResult = waitUntilProjectUpdated.wait(30000); - if (!waitResult) { - qWarning() << "waitUntilProjectUpdated() failed"; - return false; - } + const QVariant projectArgument = spyFinishedParsing.takeFirst().takeFirst(); + QTC_ASSERT(projectArgument.canConvert(), return false); + + return projectArgument.value() == project; } return true; diff --git a/src/plugins/cmakeprojectmanager/cmakeproject.cpp b/src/plugins/cmakeprojectmanager/cmakeproject.cpp index 50dd058368f..52905ad598d 100644 --- a/src/plugins/cmakeprojectmanager/cmakeproject.cpp +++ b/src/plugins/cmakeprojectmanager/cmakeproject.cpp @@ -145,6 +145,8 @@ void CMakeProject::updateProjectData() emit fileListChanged(); emit cmakeBc->emitBuildTypeChanged(); + + emit parsingFinished(); } void CMakeProject::updateQmlJSCodeModel() diff --git a/src/plugins/genericprojectmanager/genericproject.cpp b/src/plugins/genericprojectmanager/genericproject.cpp index 8ccd1793377..e33d20dd943 100644 --- a/src/plugins/genericprojectmanager/genericproject.cpp +++ b/src/plugins/genericprojectmanager/genericproject.cpp @@ -286,6 +286,7 @@ void GenericProject::refresh(RefreshOptions options) } refreshCppCodeModel(); + emit parsingFinished(); } /** diff --git a/src/plugins/nim/project/nimproject.cpp b/src/plugins/nim/project/nimproject.cpp index 2f57238ef61..eb0829e7a68 100644 --- a/src/plugins/nim/project/nimproject.cpp +++ b/src/plugins/nim/project/nimproject.cpp @@ -112,6 +112,8 @@ void NimProject::populateProject() rootProjectNode()->buildTree(fileNodes); emit fileListChanged(); + + emit parsingFinished(); } void NimProject::recursiveScanDirectory(const QDir &dir, QSet &container) diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index f7dbc037c75..7f636f8ad81 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -168,6 +168,9 @@ signals: void projectContextUpdated(); void projectLanguagesUpdated(); +signals: // for tests only + void parsingFinished(); + protected: virtual RestoreResult fromMap(const QVariantMap &map, QString *errorMessage); virtual bool setupTarget(Target *t); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index a441ca87c5b..6c9d6ab557e 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -1684,6 +1684,9 @@ ProjectExplorerPlugin::OpenProjectResult ProjectExplorerPlugin::openProjects(con foundProjectManager = true; QString tmp; if (Project *pro = manager->openProject(filePath, &tmp)) { + QObject::connect(pro, &Project::parsingFinished, [pro]() { + emit SessionManager::instance()->projectFinishedParsing(pro); + }); QString restoreError; Project::RestoreResult restoreResult = pro->restoreSettings(&restoreError); if (restoreResult == Project::RestoreResult::Ok) { diff --git a/src/plugins/projectexplorer/session.h b/src/plugins/projectexplorer/session.h index 0680c6e40ea..0b8aebdc5cd 100644 --- a/src/plugins/projectexplorer/session.h +++ b/src/plugins/projectexplorer/session.h @@ -138,6 +138,9 @@ signals: void aboutToSaveSession(); void dependencyChanged(ProjectExplorer::Project *a, ProjectExplorer::Project *b); +signals: // for tests only + void projectFinishedParsing(ProjectExplorer::Project *project); + private: static void saveActiveMode(Core::Id mode); void clearProjectFileCache(); diff --git a/src/plugins/pythoneditor/pythoneditorplugin.cpp b/src/plugins/pythoneditor/pythoneditorplugin.cpp index 7d5ede86fde..a2453ad45b1 100644 --- a/src/plugins/pythoneditor/pythoneditorplugin.cpp +++ b/src/plugins/pythoneditor/pythoneditorplugin.cpp @@ -619,6 +619,8 @@ void PythonProject::refresh() return new PythonFileNode(FileName::fromString(f), displayName); }); rootProjectNode()->buildTree(fileNodes); + + emit parsingFinished(); } /** diff --git a/src/plugins/qbsprojectmanager/qbsproject.cpp b/src/plugins/qbsprojectmanager/qbsproject.cpp index 8260547a71e..002fbdaba71 100644 --- a/src/plugins/qbsprojectmanager/qbsproject.cpp +++ b/src/plugins/qbsprojectmanager/qbsproject.cpp @@ -503,6 +503,7 @@ void QbsProject::handleQbsParsingDone(bool success) if (dataChanged) updateAfterParse(); emit projectParsingDone(success); + emit parsingFinished(); } void QbsProject::handleRuleExecutionDone() diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index db652823cc1..11af8907631 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -753,6 +753,7 @@ void QmakeProject::decrementPendingEvaluateFutures() activeTarget()->updateDefaultDeployConfigurations(); updateRunConfigurations(); emit proFilesEvaluated(); + emit parsingFinished(); if (debug) qDebug()<<" Setting state to Base"; } diff --git a/src/plugins/qmlprojectmanager/qmlproject.cpp b/src/plugins/qmlprojectmanager/qmlproject.cpp index b7d5552a8af..b8ab17a24df 100644 --- a/src/plugins/qmlprojectmanager/qmlproject.cpp +++ b/src/plugins/qmlprojectmanager/qmlproject.cpp @@ -198,6 +198,8 @@ void QmlProject::refresh(RefreshOptions options) QmlJS::Dialect::Qml); modelManager()->updateProjectInfo(projectInfo, this); + + emit parsingFinished(); } QStringList QmlProject::convertToAbsoluteFiles(const QStringList &paths) const