diff --git a/src/plugins/autotest/boost/boosttesttreeitem.cpp b/src/plugins/autotest/boost/boosttesttreeitem.cpp index 928bd24420a..0a18d06f19e 100644 --- a/src/plugins/autotest/boost/boosttesttreeitem.cpp +++ b/src/plugins/autotest/boost/boosttesttreeitem.cpp @@ -30,6 +30,7 @@ #include "boosttestparser.h" #include "../testframeworkmanager.h" +#include #include #include @@ -197,8 +198,10 @@ QList BoostTestTreeItem::getAllTestConfigurations() const ++funcChildren; }); if (funcChildren) { + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return); testsPerProjectfile[item->proFile()].testCases += funcChildren; - testsPerProjectfile[item->proFile()].internalTargets.unite(item->internalTargets()); + testsPerProjectfile[item->proFile()].internalTargets.unite(cppMM->internalTargets(item->filePath())); } }); @@ -236,6 +239,8 @@ QList BoostTestTreeItem::getTestConfigurations( if (!item->enabled()) // ignore child tests known to be disabled when using run selected return; if (predicate(item)) { + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return); QString tcName = item->name(); if (item->state().testFlag(BoostTestTreeItem::Templated)) tcName.append("<*"); @@ -244,7 +249,7 @@ QList BoostTestTreeItem::getTestConfigurations( tcName = handleSpecialFunctionNames(tcName); testCasesForProjectFile[item->proFile()].testCases.append( item->prependWithParentsSuitePaths(tcName)); - testCasesForProjectFile[item->proFile()].internalTargets.unite(item->internalTargets()); + testCasesForProjectFile[item->proFile()].internalTargets.unite(cppMM->internalTargets(item->filePath())); } }); @@ -280,6 +285,8 @@ ITestConfiguration *BoostTestTreeItem::testConfiguration() const { ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); QTC_ASSERT(project, return nullptr); + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return nullptr); const Type itemType = type(); if (itemType == TestSuite || itemType == TestCase) { @@ -313,7 +320,7 @@ ITestConfiguration *BoostTestTreeItem::testConfiguration() const config->setProjectFile(proFile()); config->setProject(project); config->setTestCases(testCases); - config->setInternalTargets(internalTargets()); + config->setInternalTargets(cppMM->internalTargets(filePath())); return config; } return nullptr; diff --git a/src/plugins/autotest/catch/catchtreeitem.cpp b/src/plugins/autotest/catch/catchtreeitem.cpp index e0fbb145a90..cd5c6c5d1a9 100644 --- a/src/plugins/autotest/catch/catchtreeitem.cpp +++ b/src/plugins/autotest/catch/catchtreeitem.cpp @@ -27,6 +27,7 @@ #include "catchconfiguration.h" #include "catchframework.h" +#include #include #include #include @@ -157,6 +158,8 @@ ITestConfiguration *CatchTreeItem::testConfiguration() const { ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); QTC_ASSERT(project, return nullptr); + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return nullptr); if (type() != TestCase) return nullptr; @@ -167,7 +170,7 @@ ITestConfiguration *CatchTreeItem::testConfiguration() const config->setProjectFile(proFile()); config->setProject(project); config->setTestCases(QStringList(testCasesString())); - config->setInternalTargets(internalTargets()); + config->setInternalTargets(cppMM->internalTargets(filePath())); return config; } @@ -190,6 +193,8 @@ static void collectTestInfo(const TestTreeItem *item, bool ignoreCheckState) { QTC_ASSERT(item, return); + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return); const int childCount = item->childCount(); if (item->type() == TestTreeItem::GroupNode) { item->forFirstLevelChildItems([&testCasesForProfile, ignoreCheckState](TestTreeItem *it) { @@ -206,15 +211,15 @@ static void collectTestInfo(const TestTreeItem *item, CatchTreeItem *current = static_cast(it); testCasesForProfile[projectFile].names.append(current->testCasesString()); }); - testCasesForProfile[projectFile].internalTargets.unite(item->internalTargets()); + testCasesForProfile[projectFile].internalTargets.unite(cppMM->internalTargets(item->filePath())); } else if (item->checked() == Qt::PartiallyChecked) { - item->forFirstLevelChildItems([&testCasesForProfile](TestTreeItem *child) { + item->forFirstLevelChildItems([&testCasesForProfile, cppMM](TestTreeItem *child) { QTC_ASSERT(child->type() == TestTreeItem::TestCase, return); if (child->checked() == Qt::Checked) { CatchTreeItem *current = static_cast(child); testCasesForProfile[child->proFile()].names.append(current->testCasesString()); testCasesForProfile[child->proFile()].internalTargets.unite( - child->internalTargets()); + cppMM->internalTargets(child->filePath())); } }); @@ -230,11 +235,13 @@ static void collectFailedTestInfo(const CatchTreeItem *item, item->forAllChildItems([&testCasesForProfile](TestTreeItem *it) { QTC_ASSERT(it, return); QTC_ASSERT(it->parentItem(), return); + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return); if (it->type() == TestTreeItem::TestCase && it->data(0, FailedRole).toBool()) { CatchTreeItem *current = static_cast(it); testCasesForProfile[it->proFile()].names.append(current->testCasesString()); testCasesForProfile[it->proFile()].internalTargets.unite( - it->internalTargets()); + cppMM->internalTargets(it->filePath())); } }); } @@ -276,6 +283,9 @@ QList CatchTreeItem::getFailedTestConfigurations() const QList CatchTreeItem::getTestConfigurationsForFile(const Utils::FilePath &fileName) const { QList result; + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return result); + ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); if (!project || type() != Root) return result; @@ -300,7 +310,7 @@ QList CatchTreeItem::getTestConfigurationsForFile(const Ut testConfig->setTestCases(testCases); testConfig->setProjectFile(item->proFile()); testConfig->setProject(ProjectExplorer::SessionManager::startupProject()); - testConfig->setInternalTargets(item->internalTargets()); + testConfig->setInternalTargets(cppMM->internalTargets(item->filePath())); result << testConfig; } diff --git a/src/plugins/autotest/gtest/gtesttreeitem.cpp b/src/plugins/autotest/gtest/gtesttreeitem.cpp index df593b1159d..70aca519225 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.cpp +++ b/src/plugins/autotest/gtest/gtesttreeitem.cpp @@ -116,6 +116,8 @@ static bool matchesFilter(const QString &filter, const QString &fullTestName) return positive.isEmpty(); } +QSet internalTargets(const TestTreeItem &item); + QVariant GTestTreeItem::data(int column, int role) const { switch (role) { @@ -195,7 +197,7 @@ ITestConfiguration *GTestTreeItem::testConfiguration() const return nullptr; } if (config) - config->setInternalTargets(internalTargets()); + config->setInternalTargets(internalTargets(*this)); return config; } @@ -234,7 +236,7 @@ static void collectTestInfo(const GTestTreeItem *item, testCasesForProFile[projectFile].filters.append( gtestFilter(item->state()).arg(item->name()).arg('*')); testCasesForProFile[projectFile].testSetCount += childCount - 1; - testCasesForProFile[projectFile].internalTargets.unite(item->internalTargets()); + testCasesForProFile[projectFile].internalTargets.unite(internalTargets(*item)); } else if (item->checked() == Qt::PartiallyChecked) { item->forFirstLevelChildItems([&testCasesForProFile, item](TestTreeItem *child){ QTC_ASSERT(child->type() == TestTreeItem::TestCase, return); @@ -242,7 +244,7 @@ static void collectTestInfo(const GTestTreeItem *item, testCasesForProFile[child->proFile()].filters.append( gtestFilter(item->state()).arg(item->name()).arg(child->name())); testCasesForProFile[child->proFile()].internalTargets.unite( - child->internalTargets()); + internalTargets(*child)); } }); } @@ -262,7 +264,7 @@ static void collectFailedTestInfo(const GTestTreeItem *item, testCasesForProfile[it->proFile()].filters.append( gtestFilter(parent->state()).arg(parent->name()).arg(it->name())); testCasesForProfile[it->proFile()].internalTargets.unite( - it->internalTargets()); + internalTargets(*it)); } }); } @@ -348,7 +350,7 @@ QList GTestTreeItem::getTestConfigurationsForFile(const Ut GTestCases &cases = testCases[testCase->proFile()]; cases.filters.append( gtestFilter(testCase->state()).arg(testCase->name(), node->name())); - cases.internalTargets.unite(node->internalTargets()); + cases.internalTargets.unite(internalTargets(*node)); } }); for (auto it = testCases.begin(), end = testCases.end(); it != end; ++it) { @@ -517,23 +519,23 @@ QString GTestTreeItem::nameSuffix() const return suffix; } -QSet GTestTreeItem::internalTargets() const +QSet internalTargets(const TestTreeItem &item) { QSet result; const auto cppMM = CppTools::CppModelManager::instance(); const auto projectInfo = cppMM->projectInfo(ProjectExplorer::SessionManager::startupProject()); - const QString file = filePath(); + const QString file = item.filePath(); const QVector projectParts = projectInfo.projectParts(); if (projectParts.isEmpty()) - return TestTreeItem::dependingInternalTargets(cppMM, file); + return cppMM->dependingInternalTargets(file); for (const CppTools::ProjectPart::Ptr &projectPart : projectParts) { - if (projectPart->projectFile == proFile() + if (projectPart->projectFile == item.proFile() && Utils::anyOf(projectPart->files, [&file] (const CppTools::ProjectFile &pf) { return pf.path == file; })) { result.insert(projectPart->buildSystemTarget); if (projectPart->buildTargetType != ProjectExplorer::BuildTargetType::Executable) - result.unite(TestTreeItem::dependingInternalTargets(cppMM, file)); + result.unite(cppMM->dependingInternalTargets(file)); } } return result; diff --git a/src/plugins/autotest/gtest/gtesttreeitem.h b/src/plugins/autotest/gtest/gtesttreeitem.h index dd6741cca8d..0ad87085d9b 100644 --- a/src/plugins/autotest/gtest/gtesttreeitem.h +++ b/src/plugins/autotest/gtest/gtesttreeitem.h @@ -75,7 +75,6 @@ public: GTestTreeItem::TestStates state, const QString &proFile) const; QString nameSuffix() const; - QSet internalTargets() const override; bool isGroupNodeFor(const TestTreeItem *other) const override; bool isGroupable() const override; TestTreeItem *applyFilters() override; diff --git a/src/plugins/autotest/qtest/qttesttreeitem.cpp b/src/plugins/autotest/qtest/qttesttreeitem.cpp index 909ee82d074..3bdcf14a5ba 100644 --- a/src/plugins/autotest/qtest/qttesttreeitem.cpp +++ b/src/plugins/autotest/qtest/qttesttreeitem.cpp @@ -28,6 +28,7 @@ #include "qttestparser.h" #include "qttestframework.h" +#include #include #include @@ -111,6 +112,8 @@ ITestConfiguration *QtTestTreeItem::testConfiguration() const { ProjectExplorer::Project *project = ProjectExplorer::SessionManager::startupProject(); QTC_ASSERT(project, return nullptr); + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return nullptr); QtTestConfiguration *config = nullptr; switch (type()) { @@ -144,13 +147,15 @@ ITestConfiguration *QtTestTreeItem::testConfiguration() const return nullptr; } if (config) - config->setInternalTargets(internalTargets()); + config->setInternalTargets(cppMM->internalTargets(filePath())); return config; } static void fillTestConfigurationsFromCheckState(const TestTreeItem *item, QList &testConfigurations) { + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return); QTC_ASSERT(item, return); if (item->type() == TestTreeItem::GroupNode) { for (int row = 0, count = item->childCount(); row < count; ++row) @@ -185,13 +190,15 @@ static void fillTestConfigurationsFromCheckState(const TestTreeItem *item, testConfig->setTestCases(testCases); testConfig->setProjectFile(item->proFile()); testConfig->setProject(ProjectExplorer::SessionManager::startupProject()); - testConfig->setInternalTargets(item->internalTargets()); + testConfig->setInternalTargets(cppMM->internalTargets(item->filePath())); testConfigurations << testConfig; } } static void collectFailedTestInfo(TestTreeItem *item, QList &testConfigs) { + const auto cppMM = CppTools::CppModelManager::instance(); + QTC_ASSERT(cppMM, return); QTC_ASSERT(item, return); if (item->type() == TestTreeItem::GroupNode) { for (int row = 0, count = item->childCount(); row < count; ++row) @@ -217,7 +224,7 @@ static void collectFailedTestInfo(TestTreeItem *item, QListsetTestCases(testCases); testConfig->setProjectFile(item->proFile()); testConfig->setProject(ProjectExplorer::SessionManager::startupProject()); - testConfig->setInternalTargets(item->internalTargets()); + testConfig->setInternalTargets(cppMM->internalTargets(item->filePath())); testConfigs << testConfig; } diff --git a/src/plugins/autotest/quick/quicktesttreeitem.cpp b/src/plugins/autotest/quick/quicktesttreeitem.cpp index d93df667590..2e449cf93b2 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.cpp +++ b/src/plugins/autotest/quick/quicktesttreeitem.cpp @@ -36,6 +36,8 @@ namespace Autotest { namespace Internal { +QSet internalTargets(const QString &proFile); + TestTreeItem *QuickTestTreeItem::copyWithoutChildren() { QuickTestTreeItem *copied = new QuickTestTreeItem(framework()); @@ -156,7 +158,7 @@ ITestConfiguration *QuickTestTreeItem::testConfiguration() const return nullptr; } if (config) - config->setInternalTargets(internalTargets()); + config->setInternalTargets(internalTargets(proFile())); return config; } @@ -189,7 +191,7 @@ static QList testConfigurationsFor( auto tc = new QuickTestConfiguration(treeItem->framework()); tc->setProjectFile(treeItem->proFile()); tc->setProject(ProjectExplorer::SessionManager::startupProject()); - tc->setInternalTargets(treeItem->internalTargets()); + tc->setInternalTargets(internalTargets(treeItem->proFile())); it = configurationForProFiles.insert(treeItem->proFile(), tc); } it.value()->setTestCases(it.value()->testCases() + functions); @@ -216,7 +218,7 @@ struct Tests { static void addTestsForItem(Tests &tests, const TestTreeItem *item) { tests.testCount += item->childCount(); - tests.internalTargets = item->internalTargets(); + tests.internalTargets = internalTargets(item->proFile()); } QList QuickTestTreeItem::getAllTestConfigurations() const @@ -234,7 +236,7 @@ QList QuickTestTreeItem::getAllTestConfigurations() const child->forFirstLevelChildItems([&testsForProfile](TestTreeItem *grandChild) { const QString &proFile = grandChild->proFile(); ++(testsForProfile[proFile].testCount); - testsForProfile[proFile].internalTargets = grandChild->internalTargets(); + testsForProfile[proFile].internalTargets = internalTargets(grandChild->proFile()); }); return; } @@ -384,7 +386,7 @@ bool QuickTestTreeItem::isGroupable() const return type() == TestCase && !name().isEmpty() && !filePath().isEmpty(); } -QSet QuickTestTreeItem::internalTargets() const +QSet internalTargets(const QString &proFile) { QSet result; const auto cppMM = CppTools::CppModelManager::instance(); @@ -392,7 +394,7 @@ QSet QuickTestTreeItem::internalTargets() const for (const CppTools::ProjectPart::Ptr &projectPart : projectInfo.projectParts()) { if (projectPart->buildTargetType != ProjectExplorer::BuildTargetType::Executable) continue; - if (projectPart->projectFile == proFile()) + if (projectPart->projectFile == proFile) result.insert(projectPart->buildSystemTarget); } return result; diff --git a/src/plugins/autotest/quick/quicktesttreeitem.h b/src/plugins/autotest/quick/quicktesttreeitem.h index a599c6ceab0..5397d01f779 100644 --- a/src/plugins/autotest/quick/quicktesttreeitem.h +++ b/src/plugins/autotest/quick/quicktesttreeitem.h @@ -59,7 +59,6 @@ public: bool removeOnSweepIfEmpty() const override; TestTreeItem *createParentGroupNode() const override; bool isGroupable() const override; - QSet internalTargets() const override; void markForRemovalRecursively(const QString &filePath) override; private: TestTreeItem *findChildByFileNameAndType(const QString &filePath, const QString &name, diff --git a/src/plugins/autotest/testtreeitem.cpp b/src/plugins/autotest/testtreeitem.cpp index a5a40a8922e..a93b2ec45bc 100644 --- a/src/plugins/autotest/testtreeitem.cpp +++ b/src/plugins/autotest/testtreeitem.cpp @@ -30,9 +30,6 @@ #include "itestparser.h" #include "testconfiguration.h" -#include -#include -#include #include #include @@ -320,22 +317,6 @@ bool TestTreeItem::isGroupable() const return true; } -QSet TestTreeItem::internalTargets() const -{ - auto cppMM = CppTools::CppModelManager::instance(); - const QList projectParts = cppMM->projectPart(filePath()); - // if we have no project parts it's most likely a header with declarations only and CMake based - if (projectParts.isEmpty()) - return TestTreeItem::dependingInternalTargets(cppMM, filePath()); - QSet targets; - for (const CppTools::ProjectPart::Ptr &part : projectParts) { - targets.insert(part->buildSystemTarget); - if (part->buildTargetType != ProjectExplorer::BuildTargetType::Executable) - targets.unite(TestTreeItem::dependingInternalTargets(cppMM, filePath())); - } - return targets; -} - void TestTreeItem::forAllChildItems(const std::function &pred) const { for (int row = 0, end = childCount(); row < end; ++row) { @@ -401,27 +382,4 @@ ITestFramework *TestTreeItem::framework() const return static_cast(testBase()); } -/* - * try to find build system target that depends on the given file - if the file is no header - * try to find the corresponding header and use this instead to find the respective target - */ -QSet TestTreeItem::dependingInternalTargets(CppTools::CppModelManager *cppMM, - const QString &file) -{ - QSet result; - QTC_ASSERT(cppMM, return result); - const CPlusPlus::Snapshot snapshot = cppMM->snapshot(); - QTC_ASSERT(snapshot.contains(file), return result); - bool wasHeader; - const QString correspondingFile - = CppTools::correspondingHeaderOrSource(file, &wasHeader, CppTools::CacheUsage::ReadOnly); - const Utils::FilePaths dependingFiles = snapshot.filesDependingOn( - wasHeader ? file : correspondingFile); - for (const Utils::FilePath &fn : dependingFiles) { - for (const CppTools::ProjectPart::Ptr &part : cppMM->projectPart(fn)) - result.insert(part->buildSystemTarget); - } - return result; -} - } // namespace Autotest diff --git a/src/plugins/autotest/testtreeitem.h b/src/plugins/autotest/testtreeitem.h index 21237146a64..f06abb74860 100644 --- a/src/plugins/autotest/testtreeitem.h +++ b/src/plugins/autotest/testtreeitem.h @@ -42,7 +42,6 @@ namespace { }; } -namespace CppTools { class CppModelManager; } namespace Utils { class FilePath; } namespace Autotest { @@ -166,7 +165,6 @@ public: virtual TestTreeItem *applyFilters() { return nullptr; } // decide whether an item should still be added to the treemodel virtual bool shouldBeAddedAfterFiltering() const { return true; } - virtual QSet internalTargets() const; void forAllChildItems(const std::function &pred) const; void forFirstLevelChildItems(const std::function &pred) const; @@ -174,8 +172,6 @@ public: protected: void copyBasicDataFrom(const TestTreeItem *other); typedef std::function CompareFunction; - static QSet dependingInternalTargets(CppTools::CppModelManager *cppMM, - const QString &file); private: bool modifyFilePath(const QString &filepath); diff --git a/src/plugins/cpptools/cppmodelmanager.cpp b/src/plugins/cpptools/cppmodelmanager.cpp index 5f6f296503f..9c2de6bbc22 100644 --- a/src/plugins/cpptools/cppmodelmanager.cpp +++ b/src/plugins/cpptools/cppmodelmanager.cpp @@ -1389,6 +1389,38 @@ void CppModelManager::onAboutToLoadSession() GC(); } +QSet CppModelManager::dependingInternalTargets(const QString &file) const +{ + QSet result; + const Snapshot snapshot = this->snapshot(); + QTC_ASSERT(snapshot.contains(file), return result); + bool wasHeader; + const QString correspondingFile + = correspondingHeaderOrSource(file, &wasHeader, CacheUsage::ReadOnly); + const Utils::FilePaths dependingFiles = snapshot.filesDependingOn( + wasHeader ? file : correspondingFile); + for (const Utils::FilePath &fn : qAsConst(dependingFiles)) { + for (const ProjectPart::Ptr &part : projectPart(fn)) + result.insert(part->buildSystemTarget); + } + return result; +} + +QSet CppModelManager::internalTargets(const QString &filePath) const +{ + const QList projectParts = projectPart(filePath); + // if we have no project parts it's most likely a header with declarations only and CMake based + if (projectParts.isEmpty()) + return dependingInternalTargets(filePath); + QSet targets; + for (const ProjectPart::Ptr &part : projectParts) { + targets.insert(part->buildSystemTarget); + if (part->buildTargetType != ProjectExplorer::BuildTargetType::Executable) + targets.unite(dependingInternalTargets(filePath)); + } + return targets; +} + void CppModelManager::renameIncludes(const QString &oldFileName, const QString &newFileName) { if (oldFileName.isEmpty() || newFileName.isEmpty()) diff --git a/src/plugins/cpptools/cppmodelmanager.h b/src/plugins/cpptools/cppmodelmanager.h index 253e4856cc5..48c8ceabb06 100644 --- a/src/plugins/cpptools/cppmodelmanager.h +++ b/src/plugins/cpptools/cppmodelmanager.h @@ -230,6 +230,14 @@ public: Core::IFindFilter *symbolsFindFilter() const; Core::ILocatorFilter *currentDocumentFilter() const; + /* + * try to find build system target that depends on the given file - if the file is no header + * try to find the corresponding header and use this instead to find the respective target + */ + QSet dependingInternalTargets(const QString &file) const; + + QSet internalTargets(const QString &filePath) const; + void renameIncludes(const QString &oldFileName, const QString &newFileName); // for VcsBaseSubmitEditor