summaryrefslogtreecommitdiff
path: root/src/plugins/projectexplorer
diff options
context:
space:
mode:
authorChristian Kandeler <christian.kandeler@qt.io>2021-05-05 11:18:51 +0200
committerChristian Kandeler <christian.kandeler@qt.io>2021-05-06 10:08:24 +0000
commit201786d3fc39f92cec4ad9eafa548e534e5cc442 (patch)
tree9c07b303539261e4b100603360c0e7a4939041ad /src/plugins/projectexplorer
parenteafba223a596a82954dfc4bbbe44f47ca72ad063 (diff)
downloadqt-creator-201786d3fc39f92cec4ad9eafa548e534e5cc442.tar.gz
ProjectExplorer: Prevent target switch on project that's to be removed
Switching targets starts up a lot of machinery that is undesired for a project that's going away. The same goes for switching build configurations on a target that is being removed. Fixes: QTCREATORBUG-25655 Change-Id: I0cb6e395cca8f89bfeb70fcdf571bbcb64f94247 Reviewed-by: hjk <hjk@qt.io> Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org>
Diffstat (limited to 'src/plugins/projectexplorer')
-rw-r--r--src/plugins/projectexplorer/CMakeLists.txt10
-rw-r--r--src/plugins/projectexplorer/project.cpp72
-rw-r--r--src/plugins/projectexplorer/project.h3
-rw-r--r--src/plugins/projectexplorer/projectexplorer.h1
-rw-r--r--src/plugins/projectexplorer/projectexplorer.pro4
-rw-r--r--src/plugins/projectexplorer/projectexplorer.qbs11
-rw-r--r--src/plugins/projectexplorer/projectexplorer_dependencies.pri2
-rw-r--r--src/plugins/projectexplorer/session.cpp14
-rw-r--r--src/plugins/projectexplorer/target.cpp15
-rw-r--r--src/plugins/projectexplorer/target.h3
-rw-r--r--src/plugins/projectexplorer/testdata/generic-project/generic-project.cflags0
-rw-r--r--src/plugins/projectexplorer/testdata/generic-project/generic-project.config0
-rw-r--r--src/plugins/projectexplorer/testdata/generic-project/generic-project.creator1
-rw-r--r--src/plugins/projectexplorer/testdata/generic-project/generic-project.cxxflags0
-rw-r--r--src/plugins/projectexplorer/testdata/generic-project/generic-project.files1
-rw-r--r--src/plugins/projectexplorer/testdata/generic-project/generic-project.includes0
-rw-r--r--src/plugins/projectexplorer/testdata/generic-project/main.cpp1
17 files changed, 137 insertions, 1 deletions
diff --git a/src/plugins/projectexplorer/CMakeLists.txt b/src/plugins/projectexplorer/CMakeLists.txt
index 84141f3d79..1be0ea8a80 100644
--- a/src/plugins/projectexplorer/CMakeLists.txt
+++ b/src/plugins/projectexplorer/CMakeLists.txt
@@ -1,6 +1,7 @@
add_qtc_plugin(ProjectExplorer
DEPENDS QtcSsh Qt5::Qml
PLUGIN_DEPENDS Core TextEditor
+ PLUGIN_TEST_DEPENDS GenericProjectManager
SOURCES
abi.cpp abi.h
abiwidget.cpp abiwidget.h
@@ -214,6 +215,15 @@ extend_qtc_plugin(ProjectExplorer
jsonwizard/jsonwizard_test.cpp
outputparser_test.cpp outputparser_test.h
)
+
+file(GLOB_RECURSE test_resources RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} testdata/*)
+qt_add_resources(ProjectExplorer "testdata"
+ CONDITION WITH_TESTS
+ PREFIX "/projectexplorer"
+ BASE "."
+ FILES ${test_resources}
+)
+
qtc_plugin_enabled(_projectexplorer_enabled ProjectExplorer)
if (WITH_TESTS AND _projectexplorer_enabled)
set_source_files_properties(jsonwizard/jsonwizard_test.cpp
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp
index 908438b862..ec30204f91 100644
--- a/src/plugins/projectexplorer/project.cpp
+++ b/src/plugins/projectexplorer/project.cpp
@@ -187,6 +187,7 @@ public:
bool m_hasMakeInstallEquivalent = false;
bool m_needsBuildConfigurations = true;
bool m_needsDeployConfigurations = true;
+ bool m_shuttingDown = false;
std::function<BuildSystem *(Target *)> m_buildSystemCreator;
@@ -246,6 +247,16 @@ Utils::Id Project::id() const
return d->m_id;
}
+void Project::markAsShuttingDown()
+{
+ d->m_shuttingDown = true;
+}
+
+bool Project::isShuttingDown() const
+{
+ return d->m_shuttingDown;
+}
+
QString Project::mimeType() const
{
return d->m_document->mimeType();
@@ -311,6 +322,7 @@ bool Project::removeTarget(Target *target)
if (BuildManager::isBuilding(target))
return false;
+ target->markAsShuttingDown();
emit aboutToRemoveTarget(target);
auto keep = Utils::take(d->m_targets, target);
if (target == d->m_activeTarget) {
@@ -1065,10 +1077,14 @@ QStringList Project::availableQmlPreviewTranslations(QString *errorMessage)
} // namespace ProjectExplorer
+#include <coreplugin/editormanager/editormanager.h>
#include <utils/hostosinfo.h>
+#include <utils/temporarydirectory.h>
-#include <QTest>
+#include <QEventLoop>
#include <QSignalSpy>
+#include <QTest>
+#include <QTimer>
namespace ProjectExplorer {
@@ -1265,6 +1281,60 @@ void ProjectExplorerPlugin::testProject_projectTree()
QVERIFY(!project.rootProjectNode());
}
+void ProjectExplorerPlugin::testProject_multipleBuildConfigs()
+{
+ // Find suitable kit.
+ Kit * const kit = Utils::findOr(KitManager::kits(), nullptr, [](const Kit *k) {
+ return k->isValid();
+ });
+ if (!kit)
+ QSKIP("The test requires at least one valid kit.");
+
+ // Copy project from qrc file and set it up.
+ using namespace Utils;
+ QTemporaryDir * const tempDir = TemporaryDirectory::masterTemporaryDirectory();
+ QVERIFY(tempDir->isValid());
+ QString error;
+ const FilePath projectDir = FilePath::fromString(tempDir->path() + "/generic-project");
+ FileUtils::copyRecursively(FilePath::fromString(":/projectexplorer/testdata/generic-project"),
+ projectDir, &error);
+ QVERIFY2(error.isEmpty(), qPrintable(error));
+ const QFileInfoList files = QDir(projectDir.toString()).entryInfoList(QDir::Files | QDir::Dirs);
+ for (const QFileInfo &f : files)
+ QFile(f.absoluteFilePath()).setPermissions(f.permissions() | QFile::WriteUser);
+ const auto theProject = openProject(projectDir.pathAppended("generic-project.creator")
+ .toString());
+ QVERIFY2(theProject, qPrintable(theProject.errorMessage()));
+ theProject.project()->configureAsExampleProject(kit);
+ QCOMPARE(theProject.project()->targets().size(), 1);
+ Target * const target = theProject.project()->activeTarget();
+ QVERIFY(target);
+ QCOMPARE(target->buildConfigurations().size(), 6);
+ SessionManager::setActiveBuildConfiguration(target, target->buildConfigurations().at(1),
+ SetActive::Cascade);
+ BuildSystem * const bs = theProject.project()->activeTarget()->buildSystem();
+ QVERIFY(bs);
+ QCOMPARE(bs, target->activeBuildConfiguration()->buildSystem());
+ if (bs->isWaitingForParse() || bs->isParsing()) {
+ QEventLoop loop;
+ QTimer t;
+ t.setSingleShot(true);
+ connect(&t, &QTimer::timeout, &loop, &QEventLoop::quit);
+ connect(bs, &BuildSystem::parsingFinished, &loop, &QEventLoop::quit);
+ t.start(10000);
+ QVERIFY(loop.exec());
+ QVERIFY(t.isActive());
+ }
+ QVERIFY(!bs->isWaitingForParse() && !bs->isParsing());
+
+ QCOMPARE(SessionManager::startupProject(), theProject.project());
+ QCOMPARE(ProjectTree::currentProject(), theProject.project());
+ QVERIFY(Core::EditorManager::openEditor(projectDir.pathAppended("main.cpp").toString()));
+ QVERIFY(ProjectTree::currentNode());
+ ProjectTree::instance()->expandAll();
+ SessionManager::closeAllProjects(); // QTCREATORBUG-25655
+}
+
#endif // WITH_TESTS
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h
index e91fec8e7c..c16af95946 100644
--- a/src/plugins/projectexplorer/project.h
+++ b/src/plugins/projectexplorer/project.h
@@ -80,6 +80,9 @@ public:
QString displayName() const;
Utils::Id id() const;
+ void markAsShuttingDown();
+ bool isShuttingDown() const;
+
QString mimeType() const;
bool canBuildProducts() const;
diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h
index 71a7d87f9a..2d6aaf9a51 100644
--- a/src/plugins/projectexplorer/projectexplorer.h
+++ b/src/plugins/projectexplorer/projectexplorer.h
@@ -273,6 +273,7 @@ private slots:
void testProject_parsingSuccess();
void testProject_parsingFail();
void testProject_projectTree();
+ void testProject_multipleBuildConfigs();
void testSessionSwitch();
#endif // WITH_TESTS
diff --git a/src/plugins/projectexplorer/projectexplorer.pro b/src/plugins/projectexplorer/projectexplorer.pro
index 1a84076ad8..07ecca97b8 100644
--- a/src/plugins/projectexplorer/projectexplorer.pro
+++ b/src/plugins/projectexplorer/projectexplorer.pro
@@ -342,6 +342,10 @@ equals(TEST, 1) {
outputparser_test.cpp
HEADERS += \
outputparser_test.h
+ test_files.files = $$files(testdata/*, true)
+ test_files.base = $$PWD
+ test_files.prefix = /projectexplorer
+ RESOURCES += test_files
}
journald {
diff --git a/src/plugins/projectexplorer/projectexplorer.qbs b/src/plugins/projectexplorer/projectexplorer.qbs
index 8c8b0c615d..e6e64c98fa 100644
--- a/src/plugins/projectexplorer/projectexplorer.qbs
+++ b/src/plugins/projectexplorer/projectexplorer.qbs
@@ -16,6 +16,8 @@ Project {
Depends { name: "libclang"; required: false }
Depends { name: "clang_defines" }
+ pluginTestDepends: ["GenericProjectManager"]
+
Group {
name: "General"
files: [
@@ -252,6 +254,15 @@ Project {
files: ["outputparser_test.h", "outputparser_test.cpp"]
}
+ Group {
+ name: "Test resources"
+ condition: qtc.testsEnabled
+ files: ["testdata/**"]
+ fileTags: ["qt.core.resource_data"]
+ Qt.core.resourcePrefix: "/projectexplorer"
+ Qt.core.resourceSourceBase: path
+ }
+
Export {
Depends { name: "Qt.network" }
}
diff --git a/src/plugins/projectexplorer/projectexplorer_dependencies.pri b/src/plugins/projectexplorer/projectexplorer_dependencies.pri
index df12aea613..00fa9e9c05 100644
--- a/src/plugins/projectexplorer/projectexplorer_dependencies.pri
+++ b/src/plugins/projectexplorer/projectexplorer_dependencies.pri
@@ -8,3 +8,5 @@ QTC_PLUGIN_DEPENDS += \
coreplugin \
texteditor
QT *= network
+QTC_TEST_DEPENDS += \
+ genericprojectmanager
diff --git a/src/plugins/projectexplorer/session.cpp b/src/plugins/projectexplorer/session.cpp
index 19b2e8bbe5..77c26714be 100644
--- a/src/plugins/projectexplorer/session.cpp
+++ b/src/plugins/projectexplorer/session.cpp
@@ -286,6 +286,9 @@ void SessionManager::setActiveTarget(Project *project, Target *target, SetActive
{
QTC_ASSERT(project, return);
+ if (project->isShuttingDown())
+ return;
+
project->setActiveTarget(target);
if (!target) // never cascade setting no target
@@ -307,6 +310,11 @@ void SessionManager::setActiveTarget(Project *project, Target *target, SetActive
void SessionManager::setActiveBuildConfiguration(Target *target, BuildConfiguration *bc, SetActive cascade)
{
QTC_ASSERT(target, return);
+ QTC_ASSERT(target->project(), return);
+
+ if (target->project()->isShuttingDown() || target->isShuttingDown())
+ return;
+
target->setActiveBuildConfiguration(bc);
if (!bc)
@@ -335,6 +343,11 @@ void SessionManager::setActiveBuildConfiguration(Target *target, BuildConfigurat
void SessionManager::setActiveDeployConfiguration(Target *target, DeployConfiguration *dc, SetActive cascade)
{
QTC_ASSERT(target, return);
+ QTC_ASSERT(target->project(), return);
+
+ if (target->project()->isShuttingDown() || target->isShuttingDown())
+ return;
+
target->setActiveDeployConfiguration(dc);
if (!dc)
@@ -724,6 +737,7 @@ void SessionManager::removeProjects(const QList<Project *> &remove)
// Delete projects
for (Project *pro : remove) {
pro->saveSettings();
+ pro->markAsShuttingDown();
// Remove the project node:
d->m_projects.removeOne(pro);
diff --git a/src/plugins/projectexplorer/target.cpp b/src/plugins/projectexplorer/target.cpp
index f2d79dec95..8c1fb78533 100644
--- a/src/plugins/projectexplorer/target.cpp
+++ b/src/plugins/projectexplorer/target.cpp
@@ -122,6 +122,8 @@ public:
ProjectConfigurationModel m_buildConfigurationModel;
ProjectConfigurationModel m_deployConfigurationModel;
ProjectConfigurationModel m_runConfigurationModel;
+
+ bool m_shuttingDown = false;
};
@@ -232,6 +234,16 @@ bool Target::isActive() const
return project()->activeTarget() == this;
}
+void Target::markAsShuttingDown()
+{
+ d->m_shuttingDown = true;
+}
+
+bool Target::isShuttingDown() const
+{
+ return d->m_shuttingDown;
+}
+
Project *Target::project() const
{
return static_cast<Project *>(parent());
@@ -511,6 +523,9 @@ RunConfiguration *Target::activeRunConfiguration() const
void Target::setActiveRunConfiguration(RunConfiguration *rc)
{
+ if (isShuttingDown())
+ return;
+
if ((!rc && d->m_runConfigurations.isEmpty()) ||
(rc && d->m_runConfigurations.contains(rc) &&
rc != d->m_activeRunConfiguration)) {
diff --git a/src/plugins/projectexplorer/target.h b/src/plugins/projectexplorer/target.h
index ce8440fa38..12cf80d01a 100644
--- a/src/plugins/projectexplorer/target.h
+++ b/src/plugins/projectexplorer/target.h
@@ -63,6 +63,9 @@ public:
bool isActive() const;
+ void markAsShuttingDown();
+ bool isShuttingDown() const;
+
Project *project() const;
Kit *kit() const;
BuildSystem *buildSystem() const;
diff --git a/src/plugins/projectexplorer/testdata/generic-project/generic-project.cflags b/src/plugins/projectexplorer/testdata/generic-project/generic-project.cflags
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/plugins/projectexplorer/testdata/generic-project/generic-project.cflags
diff --git a/src/plugins/projectexplorer/testdata/generic-project/generic-project.config b/src/plugins/projectexplorer/testdata/generic-project/generic-project.config
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/plugins/projectexplorer/testdata/generic-project/generic-project.config
diff --git a/src/plugins/projectexplorer/testdata/generic-project/generic-project.creator b/src/plugins/projectexplorer/testdata/generic-project/generic-project.creator
new file mode 100644
index 0000000000..e94cbbd302
--- /dev/null
+++ b/src/plugins/projectexplorer/testdata/generic-project/generic-project.creator
@@ -0,0 +1 @@
+[General]
diff --git a/src/plugins/projectexplorer/testdata/generic-project/generic-project.cxxflags b/src/plugins/projectexplorer/testdata/generic-project/generic-project.cxxflags
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/plugins/projectexplorer/testdata/generic-project/generic-project.cxxflags
diff --git a/src/plugins/projectexplorer/testdata/generic-project/generic-project.files b/src/plugins/projectexplorer/testdata/generic-project/generic-project.files
new file mode 100644
index 0000000000..f0ce4404d8
--- /dev/null
+++ b/src/plugins/projectexplorer/testdata/generic-project/generic-project.files
@@ -0,0 +1 @@
+main.cpp
diff --git a/src/plugins/projectexplorer/testdata/generic-project/generic-project.includes b/src/plugins/projectexplorer/testdata/generic-project/generic-project.includes
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/src/plugins/projectexplorer/testdata/generic-project/generic-project.includes
diff --git a/src/plugins/projectexplorer/testdata/generic-project/main.cpp b/src/plugins/projectexplorer/testdata/generic-project/main.cpp
new file mode 100644
index 0000000000..237c8ce181
--- /dev/null
+++ b/src/plugins/projectexplorer/testdata/generic-project/main.cpp
@@ -0,0 +1 @@
+int main() {}