diff options
author | Christian Kandeler <christian.kandeler@qt.io> | 2020-09-10 10:39:56 +0200 |
---|---|---|
committer | Christian Kandeler <christian.kandeler@qt.io> | 2020-09-15 09:19:23 +0000 |
commit | f3bd07efd171da8a153d0fa298d6930b82c39f8f (patch) | |
tree | 5d63806ecfb1c9fd503b1e69f8a73847ddb5b4bc | |
parent | a50f1baf5dee2c42f9e44d3c42acd834e4f0d81e (diff) |
QmakeProjectManager: Restore incremental re-parsing
This was broken in commit 37aecdd112, where we overlooked that a special
type of IDocument was used that triggers a re-parse of only the affected
part of the project tree. As a result, all changes to a .pri or .pro file
would trigger a re-parse of the entire project.
Fixes: QTCREATORBUG-24572
Change-Id: I480cff4e53cf86a17e1eaac0eb9b32901bc87051
Reviewed-by: hjk <hjk@qt.io>
-rw-r--r-- | src/plugins/projectexplorer/project.cpp | 27 | ||||
-rw-r--r-- | src/plugins/projectexplorer/project.h | 9 | ||||
-rw-r--r-- | src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp | 35 | ||||
-rw-r--r-- | src/plugins/qmakeprojectmanager/qmakeproject.cpp | 44 |
4 files changed, 73 insertions, 42 deletions
diff --git a/src/plugins/projectexplorer/project.cpp b/src/plugins/projectexplorer/project.cpp index 03e24ee3af..7f32733e1a 100644 --- a/src/plugins/projectexplorer/project.cpp +++ b/src/plugins/projectexplorer/project.cpp @@ -64,7 +64,6 @@ #include <QFileDialog> #include <limits> -#include <memory> /*! \class ProjectExplorer::Project @@ -357,7 +356,8 @@ void Project::setNeedsInitialExpansion(bool needsExpansion) d->m_needsInitialExpansion = needsExpansion; } -void Project::setExtraProjectFiles(const QSet<Utils::FilePath> &projectDocumentPaths) +void Project::setExtraProjectFiles(const QSet<Utils::FilePath> &projectDocumentPaths, + const DocGenerator docGenerator) { QSet<Utils::FilePath> uniqueNewFiles = projectDocumentPaths; uniqueNewFiles.remove(projectFilePath()); // Make sure to never add the main project file! @@ -372,8 +372,14 @@ void Project::setExtraProjectFiles(const QSet<Utils::FilePath> &projectDocumentP return toRemove.contains(d->filePath()); }); for (const Utils::FilePath &p : toAdd) { - d->m_extraProjectDocuments.emplace_back( - std::make_unique<ProjectDocument>(d->m_document->mimeType(), p, this)); + if (docGenerator) { + std::unique_ptr<Core::IDocument> doc = docGenerator(p); + QTC_ASSERT(doc, continue); + d->m_extraProjectDocuments.push_back(std::move(doc)); + } else { + d->m_extraProjectDocuments.emplace_back(std::make_unique<ProjectDocument>( + d->m_document->mimeType(), p, this)); + } } } @@ -802,6 +808,19 @@ bool Project::isKnownFile(const Utils::FilePath &filename) const &element, nodeLessThan); } +const Node *Project::nodeForFilePath(const Utils::FilePath &filePath, + const Project::NodeMatcher &extraMatcher) +{ + const FileNode dummy(filePath, FileType::Unknown); + const auto range = std::equal_range(d->m_sortedNodeList.cbegin(), d->m_sortedNodeList.cend(), + &dummy, &nodeLessThan); + for (auto it = range.first; it != range.second; ++it) { + if ((*it)->filePath() == filePath && (!extraMatcher || extraMatcher(*it))) + return *it; + } + return nullptr; +} + void Project::setProjectLanguages(Core::Context language) { if (d->m_projectLanguages == language) diff --git a/src/plugins/projectexplorer/project.h b/src/plugins/projectexplorer/project.h index 8d12e4c15c..42fd4282c5 100644 --- a/src/plugins/projectexplorer/project.h +++ b/src/plugins/projectexplorer/project.h @@ -39,6 +39,7 @@ #include <QFileSystemModel> #include <functional> +#include <memory> namespace Core { class Context; } namespace Utils { @@ -123,6 +124,8 @@ public: Utils::FilePaths files(const NodeMatcher &matcher) const; bool isKnownFile(const Utils::FilePath &filename) const; + const Node *nodeForFilePath(const Utils::FilePath &filePath, + const NodeMatcher &extraMatcher = {}); virtual QVariantMap toMap() const; @@ -159,9 +162,11 @@ public: void setRootProjectNode(std::unique_ptr<ProjectNode> &&root); - // Set project files that will be watched and trigger the same callback + // Set project files that will be watched and by default trigger the same callback // as the main project file. - void setExtraProjectFiles(const QSet<Utils::FilePath> &projectDocumentPaths); + using DocGenerator = std::function<std::unique_ptr<Core::IDocument>(const Utils::FilePath &)>; + void setExtraProjectFiles(const QSet<Utils::FilePath> &projectDocumentPaths, + const DocGenerator docGenerator = {}); void setDisplayName(const QString &name); void setProjectLanguage(Utils::Id id, bool enabled); diff --git a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp index b694d2255c..6f16d26d29 100644 --- a/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeparsernodes.cpp @@ -63,41 +63,6 @@ using namespace QmakeProjectManager::Internal; using namespace QMakeInternal; using namespace Utils; -namespace { - -class QmakePriFileDocument : public Core::IDocument -{ -public: - QmakePriFileDocument(QmakePriFile *qmakePriFile, const Utils::FilePath &filePath) : - IDocument(nullptr), m_priFile(qmakePriFile) - { - setId("Qmake.PriFile"); - setMimeType(QLatin1String(QmakeProjectManager::Constants::PROFILE_MIMETYPE)); - setFilePath(filePath); - } - - ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override - { - Q_UNUSED(state) - Q_UNUSED(type) - return BehaviorSilent; - } - bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override - { - Q_UNUSED(errorString) - Q_UNUSED(flag) - if (type == TypePermissions) - return true; - m_priFile->scheduleUpdate(); - return true; - } - -private: - QmakePriFile *m_priFile; -}; - -} // namespace - namespace QmakeProjectManager { static Q_LOGGING_CATEGORY(qmakeParse, "qtc.qmake.parsing", QtWarningMsg); diff --git a/src/plugins/qmakeprojectmanager/qmakeproject.cpp b/src/plugins/qmakeprojectmanager/qmakeproject.cpp index 7a5eb09c4d..28707f26bb 100644 --- a/src/plugins/qmakeprojectmanager/qmakeproject.cpp +++ b/src/plugins/qmakeprojectmanager/qmakeproject.cpp @@ -33,6 +33,7 @@ #include "qmakeprojectmanagerconstants.h" #include "qmakestep.h" +#include <coreplugin/documentmanager.h> #include <coreplugin/editormanager/editormanager.h> #include <coreplugin/icontext.h> #include <coreplugin/icore.h> @@ -98,6 +99,38 @@ static Q_LOGGING_CATEGORY(qmakeBuildSystemLog, "qtc.qmake.buildsystem", QtWarnin << msg; \ } +class QmakePriFileDocument : public Core::IDocument +{ +public: + QmakePriFileDocument(QmakePriFile *qmakePriFile, const Utils::FilePath &filePath) : + IDocument(nullptr), m_priFile(qmakePriFile) + { + setId("Qmake.PriFile"); + setMimeType(QLatin1String(QmakeProjectManager::Constants::PROFILE_MIMETYPE)); + setFilePath(filePath); + Core::DocumentManager::addDocument(this); + } + + ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override + { + Q_UNUSED(state) + Q_UNUSED(type) + return BehaviorSilent; + } + bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override + { + Q_UNUSED(errorString) + Q_UNUSED(flag) + if (type == TypePermissions) + return true; + m_priFile->scheduleUpdate(); + return true; + } + +private: + QmakePriFile *m_priFile; +}; + /// Watches folders for QmakePriFile nodes /// use one file system watcher to watch all folders /// such minimizing system ressouce usage @@ -270,8 +303,17 @@ void QmakeBuildSystem::updateDocuments() QSet<FilePath> projectDocuments; project()->rootProjectNode()->forEachProjectNode([&projectDocuments](const ProjectNode *n) { projectDocuments.insert(n->filePath()); + + }); + project()->setExtraProjectFiles(projectDocuments, [p = project()](const FilePath &fp) + -> std::unique_ptr<Core::IDocument> { + const Node * const n = p->nodeForFilePath(fp, [](const Node *n) { + return dynamic_cast<const QmakePriFileNode *>(n); }); + QTC_ASSERT(n, return std::make_unique<Core::IDocument>()); + QmakePriFile * const priFile = static_cast<const QmakePriFileNode *>(n)->priFile(); + QTC_ASSERT(priFile, return std::make_unique<Core::IDocument>()); + return std::make_unique<QmakePriFileDocument>(priFile, fp); }); - project()->setExtraProjectFiles(projectDocuments); } void QmakeBuildSystem::updateCppCodeModel() |