[core] Replace expressions RTTI with enums + static cast
This commit is contained in:
@@ -47,13 +47,17 @@ struct Converter<DataDrivenPropertyValue<T>> {
|
||||
return {};
|
||||
} else if (!(*expression).isFeatureConstant() || !(*expression).isZoomConstant()) {
|
||||
return { std::move(*expression) };
|
||||
} else {
|
||||
} else if ((*expression).getExpression().getKind() == Kind::Literal) {
|
||||
optional<T> constant = fromExpressionValue<T>(
|
||||
dynamic_cast<const Literal&>((*expression).getExpression()).getValue());
|
||||
static_cast<const Literal&>((*expression).getExpression()).getValue());
|
||||
if (!constant) {
|
||||
return {};
|
||||
}
|
||||
return DataDrivenPropertyValue<T>(*constant);
|
||||
} else {
|
||||
assert(false);
|
||||
error = { "expected a literal expression" };
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -54,13 +54,17 @@ struct Converter<PropertyValue<T>> {
|
||||
return {};
|
||||
} else if (!(*expression).isZoomConstant()) {
|
||||
return { std::move(*expression) };
|
||||
} else {
|
||||
} else if ((*expression).getExpression().getKind() == Kind::Literal) {
|
||||
optional<T> constant = fromExpressionValue<T>(
|
||||
dynamic_cast<const Literal&>((*expression).getExpression()).getValue());
|
||||
static_cast<const Literal&>((*expression).getExpression()).getValue());
|
||||
if (!constant) {
|
||||
return {};
|
||||
}
|
||||
return PropertyValue<T>(*constant);
|
||||
} else {
|
||||
assert(false);
|
||||
error = { "expected a literal expression" };
|
||||
return {};
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -14,7 +14,7 @@ namespace expression {
|
||||
class ArrayAssertion : public Expression {
|
||||
public:
|
||||
ArrayAssertion(type::Array type_, std::unique_ptr<Expression> input_) :
|
||||
Expression(type_),
|
||||
Expression(Kind::ArrayAssertion, type_),
|
||||
input(std::move(input_))
|
||||
{}
|
||||
|
||||
@@ -24,7 +24,8 @@ public:
|
||||
void eachChild(const std::function<void(const Expression&)>& visit) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
if (auto rhs = dynamic_cast<const ArrayAssertion*>(&e)) {
|
||||
if (e.getKind() == Kind::ArrayAssertion) {
|
||||
auto rhs = static_cast<const ArrayAssertion*>(&e);
|
||||
return getType() == rhs->getType() && *input == *(rhs->input);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace expression {
|
||||
class At : public Expression {
|
||||
public:
|
||||
At(std::unique_ptr<Expression> index_, std::unique_ptr<Expression> input_) :
|
||||
Expression(input_->getType().get<type::Array>().itemType),
|
||||
Expression(Kind::At, input_->getType().get<type::Array>().itemType),
|
||||
index(std::move(index_)),
|
||||
input(std::move(input_))
|
||||
{}
|
||||
@@ -22,7 +22,8 @@ public:
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
if (auto rhs = dynamic_cast<const At*>(&e)) {
|
||||
if (e.getKind() == Kind::At) {
|
||||
auto rhs = static_cast<const At*>(&e);
|
||||
return *index == *(rhs->index) && *input == *(rhs->input);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -12,7 +12,7 @@ namespace expression {
|
||||
class Any : public Expression {
|
||||
public:
|
||||
Any(std::vector<std::unique_ptr<Expression>> inputs_) :
|
||||
Expression(type::Boolean),
|
||||
Expression(Kind::Any, type::Boolean),
|
||||
inputs(std::move(inputs_))
|
||||
{}
|
||||
|
||||
@@ -31,7 +31,7 @@ private:
|
||||
class All : public Expression {
|
||||
public:
|
||||
All(std::vector<std::unique_ptr<Expression>> inputs_) :
|
||||
Expression(type::Boolean),
|
||||
Expression(Kind::All, type::Boolean),
|
||||
inputs(std::move(inputs_))
|
||||
{}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
using Branch = std::pair<std::unique_ptr<Expression>, std::unique_ptr<Expression>>;
|
||||
|
||||
Case(type::Type type_, std::vector<Branch> branches_, std::unique_ptr<Expression> otherwise_)
|
||||
: Expression(type_), branches(std::move(branches_)), otherwise(std::move(otherwise_)) {
|
||||
: Expression(Kind::Case, type_), branches(std::move(branches_)), otherwise(std::move(otherwise_)) {
|
||||
}
|
||||
|
||||
static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
|
||||
|
||||
@@ -15,7 +15,7 @@ class Coalesce : public Expression {
|
||||
public:
|
||||
using Args = std::vector<std::unique_ptr<Expression>>;
|
||||
Coalesce(const type::Type& type_, Args args_) :
|
||||
Expression(type_),
|
||||
Expression(Kind::Coalesce, type_),
|
||||
args(std::move(args_))
|
||||
{}
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ struct SignatureBase {
|
||||
class CompoundExpressionBase : public Expression {
|
||||
public:
|
||||
CompoundExpressionBase(std::string name_, const detail::SignatureBase& signature) :
|
||||
Expression(signature.result),
|
||||
Expression(Kind::CompoundExpression, signature.result),
|
||||
name(std::move(name_)),
|
||||
params(signature.params)
|
||||
{}
|
||||
@@ -108,7 +108,8 @@ public:
|
||||
}
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
if (auto rhs = dynamic_cast<const CompoundExpression*>(&e)) {
|
||||
if (e.getKind() == Kind::CompoundExpression) {
|
||||
auto rhs = static_cast<const CompoundExpression*>(&e);
|
||||
return getName() == rhs->getName() && Expression::childrenEqual(args, rhs->args);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -11,13 +11,13 @@ namespace expression {
|
||||
class Error : public Expression {
|
||||
public:
|
||||
Error(std::string message_)
|
||||
: Expression(type::Error),
|
||||
: Expression(Kind::Error, type::Error),
|
||||
message(std::move(message_)) {}
|
||||
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override {}
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
return dynamic_cast<const Error*>(&e);
|
||||
return e.getKind() == Kind::Error;
|
||||
}
|
||||
|
||||
EvaluationResult evaluate(const EvaluationContext&) const override {
|
||||
|
||||
@@ -113,9 +113,32 @@ public:
|
||||
ParseResult ExpressionClass::parse(const V&, ParsingContext),
|
||||
which handles parsing a style-spec JSON representation of the expression.
|
||||
*/
|
||||
|
||||
enum class Kind : int32_t {
|
||||
Coalesce,
|
||||
CompoundExpression,
|
||||
Literal,
|
||||
ArrayAssertion,
|
||||
At,
|
||||
Interpolate,
|
||||
Assertion,
|
||||
Length,
|
||||
Step,
|
||||
Let,
|
||||
Var,
|
||||
CollatorExpression,
|
||||
Coercion,
|
||||
Match,
|
||||
Error,
|
||||
Case,
|
||||
Any,
|
||||
All,
|
||||
Equals,
|
||||
};
|
||||
|
||||
class Expression {
|
||||
public:
|
||||
Expression(type::Type type_) : type(std::move(type_)) {}
|
||||
Expression(Kind kind_, type::Type type_) : kind(kind_), type(std::move(type_)) {}
|
||||
virtual ~Expression() = default;
|
||||
|
||||
virtual EvaluationResult evaluate(const EvaluationContext& params) const = 0;
|
||||
@@ -125,6 +148,7 @@ public:
|
||||
return !operator==(rhs);
|
||||
}
|
||||
|
||||
Kind getKind() const { return kind; };
|
||||
type::Type getType() const { return type; };
|
||||
|
||||
EvaluationResult evaluate(optional<float> zoom, const Feature& feature, optional<double> heatmapDensity) const;
|
||||
@@ -182,6 +206,7 @@ protected:
|
||||
}
|
||||
|
||||
private:
|
||||
Kind kind;
|
||||
type::Type type;
|
||||
};
|
||||
|
||||
|
||||
@@ -51,7 +51,8 @@ public:
|
||||
}
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
if (auto rhs = dynamic_cast<const Interpolate*>(&e)) {
|
||||
if (e.getKind() == Kind::Interpolate) {
|
||||
auto rhs = static_cast<const Interpolate*>(&e);
|
||||
if (interpolator != rhs->interpolator ||
|
||||
*input != *(rhs->input) ||
|
||||
stops.size() != rhs->stops.size())
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace expression {
|
||||
|
||||
template <typename T>
|
||||
bool isGlobalPropertyConstant(const Expression& expression, const T& properties) {
|
||||
if (auto e = dynamic_cast<const CompoundExpressionBase*>(&expression)) {
|
||||
if (expression.getKind() == Kind::CompoundExpression) {
|
||||
auto e = static_cast<const CompoundExpressionBase*>(&expression);
|
||||
for (const std::string& property : properties) {
|
||||
if (e->getName() == property) {
|
||||
return false;
|
||||
|
||||
@@ -16,7 +16,7 @@ public:
|
||||
using Bindings = std::map<std::string, std::shared_ptr<Expression>>;
|
||||
|
||||
Let(Bindings bindings_, std::unique_ptr<Expression> result_) :
|
||||
Expression(result_->getType()),
|
||||
Expression(Kind::Let, result_->getType()),
|
||||
bindings(std::move(bindings_)),
|
||||
result(std::move(result_))
|
||||
{}
|
||||
@@ -27,7 +27,8 @@ public:
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
if (auto rhs = dynamic_cast<const Let*>(&e)) {
|
||||
if (e.getKind() == Kind::Let) {
|
||||
auto rhs = static_cast<const Let*>(&e);
|
||||
return *result == *(rhs->result);
|
||||
}
|
||||
return false;
|
||||
@@ -49,7 +50,7 @@ private:
|
||||
class Var : public Expression {
|
||||
public:
|
||||
Var(std::string name_, std::shared_ptr<Expression> value_) :
|
||||
Expression(value_->getType()),
|
||||
Expression(Kind::Var, value_->getType()),
|
||||
name(std::move(name_)),
|
||||
value(value_)
|
||||
{}
|
||||
@@ -60,7 +61,8 @@ public:
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override;
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
if (auto rhs = dynamic_cast<const Var*>(&e)) {
|
||||
if (e.getKind() == Kind::Var) {
|
||||
auto rhs = static_cast<const Var*>(&e);
|
||||
return *value == *(rhs->value);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -13,12 +13,12 @@ namespace expression {
|
||||
class Literal : public Expression {
|
||||
public:
|
||||
Literal(Value value_)
|
||||
: Expression(typeOf(value_))
|
||||
: Expression(Kind::Literal, typeOf(value_))
|
||||
, value(value_)
|
||||
{}
|
||||
|
||||
Literal(type::Array type_, std::vector<Value> value_)
|
||||
: Expression(type_)
|
||||
: Expression(Kind::Literal, type_)
|
||||
, value(value_)
|
||||
{}
|
||||
|
||||
@@ -31,7 +31,8 @@ public:
|
||||
void eachChild(const std::function<void(const Expression&)>&) const override {}
|
||||
|
||||
bool operator==(const Expression& e) const override {
|
||||
if (auto rhs = dynamic_cast<const Literal*>(&e)) {
|
||||
if (e.getKind() == Kind::Literal) {
|
||||
auto rhs = static_cast<const Literal*>(&e);
|
||||
return value == rhs->value;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -19,7 +19,7 @@ public:
|
||||
std::unique_ptr<Expression> input_,
|
||||
Branches branches_,
|
||||
std::unique_ptr<Expression> otherwise_
|
||||
) : Expression(type_),
|
||||
) : Expression(Kind::Match, type_),
|
||||
input(std::move(input_)),
|
||||
branches(std::move(branches_)),
|
||||
otherwise(std::move(otherwise_))
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace expression {
|
||||
using namespace mbgl::style::conversion;
|
||||
|
||||
Assertion::Assertion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_) :
|
||||
Expression(type_),
|
||||
Expression(Kind::Assertion, type_),
|
||||
inputs(std::move(inputs_))
|
||||
{
|
||||
assert(!inputs.empty());
|
||||
@@ -72,7 +72,8 @@ void Assertion::eachChild(const std::function<void(const Expression&)>& visit) c
|
||||
};
|
||||
|
||||
bool Assertion::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const Assertion*>(&e)) {
|
||||
if (e.getKind() == Kind::Assertion) {
|
||||
auto rhs = static_cast<const Assertion*>(&e);
|
||||
return getType() == rhs->getType() && Expression::childrenEqual(inputs, rhs->inputs);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -20,7 +20,8 @@ void Any::eachChild(const std::function<void(const Expression&)>& visit) const {
|
||||
}
|
||||
|
||||
bool Any::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const Any*>(&e)) {
|
||||
if (e.getKind() == Kind::Any) {
|
||||
auto rhs = static_cast<const Any*>(&e);
|
||||
return Expression::childrenEqual(inputs, rhs->inputs);
|
||||
}
|
||||
return false;
|
||||
@@ -47,7 +48,8 @@ void All::eachChild(const std::function<void(const Expression&)>& visit) const {
|
||||
}
|
||||
|
||||
bool All::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const All*>(&e)) {
|
||||
if (e.getKind() == Kind::All) {
|
||||
auto rhs = static_cast<const All*>(&e);
|
||||
return Expression::childrenEqual(inputs, rhs->inputs);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -28,7 +28,8 @@ void Case::eachChild(const std::function<void(const Expression&)>& visit) const
|
||||
}
|
||||
|
||||
bool Case::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const Case*>(&e)) {
|
||||
if (e.getKind() == Kind::Case) {
|
||||
auto rhs = static_cast<const Case*>(&e);
|
||||
return *otherwise == *(rhs->otherwise) && Expression::childrenEqual(branches, rhs->branches);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -21,7 +21,8 @@ void Coalesce::eachChild(const std::function<void(const Expression&)>& visit) co
|
||||
}
|
||||
|
||||
bool Coalesce::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const Coalesce*>(&e)) {
|
||||
if (e.getKind() == Kind::Coalesce) {
|
||||
auto rhs = static_cast<const Coalesce*>(&e);
|
||||
return Expression::childrenEqual(args, rhs->args);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -68,7 +68,7 @@ EvaluationResult toColor(const Value& colorValue) {
|
||||
}
|
||||
|
||||
Coercion::Coercion(type::Type type_, std::vector<std::unique_ptr<Expression>> inputs_) :
|
||||
Expression(std::move(type_)),
|
||||
Expression(Kind::Coercion, std::move(type_)),
|
||||
inputs(std::move(inputs_))
|
||||
{
|
||||
assert(!inputs.empty());
|
||||
@@ -138,7 +138,8 @@ void Coercion::eachChild(const std::function<void(const Expression&)>& visit) co
|
||||
};
|
||||
|
||||
bool Coercion::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const Coercion*>(&e)) {
|
||||
if (e.getKind() == Kind::Coercion) {
|
||||
auto rhs = static_cast<const Coercion*>(&e);
|
||||
return getType() == rhs->getType() && Expression::childrenEqual(inputs, rhs->inputs);
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace expression {
|
||||
CollatorExpression::CollatorExpression(std::unique_ptr<Expression> caseSensitive_,
|
||||
std::unique_ptr<Expression> diacriticSensitive_,
|
||||
optional<std::unique_ptr<Expression>> locale_)
|
||||
: Expression(type::Collator)
|
||||
: Expression(Kind::CollatorExpression, type::Collator)
|
||||
, caseSensitive(std::move(caseSensitive_))
|
||||
, diacriticSensitive(std::move(diacriticSensitive_))
|
||||
, locale(std::move(locale_))
|
||||
@@ -73,7 +73,8 @@ void CollatorExpression::eachChild(const std::function<void(const Expression&)>&
|
||||
}
|
||||
|
||||
bool CollatorExpression::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const CollatorExpression*>(&e)) {
|
||||
if (e.getKind() == Kind::CollatorExpression) {
|
||||
auto rhs = static_cast<const CollatorExpression*>(&e);
|
||||
if ((locale && (!rhs->locale || **locale != **(rhs->locale))) ||
|
||||
(!locale && rhs->locale)) {
|
||||
return false;
|
||||
|
||||
@@ -13,7 +13,7 @@ static bool isComparableType(const type::Type& type) {
|
||||
}
|
||||
|
||||
Equals::Equals(std::unique_ptr<Expression> lhs_, std::unique_ptr<Expression> rhs_, optional<std::unique_ptr<Expression>> collator_, bool negate_)
|
||||
: Expression(type::Boolean),
|
||||
: Expression(Kind::Equals, type::Boolean),
|
||||
lhs(std::move(lhs_)),
|
||||
rhs(std::move(rhs_)),
|
||||
collator(std::move(collator_)),
|
||||
@@ -53,7 +53,8 @@ void Equals::eachChild(const std::function<void(const Expression&)>& visit) cons
|
||||
}
|
||||
|
||||
bool Equals::operator==(const Expression& e) const {
|
||||
if (auto eq = dynamic_cast<const Equals*>(&e)) {
|
||||
if (e.getKind() == Kind::Equals) {
|
||||
auto eq = static_cast<const Equals*>(&e);
|
||||
return eq->negate == negate && *eq->lhs == *lhs && *eq->rhs == *rhs;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -14,9 +14,14 @@ namespace expression {
|
||||
optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(const expression::Expression* e) {
|
||||
optional<variant<const Interpolate*, const Step*, ParsingError>> result;
|
||||
|
||||
if (auto let = dynamic_cast<const Let*>(e)) {
|
||||
switch (e->getKind()) {
|
||||
case Kind::Let: {
|
||||
auto let = static_cast<const Let*>(e);
|
||||
result = findZoomCurve(let->getResult());
|
||||
} else if (auto coalesce = dynamic_cast<const Coalesce*>(e)) {
|
||||
break;
|
||||
}
|
||||
case Kind::Coalesce: {
|
||||
auto coalesce = static_cast<const Coalesce*>(e);
|
||||
std::size_t length = coalesce->getLength();
|
||||
for (std::size_t i = 0; i < length; i++) {
|
||||
result = findZoomCurve(coalesce->getChild(i));
|
||||
@@ -24,16 +29,30 @@ optional<variant<const Interpolate*, const Step*, ParsingError>> findZoomCurve(c
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (auto curve = dynamic_cast<const Interpolate*>(e)) {
|
||||
auto z = dynamic_cast<CompoundExpressionBase*>(curve->getInput().get());
|
||||
if (z && z->getName() == "zoom") {
|
||||
result = {curve};
|
||||
break;
|
||||
}
|
||||
case Kind::Interpolate: {
|
||||
auto curve = static_cast<const Interpolate*>(e);
|
||||
if (curve->getInput()->getKind() == Kind::CompoundExpression) {
|
||||
auto z = static_cast<CompoundExpressionBase*>(curve->getInput().get());
|
||||
if (z && z->getName() == "zoom") {
|
||||
result = {curve};
|
||||
}
|
||||
}
|
||||
} else if (auto step = dynamic_cast<const Step*>(e)) {
|
||||
auto z = dynamic_cast<CompoundExpressionBase*>(step->getInput().get());
|
||||
if (z && z->getName() == "zoom") {
|
||||
result = {step};
|
||||
break;
|
||||
}
|
||||
case Kind::Step: {
|
||||
auto step = static_cast<const Step*>(e);
|
||||
if (step->getInput()->getKind() == Kind::CompoundExpression) {
|
||||
auto z = static_cast<CompoundExpressionBase*>(step->getInput().get());
|
||||
if (z && z->getName() == "zoom") {
|
||||
result = {step};
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (result && result->is<ParsingError>()) {
|
||||
|
||||
@@ -264,7 +264,7 @@ Interpolate::Interpolate(const type::Type& type_,
|
||||
Interpolator interpolator_,
|
||||
std::unique_ptr<Expression> input_,
|
||||
std::map<double, std::unique_ptr<Expression>> stops_)
|
||||
: Expression(type_),
|
||||
: Expression(Kind::Interpolate, type_),
|
||||
interpolator(std::move(interpolator_)),
|
||||
input(std::move(input_)),
|
||||
stops(std::move(stops_)) {
|
||||
|
||||
@@ -9,7 +9,8 @@ namespace expression {
|
||||
constexpr static const char filter[] = "filter-";
|
||||
|
||||
bool isFeatureConstant(const Expression& expression) {
|
||||
if (auto e = dynamic_cast<const CompoundExpressionBase*>(&expression)) {
|
||||
if (expression.getKind() == Kind::CompoundExpression) {
|
||||
auto e = static_cast<const CompoundExpressionBase*>(&expression);
|
||||
const std::string name = e->getName();
|
||||
optional<std::size_t> parameterCount = e->getParameterCount();
|
||||
if (name == "get" && parameterCount && *parameterCount == 1) {
|
||||
@@ -28,7 +29,7 @@ bool isFeatureConstant(const Expression& expression) {
|
||||
}
|
||||
}
|
||||
|
||||
if (dynamic_cast<const CollatorExpression*>(&expression)) {
|
||||
if (expression.getKind() == Kind::CollatorExpression) {
|
||||
// Although the results of a Collator expression with fixed arguments
|
||||
// generally shouldn't change between executions, we can't serialize them
|
||||
// as constant expressions because results change based on environment.
|
||||
|
||||
@@ -6,7 +6,7 @@ namespace style {
|
||||
namespace expression {
|
||||
|
||||
Length::Length(std::unique_ptr<Expression> input_)
|
||||
: Expression(type::Number),
|
||||
: Expression(Kind::Length, type::Number),
|
||||
input(std::move(input_)) {
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ void Length::eachChild(const std::function<void(const Expression&)>& visit) cons
|
||||
}
|
||||
|
||||
bool Length::operator==(const Expression& e) const {
|
||||
if (auto eq = dynamic_cast<const Length*>(&e)) {
|
||||
if (e.getKind() == Kind::Length) {
|
||||
auto eq = static_cast<const Length*>(&e);
|
||||
return *eq->input == *input;
|
||||
}
|
||||
return false;
|
||||
|
||||
@@ -18,7 +18,8 @@ void Match<T>::eachChild(const std::function<void(const Expression&)>& visit) co
|
||||
|
||||
template <typename T>
|
||||
bool Match<T>::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const Match*>(&e)) {
|
||||
if (e.getKind() == Kind::Match) {
|
||||
auto rhs = static_cast<const Match*>(&e);
|
||||
return (*input == *(rhs->input) &&
|
||||
*otherwise == *(rhs->otherwise) &&
|
||||
Expression::childrenEqual(branches, rhs->branches));
|
||||
|
||||
@@ -32,19 +32,21 @@ namespace style {
|
||||
namespace expression {
|
||||
|
||||
bool isConstant(const Expression& expression) {
|
||||
if (auto varExpression = dynamic_cast<const Var*>(&expression)) {
|
||||
if (expression.getKind() == Kind::Var) {
|
||||
auto varExpression = static_cast<const Var*>(&expression);
|
||||
return isConstant(*varExpression->getBoundExpression());
|
||||
}
|
||||
|
||||
if (auto compound = dynamic_cast<const CompoundExpressionBase*>(&expression)) {
|
||||
if (expression.getKind() == Kind::CompoundExpression) {
|
||||
auto compound = static_cast<const CompoundExpressionBase*>(&expression);
|
||||
if (compound->getName() == "error") {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool isTypeAnnotation = dynamic_cast<const Coercion*>(&expression) ||
|
||||
dynamic_cast<const Assertion*>(&expression) ||
|
||||
dynamic_cast<const ArrayAssertion*>(&expression);
|
||||
bool isTypeAnnotation = expression.getKind() == Kind::Coercion ||
|
||||
expression.getKind() == Kind::Assertion ||
|
||||
expression.getKind() == Kind::ArrayAssertion;
|
||||
|
||||
bool childrenConstant = true;
|
||||
expression.eachChild([&](const Expression& child) {
|
||||
@@ -58,7 +60,7 @@ bool isConstant(const Expression& expression) {
|
||||
if (isTypeAnnotation) {
|
||||
childrenConstant = childrenConstant && isConstant(child);
|
||||
} else {
|
||||
childrenConstant = childrenConstant && dynamic_cast<const Literal*>(&child);
|
||||
childrenConstant = childrenConstant && child.getKind() == Kind::Literal;
|
||||
}
|
||||
});
|
||||
if (!childrenConstant) {
|
||||
@@ -186,7 +188,7 @@ ParseResult ParsingContext::parse(const Convertible& value, TypeAnnotationOption
|
||||
// If an expression's arguments are all constant, we can evaluate
|
||||
// it immediately and replace it with a literal value in the
|
||||
// parsed result.
|
||||
if (!dynamic_cast<Literal *>(parsed->get()) && isConstant(**parsed)) {
|
||||
if ((*parsed)->getKind() != Kind::Literal && isConstant(**parsed)) {
|
||||
EvaluationContext params(nullptr);
|
||||
EvaluationResult evaluated((*parsed)->evaluate(params));
|
||||
if (!evaluated) {
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace expression {
|
||||
Step::Step(const type::Type& type_,
|
||||
std::unique_ptr<Expression> input_,
|
||||
std::map<double, std::unique_ptr<Expression>> stops_)
|
||||
: Expression(type_),
|
||||
: Expression(Kind::Step, type_),
|
||||
input(std::move(input_)),
|
||||
stops(std::move(stops_))
|
||||
{
|
||||
@@ -57,7 +57,8 @@ void Step::eachStop(const std::function<void(double, const Expression&)>& visit)
|
||||
}
|
||||
|
||||
bool Step::operator==(const Expression& e) const {
|
||||
if (auto rhs = dynamic_cast<const Step*>(&e)) {
|
||||
if (e.getKind() == Kind::Step) {
|
||||
auto rhs = static_cast<const Step*>(&e);
|
||||
return *input == *(rhs->input) && Expression::childrenEqual(stops, rhs->stops);
|
||||
}
|
||||
return false;
|
||||
|
||||
Reference in New Issue
Block a user