From 6829e33dc25051b35d665edeada4d668875ad0e5 Mon Sep 17 00:00:00 2001 From: Tobias Hunger Date: Tue, 28 Mar 2017 16:25:10 +0200 Subject: [PATCH] CMake: Move headers into their own folder in server-mode Move all project headers into one folder. This reduces the time it takes to generate the project tree, since the headers will only show up once now (instead of once per target), severly reducing the number of nodes in the tree. Change-Id: Ibcfa7c02c1aec4a98054f4f8a97b69dfb4c25ae4 Reviewed-by: hjk --- .../cmakeprojectmanager/servermodereader.cpp | 80 ++++++++++--------- .../cmakeprojectmanager/servermodereader.h | 13 +-- 2 files changed, 50 insertions(+), 43 deletions(-) diff --git a/src/plugins/cmakeprojectmanager/servermodereader.cpp b/src/plugins/cmakeprojectmanager/servermodereader.cpp index 86430e041f8..92256420251 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.cpp +++ b/src/plugins/cmakeprojectmanager/servermodereader.cpp @@ -285,7 +285,10 @@ void ServerModeReader::generateProjectTree(CMakeProjectNode *root, cmakeFilesSource, cmakeFilesBuild, cmakeFilesOther); QHash cmakeListsNodes = addCMakeLists(root, cmakeLists); - addProjects(cmakeListsNodes, m_projects, allFiles); + QList knownHeaders; + addProjects(cmakeListsNodes, m_projects, knownHeaders); + + addHeaderNodes(root, knownHeaders, allFiles); } void ServerModeReader::updateCodeModel(CppTools::RawProjectParts &rpps) @@ -575,19 +578,12 @@ static ProjectNode *createProjectNode(const QHash &cmakeListsNodes, const QList &projects, - const QList &allFiles) + QList &knownHeaderNodes) { - QHash> includeFiles; - for (const FileNode *f : allFiles) { - if (f->fileType() != FileType::Header) - continue; - includeFiles[f->filePath().parentDir()].append(f); - } - for (const Project *p : projects) { ProjectNode *pNode = createProjectNode(cmakeListsNodes, p->sourceDirectory, p->name); QTC_ASSERT(pNode, qDebug() << p->sourceDirectory.toUserOutput() ; continue); - addTargets(cmakeListsNodes, p->targets, includeFiles); + addTargets(cmakeListsNodes, p->targets, knownHeaderNodes); } } @@ -609,15 +605,15 @@ static CMakeTargetNode *createTargetNode(const QHash &cmakeListsNodes, - const QList &targets, - const QHash> &headers) +void ServerModeReader::addTargets(const QHash &cmakeListsNodes, + const QList &targets, + QList &knownHeaderNodes) { for (const Target *t : targets) { CMakeTargetNode *tNode = createTargetNode(cmakeListsNodes, t->sourceDirectory, t->name); - QTC_ASSERT(tNode, qDebug() << "No target node for" << t->sourceDirectory << t->name; return); + QTC_ASSERT(tNode, qDebug() << "No target node for" << t->sourceDirectory << t->name; continue); tNode->setTargetInformation(t->artifacts, t->type); - addFileGroups(tNode, t->sourceDirectory, t->buildDirectory, t->fileGroups, headers); + addFileGroups(tNode, t->sourceDirectory, t->buildDirectory, t->fileGroups, knownHeaderNodes); } } @@ -625,7 +621,7 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot, const Utils::FileName &sourceDirectory, const Utils::FileName &buildDirectory, const QList &fileGroups, - const QHash> &headers) + QList &knownHeaderNodes) { QList toList; QSet alreadyListed; @@ -635,30 +631,14 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot, alreadyListed.insert(fn); return count != alreadyListed.count(); }); - const QList newFileNodes = Utils::transform(newSources, [f](const Utils::FileName &fn) { - return new FileNode(fn, Node::fileTypeForFileName(fn), f->isGenerated); + const QList newFileNodes + = Utils::transform(newSources, [f, &knownHeaderNodes](const Utils::FileName &fn) { + auto node = new FileNode(fn, Node::fileTypeForFileName(fn), f->isGenerated); + if (node->fileType() == FileType::Header) + knownHeaderNodes.append(node); + return node; }); toList.append(newFileNodes); - - // Add scanned header files: - const FileNameList headerPaths = headers.keys(); - for (const IncludePath *i : f->includePaths) { - for (const FileName &hp : headerPaths) { - if (hp != i->path && !hp.isChildOf(i->path)) - continue; - const QList &headerFiles = headers.value(hp); - const QList unseenHeaders = Utils::filtered(headerFiles, [&alreadyListed](const FileNode *fn) { - const int count = alreadyListed.count(); - alreadyListed.insert(fn->filePath()); - return count != alreadyListed.count(); - }); - toList.append(Utils::transform(unseenHeaders, [](const FileNode *fn) { - auto copy = new FileNode(fn->filePath(), fn->fileType(), fn->isGenerated()); - copy->setEnabled(false); - return copy; - })); - } - } } // Split up files in groups (based on location): @@ -679,5 +659,29 @@ void ServerModeReader::addFileGroups(ProjectNode *targetRoot, addCMakeVFolder(targetRoot, Utils::FileName(), 10, tr(""), otherFileNodes); } +void ServerModeReader::addHeaderNodes(ProjectNode *root, const QList knownHeaders, + const QList &allFiles) +{ + auto headerNode = new VirtualFolderNode(root->filePath(), Node::DefaultPriority - 5); + headerNode->setDisplayName(tr("")); + root->addNode(headerNode); + + // 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) { + auto node = new FileNode(*fn); + node->setEnabled(false); + headerNode->addNestedNode(node); + } + } +} + } // namespace Internal } // namespace CMakeProjectManager diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h index 7eb831df8ec..01c98182ea3 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.h +++ b/src/plugins/cmakeprojectmanager/servermodereader.h @@ -117,15 +117,18 @@ private: addCMakeLists(CMakeProjectNode *root, const QList &cmakeLists); void addProjects(const QHash &cmakeListsNodes, const QList &projects, - const QList &allFiles); + QList &knownHeaderNodes); void addTargets(const QHash &cmakeListsNodes, const QList &targets, - const QHash> &headers); + QList &knownHeaderNodes); void addFileGroups(ProjectExplorer::ProjectNode *targetRoot, const Utils::FileName &sourceDirectory, - const Utils::FileName &buildDirectory, - const QList &fileGroups, - const QHash> &headers); + const Utils::FileName &buildDirectory, const QList &fileGroups, + QList &knowHeaderNodes); + + void addHeaderNodes(ProjectExplorer::ProjectNode *root, + const QList knownHeaders, + const QList &allFiles); bool m_hasData = false;