From 21b0e7c37e8f04dfc763852089174b51d5675a1c Mon Sep 17 00:00:00 2001 From: Tobias Hunger <tobias.hunger@qt.io> Date: Mon, 30 Oct 2017 16:59:46 +0100 Subject: [PATCH] Qmake: Make finding pro-files fast Finding the right pro-file was surprisingly slow. Make that fast again. Task-number: QTCREATORBUG-19131 Change-Id: I4b5a8887cb13c36273a553f935a00d87cee4a7b5 Reviewed-by: Eike Ziller <eike.ziller@qt.io> --- src/plugins/qmakeprojectmanager/qmakenodes.cpp | 17 +++++++++-------- src/plugins/qmakeprojectmanager/qmakenodes.h | 5 +++-- .../qmakenodetreebuilder.cpp | 10 +++++----- .../qmakeprojectmanager/qmakeparsernodes.cpp | 17 ++++++++++++----- .../qmakeprojectmanager/qmakeparsernodes.h | 2 ++ 5 files changed, 31 insertions(+), 20 deletions(-) diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.cpp b/src/plugins/qmakeprojectmanager/qmakenodes.cpp index f19723df95..2d0ff67465 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodes.cpp @@ -44,20 +44,21 @@ namespace QmakeProjectManager { */ QmakePriFileNode::QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmakeProFileNode, - const FileName &filePath) : + const FileName &filePath, QmakePriFile *pf) : ProjectNode(filePath), m_project(project), - m_qmakeProFileNode(qmakeProFileNode) + m_qmakeProFileNode(qmakeProFileNode), + m_qmakePriFile(pf) { } QmakePriFile *QmakePriFileNode::priFile() const { - return m_project->rootProFile()->findPriFile(filePath()); + return m_qmakePriFile; } bool QmakePriFileNode::deploysFolder(const QString &folder) const { - QmakePriFile *pri = priFile(); + const QmakePriFile *pri = priFile(); return pri ? pri->deploysFolder(folder) : false; } @@ -145,7 +146,7 @@ bool QmakePriFileNode::supportsAction(ProjectAction action, const Node *node) co bool QmakePriFileNode::canAddSubProject(const QString &proFilePath) const { - QmakePriFile *pri = priFile(); + const QmakePriFile *pri = priFile(); return pri ? pri->canAddSubProject(proFilePath) : false; } @@ -213,8 +214,8 @@ QmakeProFileNode *QmakeProFileNode::findProFileFor(const FileName &fileName) con \class QmakeProFileNode Implements abstract ProjectNode class */ -QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FileName &filePath) : - QmakePriFileNode(project, this, filePath) +QmakeProFileNode::QmakeProFileNode(QmakeProject *project, const FileName &filePath, QmakeProFile *pf) : + QmakePriFileNode(project, this, filePath, pf) { } bool QmakeProFileNode::showInSimpleTree() const @@ -224,7 +225,7 @@ bool QmakeProFileNode::showInSimpleTree() const QmakeProFile *QmakeProFileNode::proFile() const { - return m_project->rootProFile()->findProFile(filePath()); + return static_cast<QmakeProFile*>(QmakePriFileNode::priFile()); } FolderNode::AddNewInformation QmakeProFileNode::addNewInformation(const QStringList &files, Node *context) const diff --git a/src/plugins/qmakeprojectmanager/qmakenodes.h b/src/plugins/qmakeprojectmanager/qmakenodes.h index aca17e18a2..56a2b6be62 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodes.h +++ b/src/plugins/qmakeprojectmanager/qmakenodes.h @@ -42,7 +42,7 @@ class QMAKEPROJECTMANAGER_EXPORT QmakePriFileNode : public ProjectExplorer::Proj { public: QmakePriFileNode(QmakeProject *project, QmakeProFileNode *qmakeProFileNode, - const Utils::FileName &filePath); + const Utils::FileName &filePath, QmakePriFile *pf); QmakePriFile *priFile() const; @@ -73,13 +73,14 @@ protected: private: QmakeProFileNode *m_qmakeProFileNode = nullptr; + QmakePriFile *m_qmakePriFile = nullptr; }; // Implements ProjectNode for qmake .pro files class QMAKEPROJECTMANAGER_EXPORT QmakeProFileNode : public QmakePriFileNode { public: - QmakeProFileNode(QmakeProject *project, const Utils::FileName &filePath); + QmakeProFileNode(QmakeProject *project, const Utils::FileName &filePath, QmakeProFile *pf); QmakeProFile *proFile() const; diff --git a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp index a65b9cd44b..6e071c90e0 100644 --- a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp +++ b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp @@ -183,12 +183,12 @@ static void createTree(const QmakePriFile *pri, QmakePriFileNode *node, const Fi } // Virtual folders: - for (const QmakePriFile *c : pri->children()) { + for (QmakePriFile *c : pri->children()) { QmakePriFileNode *newNode = nullptr; - if (dynamic_cast<const QmakeProFile *>(c)) - newNode = new QmakeProFileNode(c->project(), c->filePath()); + if (auto pf = dynamic_cast<QmakeProFile *>(c)) + newNode = new QmakeProFileNode(c->project(), c->filePath(), pf); else - newNode = new QmakePriFileNode(c->project(), node->proFileNode(), c->filePath()); + newNode = new QmakePriFileNode(c->project(), node->proFileNode(), c->filePath(), c); createTree(c, newNode, toExclude); node->addNode(newNode); } @@ -203,7 +203,7 @@ QmakeProFileNode *QmakeNodeTreeBuilder::buildTree(QmakeProject *project) const FileNameList toExclude = qt ? qt->directoriesToIgnoreInProjectTree() : FileNameList(); - auto root = new QmakeProFileNode(project, project->projectFilePath()); + auto root = new QmakeProFileNode(project, project->projectFilePath(), project->rootProFile()); createTree(project->rootProFile(), root, toExclude); return root; diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index 1c3f4962aa..d37a61626c 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -199,12 +199,14 @@ QmakePriFile *QmakePriFile::findPriFile(const FileName &fileName) { if (fileName == filePath()) return this; - for (QmakePriFile *n : children()) { - if (QmakePriFile *result = n->findPriFile(fileName)) - return result; - } - return nullptr; + return findOrDefault(m_children, [&fileName](QmakePriFile *pf) { return pf->findPriFile(fileName); }); +} +const QmakePriFile *QmakePriFile::findPriFile(const FileName &fileName) const +{ + if (fileName == filePath()) + return this; + return findOrDefault(m_children, [&fileName](const QmakePriFile *pf) { return pf->findPriFile(fileName); }); } void QmakePriFile::makeEmpty() @@ -1010,6 +1012,11 @@ QmakeProFile *QmakeProFile::findProFile(const FileName &fileName) return dynamic_cast<QmakeProFile *>(findPriFile(fileName)); } +const QmakeProFile *QmakeProFile::findProFile(const FileName &fileName) const +{ + return dynamic_cast<const QmakeProFile *>(findPriFile(fileName)); +} + QString QmakeProFile::makefile() const { return singleVariableValue(Variable::Makefile); diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h index 2cad1340cc..41138f4563 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.h +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.h @@ -121,6 +121,7 @@ public: QVector<QmakePriFile *> children() const; QmakePriFile *findPriFile(const Utils::FileName &fileName); + const QmakePriFile *findPriFile(const Utils::FileName &fileName) const; bool knowsFile(const Utils::FileName &filePath) const; @@ -280,6 +281,7 @@ public: QList<QmakeProFile *> allProFiles(); QmakeProFile *findProFile(const Utils::FileName &fileName); + const QmakeProFile *findProFile(const Utils::FileName &fileName) const; ProjectType projectType() const; -- GitLab