BuildSystem: Fix move semantics of ParseGuard and related code

This avoids a spurious set of parsing started/finished signals.

Change-Id: I0c723f2a2ad679a5f6cffddf9f542ebc02192be8
Reviewed-by: Cristian Adam <cristian.adam@qt.io>
Reviewed-by: Eike Ziller <eike.ziller@qt.io>
This commit is contained in:
Tobias Hunger
2019-10-08 12:54:08 +02:00
parent 7f2f112a24
commit aa1cc54b3e
4 changed files with 41 additions and 13 deletions

View File

@@ -114,6 +114,7 @@ CMakeBuildSystem::~CMakeBuildSystem()
bool CMakeBuildSystem::validateParsingContext(const ParsingContext &ctx) bool CMakeBuildSystem::validateParsingContext(const ParsingContext &ctx)
{ {
QTC_ASSERT(!m_currentContext.guard.guardsProject(), return false);
return ctx.project && qobject_cast<CMakeBuildConfiguration *>(ctx.buildConfiguration); return ctx.project && qobject_cast<CMakeBuildConfiguration *>(ctx.buildConfiguration);
} }

View File

@@ -95,6 +95,8 @@ void BuildSystem::triggerParsing()
ParsingContext ctx(p->guardParsingRun(), p, bc, e, env); ParsingContext ctx(p->guardParsingRun(), p, bc, e, env);
QTC_ASSERT(ctx.guard.guardsProject(), return );
if (validateParsingContext(ctx)) if (validateParsingContext(ctx))
parseProject(std::move(ctx)); parseProject(std::move(ctx));
} }

View File

@@ -65,8 +65,22 @@ protected:
ParsingContext(const ParsingContext &other) = delete; ParsingContext(const ParsingContext &other) = delete;
ParsingContext &operator=(const ParsingContext &other) = delete; ParsingContext &operator=(const ParsingContext &other) = delete;
ParsingContext(ParsingContext &&other) = default; ParsingContext(ParsingContext &&other)
ParsingContext &operator=(ParsingContext &&other) = default; : guard{std::move(other.guard)}
, project{std::move(other.project)}
, buildConfiguration{std::move(other.buildConfiguration)}
, expander{std::move(other.expander)}
, environment{std::move(other.environment)}
{}
ParsingContext &operator=(ParsingContext &&other)
{
guard = std::move(other.guard);
project = std::move(other.project);
buildConfiguration = std::move(other.buildConfiguration);
expander = std::move(other.expander);
environment = std::move(other.environment);
return *this;
}
Project::ParseGuard guard; Project::ParseGuard guard;

View File

@@ -192,27 +192,29 @@ public:
: ParseGuard(nullptr) : ParseGuard(nullptr)
{} {}
~ParseGuard() ~ParseGuard() { release(); }
{
if (m_project)
m_project->emitParsingFinished(m_success);
}
void markAsSuccess() const { m_success = true; } void markAsSuccess() const { m_success = true; }
bool isSuccess() const { return m_success; } bool isSuccess() const { return m_success; }
bool isNull() const { return !m_project; } bool guardsProject() const { return m_project; }
ParseGuard(const ParseGuard &other) = delete; ParseGuard(const ParseGuard &other) = delete;
ParseGuard &operator=(const ParseGuard &other) = delete; ParseGuard &operator=(const ParseGuard &other) = delete;
ParseGuard(ParseGuard &&other) ParseGuard(ParseGuard &&other)
: m_project{std::move(other.m_project)}
, m_success{std::move(other.m_success)}
{ {
std::swap(m_project, other.m_project); // No need to release this as this is invalid anyway:-)
std::swap(m_success, other.m_success); other.m_project = nullptr;
} }
ParseGuard &operator=(ParseGuard &&other) ParseGuard &operator=(ParseGuard &&other)
{ {
std::swap(m_project, other.m_project); release();
std::swap(m_success, other.m_success);
m_project = std::move(other.m_project);
m_success = std::move(other.m_success);
other.m_project = nullptr;
return *this; return *this;
} }
@@ -220,8 +222,17 @@ public:
ParseGuard(Project *p) ParseGuard(Project *p)
: m_project(p) : m_project(p)
{ {
if (m_project) if (m_project && !m_project->isParsing())
m_project->emitParsingStarted(); m_project->emitParsingStarted();
else
m_project = nullptr;
}
void release()
{
if (m_project)
m_project->emitParsingFinished(m_success);
m_project = nullptr;
} }
Project *m_project = nullptr; Project *m_project = nullptr;