From 023d9954601cca13e15848dbb8fad4cc66501b64 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Wed, 12 Jun 2019 16:18:08 +0200 Subject: [PATCH] CMake: Move some code out of the ServerModeReader ... so that it can get re-used in the to-be-written fileapi reader. Change-Id: I2693e6bb102d910eb505882bf3468c34272a5d04 Reviewed-by: Tobias Hunger --- .../cmakeprojectmanager/CMakeLists.txt | 1 + .../cmakeprojectmanager.pro | 2 + .../cmakeprojectmanager.qbs | 2 + .../cmakeprojectmanager/projecttreehelper.cpp | 204 ++++++++++++++++++ .../cmakeprojectmanager/projecttreehelper.h | 70 ++++++ .../cmakeprojectmanager/servermodereader.cpp | 153 +------------ .../cmakeprojectmanager/servermodereader.h | 6 - 7 files changed, 280 insertions(+), 158 deletions(-) create mode 100644 src/plugins/cmakeprojectmanager/projecttreehelper.cpp create mode 100644 src/plugins/cmakeprojectmanager/projecttreehelper.h diff --git a/src/plugins/cmakeprojectmanager/CMakeLists.txt b/src/plugins/cmakeprojectmanager/CMakeLists.txt index bbfede33aaf..8a5abb739b9 100644 --- a/src/plugins/cmakeprojectmanager/CMakeLists.txt +++ b/src/plugins/cmakeprojectmanager/CMakeLists.txt @@ -37,6 +37,7 @@ add_qtc_plugin(CMakeProjectManager cmaketoolsettingsaccessor.cpp cmaketoolsettingsaccessor.h configmodel.cpp configmodel.h configmodelitemdelegate.cpp configmodelitemdelegate.h + projecttreehelper.cpp projecttreehelper.h servermode.cpp servermode.h servermodereader.cpp servermodereader.h tealeafreader.cpp tealeafreader.h diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro index 6d5073f5c6a..07ee7f3555c 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.pro @@ -34,6 +34,7 @@ HEADERS = builddirmanager.h \ cmakespecificsettingspage.h \ configmodel.h \ configmodelitemdelegate.h \ + projecttreehelper.h \ servermode.h \ servermodereader.h \ tealeafreader.h @@ -68,6 +69,7 @@ SOURCES = builddirmanager.cpp \ cmakespecificsettingspage.cpp \ configmodel.cpp \ configmodelitemdelegate.cpp \ + projecttreehelper.cpp \ servermode.cpp \ servermodereader.cpp \ tealeafreader.cpp diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs index 5157f8ba715..c2352684b0c 100644 --- a/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs +++ b/src/plugins/cmakeprojectmanager/cmakeprojectmanager.qbs @@ -84,6 +84,8 @@ QtcPlugin { "configmodel.h", "configmodelitemdelegate.cpp", "configmodelitemdelegate.h", + "projecttreehelper.cpp", + "projecttreehelper.h", "servermode.cpp", "servermode.h", "servermodereader.cpp", diff --git a/src/plugins/cmakeprojectmanager/projecttreehelper.cpp b/src/plugins/cmakeprojectmanager/projecttreehelper.cpp new file mode 100644 index 00000000000..c1a3abaaaef --- /dev/null +++ b/src/plugins/cmakeprojectmanager/projecttreehelper.cpp @@ -0,0 +1,204 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "projecttreehelper.h" + +#include +#include + +#include +#include + +using namespace ProjectExplorer; + +namespace CMakeProjectManager { +namespace Internal { + +void addCMakeVFolder(FolderNode *base, + const Utils::FilePath &basePath, + int priority, + const QString &displayName, + std::vector> &&files) +{ + if (files.size() == 0) + return; + FolderNode *folder = base; + if (!displayName.isEmpty()) { + auto newFolder = std::make_unique(basePath); + newFolder->setPriority(priority); + newFolder->setDisplayName(displayName); + folder = newFolder.get(); + base->addNode(std::move(newFolder)); + } + folder->addNestedNodes(std::move(files)); + for (FolderNode *fn : folder->folderNodes()) + fn->compress(); +} + +std::vector> &&removeKnownNodes( + const QSet &knownFiles, std::vector> &&files) +{ + Utils::erase(files, [&knownFiles](const std::unique_ptr &n) { + return knownFiles.contains(n->filePath()); + }); + return std::move(files); +} + +void addCMakeInputs(FolderNode *root, + const Utils::FilePath &sourceDir, + const Utils::FilePath &buildDir, + std::vector> &&sourceInputs, + std::vector> &&buildInputs, + std::vector> &&rootInputs) +{ + std::unique_ptr cmakeVFolder = std::make_unique(root->filePath()); + + QSet knownFiles; + root->forEachGenericNode([&knownFiles](const Node *n) { + if (n->listInProject()) + knownFiles.insert(n->filePath()); + }); + + addCMakeVFolder(cmakeVFolder.get(), + sourceDir, + 1000, + QString(), + removeKnownNodes(knownFiles, std::move(sourceInputs))); + addCMakeVFolder(cmakeVFolder.get(), + buildDir, + 100, + QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", + ""), + removeKnownNodes(knownFiles, std::move(buildInputs))); + addCMakeVFolder(cmakeVFolder.get(), + Utils::FilePath(), + 10, + QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", + ""), + removeKnownNodes(knownFiles, std::move(rootInputs))); + + root->addNode(std::move(cmakeVFolder)); +} +QHash addCMakeLists( + CMakeProjectNode *root, std::vector> &&cmakeLists) +{ + QHash cmakeListsNodes; + cmakeListsNodes.insert(root->filePath(), root); + + const QSet cmakeDirs + = Utils::transform(cmakeLists, [](const std::unique_ptr &n) { + return n->filePath().parentDir(); + }); + root->addNestedNodes(std::move(cmakeLists), + Utils::FilePath(), + [&cmakeDirs, &cmakeListsNodes](const Utils::FilePath &fp) + -> std::unique_ptr { + if (cmakeDirs.contains(fp)) { + auto fn = std::make_unique(fp); + cmakeListsNodes.insert(fp, fn.get()); + return std::move(fn); + } + + return std::make_unique(fp); + }); + root->compress(); + return cmakeListsNodes; +} + +void createProjectNode(const QHash &cmakeListsNodes, + const Utils::FilePath &dir, + const QString &displayName) +{ + ProjectNode *cmln = cmakeListsNodes.value(dir); + QTC_ASSERT(cmln, return ); + + const Utils::FilePath projectName = dir.pathAppended(".project::" + displayName); + + ProjectNode *pn = cmln->projectNode(projectName); + if (!pn) { + auto newNode = std::make_unique(projectName); + pn = newNode.get(); + cmln->addNode(std::move(newNode)); + } + pn->setDisplayName(displayName); +} + +CMakeTargetNode *createTargetNode(const QHash &cmakeListsNodes, + const Utils::FilePath &dir, + const QString &displayName) +{ + ProjectNode *cmln = cmakeListsNodes.value(dir); + QTC_ASSERT(cmln, return nullptr); + + QString targetId = CMakeTargetNode::generateId(dir, displayName); + + CMakeTargetNode *tn = static_cast( + cmln->findNode([&targetId](const Node *n) { return n->buildKey() == targetId; })); + if (!tn) { + auto newNode = std::make_unique(dir, displayName); + tn = newNode.get(); + cmln->addNode(std::move(newNode)); + } + tn->setDisplayName(displayName); + return tn; +} + +void addHeaderNodes(ProjectNode *root, + const QList knownHeaders, + const QList &allFiles) +{ + if (root->isEmpty()) + return; + + static QIcon headerNodeIcon = Core::FileIconProvider::directoryIcon( + ProjectExplorer::Constants::FILEOVERLAY_H); + auto headerNode = std::make_unique(root->filePath()); + headerNode->setPriority(Node::DefaultPriority - 5); + headerNode->setDisplayName( + QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", "")); + headerNode->setIcon(headerNodeIcon); + + // knownHeaders are already listed in their targets: + QSet seenHeaders = Utils::transform(knownHeaders, &FileNode::filePath); + + // Add scanned headers: + for (const FileNode *fn : allFiles) { + if (fn->fileType() != FileType::Header || !fn->filePath().isChildOf(root->filePath())) + continue; + const int count = seenHeaders.count(); + seenHeaders.insert(fn->filePath()); + if (seenHeaders.count() != count) { + std::unique_ptr node(fn->clone()); + node->setEnabled(false); + headerNode->addNestedNode(std::move(node)); + } + } + + if (!headerNode->isEmpty()) + root->addNode(std::move(headerNode)); +} + +} // namespace Internal +} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/projecttreehelper.h b/src/plugins/cmakeprojectmanager/projecttreehelper.h new file mode 100644 index 00000000000..79eeecf0da3 --- /dev/null +++ b/src/plugins/cmakeprojectmanager/projecttreehelper.h @@ -0,0 +1,70 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "cmakeprojectnodes.h" + +#include + +#include + +#include + +namespace CMakeProjectManager { +namespace Internal { + +void addCMakeVFolder(ProjectExplorer::FolderNode *base, + const Utils::FilePath &basePath, + int priority, + const QString &displayName, + std::vector> &&files); + +std::vector> &&removeKnownNodes( + const QSet &knownFiles, + std::vector> &&files); + +void addCMakeInputs(ProjectExplorer::FolderNode *root, + const Utils::FilePath &sourceDir, + const Utils::FilePath &buildDir, + std::vector> &&sourceInputs, + std::vector> &&buildInputs, + std::vector> &&rootInputs); + +QHash addCMakeLists( + CMakeProjectNode *root, std::vector> &&cmakeLists); + +void createProjectNode(const QHash &cmakeListsNodes, + const Utils::FilePath &dir, + const QString &displayName); +CMakeTargetNode *createTargetNode( + const QHash &cmakeListsNodes, + const Utils::FilePath &dir, + const QString &displayName); + +void addHeaderNodes(ProjectExplorer::ProjectNode *root, + const QList knownHeaders, + const QList &allFiles); + +} // namespace Internal +} // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index 525dcca05f4..9551931180d 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -30,9 +30,9 @@ #include "cmakeprojectmanager.h" #include "cmakeprojectnodes.h" #include "servermode.h" +#include "projecttreehelper.h" #include -#include #include #include #include @@ -227,61 +227,6 @@ CMakeConfig ServerModeReader::takeParsedConfiguration() return config; } -static void addCMakeVFolder(FolderNode *base, const Utils::FilePath &basePath, int priority, - const QString &displayName, - std::vector> &&files) -{ - if (files.size() == 0) - return; - FolderNode *folder = base; - if (!displayName.isEmpty()) { - auto newFolder = std::make_unique(basePath); - newFolder->setPriority(priority); - newFolder->setDisplayName(displayName); - folder = newFolder.get(); - base->addNode(std::move(newFolder)); - } - folder->addNestedNodes(std::move(files)); - for (FolderNode *fn : folder->folderNodes()) - fn->compress(); -} - -static std::vector> && -removeKnownNodes(const QSet &knownFiles, - std::vector> &&files) -{ - Utils::erase(files, [&knownFiles](const std::unique_ptr &n) { - return knownFiles.contains(n->filePath()); - }); - return std::move(files); -} - -static void addCMakeInputs(FolderNode *root, - const Utils::FilePath &sourceDir, - const Utils::FilePath &buildDir, - std::vector> &&sourceInputs, - std::vector> &&buildInputs, - std::vector> &&rootInputs) -{ - std::unique_ptr cmakeVFolder = std::make_unique(root->filePath()); - - QSet knownFiles; - root->forEachGenericNode([&knownFiles](const Node *n) { - if (n->listInProject()) - knownFiles.insert(n->filePath()); - }); - - addCMakeVFolder(cmakeVFolder.get(), sourceDir, 1000, QString(), removeKnownNodes(knownFiles, std::move(sourceInputs))); - addCMakeVFolder(cmakeVFolder.get(), buildDir, 100, - QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", ""), - removeKnownNodes(knownFiles, std::move(buildInputs))); - addCMakeVFolder(cmakeVFolder.get(), Utils::FilePath(), 10, - QCoreApplication::translate("CMakeProjectManager::Internal::ServerModeReader", ""), - removeKnownNodes(knownFiles, std::move(rootInputs))); - - root->addNode(std::move(cmakeVFolder)); -} - void ServerModeReader::generateProjectTree(CMakeProjectNode *root, const QList &allFiles) { @@ -790,49 +735,6 @@ void ServerModeReader::fixTarget(ServerModeReader::Target *target) const } } -QHash -ServerModeReader::addCMakeLists(CMakeProjectNode *root, - std::vector> &&cmakeLists) -{ - QHash cmakeListsNodes; - cmakeListsNodes.insert(root->filePath(), root); - - const QSet cmakeDirs - = Utils::transform(cmakeLists, [](const std::unique_ptr &n) { - return n->filePath().parentDir(); - }); - root->addNestedNodes(std::move(cmakeLists), Utils::FilePath(), - [&cmakeDirs, &cmakeListsNodes](const Utils::FilePath &fp) - -> std::unique_ptr { - if (cmakeDirs.contains(fp)) { - auto fn = std::make_unique(fp); - cmakeListsNodes.insert(fp, fn.get()); - return fn; - } - - return std::make_unique(fp); - }); - root->compress(); - return cmakeListsNodes; -} - -static void createProjectNode(const QHash &cmakeListsNodes, - const Utils::FilePath &dir, const QString &displayName) -{ - ProjectNode *cmln = cmakeListsNodes.value(dir); - QTC_ASSERT(cmln, qDebug() << dir.toUserOutput(); return); - - const Utils::FilePath projectName = dir.pathAppended(".project::" + displayName); - - ProjectNode *pn = cmln->projectNode(projectName); - if (!pn) { - auto newNode = std::make_unique(projectName); - pn = newNode.get(); - cmln->addNode(std::move(newNode)); - } - pn->setDisplayName(displayName); -} - void ServerModeReader::addProjects(const QHash &cmakeListsNodes, const QList &projects, QList &knownHeaderNodes) @@ -843,26 +745,6 @@ void ServerModeReader::addProjects(const QHash & } } -static CMakeTargetNode *createTargetNode(const QHash &cmakeListsNodes, - const Utils::FilePath &dir, const QString &displayName) -{ - ProjectNode *cmln = cmakeListsNodes.value(dir); - QTC_ASSERT(cmln, return nullptr); - - QString targetId = CMakeTargetNode::generateId(dir, displayName); - - CMakeTargetNode *tn = static_cast(cmln->findNode([&targetId](const Node *n) { - return n->buildKey() == targetId; - })); - if (!tn) { - auto newNode = std::make_unique(dir, displayName); - tn = newNode.get(); - cmln->addNode(std::move(newNode)); - } - tn->setDisplayName(displayName); - return tn; -} - void ServerModeReader::addTargets(const QHash &cmakeListsNodes, const QList &targets, QList &knownHeaderNodes) @@ -955,39 +837,6 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot, addCMakeVFolder(targetRoot, Utils::FilePath(), 10, tr(""), std::move(otherFileNodes)); } -void ServerModeReader::addHeaderNodes(ProjectNode *root, const QList knownHeaders, - const QList &allFiles) -{ - if (root->isEmpty()) - return; - - static QIcon headerNodeIcon - = Core::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_H); - auto headerNode = std::make_unique(root->filePath()); - headerNode->setPriority(Node::DefaultPriority - 5); - headerNode->setDisplayName(tr("")); - headerNode->setIcon(headerNodeIcon); - - // knownHeaders are already listed in their targets: - QSet seenHeaders = Utils::transform(knownHeaders, &FileNode::filePath); - - // Add scanned headers: - for (const FileNode *fn : allFiles) { - if (fn->fileType() != FileType::Header || !fn->filePath().isChildOf(root->filePath())) - continue; - const int count = seenHeaders.count(); - seenHeaders.insert(fn->filePath()); - if (seenHeaders.count() != count) { - std::unique_ptr node(fn->clone()); - node->setEnabled(false); - headerNode->addNestedNode(std::move(node)); - } - } - - if (!headerNode->isEmpty()) - root->addNode(std::move(headerNode)); -} - } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h index e0c0cd5d685..4d18a08fe74 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.h +++ b/src/plugins/cmakeprojectmanager/servermodereader.h @@ -145,8 +145,6 @@ private: void fixTarget(Target *target) const; - QHash - addCMakeLists(CMakeProjectNode *root, std::vector > &&cmakeLists); void addProjects(const QHash &cmakeListsNodes, const QList &projects, QList &knownHeaderNodes); @@ -158,10 +156,6 @@ private: const Utils::FilePath &buildDirectory, const QList &fileGroups, QList &knowHeaderNodes); - void addHeaderNodes(ProjectExplorer::ProjectNode *root, - const QList knownHeaders, - const QList &allFiles); - std::unique_ptr m_cmakeServer; std::unique_ptr> m_future;