forked from qt-creator/qt-creator
CMake: Do not create file system node in main thread
The file system scanning was already in a thread, but creating a tree from the flat list of file nodes was still done in the main thread. Creating the tree looks for and creates folder nodes as needed for each file node, which is not that big of a deal but still takes 1/3 of a second for the Qt Creator source tree. Task-number: QTCREATORBUG-25783 Change-Id: I28948ed3ff5233f6fc4b86e93da94d882b81e231 Reviewed-by: Qt CI Bot <qt_ci_bot@qt-project.org> Reviewed-by: Cristian Adam <cristian.adam@qt.io>
This commit is contained in:
@@ -213,7 +213,7 @@ CMakeBuildSystem::~CMakeBuildSystem()
|
||||
|
||||
delete m_cppCodeModelUpdater;
|
||||
qDeleteAll(m_extraCompilers);
|
||||
qDeleteAll(m_allFiles);
|
||||
qDeleteAll(m_allFiles.allFiles);
|
||||
}
|
||||
|
||||
void CMakeBuildSystem::triggerParsing()
|
||||
@@ -244,7 +244,7 @@ void CMakeBuildSystem::triggerParsing()
|
||||
|
||||
qCDebug(cmakeBuildSystemLog) << "ParseGuard acquired.";
|
||||
|
||||
if (m_allFiles.isEmpty()) {
|
||||
if (m_allFiles.allFiles.isEmpty()) {
|
||||
qCDebug(cmakeBuildSystemLog)
|
||||
<< "No treescanner information available, forcing treescanner run.";
|
||||
updateReparseParameters(REPARSE_SCAN);
|
||||
@@ -466,8 +466,8 @@ void CMakeBuildSystem::handleTreeScanningFinished()
|
||||
{
|
||||
QTC_CHECK(m_waitingForScan);
|
||||
|
||||
qDeleteAll(m_allFiles);
|
||||
m_allFiles = Utils::transform(m_treeScanner.release(), [](const FileNode *fn) { return fn; });
|
||||
qDeleteAll(m_allFiles.allFiles);
|
||||
m_allFiles = m_treeScanner.release();
|
||||
|
||||
m_waitingForScan = false;
|
||||
|
||||
@@ -528,7 +528,7 @@ void CMakeBuildSystem::clearCMakeCache()
|
||||
}
|
||||
|
||||
std::unique_ptr<CMakeProjectNode> CMakeBuildSystem::generateProjectTree(
|
||||
const QList<const FileNode *> &allFiles, bool includeHeaderNodes)
|
||||
const TreeScanner::Result &allFiles, bool includeHeaderNodes)
|
||||
{
|
||||
QString errorMessage;
|
||||
auto root = m_reader.generateProjectTree(allFiles, errorMessage, includeHeaderNodes);
|
||||
|
||||
@@ -133,7 +133,7 @@ private:
|
||||
void combineScanAndParse();
|
||||
|
||||
std::unique_ptr<CMakeProjectNode> generateProjectTree(
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles, bool includeHeadersNode);
|
||||
const ProjectExplorer::TreeScanner::Result &allFiles, bool includeHeadersNode);
|
||||
void checkAndReportError(QString &errorMessage);
|
||||
|
||||
void updateCMakeConfiguration(QString &errorMessage);
|
||||
@@ -159,8 +159,8 @@ private:
|
||||
void runCTest();
|
||||
|
||||
ProjectExplorer::TreeScanner m_treeScanner;
|
||||
ProjectExplorer::TreeScanner::Result m_allFiles;
|
||||
QHash<QString, bool> m_mimeBinaryCache;
|
||||
QList<const ProjectExplorer::FileNode *> m_allFiles;
|
||||
|
||||
bool m_waitingForScan = false;
|
||||
bool m_waitingForParse = false;
|
||||
|
||||
@@ -209,14 +209,16 @@ bool FileApiReader::usesAllCapsTargets() const
|
||||
}
|
||||
|
||||
std::unique_ptr<CMakeProjectNode> FileApiReader::generateProjectTree(
|
||||
const QList<const FileNode *> &allFiles, QString &errorMessage, bool includeHeaderNodes)
|
||||
const ProjectExplorer::TreeScanner::Result &allFiles,
|
||||
QString &errorMessage,
|
||||
bool includeHeaderNodes)
|
||||
{
|
||||
Q_UNUSED(errorMessage)
|
||||
|
||||
if (includeHeaderNodes) {
|
||||
addHeaderNodes(m_rootProjectNode.get(), m_knownHeaders, allFiles);
|
||||
addHeaderNodes(m_rootProjectNode.get(), m_knownHeaders, allFiles.allFiles);
|
||||
}
|
||||
addFileSystemNodes(m_rootProjectNode.get(), allFiles);
|
||||
addFileSystemNodes(m_rootProjectNode.get(), allFiles.folderNode);
|
||||
return std::exchange(m_rootProjectNode, {});
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include "cmakeprojectnodes.h"
|
||||
|
||||
#include <projectexplorer/rawprojectpart.h>
|
||||
#include <projectexplorer/treescanner.h>
|
||||
|
||||
#include <utils/filesystemwatcher.h>
|
||||
#include <utils/optional.h>
|
||||
@@ -70,7 +71,7 @@ public:
|
||||
CMakeConfig takeParsedConfiguration(QString &errorMessage);
|
||||
QString ctestPath() const;
|
||||
std::unique_ptr<CMakeProjectNode> generateProjectTree(
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles,
|
||||
const ProjectExplorer::TreeScanner::Result &allFiles,
|
||||
QString &errorMessage,
|
||||
bool includeHeaderNodes);
|
||||
ProjectExplorer::RawProjectParts createRawProjectParts(QString &errorMessage);
|
||||
|
||||
@@ -175,7 +175,7 @@ CMakeTargetNode *createTargetNode(const QHash<Utils::FilePath, ProjectNode *> &c
|
||||
|
||||
void addHeaderNodes(ProjectNode *root,
|
||||
QSet<Utils::FilePath> &seenHeaders,
|
||||
const QList<const FileNode *> &allFiles)
|
||||
const QList<FileNode *> &allFiles)
|
||||
{
|
||||
QTC_ASSERT(root, return );
|
||||
|
||||
@@ -206,11 +206,28 @@ void addHeaderNodes(ProjectNode *root,
|
||||
root->addNode(std::move(headerNode));
|
||||
}
|
||||
|
||||
void addFileSystemNodes(ProjectNode *root, const QList<const FileNode *> &allFiles)
|
||||
template<typename Result>
|
||||
static std::unique_ptr<Result> cloneFolderNode(FolderNode *node)
|
||||
{
|
||||
auto folderNode = std::make_unique<Result>(node->filePath());
|
||||
folderNode->setDisplayName(node->displayName());
|
||||
for (Node *node : node->nodes()) {
|
||||
if (FileNode *fn = node->asFileNode()) {
|
||||
folderNode->addNode(std::unique_ptr<FileNode>(fn->clone()));
|
||||
} else if (FolderNode *fn = node->asFolderNode()) {
|
||||
folderNode->addNode(cloneFolderNode<FolderNode>(fn));
|
||||
} else {
|
||||
QTC_CHECK(false);
|
||||
}
|
||||
}
|
||||
return folderNode;
|
||||
}
|
||||
|
||||
void addFileSystemNodes(ProjectNode *root, const std::shared_ptr<FolderNode> &folderNode)
|
||||
{
|
||||
QTC_ASSERT(root, return );
|
||||
|
||||
auto fileSystemNode = std::make_unique<VirtualFolderNode>(root->filePath());
|
||||
auto fileSystemNode = cloneFolderNode<VirtualFolderNode>(folderNode.get());
|
||||
// just before special nodes like "CMake Modules"
|
||||
fileSystemNode->setPriority(Node::DefaultPriority - 6);
|
||||
fileSystemNode->setDisplayName(
|
||||
@@ -218,19 +235,12 @@ void addFileSystemNodes(ProjectNode *root, const QList<const FileNode *> &allFil
|
||||
"<File System>"));
|
||||
fileSystemNode->setIcon(DirectoryIcon(ProjectExplorer::Constants::FILEOVERLAY_UNKNOWN));
|
||||
|
||||
for (const FileNode *fn : allFiles) {
|
||||
if (!fn->filePath().isChildOf(root->filePath()))
|
||||
continue;
|
||||
|
||||
std::unique_ptr<FileNode> node(fn->clone());
|
||||
node->setEnabled(false);
|
||||
fileSystemNode->addNestedNode(std::move(node));
|
||||
}
|
||||
|
||||
if (!fileSystemNode->isEmpty()) {
|
||||
// make file system nodes less probable to be selected when syncing with the current document
|
||||
fileSystemNode->forEachGenericNode(
|
||||
[](Node *n) { n->setPriority(n->priority() + Node::DefaultProjectFilePriority + 1); });
|
||||
fileSystemNode->forEachGenericNode([](Node *n) {
|
||||
n->setPriority(n->priority() + Node::DefaultProjectFilePriority + 1);
|
||||
n->setEnabled(false);
|
||||
});
|
||||
root->addNode(std::move(fileSystemNode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,9 +66,9 @@ CMakeTargetNode *createTargetNode(
|
||||
|
||||
void addHeaderNodes(ProjectExplorer::ProjectNode *root,
|
||||
QSet<Utils::FilePath> &seenHeaders,
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles);
|
||||
const QList<ProjectExplorer::FileNode *> &allFiles);
|
||||
|
||||
void addFileSystemNodes(ProjectExplorer::ProjectNode *root,
|
||||
const QList<const ProjectExplorer::FileNode *> &allFiles);
|
||||
const std::shared_ptr<ProjectExplorer::FolderNode> &folderNode);
|
||||
} // namespace Internal
|
||||
} // namespace CMakeProjectManager
|
||||
|
||||
Reference in New Issue
Block a user