Project: Move signalling of parsing state into Project

Get rid of duplicated code to do such signaling in derived Project types.

Change-Id: I26914a1d751d72ee65c15a7943e0e7f34978f042
Reviewed-by: Tim Jenssen <tim.jenssen@qt.io>
This commit is contained in:
Tobias Hunger
2017-07-13 10:51:15 +02:00
parent 05bcba3e73
commit 09b127f9f1
22 changed files with 105 additions and 40 deletions

View File

@@ -119,6 +119,7 @@ Project::RestoreResult AutotoolsProject::fromMap(const QVariantMap &map, QString
void AutotoolsProject::loadProjectTree() void AutotoolsProject::loadProjectTree()
{ {
emitParsingStarted();
if (m_makefileParserThread) { if (m_makefileParserThread) {
// The thread is still busy parsing a previus configuration. // The thread is still busy parsing a previus configuration.
// Wait until the thread has been finished and delete it. // Wait until the thread has been finished and delete it.
@@ -218,7 +219,7 @@ void AutotoolsProject::makefileParsingFinished()
m_makefileParserThread->deleteLater(); m_makefileParserThread->deleteLater();
m_makefileParserThread = nullptr; m_makefileParserThread = nullptr;
emit parsingFinished(); emitParsingFinished(true);
} }
void AutotoolsProject::onFileChanged(const QString &file) void AutotoolsProject::onFileChanged(const QString &file)

View File

@@ -144,12 +144,15 @@ void CMakeBuildConfiguration::ctor()
connect(m_buildDirManager.get(), &BuildDirManager::dataAvailable, connect(m_buildDirManager.get(), &BuildDirManager::dataAvailable,
this, [this, project]() { this, [this, project]() {
project->updateProjectData(this);
clearError(); clearError();
project->updateProjectData(this);
emit dataAvailable(); emit dataAvailable();
}); });
connect(m_buildDirManager.get(), &BuildDirManager::errorOccured, connect(m_buildDirManager.get(), &BuildDirManager::errorOccured,
this, &CMakeBuildConfiguration::setError); this, [this, project](const QString &msg) {
setError(msg);
project->handleParsingError(this);
});
connect(m_buildDirManager.get(), &BuildDirManager::configurationStarted, connect(m_buildDirManager.get(), &BuildDirManager::configurationStarted,
this, [this, project]() { this, [this, project]() {
project->handleParsingStarted(); project->handleParsingStarted();

View File

@@ -204,7 +204,7 @@ CMakeBuildSettingsWidget::CMakeBuildSettingsWidget(CMakeBuildConfiguration *bc)
setError(bc->error()); setError(bc->error());
setWarning(bc->warning()); setWarning(bc->warning());
connect(project, &CMakeProject::parsingStarted, this, [this]() { connect(project, &ProjectExplorer::Project::parsingStarted, this, [this]() {
updateButtonState(); updateButtonState();
m_showProgressTimer.start(); m_showProgressTimer.start();
}); });

View File

@@ -188,7 +188,18 @@ void CMakeProject::updateProjectData(CMakeBuildConfiguration *bc)
emit bc->emitBuildTypeChanged(); emit bc->emitBuildTypeChanged();
emit parsingFinished(); emitParsingFinished(true);
}
void CMakeProject::handleParsingError(CMakeBuildConfiguration *bc)
{
QTC_ASSERT(bc, return);
Target *t = activeTarget();
if (!t || t->activeBuildConfiguration() != bc)
return;
emitParsingFinished(false);
} }
void CMakeProject::updateQmlJSCodeModel() void CMakeProject::updateQmlJSCodeModel()
@@ -369,7 +380,7 @@ void CMakeProject::handleActiveBuildConfigurationChanged()
void CMakeProject::handleParsingStarted() void CMakeProject::handleParsingStarted()
{ {
if (activeTarget() && activeTarget()->activeBuildConfiguration() == sender()) if (activeTarget() && activeTarget()->activeBuildConfiguration() == sender())
emit parsingStarted(); emitParsingStarted();
} }
void CMakeProject::handleTreeScanningFinished() void CMakeProject::handleTreeScanningFinished()

View File

@@ -105,10 +105,6 @@ public:
ProjectExplorer::ProjectImporter *projectImporter() const final; ProjectExplorer::ProjectImporter *projectImporter() const final;
signals:
/// emitted when cmake is running:
void parsingStarted();
protected: protected:
RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final; RestoreResult fromMap(const QVariantMap &map, QString *errorMessage) final;
bool setupTarget(ProjectExplorer::Target *t) final; bool setupTarget(ProjectExplorer::Target *t) final;
@@ -121,6 +117,7 @@ private:
void handleParsingStarted(); void handleParsingStarted();
void handleTreeScanningFinished(); void handleTreeScanningFinished();
void updateProjectData(Internal::CMakeBuildConfiguration *cmakeBc); void updateProjectData(Internal::CMakeBuildConfiguration *cmakeBc);
void handleParsingError(Internal::CMakeBuildConfiguration *bc);
void updateQmlJSCodeModel(); void updateQmlJSCodeModel();
void createGeneratedCodeModelSupport(); void createGeneratedCodeModelSupport();

View File

@@ -336,6 +336,7 @@ void GenericProject::parseProject(RefreshOptions options)
void GenericProject::refresh(RefreshOptions options) void GenericProject::refresh(RefreshOptions options)
{ {
emitParsingStarted();
parseProject(options); parseProject(options);
if (options & Files) { if (options & Files) {
@@ -362,7 +363,7 @@ void GenericProject::refresh(RefreshOptions options)
} }
refreshCppCodeModel(); refreshCppCodeModel();
emit parsingFinished(); emitParsingFinished(true);
} }
/** /**

View File

@@ -127,6 +127,7 @@ void NimProject::collectProjectFiles()
void NimProject::updateProject() void NimProject::updateProject()
{ {
emitParsingStarted();
const QStringList oldFiles = m_files; const QStringList oldFiles = m_files;
m_files.clear(); m_files.clear();
@@ -152,7 +153,7 @@ void NimProject::updateProject()
newRoot->setDisplayName(displayName()); newRoot->setDisplayName(displayName());
newRoot->addNestedNodes(fileNodes); newRoot->addNestedNodes(fileNodes);
setRootProjectNode(newRoot); setRootProjectNode(newRoot);
emit parsingFinished(); emitParsingFinished(true);
} }
bool NimProject::supportsKit(Kit *k, QString *errorMessage) const bool NimProject::supportsKit(Kit *k, QString *errorMessage) const

View File

@@ -136,6 +136,8 @@ public:
~ProjectPrivate(); ~ProjectPrivate();
Core::Id m_id; Core::Id m_id;
bool m_isParsing = false;
bool m_hasParsingData = false;
std::unique_ptr<Core::IDocument> m_document; std::unique_ptr<Core::IDocument> m_document;
ProjectNode *m_rootProjectNode = nullptr; ProjectNode *m_rootProjectNode = nullptr;
std::unique_ptr<ContainerNode> m_containerNode; std::unique_ptr<ContainerNode> m_containerNode;
@@ -464,6 +466,24 @@ bool Project::setupTarget(Target *t)
return true; return true;
} }
void Project::emitParsingStarted()
{
QTC_ASSERT(!d->m_isParsing, return);
d->m_isParsing = true;
d->m_hasParsingData = false;
emit parsingStarted();
}
void Project::emitParsingFinished(bool success)
{
QTC_ASSERT(d->m_isParsing, return);
d->m_isParsing = false;
d->m_hasParsingData = success;
emit parsingFinished(success);
}
void Project::setDisplayName(const QString &name) void Project::setDisplayName(const QString &name)
{ {
if (name == d->m_displayName) if (name == d->m_displayName)
@@ -813,6 +833,16 @@ Utils::MacroExpander *Project::macroExpander() const
return &d->m_macroExpander; return &d->m_macroExpander;
} }
bool Project::isParsing() const
{
return d->m_isParsing;
}
bool Project::hasParsingData() const
{
return d->m_hasParsingData;
}
ProjectImporter *Project::projectImporter() const ProjectImporter *Project::projectImporter() const
{ {
return nullptr; return nullptr;

View File

@@ -163,6 +163,9 @@ public:
void setup(QList<const BuildInfo *> infoList); void setup(QList<const BuildInfo *> infoList);
Utils::MacroExpander *macroExpander() const; Utils::MacroExpander *macroExpander() const;
bool isParsing() const;
bool hasParsingData() const;
signals: signals:
void displayNameChanged(); void displayNameChanged();
void fileListChanged(); void fileListChanged();
@@ -185,12 +188,19 @@ signals:
void projectContextUpdated(); void projectContextUpdated();
void projectLanguagesUpdated(); void projectLanguagesUpdated();
void parsingFinished(); void parsingStarted();
void parsingFinished(bool success);
protected: protected:
virtual RestoreResult fromMap(const QVariantMap &map, QString *errorMessage); virtual RestoreResult fromMap(const QVariantMap &map, QString *errorMessage);
virtual bool setupTarget(Target *t); virtual bool setupTarget(Target *t);
// Helper methods to manage parsing state and signalling
// Call in GUI thread before the actual parsing starts
void emitParsingStarted();
// Call in GUI thread right after the actual parsing is done
void emitParsingFinished(bool success);
void setDisplayName(const QString &name); void setDisplayName(const QString &name);
void setRequiredKitPredicate(const Kit::Predicate &predicate); void setRequiredKitPredicate(const Kit::Predicate &predicate);
void setPreferredKitPredicate(const Kit::Predicate &predicate); void setPreferredKitPredicate(const Kit::Predicate &predicate);

View File

@@ -507,6 +507,7 @@ private:
void PythonProject::refresh() void PythonProject::refresh()
{ {
emitParsingStarted();
parseProject(); parseProject();
QDir baseDir(projectDirectory().toString()); QDir baseDir(projectDirectory().toString());
@@ -517,7 +518,7 @@ void PythonProject::refresh()
} }
setRootProjectNode(newRoot); setRootProjectNode(newRoot);
emit parsingFinished(); emitParsingFinished(true);
} }
/** /**

View File

@@ -69,8 +69,8 @@ QbsBuildConfiguration::QbsBuildConfiguration(Target *target) :
m_isParsing(true), m_isParsing(true),
m_parsingError(false) m_parsingError(false)
{ {
connect(project(), &QbsProject::projectParsingStarted, this, &BuildConfiguration::enabledChanged); connect(project(), &Project::parsingStarted, this, &BuildConfiguration::enabledChanged);
connect(project(), &QbsProject::projectParsingDone, this, &BuildConfiguration::enabledChanged); connect(project(), &Project::parsingFinished, this, &BuildConfiguration::enabledChanged);
BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD); BuildStepList *bsl = stepList(ProjectExplorer::Constants::BUILDSTEPS_BUILD);
connect(bsl, &BuildStepList::stepInserted, this, &QbsBuildConfiguration::buildStepInserted); connect(bsl, &BuildStepList::stepInserted, this, &QbsBuildConfiguration::buildStepInserted);

View File

@@ -346,7 +346,8 @@ void QbsBuildStep::buildingDone(bool success)
void QbsBuildStep::reparsingDone(bool success) void QbsBuildStep::reparsingDone(bool success)
{ {
disconnect(qbsProject(), &QbsProject::projectParsingDone, this, &QbsBuildStep::reparsingDone); disconnect(qbsProject(), &ProjectExplorer::Project::parsingFinished,
this, &QbsBuildStep::reparsingDone);
m_parsingProject = false; m_parsingProject = false;
if (m_job) { // This was a scheduled reparsing after building. if (m_job) { // This was a scheduled reparsing after building.
finish(); finish();
@@ -485,7 +486,8 @@ void QbsBuildStep::setCleanInstallRoot(bool clean)
void QbsBuildStep::parseProject() void QbsBuildStep::parseProject()
{ {
m_parsingProject = true; m_parsingProject = true;
connect(qbsProject(), &QbsProject::projectParsingDone, this, &QbsBuildStep::reparsingDone); connect(qbsProject(), &ProjectExplorer::Project::parsingFinished,
this, &QbsBuildStep::reparsingDone);
qbsProject()->parseCurrentBuildConfiguration(); qbsProject()->parseCurrentBuildConfiguration();
} }

View File

@@ -286,7 +286,7 @@ QbsInstallStepConfigWidget::QbsInstallStepConfigWidget(QbsInstallStep *step) :
connect(m_ui->keepGoingCheckBox, &QAbstractButton::toggled, connect(m_ui->keepGoingCheckBox, &QAbstractButton::toggled,
this, &QbsInstallStepConfigWidget::changeKeepGoing); this, &QbsInstallStepConfigWidget::changeKeepGoing);
connect(project, &QbsProject::projectParsingDone, connect(project, &ProjectExplorer::Project::parsingFinished,
this, &QbsInstallStepConfigWidget::updateState); this, &QbsInstallStepConfigWidget::updateState);
updateState(); updateState();

View File

@@ -502,8 +502,7 @@ void QbsProject::handleQbsParsingDone(bool success)
if (dataChanged) if (dataChanged)
updateAfterParse(); updateAfterParse();
emit projectParsingDone(success); emitParsingFinished(success);
emit parsingFinished();
} }
void QbsProject::rebuildProjectTree() void QbsProject::rebuildProjectTree()
@@ -529,7 +528,7 @@ void QbsProject::handleRuleExecutionDone()
QTC_ASSERT(m_qbsProject.isValid(), return); QTC_ASSERT(m_qbsProject.isValid(), return);
m_projectData = m_qbsProject.projectData(); m_projectData = m_qbsProject.projectData();
updateAfterParse(); updateAfterParse();
emit projectParsingDone(true); // finishParsing(true);
} }
void QbsProject::targetWasAdded(Target *t) void QbsProject::targetWasAdded(Target *t)
@@ -699,7 +698,7 @@ void QbsProject::parse(const QVariantMap &config, const Environment &env, const
QbsManager::instance()->updateProfileIfNecessary(activeTarget()->kit()); QbsManager::instance()->updateProfileIfNecessary(activeTarget()->kit());
m_qbsProjectParser->parse(config, env, dir, configName); m_qbsProjectParser->parse(config, env, dir, configName);
emit projectParsingStarted(); emitParsingStarted();
} }
void QbsProject::prepareForParsing() void QbsProject::prepareForParsing()

View File

@@ -108,14 +108,9 @@ public:
const qbs::ProductData &product); const qbs::ProductData &product);
static QString uniqueProductName(const qbs::ProductData &product); static QString uniqueProductName(const qbs::ProductData &product);
public:
void invalidate(); void invalidate();
void delayParsing(); void delayParsing();
signals:
void projectParsingStarted();
void projectParsingDone(bool);
private: private:
void handleQbsParsingDone(bool success); void handleQbsParsingDone(bool success);

View File

@@ -295,9 +295,9 @@ void QbsProjectManagerPlugin::projectWasAdded(Project *project)
if (!qbsProject) if (!qbsProject)
return; return;
connect(qbsProject, &QbsProject::projectParsingStarted, connect(qbsProject, &Project::parsingStarted,
this, &QbsProjectManagerPlugin::projectChanged); this, &QbsProjectManagerPlugin::projectChanged);
connect(qbsProject, &QbsProject::projectParsingDone, connect(qbsProject, &Project::parsingFinished,
this, &QbsProjectManagerPlugin::projectChanged); this, &QbsProjectManagerPlugin::projectChanged);
} }

View File

@@ -119,7 +119,7 @@ QbsRunConfiguration::QbsRunConfiguration(Target *parent, Core::Id id) :
} }
); );
addExtraAspect(envAspect); addExtraAspect(envAspect);
connect(static_cast<QbsProject *>(parent->project()), &QbsProject::parsingFinished, this, connect(static_cast<QbsProject *>(parent->project()), &Project::parsingFinished, this,
[envAspect]() { envAspect->buildEnvironmentHasChanged(); }); [envAspect]() { envAspect->buildEnvironmentHasChanged(); });
addExtraAspect(new ArgumentsAspect(this, QStringLiteral("Qbs.RunConfiguration.CommandLineArguments"))); addExtraAspect(new ArgumentsAspect(this, QStringLiteral("Qbs.RunConfiguration.CommandLineArguments")));
addExtraAspect(new WorkingDirectoryAspect(this, QStringLiteral("Qbs.RunConfiguration.WorkingDirectory"))); addExtraAspect(new WorkingDirectoryAspect(this, QStringLiteral("Qbs.RunConfiguration.WorkingDirectory")));
@@ -162,8 +162,8 @@ void QbsRunConfiguration::ctor()
setDefaultDisplayName(defaultDisplayName()); setDefaultDisplayName(defaultDisplayName());
QbsProject *project = static_cast<QbsProject *>(target()->project()); QbsProject *project = static_cast<QbsProject *>(target()->project());
connect(project, &QbsProject::projectParsingStarted, this, &RunConfiguration::enabledChanged); connect(project, &Project::parsingStarted, this, &RunConfiguration::enabledChanged);
connect(project, &QbsProject::projectParsingDone, this, [this](bool success) { connect(project, &Project::parsingFinished, this, [this](bool success) {
auto terminalAspect = extraAspect<TerminalAspect>(); auto terminalAspect = extraAspect<TerminalAspect>();
if (success && !terminalAspect->isUserSet()) if (success && !terminalAspect->isUserSet())
terminalAspect->setUseTerminal(isConsoleApplication()); terminalAspect->setUseTerminal(isConsoleApplication());

View File

@@ -1473,7 +1473,7 @@ void QmakeProFile::asyncEvaluate(QFutureInterface<QmakeEvalResult *> &fi, QmakeE
void QmakeProFile::applyAsyncEvaluate() void QmakeProFile::applyAsyncEvaluate()
{ {
applyEvaluate(m_parseFutureWatcher.result()); applyEvaluate(m_parseFutureWatcher.result());
m_project->decrementPendingEvaluateFutures(); m_project->decrementPendingEvaluateFutures(validParse());
} }
bool sortByParserNodes(Node *a, Node *b) bool sortByParserNodes(Node *a, Node *b)

View File

@@ -408,6 +408,7 @@ void QmakeProject::scheduleAsyncUpdate(QmakeProFile *file, QmakeProFile::AsyncUp
return; return;
} }
emitParsingStarted();
file->setParseInProgressRecursive(true); file->setParseInProgressRecursive(true);
setAllBuildConfigurationsEnabled(false); setAllBuildConfigurationsEnabled(false);
@@ -464,6 +465,7 @@ void QmakeProject::scheduleAsyncUpdate(QmakeProFile::AsyncUpdateDelay delay)
return; return;
} }
emitParsingStarted();
rootProFile()->setParseInProgressRecursive(true); rootProFile()->setParseInProgressRecursive(true);
setAllBuildConfigurationsEnabled(false); setAllBuildConfigurationsEnabled(false);
@@ -492,19 +494,26 @@ void QmakeProject::startAsyncTimer(QmakeProFile::AsyncUpdateDelay delay)
void QmakeProject::incrementPendingEvaluateFutures() void QmakeProject::incrementPendingEvaluateFutures()
{ {
++m_pendingEvaluateFuturesCount; ++m_pendingEvaluateFuturesCount;
if (m_pendingEvaluateFuturesCount == 1)
m_totalEvaluationSuccess = true;
m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(), m_asyncUpdateFutureInterface->setProgressRange(m_asyncUpdateFutureInterface->progressMinimum(),
m_asyncUpdateFutureInterface->progressMaximum() + 1); m_asyncUpdateFutureInterface->progressMaximum() + 1);
} }
void QmakeProject::decrementPendingEvaluateFutures() void QmakeProject::decrementPendingEvaluateFutures(bool success)
{ {
--m_pendingEvaluateFuturesCount; --m_pendingEvaluateFuturesCount;
m_totalEvaluationSuccess = m_totalEvaluationSuccess && success;
m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + 1); m_asyncUpdateFutureInterface->setProgressValue(m_asyncUpdateFutureInterface->progressValue() + 1);
if (m_pendingEvaluateFuturesCount == 0) { if (m_pendingEvaluateFuturesCount == 0) {
// We are done! // We are done!
setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this)); setRootProjectNode(QmakeNodeTreeBuilder::buildTree(this));
if (!m_totalEvaluationSuccess)
m_asyncUpdateFutureInterface->reportCanceled();
m_asyncUpdateFutureInterface->reportFinished(); m_asyncUpdateFutureInterface->reportFinished();
delete m_asyncUpdateFutureInterface; delete m_asyncUpdateFutureInterface;
m_asyncUpdateFutureInterface = nullptr; m_asyncUpdateFutureInterface = nullptr;
@@ -512,6 +521,7 @@ void QmakeProject::decrementPendingEvaluateFutures()
// TODO clear the profile cache ? // TODO clear the profile cache ?
if (m_asyncUpdateState == AsyncFullUpdatePending || m_asyncUpdateState == AsyncPartialUpdatePending) { if (m_asyncUpdateState == AsyncFullUpdatePending || m_asyncUpdateState == AsyncPartialUpdatePending) {
// Already parsing!
rootProFile()->setParseInProgressRecursive(true); rootProFile()->setParseInProgressRecursive(true);
setAllBuildConfigurationsEnabled(false); setAllBuildConfigurationsEnabled(false);
startAsyncTimer(QmakeProFile::ParseLater); startAsyncTimer(QmakeProFile::ParseLater);
@@ -526,7 +536,7 @@ void QmakeProject::decrementPendingEvaluateFutures()
activeTarget()->updateDefaultDeployConfigurations(); activeTarget()->updateDefaultDeployConfigurations();
updateRunConfigurations(); updateRunConfigurations();
emit proFilesEvaluated(); emit proFilesEvaluated();
emit parsingFinished(); emitParsingFinished(true); // Qmake always returns (some) data, even when it failed:-)
} }
} }
} }
@@ -542,6 +552,8 @@ void QmakeProject::asyncUpdate()
m_qmakeVfs->invalidateCache(); m_qmakeVfs->invalidateCache();
emitParsingStarted();
Q_ASSERT(!m_asyncUpdateFutureInterface); Q_ASSERT(!m_asyncUpdateFutureInterface);
m_asyncUpdateFutureInterface = new QFutureInterface<void>(); m_asyncUpdateFutureInterface = new QFutureInterface<void>();

View File

@@ -102,7 +102,7 @@ public:
/// \internal /// \internal
void incrementPendingEvaluateFutures(); void incrementPendingEvaluateFutures();
/// \internal /// \internal
void decrementPendingEvaluateFutures(); void decrementPendingEvaluateFutures(bool success);
/// \internal /// \internal
bool wasEvaluateCanceled(); bool wasEvaluateCanceled();
@@ -188,6 +188,7 @@ private:
// cached data during project rescan // cached data during project rescan
QMakeGlobals *m_qmakeGlobals = nullptr; QMakeGlobals *m_qmakeGlobals = nullptr;
int m_qmakeGlobalsRefCnt = 0; int m_qmakeGlobalsRefCnt = 0;
bool m_totalEvaluationSuccess = false;
QString m_qmakeSysroot; QString m_qmakeSysroot;

View File

@@ -279,8 +279,8 @@ void QmakeProjectManagerPlugin::projectChanged()
if (m_previousStartupProject) { if (m_previousStartupProject) {
connect(m_previousStartupProject, &Project::activeTargetChanged, connect(m_previousStartupProject, &Project::activeTargetChanged,
this, &QmakeProjectManagerPlugin::activeTargetChanged); this, &QmakeProjectManagerPlugin::activeTargetChanged);
connect(m_previousStartupProject, &QmakeProject::parsingFinished, connect(m_previousStartupProject, &Project::parsingFinished,
this, &QmakeProjectManagerPlugin::updateActions); this, &QmakeProjectManagerPlugin::updateActions);
} }

View File

@@ -170,6 +170,7 @@ void QmlProject::parseProject(RefreshOptions options)
void QmlProject::refresh(RefreshOptions options) void QmlProject::refresh(RefreshOptions options)
{ {
emitParsingStarted();
parseProject(options); parseProject(options);
if (options & Files) if (options & Files)
@@ -187,7 +188,7 @@ void QmlProject::refresh(RefreshOptions options)
modelManager->updateProjectInfo(projectInfo, this); modelManager->updateProjectInfo(projectInfo, this);
emit parsingFinished(); emitParsingFinished(true);
} }
QString QmlProject::mainFile() const QString QmlProject::mainFile() const