diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.cpp b/src/plugins/cmakeprojectmanager/builddirmanager.cpp index 94ca25015bf..be570ad6812 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.cpp +++ b/src/plugins/cmakeprojectmanager/builddirmanager.cpp @@ -306,6 +306,33 @@ void BuildDirManager::parse(int reparseParameters) reparseParameters & REPARSE_FORCE_CONFIGURATION); } +QVector BuildDirManager::takeProjectFilesToWatch() +{ + QTC_ASSERT(!m_isHandlingError, return {}); + QTC_ASSERT(m_reader, return {}); + + Utils::FilePath sourceDir = m_parameters.sourceDirectory; + Utils::FilePath buildDir = m_parameters.workDirectory; + + const QVector toWatch = Utils::filtered(m_reader->takeProjectFilesToWatch(), + [&sourceDir, + &buildDir](const Utils::FilePath &p) { + return p.isChildOf(sourceDir) + || p.isChildOf(buildDir); + }); + + if (!toWatch.isEmpty()) { + connect(project(), &Project::projectFileIsDirty, this, [this]() { + if (m_parameters.cmakeTool() && m_parameters.cmakeTool()->isAutoRun()) + requestReparse(REPARSE_DEFAULT); + }); + } else { + disconnect(project(), nullptr, this, nullptr); + } + + return toWatch; +} + std::unique_ptr BuildDirManager::generateProjectTree( const QList &allFiles, QString &errorMessage) const { diff --git a/src/plugins/cmakeprojectmanager/builddirmanager.h b/src/plugins/cmakeprojectmanager/builddirmanager.h index 5e0f017a813..99a1e7adb0b 100644 --- a/src/plugins/cmakeprojectmanager/builddirmanager.h +++ b/src/plugins/cmakeprojectmanager/builddirmanager.h @@ -80,6 +80,7 @@ public: void parse(int reparseParameters); + QVector takeProjectFilesToWatch(); std::unique_ptr generateProjectTree(const QList &allFiles, QString &errorMessage) const; CppTools::RawProjectParts createRawProjectParts(QString &errorMessage) const; diff --git a/src/plugins/cmakeprojectmanager/builddirreader.h b/src/plugins/cmakeprojectmanager/builddirreader.h index 755e7ed0950..e42f8ebadfd 100644 --- a/src/plugins/cmakeprojectmanager/builddirreader.h +++ b/src/plugins/cmakeprojectmanager/builddirreader.h @@ -38,6 +38,7 @@ #include #include +#include namespace ProjectExplorer { class FileNode; } @@ -62,6 +63,7 @@ public: virtual bool isParsing() const = 0; + virtual QVector takeProjectFilesToWatch() = 0; virtual QList takeBuildTargets(QString &errorMessage) = 0; virtual CMakeConfig takeParsedConfiguration(QString &errorMessage) = 0; virtual std::unique_ptr generateProjectTree( diff --git a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp index ee9edca4484..a0203742965 100644 --- a/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp +++ b/src/plugins/cmakeprojectmanager/cmakebuildsystem.cpp @@ -310,6 +310,8 @@ void CMakeBuildSystem::updateProjectData(CMakeProject *p, CMakeBuildConfiguratio QTC_ASSERT(m_treeScanner.isFinished() && !bc->m_buildDirManager.isParsing(), return ); + project()->setExtraProjectFiles(bc->m_buildDirManager.takeProjectFilesToWatch()); + CMakeConfig patchedConfig = bc->configurationFromCMake(); { CMakeConfigItem settingFileItem; diff --git a/src/plugins/cmakeprojectmanager/fileapireader.cpp b/src/plugins/cmakeprojectmanager/fileapireader.cpp index a984231082e..03aee9db38e 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.cpp +++ b/src/plugins/cmakeprojectmanager/fileapireader.cpp @@ -175,6 +175,11 @@ bool FileApiReader::isParsing() const return m_isParsing; } +QVector FileApiReader::takeProjectFilesToWatch() +{ + return QVector::fromList(m_cmakeFiles.toList()); +} + QList FileApiReader::takeBuildTargets(QString &errorMessage){ Q_UNUSED(errorMessage) diff --git a/src/plugins/cmakeprojectmanager/fileapireader.h b/src/plugins/cmakeprojectmanager/fileapireader.h index 694f60e1a27..ce1ed3fbbe6 100644 --- a/src/plugins/cmakeprojectmanager/fileapireader.h +++ b/src/plugins/cmakeprojectmanager/fileapireader.h @@ -62,6 +62,7 @@ public: bool isParsing() const final; + QVector takeProjectFilesToWatch() final; QList takeBuildTargets(QString &errorMessage) final; CMakeConfig takeParsedConfiguration(QString &errorMessage) final; std::unique_ptr generateProjectTree( diff --git a/src/plugins/cmakeprojectmanager/servermodereader.h b/src/plugins/cmakeprojectmanager/servermodereader.h index 3c4e9216c7d..90bdd226d15 100644 --- a/src/plugins/cmakeprojectmanager/servermodereader.h +++ b/src/plugins/cmakeprojectmanager/servermodereader.h @@ -55,6 +55,7 @@ public: bool isParsing() const final; + QVector takeProjectFilesToWatch() final { return {}; }; QList takeBuildTargets(QString &errorMessage) final; CMakeConfig takeParsedConfiguration(QString &errorMessage) final; std::unique_ptr generateProjectTree( diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.cpp b/src/plugins/cmakeprojectmanager/tealeafreader.cpp index 792c6b91180..0d9e4fb1723 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.cpp +++ b/src/plugins/cmakeprojectmanager/tealeafreader.cpp @@ -54,49 +54,9 @@ using namespace Core; using namespace ProjectExplorer; using namespace Utils; -// -------------------------------------------------------------------- -// Helper: -// -------------------------------------------------------------------- - namespace CMakeProjectManager { namespace Internal { -class CMakeFile : public IDocument -{ -public: - CMakeFile(TeaLeafReader *r, const FilePath &fileName); - - ReloadBehavior reloadBehavior(ChangeTrigger state, ChangeType type) const override; - bool reload(QString *errorString, ReloadFlag flag, ChangeType type) override; - -private: - TeaLeafReader *m_reader; -}; - -CMakeFile::CMakeFile(TeaLeafReader *r, const FilePath &fileName) : m_reader(r) -{ - setId("Cmake.ProjectFile"); - setMimeType(Constants::CMAKEPROJECTMIMETYPE); - setFilePath(fileName); -} - -IDocument::ReloadBehavior CMakeFile::reloadBehavior(ChangeTrigger state, ChangeType type) const -{ - Q_UNUSED(state) - Q_UNUSED(type) - return BehaviorSilent; -} - -bool CMakeFile::reload(QString *errorString, IDocument::ReloadFlag flag, IDocument::ChangeType type) -{ - Q_UNUSED(errorString) - Q_UNUSED(flag) - - if (type != TypePermissions) - emit m_reader->dirty(); - return true; -} - // -------------------------------------------------------------------- // TeaLeafReader: // -------------------------------------------------------------------- @@ -140,9 +100,6 @@ bool TeaLeafReader::isCompatible(const BuildDirParameters &p) void TeaLeafReader::resetData() { - qDeleteAll(m_watchedFiles); - m_watchedFiles.clear(); - m_projectName.clear(); m_buildTargets.clear(); m_files.clear(); @@ -202,6 +159,11 @@ bool TeaLeafReader::isParsing() const return m_cmakeProcess && m_cmakeProcess->state() != QProcess::NotRunning; } +QVector TeaLeafReader::takeProjectFilesToWatch() +{ + return transform(m_cmakeFiles, [](const FilePath &p) { return p; }); +} + QList TeaLeafReader::takeBuildTargets(QString &errorMessage) { Q_UNUSED(errorMessage) @@ -244,29 +206,6 @@ std::unique_ptr TeaLeafReader::generateProjectTree( auto root = std::make_unique(m_parameters.sourceDirectory); root->setDisplayName(m_projectName); - // Delete no longer necessary file watcher based on m_cmakeFiles: - const QSet currentWatched - = transform(m_watchedFiles, &CMakeFile::filePath); - const QSet toWatch = m_cmakeFiles; - QSet toDelete = currentWatched; - toDelete.subtract(toWatch); - m_watchedFiles = filtered(m_watchedFiles, [&toDelete](Internal::CMakeFile *cmf) { - if (toDelete.contains(cmf->filePath())) { - delete cmf; - return false; - } - return true; - }); - - // Add new file watchers: - QSet toAdd = toWatch; - toAdd.subtract(currentWatched); - foreach (const FilePath &fn, toAdd) { - auto cm = new CMakeFile(this, fn); - DocumentManager::addDocument(cm); - m_watchedFiles.insert(cm); - } - QSet allIncludePathSet; for (const CMakeBuildTarget &bt : m_buildTargets) { const QList targetIncludePaths diff --git a/src/plugins/cmakeprojectmanager/tealeafreader.h b/src/plugins/cmakeprojectmanager/tealeafreader.h index db64cbaf9a4..c0c4c5a1168 100644 --- a/src/plugins/cmakeprojectmanager/tealeafreader.h +++ b/src/plugins/cmakeprojectmanager/tealeafreader.h @@ -37,8 +37,6 @@ namespace Utils { class QtcProcess; } namespace CMakeProjectManager { namespace Internal { -class CMakeFile; - class TeaLeafReader : public BuildDirReader { Q_OBJECT @@ -56,6 +54,7 @@ public: bool isParsing() const final; + QVector takeProjectFilesToWatch() final; QList takeBuildTargets(QString &errorMessage) final; CMakeConfig takeParsedConfiguration(QString &errorMessage) final; std::unique_ptr generateProjectTree( @@ -80,7 +79,6 @@ private: QString m_projectName; QList m_buildTargets; std::vector> m_files; - QSet m_watchedFiles; // RegExps for function-like macrosses names fixups QRegularExpression m_macroFixupRe1;