CMake: Simplify based on Project::projectFileIsDirty signal

Delegate all the necessary file watching to Project and connect
to the relevant signal.

Server-mode insists on watching files itself, so that may not
report extra project files.

Change-Id: If821c54a7b0f8b72beed53dd1c83f255973faf3e
Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
Tobias Hunger
2019-08-15 12:22:09 +02:00
parent c89a8a4084
commit b8be7da158
9 changed files with 45 additions and 69 deletions

View File

@@ -306,6 +306,33 @@ void BuildDirManager::parse(int reparseParameters)
reparseParameters & REPARSE_FORCE_CONFIGURATION);
}
QVector<FilePath> 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<FilePath> 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<CMakeProjectNode> BuildDirManager::generateProjectTree(
const QList<const FileNode *> &allFiles, QString &errorMessage) const
{

View File

@@ -80,6 +80,7 @@ public:
void parse(int reparseParameters);
QVector<Utils::FilePath> takeProjectFilesToWatch();
std::unique_ptr<CMakeProjectNode> generateProjectTree(const QList<const ProjectExplorer::FileNode *> &allFiles,
QString &errorMessage) const;
CppTools::RawProjectParts createRawProjectParts(QString &errorMessage) const;

View File

@@ -38,6 +38,7 @@
#include <QFutureInterface>
#include <QObject>
#include <QVector>
namespace ProjectExplorer { class FileNode; }
@@ -62,6 +63,7 @@ public:
virtual bool isParsing() const = 0;
virtual QVector<Utils::FilePath> takeProjectFilesToWatch() = 0;
virtual QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) = 0;
virtual CMakeConfig takeParsedConfiguration(QString &errorMessage) = 0;
virtual std::unique_ptr<CMakeProjectNode> generateProjectTree(

View File

@@ -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;

View File

@@ -175,6 +175,11 @@ bool FileApiReader::isParsing() const
return m_isParsing;
}
QVector<FilePath> FileApiReader::takeProjectFilesToWatch()
{
return QVector<FilePath>::fromList(m_cmakeFiles.toList());
}
QList<CMakeBuildTarget> FileApiReader::takeBuildTargets(QString &errorMessage){
Q_UNUSED(errorMessage)

View File

@@ -62,6 +62,7 @@ public:
bool isParsing() const final;
QVector<Utils::FilePath> takeProjectFilesToWatch() final;
QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) final;
CMakeConfig takeParsedConfiguration(QString &errorMessage) final;
std::unique_ptr<CMakeProjectNode> generateProjectTree(

View File

@@ -55,6 +55,7 @@ public:
bool isParsing() const final;
QVector<Utils::FilePath> takeProjectFilesToWatch() final { return {}; };
QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) final;
CMakeConfig takeParsedConfiguration(QString &errorMessage) final;
std::unique_ptr<CMakeProjectNode> generateProjectTree(

View File

@@ -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<FilePath> TeaLeafReader::takeProjectFilesToWatch()
{
return transform<QVector>(m_cmakeFiles, [](const FilePath &p) { return p; });
}
QList<CMakeBuildTarget> TeaLeafReader::takeBuildTargets(QString &errorMessage)
{
Q_UNUSED(errorMessage)
@@ -244,29 +206,6 @@ std::unique_ptr<CMakeProjectNode> TeaLeafReader::generateProjectTree(
auto root = std::make_unique<CMakeProjectNode>(m_parameters.sourceDirectory);
root->setDisplayName(m_projectName);
// Delete no longer necessary file watcher based on m_cmakeFiles:
const QSet<FilePath> currentWatched
= transform(m_watchedFiles, &CMakeFile::filePath);
const QSet<FilePath> toWatch = m_cmakeFiles;
QSet<FilePath> 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<FilePath> toAdd = toWatch;
toAdd.subtract(currentWatched);
foreach (const FilePath &fn, toAdd) {
auto cm = new CMakeFile(this, fn);
DocumentManager::addDocument(cm);
m_watchedFiles.insert(cm);
}
QSet<FilePath> allIncludePathSet;
for (const CMakeBuildTarget &bt : m_buildTargets) {
const QList<Utils::FilePath> targetIncludePaths

View File

@@ -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<Utils::FilePath> takeProjectFilesToWatch() final;
QList<CMakeBuildTarget> takeBuildTargets(QString &errorMessage) final;
CMakeConfig takeParsedConfiguration(QString &errorMessage) final;
std::unique_ptr<CMakeProjectNode> generateProjectTree(
@@ -80,7 +79,6 @@ private:
QString m_projectName;
QList<CMakeBuildTarget> m_buildTargets;
std::vector<std::unique_ptr<ProjectExplorer::FileNode>> m_files;
QSet<Internal::CMakeFile *> m_watchedFiles;
// RegExps for function-like macrosses names fixups
QRegularExpression m_macroFixupRe1;