diff --git a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp index 980f5c44604..81cc7274f5d 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildconfiguration.cpp @@ -33,6 +33,7 @@ #include "cmakeprojectconstants.h" #include "cmakebuildsettingswidget.h" #include "cmakeprojectmanager.h" +#include "cmakeprojectnodes.h" #include #include @@ -216,6 +217,9 @@ void CMakeBuildConfiguration::generateProjectTree(CMakeListsNode *root, if (!m_buildDirManager || m_buildDirManager->isParsing()) return; + root->removeProjectNodes(); + root->setFolderNodes({}); + root->setFileNodes({}); m_buildDirManager->generateProjectTree(root, allFiles); } diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index dcb12eba0f1..5c0a39e7696 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -250,11 +250,11 @@ static ProjectNode *updateCMakeInputs(CMakeListsNode *root, if (!cmakeVFolder) { if (hasInputs) { cmakeVFolder = new CMakeInputsNode(root->filePath()); - root->addProjectNodes({ cmakeVFolder }); + root->addProjectNode(cmakeVFolder); } } else { if (!hasInputs) - root->removeProjectNodes({ cmakeVFolder }); + root->removeProjectNode(cmakeVFolder); } if (!hasInputs) return nullptr; @@ -304,15 +304,11 @@ void ServerModeReader::generateProjectTree(CMakeListsNode *root, if (!m_projects.isEmpty()) root->setDisplayName(m_projects.at(0)->name); - QSet usedNodes; - usedNodes.insert(updateCMakeInputs(root, m_parameters.sourceDirectory, m_parameters.buildDirectory, - cmakeFilesSource, cmakeFilesBuild, cmakeFilesOther)); + updateCMakeInputs(root, m_parameters.sourceDirectory, m_parameters.buildDirectory, + cmakeFilesSource, cmakeFilesBuild, cmakeFilesOther); - usedNodes.unite(updateCMakeLists(root, cmakeLists)); - usedNodes.unite(updateProjects(root, m_projects, allFiles)); - - // Trim out unused nodes: - root->trim(usedNodes); + updateCMakeLists(root, cmakeLists); + updateProjects(root, m_projects, allFiles); } QSet ServerModeReader::updateCodeModel(CppTools::ProjectPartBuilder &ppBuilder) @@ -583,7 +579,7 @@ QSet ServerModeReader::updateCMakeLists(CMakeListsNode *root, cmln = static_cast(parentNode->projectNode(fn->filePath())); if (!cmln) { cmln = new CMakeListsNode(fn->filePath()); - parentNode->addProjectNodes({ cmln }); + parentNode->addProjectNode(cmln); } // Find or create CMakeLists.txt filenode below CMakeListsNode: @@ -647,7 +643,7 @@ static CMakeProjectNode *findOrCreateProjectNode(CMakeListsNode *root, const Uti CMakeProjectNode *pn = static_cast(cmln->projectNode(projectName)); if (!pn) { pn = new CMakeProjectNode(projectName); - cmln->addProjectNodes({ pn }); + cmln->addProjectNode(pn); } pn->setDisplayName(displayName); return pn; @@ -688,7 +684,7 @@ static CMakeTargetNode *findOrCreateTargetNode(CMakeListsNode *root, const Utils CMakeTargetNode *tn = static_cast(cmln->projectNode(targetName)); if (!tn) { tn = new CMakeTargetNode(targetName); - cmln->addProjectNodes({ tn }); + cmln->addProjectNode(tn); } tn->setDisplayName(displayName); return tn; diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp index ec915a6a1a7..7b8fa2a1d73 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp +++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp @@ -243,20 +243,6 @@ CMakeConfig TeaLeafReader::takeParsedConfiguration() return result; } -static void sanitizeTree(CMakeListsNode *root) -{ - QSet uniqueFileNames; - QSet uniqueNodes; - foreach (FileNode *fn, root->recursiveFileNodes()) { - const int count = uniqueFileNames.count(); - uniqueFileNames.insert(fn->filePath()); - if (count != uniqueFileNames.count()) - uniqueNodes.insert(static_cast(fn)); - } - root->trim(uniqueNodes); - root->removeProjectNodes(root->projectNodes()); // Remove all project nodes -} - void TeaLeafReader::generateProjectTree(CMakeListsNode *root, const QList &allFiles) { root->setDisplayName(m_projectName); @@ -308,7 +294,6 @@ void TeaLeafReader::generateProjectTree(CMakeListsNode *root, const QList fileNodes = m_files + Utils::transform(missingHeaders, [](const FileNode *fn) { return new FileNode(*fn); }); - sanitizeTree(root); // Filter out duplicate nodes that e.g. the servermode reader introduces: root->buildTree(fileNodes, m_parameters.sourceDirectory); m_files.clear(); // Some of the FileNodes in files() were deleted! } diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 77d2e8d36f9..ae189a38561 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -185,11 +185,6 @@ void Node::emitTreeChanged() ProjectTree::emitDataChanged(); } -Node *Node::trim(const QSet &keepers) -{ - return keepers.contains(this) ? nullptr : this; -} - bool Node::sortByPath(const Node *a, const Node *b) { return a->filePath() < b->filePath(); @@ -339,26 +334,6 @@ QIcon FolderNode::icon() const return m_icon; } -Node *FolderNode::trim(const QSet &keepers) -{ - if (keepers.contains(this)) - return nullptr; - - bool keepThis = false; - QList toTrim = Utils::transform(m_fileNodes, [&keepers](Node *n) { return n->trim(keepers); }); - int count = toTrim.count(); - toTrim = Utils::filtered(toTrim, [](const Node *n) { return n; }); - keepThis = (count != toTrim.count()); - removeFileNodes(Utils::transform(toTrim, [](Node *n) { return static_cast(n); })); - - toTrim = Utils::transform(m_folderNodes, [&keepers](Node *n) { return n->trim(keepers); }); - count = toTrim.count(); - toTrim = Utils::filtered(toTrim, [](const Node *n) { return n; }); - keepThis = keepThis || (count != toTrim.count()); - removeFolderNodes(Utils::transform(toTrim, [](Node *n) { return static_cast(n); })); - return keepThis ? nullptr : this; -} - QList FolderNode::fileNodes() const { return m_fileNodes; @@ -829,26 +804,20 @@ QList ProjectNode::projectNodes() const Adds project nodes specified by \a subProjects to the node hierarchy and emits the corresponding signals. */ -void ProjectNode::addProjectNodes(const QList &subProjects) +void ProjectNode::addProjectNode(ProjectNode *subProject) { - if (!subProjects.isEmpty()) { - QList folderNodes; - foreach (ProjectNode *projectNode, subProjects) - folderNodes << projectNode; + QTC_ASSERT(subProject, return); + QTC_ASSERT(!subProject->parentFolderNode(), return); - foreach (ProjectNode *project, subProjects) { - QTC_ASSERT(!project->parentFolderNode() || project->parentFolderNode() == this, - qDebug("Project node has already a parent")); - project->setParentFolderNode(this); - m_folderNodes.append(project); - m_projectNodes.append(project); - } + subProject->setParentFolderNode(this); + m_folderNodes.append(subProject); + m_projectNodes.append(subProject); - Utils::sort(m_folderNodes); - Utils::sort(m_projectNodes); - } + Utils::sort(m_folderNodes); + Utils::sort(m_projectNodes); } + /*! Removes project nodes specified by \a subProjects from the node hierarchy and emits the corresponding signals. @@ -856,50 +825,20 @@ void ProjectNode::addProjectNodes(const QList &subProjects) All objects in the \a subProjects list are deleted. */ -void ProjectNode::removeProjectNodes(const QList &subProjects) +void ProjectNode::removeProjectNodes() { - if (!subProjects.isEmpty()) { - QList toRemove; - foreach (ProjectNode *projectNode, subProjects) - toRemove << projectNode; - Utils::sort(toRemove); + foreach (ProjectNode *subProject, m_projectNodes) + m_folderNodes.removeAll(subProject); - auto toRemoveIter = toRemove.constBegin(); - auto folderIter = m_folderNodes.begin(); - auto projectIter = m_projectNodes.begin(); - for (; toRemoveIter != toRemove.constEnd(); ++toRemoveIter) { - while (*projectIter != *toRemoveIter) { - ++projectIter; - QTC_ASSERT(projectIter != m_projectNodes.end(), - qDebug("Project to remove is not part of specified folder!")); - } - while (*folderIter != *toRemoveIter) { - ++folderIter; - QTC_ASSERT(folderIter != m_folderNodes.end(), - qDebug("Project to remove is not part of specified folder!")); - } - delete *projectIter; - projectIter = m_projectNodes.erase(projectIter); - folderIter = m_folderNodes.erase(folderIter); - } - } + qDeleteAll(m_projectNodes); + m_projectNodes.clear(); } -Node *ProjectNode::trim(const QSet &keepers) +void ProjectNode::removeProjectNode(ProjectNode *subProject) { - if (keepers.contains(this)) - return nullptr; - - QList toTrim - = Utils::transform(m_projectNodes, [&keepers](Node *n) { return n->trim(keepers); }); - int count = toTrim.count(); - toTrim = Utils::filtered(toTrim, [](Node *n) { return n; }); - removeProjectNodes(Utils::transform(toTrim, [](Node *n) { return static_cast(n); })); - - if (!FolderNode::trim(keepers)) - return nullptr; - - return (toTrim.count() != count) ? nullptr : this; + m_projectNodes.removeOne(subProject); + m_folderNodes.removeOne(subProject); + delete subProject; } /*! diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index fc8aa6cdc8c..80a0ee8fc52 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -144,8 +144,6 @@ public: void emitNodeUpdated(); void emitTreeChanged(); - virtual Node *trim(const QSet &keepers); - virtual FileNode *asFileNode() { return nullptr; } virtual const FileNode *asFileNode() const { return nullptr; } virtual FolderNode *asFolderNode() { return nullptr; } @@ -208,8 +206,6 @@ public: QString displayName() const override; QIcon icon() const; - Node *trim(const QSet &keepers) override; - QList fileNodes() const; FileNode *fileNode(const Utils::FileName &file) const; FileNode *recursiveFileNode(const Utils::FileName &file) const; @@ -304,14 +300,13 @@ public: ProjectNode *projectNode(const Utils::FileName &file) const; // all subFolders that are projects QList projectNodes() const; - void addProjectNodes(const QList &subProjects); - void removeProjectNodes(const QList &subProjects); + void addProjectNode(ProjectNode *subProject); + void removeProjectNodes(); + void removeProjectNode(ProjectNode *subProject); ProjectNode *asProjectNode() final { return this; } const ProjectNode *asProjectNode() const final { return this; } - Node *trim(const QSet &keepers) override; - protected: // this is just the in-memory representation, a subclass // will add the persistent stuff diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp index 27796ed6d45..b314e4f3f0e 100644 --- a/src/plugins/qbsprojectmanager/qbsnodes.cpp +++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp @@ -681,7 +681,6 @@ void QbsProductNode::setQbsProductData(const qbs::Project &project, const qbs::P idx->setAbsoluteFilePathAndLine(Utils::FileName::fromString(prd.location().filePath()), prd.location().line()); - QList toAdd; QList toRemove = projectNodes(); foreach (const qbs::GroupData &grp, prd.groups()) { @@ -697,7 +696,7 @@ void QbsProductNode::setQbsProductData(const qbs::Project &project, const qbs::P gn->updateQbsGroupData(grp, productPath, productWasEnabled, productIsEnabled); } else { gn = new QbsGroupNode(grp, productPath); - toAdd.append(gn); + addProjectNode(gn); } } @@ -708,8 +707,8 @@ void QbsProductNode::setQbsProductData(const qbs::Project &project, const qbs::P prd.buildDirectory(), true, true); } - addProjectNodes(toAdd); - removeProjectNodes(toRemove); + for (ProjectNode *node : toRemove) + removeProjectNode(node); m_qbsProductData = prd; if (updateExisting) @@ -761,7 +760,6 @@ QbsProjectNode::~QbsProjectNode() void QbsProjectNode::update(const qbs::Project &qbsProject, const qbs::ProjectData &prjData) { - QList toAdd; QList toRemove = projectNodes(); foreach (const qbs::ProjectData &subData, prjData.subProjects()) { @@ -770,7 +768,7 @@ void QbsProjectNode::update(const qbs::Project &qbsProject, const qbs::ProjectDa auto subProject = new QbsProjectNode(Utils::FileName::fromString(subData.location().filePath())); subProject->update(qbsProject, subData); - toAdd << subProject; + addProjectNode(subProject); } else { qn->update(qbsProject, subData); toRemove.removeOne(qn); @@ -780,7 +778,7 @@ void QbsProjectNode::update(const qbs::Project &qbsProject, const qbs::ProjectDa foreach (const qbs::ProductData &prd, prjData.products()) { QbsProductNode *qn = findProductNode(QbsProject::uniqueProductName(prd)); if (!qn) { - toAdd << new QbsProductNode(qbsProject, prd); + addProjectNode(new QbsProductNode(qbsProject, prd)); } else { qn->setQbsProductData(qbsProject, prd); toRemove.removeOne(qn); @@ -792,8 +790,8 @@ void QbsProjectNode::update(const qbs::Project &qbsProject, const qbs::ProjectDa else setDisplayName(project()->displayName()); - removeProjectNodes(toRemove); - addProjectNodes(toAdd); + foreach (ProjectNode *node, toRemove) + removeProjectNode(node); m_projectData = prjData; } diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index 13d91af08f4..d7c4eef014c 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -2043,7 +2043,7 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult) // delete files && folders && projects setFileNodes({}); - removeProjectNodes(projectNodes()); + removeProjectNodes(); setFolderNodes({}); m_projectType = InvalidProject; @@ -2065,7 +2065,7 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult) } setFileNodes({}); - removeProjectNodes(projectNodes()); + removeProjectNodes(); setFolderNodes({}); m_projectType = result->projectType; @@ -2091,7 +2091,6 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult) Utils::sort(existingProjectNodes, sortByPath); // result is already sorted - QList toAdd; QList toRemove; QList::const_iterator existingIt = existingProjectNodes.constBegin(); @@ -2130,21 +2129,19 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult) } else { if (nodeToAdd->proFile) { QmakePriFileNode *qmakePriFileNode = new QmakePriFileNode(m_project, this, nodeToAdd->name); - qmakePriFileNode->setParentFolderNode(pn); // Needed for loop detection + pn->addProjectNode(qmakePriFileNode); qmakePriFileNode->setIncludedInExactParse( (result->state == EvalResult::EvalOk) && pn->includedInExactParse()); - toAdd << qmakePriFileNode; qmakePriFileNode->update(nodeToAdd->result); toCompare.append(qMakePair(qmakePriFileNode, nodeToAdd)); } else { QmakeProFileNode *qmakeProFileNode = new QmakeProFileNode(m_project, nodeToAdd->name); - qmakeProFileNode->setParentFolderNode(pn); // Needed for loop detection + pn->addProjectNode(qmakeProFileNode); qmakeProFileNode->setIncludedInExactParse( result->exactSubdirs.contains(qmakeProFileNode->filePath()) && pn->includedInExactParse()); qmakeProFileNode->setParseInProgress(true); qmakeProFileNode->asyncUpdate(); - toAdd << qmakeProFileNode; } } } else { @@ -2176,12 +2173,8 @@ void QmakeProFileNode::applyEvaluate(EvalResult *evalResult) qmakeProFileNode->setValidParseRecursive(false); qmakeProFileNode->setParseInProgressRecursive(false); } + pn->removeProjectNode(node); } - - if (!toRemove.isEmpty()) - pn->removeProjectNodes(toRemove); - if (!toAdd.isEmpty()) - pn->addProjectNodes(toAdd); } QmakePriFileNode::update(result->includedFiles.result); diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp index 7603dd6d41e..58500fab598 100644 --- a/src/plugins/resourceeditor/resourcenode.cpp +++ b/src/plugins/resourceeditor/resourcenode.cpp @@ -91,18 +91,6 @@ static bool addFilesToResource(const Utils::FileName &resourceFile, return true; } -static bool sortByPrefixAndLang(ProjectExplorer::FolderNode *a, ProjectExplorer::FolderNode *b) -{ - ResourceFolderNode *aa = static_cast(a); - ResourceFolderNode *bb = static_cast(b); - - if (aa->prefix() < bb->prefix()) - return true; - if (bb->prefix() < aa->prefix()) - return false; - return aa->lang() < bb->lang(); -} - ResourceTopLevelNode::ResourceTopLevelNode( const Utils::FileName &filePath, const QString &contents, ProjectExplorer::FolderNode *parent)