Qbs: Simplify based on Project::projectFileIsDirty signal

Change-Id: Idbb55851a3c6ec0c42c75eaa5c0bc89048bd5077
Reviewed-by: Christian Kandeler <christian.kandeler@qt.io>
This commit is contained in:
Tobias Hunger
2019-08-15 12:25:20 +02:00
parent b8be7da158
commit 929083e7b6
2 changed files with 26 additions and 85 deletions

View File

@@ -37,20 +37,22 @@
#include <coreplugin/documentmanager.h> #include <coreplugin/documentmanager.h>
#include <coreplugin/icontext.h> #include <coreplugin/icontext.h>
#include <coreplugin/id.h>
#include <coreplugin/icore.h> #include <coreplugin/icore.h>
#include <coreplugin/id.h>
#include <coreplugin/iversioncontrol.h> #include <coreplugin/iversioncontrol.h>
#include <coreplugin/vcsmanager.h>
#include <coreplugin/messagemanager.h> #include <coreplugin/messagemanager.h>
#include <coreplugin/progressmanager/progressmanager.h> #include <coreplugin/progressmanager/progressmanager.h>
#include <coreplugin/vcsmanager.h>
#include <cpptools/cppmodelmanager.h> #include <cpptools/cppmodelmanager.h>
#include <cpptools/cppprojectupdater.h> #include <cpptools/cppprojectupdater.h>
#include <cpptools/generatedcodemodelsupport.h>
#include <extensionsystem/pluginmanager.h> #include <extensionsystem/pluginmanager.h>
#include <projectexplorer/buildenvironmentwidget.h> #include <projectexplorer/buildenvironmentwidget.h>
#include <projectexplorer/buildinfo.h> #include <projectexplorer/buildinfo.h>
#include <projectexplorer/buildmanager.h> #include <projectexplorer/buildmanager.h>
#include <projectexplorer/buildtargetinfo.h> #include <projectexplorer/buildtargetinfo.h>
#include <projectexplorer/deploymentdata.h> #include <projectexplorer/deploymentdata.h>
#include <projectexplorer/headerpath.h>
#include <projectexplorer/kit.h> #include <projectexplorer/kit.h>
#include <projectexplorer/kitinformation.h> #include <projectexplorer/kitinformation.h>
#include <projectexplorer/projectexplorer.h> #include <projectexplorer/projectexplorer.h>
@@ -58,14 +60,13 @@
#include <projectexplorer/target.h> #include <projectexplorer/target.h>
#include <projectexplorer/taskhub.h> #include <projectexplorer/taskhub.h>
#include <projectexplorer/toolchain.h> #include <projectexplorer/toolchain.h>
#include <projectexplorer/headerpath.h> #include <utils/algorithm.h>
#include <qtsupport/qtcppkitinfo.h>
#include <qtsupport/qtkitinformation.h>
#include <cpptools/generatedcodemodelsupport.h>
#include <qmljstools/qmljsmodelmanager.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <utils/hostosinfo.h> #include <utils/hostosinfo.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <qmljs/qmljsmodelmanagerinterface.h>
#include <qmljstools/qmljsmodelmanager.h>
#include <qtsupport/qtcppkitinfo.h>
#include <qtsupport/qtkitinformation.h>
#include <qbs.h> #include <qbs.h>
@@ -121,9 +122,9 @@ private:
// QbsProject: // QbsProject:
// -------------------------------------------------------------------- // --------------------------------------------------------------------
QbsProject::QbsProject(const FilePath &fileName) : QbsProject::QbsProject(const FilePath &fileName)
Project(Constants::MIME_TYPE, fileName, [this] { delayParsing(); }), : Project(Constants::MIME_TYPE, fileName)
m_cppCodeModelUpdater(new CppTools::CppProjectUpdater) , m_cppCodeModelUpdater(new CppTools::CppProjectUpdater)
{ {
m_parsingDelay.setInterval(1000); // delay parsing by 1s. m_parsingDelay.setInterval(1000); // delay parsing by 1s.
@@ -151,6 +152,8 @@ QbsProject::QbsProject(const FilePath &fileName) :
this, &QbsProject::delayParsing); this, &QbsProject::delayParsing);
connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing); connect(&m_parsingDelay, &QTimer::timeout, this, &QbsProject::startParsing);
connect(this, &QbsProject::projectFileIsDirty, this, &QbsProject::delayParsing);
} }
QbsProject::~QbsProject() QbsProject::~QbsProject()
@@ -165,8 +168,6 @@ QbsProject::~QbsProject()
m_qbsUpdateFutureInterface = nullptr; m_qbsUpdateFutureInterface = nullptr;
} }
qDeleteAll(m_extraCompilers); qDeleteAll(m_extraCompilers);
std::for_each(m_qbsDocuments.cbegin(), m_qbsDocuments.cend(),
[](Core::IDocument *doc) { doc->deleteLater(); });
} }
void QbsProject::projectLoaded() void QbsProject::projectLoaded()
@@ -215,36 +216,6 @@ bool QbsProject::isProjectEditable() const
return m_qbsProject.isValid() && !isParsing() && !BuildManager::isBuilding(); return m_qbsProject.isValid() && !isParsing() && !BuildManager::isBuilding();
} }
class ChangeExpector
{
public:
ChangeExpector(const QString &filePath, const QSet<IDocument *> &documents)
: m_document(nullptr)
{
foreach (IDocument * const doc, documents) {
if (doc->filePath().toString() == filePath) {
m_document = doc;
break;
}
}
QTC_ASSERT(m_document, return);
DocumentManager::expectFileChange(filePath);
m_wasInDocumentManager = DocumentManager::removeDocument(m_document);
QTC_CHECK(m_wasInDocumentManager);
}
~ChangeExpector()
{
QTC_ASSERT(m_document, return);
DocumentManager::addDocument(m_document);
DocumentManager::unexpectFileChange(m_document->filePath().toString());
}
private:
IDocument *m_document;
bool m_wasInDocumentManager;
};
bool QbsProject::ensureWriteableQbsFile(const QString &file) bool QbsProject::ensureWriteableQbsFile(const QString &file)
{ {
// Ensure that the file is not read only // Ensure that the file is not read only
@@ -273,7 +244,7 @@ bool QbsProject::addFilesToProduct(const QStringList &filePaths,
QTC_ASSERT(m_qbsProject.isValid(), return false); QTC_ASSERT(m_qbsProject.isValid(), return false);
QStringList allPaths = groupData.allFilePaths(); QStringList allPaths = groupData.allFilePaths();
const QString productFilePath = productData.location().filePath(); const QString productFilePath = productData.location().filePath();
ChangeExpector expector(productFilePath, m_qbsDocuments); Core::FileChangeBlocker expector(productFilePath);
ensureWriteableQbsFile(productFilePath); ensureWriteableQbsFile(productFilePath);
foreach (const QString &path, filePaths) { foreach (const QString &path, filePaths) {
qbs::ErrorInfo err = m_qbsProject.addFiles(productData, groupData, QStringList() << path); qbs::ErrorInfo err = m_qbsProject.addFiles(productData, groupData, QStringList() << path);
@@ -310,7 +281,7 @@ RemovedFilesFromProject QbsProject::removeFilesFromProduct(const QStringList &fi
} }
} }
const QString productFilePath = productData.location().filePath(); const QString productFilePath = productData.location().filePath();
ChangeExpector expector(productFilePath, m_qbsDocuments); Core::FileChangeBlocker expector(productFilePath);
ensureWriteableQbsFile(productFilePath); ensureWriteableQbsFile(productFilePath);
for (const QString &path : qAsConst(nonWildcardFiles)) { for (const QString &path : qAsConst(nonWildcardFiles)) {
const qbs::ErrorInfo err = m_qbsProject.removeFiles(productData, groupData, {path}); const qbs::ErrorInfo err = m_qbsProject.removeFiles(productData, groupData, {path});
@@ -468,20 +439,12 @@ bool QbsProject::checkCancelStatus()
return true; return true;
} }
static QSet<QString> toQStringSet(const std::set<QString> &src)
{
QSet<QString> result;
result.reserve(int(src.size()));
std::copy(src.begin(), src.end(), Utils::inserter(result));
return result;
}
void QbsProject::updateAfterParse() void QbsProject::updateAfterParse()
{ {
qCDebug(qbsPmLog) << "Updating data after parse"; qCDebug(qbsPmLog) << "Updating data after parse";
OpTimer opTimer("updateAfterParse"); OpTimer opTimer("updateAfterParse");
updateProjectNodes(); updateProjectNodes();
updateDocuments(toQStringSet(m_qbsProject.buildSystemFiles())); updateDocuments(m_qbsProject.buildSystemFiles());
updateBuildTargetData(); updateBuildTargetData();
updateCppCodeModel(); updateCppCodeModel();
updateQmlJsCodeModel(); updateQmlJsCodeModel();
@@ -758,40 +721,19 @@ void QbsProject::prepareForParsing()
m_qbsUpdateFutureInterface->reportStarted(); m_qbsUpdateFutureInterface->reportStarted();
} }
void QbsProject::updateDocuments(const QSet<QString> &files) void QbsProject::updateDocuments(const std::set<QString> &files)
{ {
OpTimer opTimer("updateDocuments"); OpTimer opTimer("updateDocuments");
// Update documents:
QSet<QString> newFiles = files;
QTC_ASSERT(!newFiles.isEmpty(), newFiles << projectFilePath().toString());
QSet<QString> oldFiles;
foreach (IDocument *doc, m_qbsDocuments)
oldFiles.insert(doc->filePath().toString());
QSet<QString> filesToAdd = newFiles; const QVector<FilePath> filePaths = transform<QVector>(files, &FilePath::fromString);
filesToAdd.subtract(oldFiles);
QSet<QString> filesToRemove = oldFiles;
filesToRemove.subtract(newFiles);
QSet<IDocument *> currentDocuments = m_qbsDocuments;
foreach (IDocument *doc, currentDocuments) {
if (filesToRemove.contains(doc->filePath().toString())) {
m_qbsDocuments.remove(doc);
doc->deleteLater();
}
}
QSet<IDocument *> toAdd;
const FilePath buildDir = FilePath::fromString(m_projectData.buildDirectory()); const FilePath buildDir = FilePath::fromString(m_projectData.buildDirectory());
for (const QString &f : qAsConst(filesToAdd)) { const QVector<FilePath> nonBuildDirFilePaths = filtered(filePaths,
// A changed qbs file (project, module etc) should trigger a re-parse, but not if [buildDir](const FilePath &p) {
// the file was generated by qbs itself, in which case that might cause an infinite loop. return p.isChildOf(buildDir);
const FilePath fp = FilePath::fromString(f); });
static const ProjectDocument::ProjectCallback noOpCallback = []{};
const ProjectDocument::ProjectCallback reparseCallback = [this]() { delayParsing(); }; setExtraProjectFiles(nonBuildDirFilePaths);
toAdd.insert(new ProjectDocument(Constants::MIME_TYPE, fp, fp.isChildOf(buildDir)
? noOpCallback : reparseCallback));
}
m_qbsDocuments.unite(toAdd);
} }
static CppTools::ProjectFile::Kind cppFileType(const qbs::ArtifactData &sourceFile) static CppTools::ProjectFile::Kind cppFileType(const qbs::ArtifactData &sourceFile)

View File

@@ -117,7 +117,7 @@ private:
const QString &configName); const QString &configName);
void prepareForParsing(); void prepareForParsing();
void updateDocuments(const QSet<QString> &files); void updateDocuments(const std::set<QString> &files);
void updateCppCodeModel(); void updateCppCodeModel();
void updateQmlJsCodeModel(); void updateQmlJsCodeModel();
void updateApplicationTargets(); void updateApplicationTargets();
@@ -145,7 +145,6 @@ private:
qbs::Project m_qbsProject; // for activeTarget() qbs::Project m_qbsProject; // for activeTarget()
qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData() qbs::ProjectData m_projectData; // Cached m_qbsProject.projectData()
Utils::Environment m_lastParseEnv; Utils::Environment m_lastParseEnv;
QSet<Core::IDocument *> m_qbsDocuments;
QbsProjectParser *m_qbsProjectParser = nullptr; QbsProjectParser *m_qbsProjectParser = nullptr;