cmGeneratorExpressionNode: refactor TargetPropertyNode

Re-order logic to improve readability and de-duplicate conditions.
Factor out error message generation into a helper.
This commit is contained in:
Leonid Pospelov
2019-04-15 16:34:08 +03:00
committed by Brad King
parent 9e1df5df54
commit 3d856eba16

View File

@@ -1029,62 +1029,44 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
// This node handles errors on parameter count itself. // This node handles errors on parameter count itself.
int NumExpectedParameters() const override { return OneOrMoreParameters; } int NumExpectedParameters() const override { return OneOrMoreParameters; }
static const char* GetErrorText(std::string const& targetName,
std::string const& propertyName)
{
static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
if (targetName.empty() && propertyName.empty()) {
return "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
"target name and property name.";
}
if (targetName.empty()) {
return "$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
"target name.";
}
if (!cmGeneratorExpression::IsValidTargetName(targetName)) {
if (!propertyNameValidator.find(propertyName)) {
return "Target name and property name not supported.";
}
return "Target name not supported.";
}
return nullptr;
}
std::string Evaluate( std::string Evaluate(
const std::vector<std::string>& parameters, const std::vector<std::string>& parameters,
cmGeneratorExpressionContext* context, cmGeneratorExpressionContext* context,
const GeneratorExpressionContent* content, const GeneratorExpressionContent* content,
cmGeneratorExpressionDAGChecker* dagCheckerParent) const override cmGeneratorExpressionDAGChecker* dagCheckerParent) const override
{ {
if (parameters.size() != 1 && parameters.size() != 2) {
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:...> expression requires one or two parameters");
return std::string();
}
static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$"); static cmsys::RegularExpression propertyNameValidator("^[A-Za-z0-9_]+$");
cmGeneratorTarget const* target = context->HeadTarget; cmGeneratorTarget const* target = nullptr;
std::string propertyName = parameters.front(); std::string targetName, propertyName;
if (parameters.size() == 1) {
context->HadHeadSensitiveCondition = true;
}
if (!target && parameters.size() == 1) {
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:prop> may only be used with binary targets. "
"It may not be used with add_custom_command or add_custom_target. "
"Specify the target to read a property from using the "
"$<TARGET_PROPERTY:tgt,prop> signature instead.");
return std::string();
}
if (parameters.size() == 2) { if (parameters.size() == 2) {
if (parameters.front().empty() && parameters[1].empty()) { targetName = parameters[0];
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
"target name and property name.");
return std::string();
}
if (parameters.front().empty()) {
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:tgt,prop> expression requires a non-empty "
"target name.");
return std::string();
}
std::string targetName = parameters.front();
propertyName = parameters[1]; propertyName = parameters[1];
if (!cmGeneratorExpression::IsValidTargetName(targetName)) {
if (!propertyNameValidator.find(propertyName)) { if (const char* e = GetErrorText(targetName, propertyName)) {
::reportError(context, content->GetOriginalExpression(), reportError(context, content->GetOriginalExpression(), e);
"Target name and property name not supported.");
return std::string();
}
::reportError(context, content->GetOriginalExpression(),
"Target name not supported.");
return std::string(); return std::string();
} }
if (propertyName == "ALIASED_TARGET"_s) { if (propertyName == "ALIASED_TARGET"_s) {
@@ -1094,7 +1076,7 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return tgt->GetName(); return tgt->GetName();
} }
} }
return ""; return std::string();
} }
target = context->LG->FindGeneratorTargetToUse(targetName); target = context->LG->FindGeneratorTargetToUse(targetName);
@@ -1105,15 +1087,34 @@ static const struct TargetPropertyNode : public cmGeneratorExpressionNode
return std::string(); return std::string();
} }
context->AllTargets.insert(target); context->AllTargets.insert(target);
}
if (target == context->HeadTarget) { } else if (parameters.size() == 1) {
target = context->HeadTarget;
propertyName = parameters[0];
// Keep track of the properties seen while processing. // Keep track of the properties seen while processing.
// The evaluation of the LINK_LIBRARIES generator expressions // The evaluation of the LINK_LIBRARIES generator expressions
// will check this to ensure that properties have one consistent // will check this to ensure that properties have one consistent
// value for all evaluations. // value for all evaluations.
context->SeenTargetProperties.insert(propertyName); context->SeenTargetProperties.insert(propertyName);
context->HadHeadSensitiveCondition = true;
if (!target) {
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:prop> may only be used with binary targets. "
"It may not be used with add_custom_command or add_custom_target. "
"Specify the target to read a property from using the "
"$<TARGET_PROPERTY:tgt,prop> signature instead.");
return std::string();
}
} else {
reportError(
context, content->GetOriginalExpression(),
"$<TARGET_PROPERTY:...> expression requires one or two parameters");
return std::string();
} }
if (propertyName == "SOURCES") { if (propertyName == "SOURCES") {
context->SourceSensitiveTargets.insert(target); context->SourceSensitiveTargets.insert(target);
} }