summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAnand Thakker <github@anandthakker.net>2017-10-25 11:51:03 -0400
committerAnand Thakker <github@anandthakker.net>2017-10-25 11:53:49 -0400
commit66d10dd00b2dcd192e0d9eadf1443c9a20b64234 (patch)
treef0823b9a14d357e777a564f898a381c511fb8072
parent02af0a671b43898a0739077a86e146968b3def23 (diff)
downloadqtlocation-mapboxgl-66d10dd00b2dcd192e0d9eadf1443c9a20b64234.tar.gz
Implement constant folding
-rw-r--r--src/mbgl/style/expression/parsing_context.cpp57
1 files changed, 55 insertions, 2 deletions
diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp
index 79b173ad87..9b8a352c7b 100644
--- a/src/mbgl/style/expression/parsing_context.cpp
+++ b/src/mbgl/style/expression/parsing_context.cpp
@@ -1,5 +1,10 @@
#include <mbgl/style/expression/parsing_context.hpp>
+#include <mbgl/style/expression/check_subtype.hpp>
+#include <mbgl/style/expression/is_constant.hpp>
+#include <mbgl/style/expression/type.hpp>
+
+#include <mbgl/style/expression/expression.hpp>
#include <mbgl/style/expression/at.hpp>
#include <mbgl/style/expression/array_assertion.hpp>
#include <mbgl/style/expression/assertion.hpp>
@@ -12,14 +17,38 @@
#include <mbgl/style/expression/let.hpp>
#include <mbgl/style/expression/literal.hpp>
#include <mbgl/style/expression/match.hpp>
-#include <mbgl/style/expression/type.hpp>
+
#include <mbgl/style/conversion/get_json_type.hpp>
-#include <mbgl/style/expression/check_subtype.hpp>
namespace mbgl {
namespace style {
namespace expression {
+bool isConstant(const Expression* expression) {
+ if (dynamic_cast<const Var*>(expression)) {
+ return false;
+ }
+
+ if (auto compound = dynamic_cast<const CompoundExpressionBase*>(expression)) {
+ if (compound->getName() == "error") {
+ return false;
+ }
+ }
+
+ bool literalArgs = true;
+ expression->eachChild([&](const Expression* child) {
+ if (!dynamic_cast<const Literal*>(child)) {
+ literalArgs = false;
+ }
+ });
+ if (!literalArgs) {
+ return false;
+ }
+
+ return isFeatureConstant(expression) &&
+ isGlobalPropertyConstant(expression, std::array<std::string, 2>{{"zoom", "heatmap-density"}});
+}
+
ParseResult ParsingContext::parse(const mbgl::style::conversion::Convertible& value)
{
using namespace mbgl::style::conversion;
@@ -114,6 +143,30 @@ ParseResult ParsingContext::parse(const mbgl::style::conversion::Convertible& va
}
}
+ // If an expression's arguments are all literals, we can evaluate
+ // it immediately and replace it with a literal value in the
+ // parsed result.
+ if (parsed && !dynamic_cast<Literal *>(parsed->get()) && isConstant(parsed->get())) {
+ EvaluationParameters params(nullptr);
+ EvaluationResult evaluated((*parsed)->evaluate(params));
+ if (!evaluated) {
+ error(evaluated.error().message);
+ return ParseResult();
+ }
+
+ const type::Type type = (*parsed)->getType();
+ if (type.is<type::Array>()) {
+ // keep the original expression's array type, even if the evaluated
+ // type is more specific.
+ return ParseResult(std::make_unique<Literal>(
+ type.get<type::Array>(),
+ evaluated->get<std::vector<Value>>())
+ );
+ } else {
+ return ParseResult(std::make_unique<Literal>(*evaluated));
+ }
+ }
+
return parsed;
}