From 1621aaa26eff78f17ef3cbd61fed5a6ca859046b Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 14 Mar 2017 16:21:33 +0100 Subject: [PATCH] CMake: Fix some more SOFT-ASSERTS in CMake server-mode Fix two more SOFT-ASSERTs in CMake server-mode that could be triggered by complex projects. Move and simplify search functionality into FolderNode and use that instead of hand-crafting a custom tree search in CMake. Change-Id: If4bde5c4a7ff84c7d5dba4f595e99b39f54ac8aa Reviewed-by: Tim Jenssen --- .../cmakeprojectmanager/servermodereader.cpp | 31 ++++++------------- src/plugins/projectexplorer/projectnodes.cpp | 31 +++++++++++++++++++ src/plugins/projectexplorer/projectnodes.h | 3 ++ 3 files changed, 43 insertions(+), 22 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index 93f719b272d..6bb09612f1d 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -540,28 +540,16 @@ void ServerModeReader::addCMakeLists(CMakeProjectNode *root, const QListfilePath(); - - QStringList relative = stepDir.relativeChildPath(topDir).toString().split('/', QString::SkipEmptyParts); - - FolderNode *result = root; - while (!relative.isEmpty()) { - Utils::FileName nextFullPath = result->filePath(); - nextFullPath.appendPath(relative.takeFirst()); - result = findOrDefault(result->folderNodes(), Utils::equal(&FolderNode::filePath, nextFullPath)); - if (!result) - return nullptr; - } - return dynamic_cast(result); + Node *n = root->findNode([&dir](Node *n) { return n->asProjectNode() && n->filePath() == dir; }); + return n ? n->asProjectNode() : nullptr; } -static CMakeProjectNode *findOrCreateProjectNode(FolderNode *root, const Utils::FileName &dir, - const QString &displayName) +static ProjectNode *findOrCreateProjectNode(ProjectNode *root, const Utils::FileName &dir, + const QString &displayName) { - CMakeListsNode *cmln = findCMakeNode(root, dir); + ProjectNode *cmln = findCMakeNode(root, dir); QTC_ASSERT(cmln, return nullptr); Utils::FileName projectName = dir; @@ -588,17 +576,16 @@ void ServerModeReader::addProjects(CMakeProjectNode *root, } for (const Project *p : projects) { - CMakeProjectNode *pNode = findOrCreateProjectNode(root, p->sourceDirectory, p->name); + ProjectNode *pNode = findOrCreateProjectNode(root, p->sourceDirectory, p->name); QTC_ASSERT(pNode, continue); - QTC_ASSERT(root, continue); addTargets(root, p->targets, includeFiles); } } -static CMakeTargetNode *findOrCreateTargetNode(FolderNode *root, const Utils::FileName &dir, +static CMakeTargetNode *findOrCreateTargetNode(ProjectNode *root, const Utils::FileName &dir, const QString &displayName) { - CMakeListsNode *cmln = findCMakeNode(root, dir); + ProjectNode *cmln = findCMakeNode(root, dir); QTC_ASSERT(cmln, return nullptr); Utils::FileName targetName = dir; diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 099ff9b76ad..d0fbf0b2767 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -401,6 +401,37 @@ QIcon FolderNode::icon() const return m_icon; } +Node *FolderNode::findNode(const std::function &filter) +{ + if (filter(this)) + return this; + + for (Node *n : m_nodes) { + if (n->asFileNode() && filter(n)) { + return n; + } else if (FolderNode *folder = n->asFolderNode()) { + Node *result = folder->findNode(filter); + if (result) + return result; + } + } + return nullptr; +} + +QList FolderNode::findNodes(const std::function &filter) +{ + QList result; + if (filter(this)) + result.append(this); + for (Node *n : m_nodes) { + if (n->asFileNode() && filter(n)) + result.append(n); + else if (FolderNode *folder = n->asFolderNode()) + result.append(folder->findNode(filter)); + } + return result; +} + void FolderNode::forEachNode(const std::function &fileTask, const std::function &folderTask, const std::function &folderFilterTask) const diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index 9ac9d678cce..03858db5e73 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -192,6 +192,9 @@ public: QString displayName() const override; QIcon icon() const; + Node *findNode(const std::function &filter); + QList findNodes(const std::function &filter); + void forEachNode(const std::function &fileTask, const std::function &folderTask = {}, const std::function &folderFilterTask = {}) const;