From 1f55ba9012eea79fafedddf270ef401aa6988298 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Thu, 26 Apr 2018 11:00:59 +0200 Subject: [PATCH] ProjectExplorer: Use unique_ptr to hold ProjectNodes Change-Id: Iaa5bea221686564de24138a99b5fe0d09521c118 Reviewed-by: Ulf Hermann --- .../cmakeprojectmanager/servermodereader.cpp | 2 +- src/plugins/projectexplorer/project.cpp | 2 +- src/plugins/projectexplorer/projectnodes.cpp | 85 +++++++++++-------- src/plugins/projectexplorer/projectnodes.h | 7 +- 4 files changed, 55 insertions(+), 41 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index f42291757b9..4d71947ff22 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -907,7 +907,7 @@ void ServerModeReader::addHeaderNodes(ProjectNode *root, const QList } } - if (headerNode->nodes().isEmpty()) + if (headerNode->isEmpty()) delete headerNode; // No Headers, do not show this Folder. else root->addNode(headerNode); diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index c70202d39ef..5208a3df7ac 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -496,7 +496,7 @@ void Project::setRootProjectNode(ProjectNode *root) if (d->m_rootProjectNode.get() == root) return; - if (root && root->nodes().isEmpty()) { + if (root && root->isEmpty()) { // Something went wrong with parsing: At least the project file needs to be // shown so that the user can fix the breakage. // Do not leak root and use default project tree in this case. diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp index 48791e84c16..7162f2102ef 100644 --- a/src/plugins/projectexplorer/projectnodes.cpp +++ b/src/plugins/projectexplorer/projectnodes.cpp @@ -39,6 +39,7 @@ #include #include #include +#include #include #include @@ -53,9 +54,8 @@ namespace ProjectExplorer { static FolderNode *folderNode(const FolderNode *folder, const Utils::FileName &directory) { - return static_cast(Utils::findOrDefault(folder->nodes(), - [&directory](const Node *n) { - const FolderNode *fn = n->asFolderNode(); + return static_cast(Utils::findOrDefault(folder->folderNodes(), + [&directory](const FolderNode *fn) { return fn && fn->filePath() == directory; })); } @@ -428,11 +428,6 @@ FolderNode::FolderNode(const Utils::FileName &folderPath, NodeType nodeType, m_displayName = folderPath.toUserOutput(); } -FolderNode::~FolderNode() -{ - qDeleteAll(m_nodes); -} - /*! Contains the display name that should be used in a view. \sa setFolderName() @@ -461,9 +456,9 @@ Node *FolderNode::findNode(const std::function &filter) if (filter(this)) return this; - for (Node *n : m_nodes) { - if (n->asFileNode() && filter(n)) { - return n; + for (const std::unique_ptr &n : m_nodes) { + if (n->asFileNode() && filter(n.get())) { + return n.get(); } else if (FolderNode *folder = n->asFolderNode()) { Node *result = folder->findNode(filter); if (result) @@ -478,9 +473,9 @@ 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); + for (const std::unique_ptr &n : m_nodes) { + if (n->asFileNode() && filter(n.get())) + result.append(n.get()); else if (FolderNode *folder = n->asFolderNode()) result.append(folder->findNode(filter)); } @@ -496,12 +491,12 @@ void FolderNode::forEachNode(const std::function &fileTask, return; } if (fileTask) { - for (Node *n : m_nodes) { + for (const std::unique_ptr &n : m_nodes) { if (FileNode *fn = n->asFileNode()) fileTask(fn); } } - for (Node *n : m_nodes) { + for (const std::unique_ptr &n : m_nodes) { if (FolderNode *fn = n->asFolderNode()) { if (folderTask) folderTask(fn); @@ -512,17 +507,22 @@ void FolderNode::forEachNode(const std::function &fileTask, void FolderNode::forEachGenericNode(const std::function &genericTask) const { - for (Node *n : m_nodes) { - genericTask(n); + for (const std::unique_ptr &n : m_nodes) { + genericTask(n.get()); if (FolderNode *fn = n->asFolderNode()) fn->forEachGenericNode(genericTask); } } +const QList FolderNode::nodes() const +{ + return Utils::toRawPointer(m_nodes); +} + QList FolderNode::fileNodes() const { QList result; - for (Node *n : m_nodes) { + for (const std::unique_ptr &n : m_nodes) { if (FileNode *fn = n->asFileNode()) result.append(fn); } @@ -531,7 +531,8 @@ QList FolderNode::fileNodes() const FileNode *FolderNode::fileNode(const Utils::FileName &file) const { - return static_cast(Utils::findOrDefault(m_nodes, [&file](const Node *n) { + return static_cast(Utils::findOrDefault(m_nodes, + [&file](const std::unique_ptr &n) { const FileNode *fn = n->asFileNode(); return fn && fn->filePath() == file; })); @@ -540,7 +541,7 @@ FileNode *FolderNode::fileNode(const Utils::FileName &file) const QList FolderNode::folderNodes() const { QList result; - for (Node *n : m_nodes) { + for (const std::unique_ptr &n : m_nodes) { if (FolderNode *fn = n->asFolderNode()) result.append(fn); } @@ -570,21 +571,19 @@ void FolderNode::addNestedNodes(const QList &files, const Utils::Fil // files. void FolderNode::compress() { - QList children = nodes(); - if (auto subFolder = children.count() == 1 ? children.at(0)->asFolderNode() : nullptr) { + if (auto subFolder = m_nodes.size() == 1 ? m_nodes.at(0)->asFolderNode() : nullptr) { if (subFolder->nodeType() != nodeType()) return; // Only one subfolder: Compress! setDisplayName(QDir::toNativeSeparators(displayName() + "/" + subFolder->displayName())); for (Node *n : subFolder->nodes()) { - subFolder->removeNode(n); - n->setParentFolderNode(nullptr); - addNode(n); + std::unique_ptr toMove = subFolder->takeNode(n); + toMove->setParentFolderNode(nullptr); + addNode(std::move(toMove)); } setAbsoluteFilePathAndLine(subFolder->filePath(), -1); removeNode(subFolder); - delete subFolder; compress(); } else { @@ -610,11 +609,13 @@ bool FolderNode::replaceSubtree(Node *oldNode, Node *newNode) addNode(nn.release()); // Happens e.g. when a project is registered } else { auto it = std::find_if(m_nodes.begin(), m_nodes.end(), - [oldNode](const Node *n) { return oldNode == n; }); + [oldNode](const std::unique_ptr &n) { + return oldNode == n.get(); + }); QTC_ASSERT(it != m_nodes.end(), return false); if (nn) { nn->setParentFolderNode(this); - *it = nn.release(); + *it = std::move(nn); } else { removeNode(oldNode); // Happens e.g. when project is shutting down } @@ -713,9 +714,17 @@ FolderNode::AddNewInformation FolderNode::addNewInformation(const QStringList &f void FolderNode::addNode(Node *node) { QTC_ASSERT(node, return); - QTC_ASSERT(!node->parentFolderNode(), qDebug("File node has already a parent folder")); + QTC_ASSERT(!node->parentFolderNode(), qDebug("Node has already a parent folder")); node->setParentFolderNode(this); - m_nodes.append(node); + m_nodes.emplace_back(std::unique_ptr(node)); +} + +void FolderNode::addNode(std::unique_ptr &&node) +{ + QTC_ASSERT(node, return); + QTC_ASSERT(!node->parentFolderNode(), qDebug("Node has already a parent folder")); + node->setParentFolderNode(this); + m_nodes.emplace_back(std::move(node)); } /*! @@ -725,7 +734,12 @@ void FolderNode::addNode(Node *node) void FolderNode::removeNode(Node *node) { - m_nodes.removeOne(node); + takeNode(node); +} + +std::unique_ptr FolderNode::takeNode(Node *node) +{ + return Utils::takeOrDefault(m_nodes, node); } bool FolderNode::showInSimpleTree() const @@ -848,8 +862,8 @@ bool ProjectNode::deploysFolder(const QString &folder) const ProjectNode *ProjectNode::projectNode(const Utils::FileName &file) const { - for (Node *node : m_nodes) { - if (ProjectNode *pnode = node->asProjectNode()) + for (const std::unique_ptr &n: m_nodes) { + if (ProjectNode *pnode = n->asProjectNode()) if (pnode->filePath() == file) return pnode; } @@ -858,7 +872,7 @@ ProjectNode *ProjectNode::projectNode(const Utils::FileName &file) const bool FolderNode::isEmpty() const { - return m_nodes.isEmpty(); + return m_nodes.size() == 0; } void FolderNode::handleSubTreeChanged(FolderNode *node) @@ -899,7 +913,6 @@ ProjectNode *ContainerNode::rootProjectNode() const void ContainerNode::removeAllChildren() { - qDeleteAll(m_nodes); m_nodes.clear(); } diff --git a/src/plugins/projectexplorer/projectnodes.h b/src/plugins/projectexplorer/projectnodes.h index 1b5a10eb9ea..8f990aae8eb 100644 --- a/src/plugins/projectexplorer/projectnodes.h +++ b/src/plugins/projectexplorer/projectnodes.h @@ -206,7 +206,6 @@ class PROJECTEXPLORER_EXPORT FolderNode : public Node public: explicit FolderNode(const Utils::FileName &folderPath, NodeType nodeType = NodeType::Folder, const QString &displayName = QString(), const QByteArray &id = {}); - ~FolderNode() override; QString displayName() const override; QIcon icon() const; @@ -218,7 +217,7 @@ public: const std::function &folderTask = {}, const std::function &folderFilterTask = {}) const; void forEachGenericNode(const std::function &genericTask) const; - const QList nodes() const { return m_nodes; } + const QList nodes() const; QList fileNodes() const; FileNode *fileNode(const Utils::FileName &file) const; QList folderNodes() const; @@ -279,7 +278,9 @@ public: virtual bool showWhenEmpty() const; void addNode(Node *node); + void addNode(std::unique_ptr &&node); void removeNode(Node *node); + std::unique_ptr takeNode(Node *node); bool isEmpty() const; @@ -289,7 +290,7 @@ public: protected: virtual void handleSubTreeChanged(FolderNode *node); - QList m_nodes; + std::vector> m_nodes; QList m_locations; private: