summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Firebaugh <john.firebaugh@gmail.com>2018-03-01 16:02:56 -0800
committerJohn Firebaugh <john.firebaugh@gmail.com>2018-03-01 17:02:26 -0800
commit54f3dc961e3a9e668312d7210706cddcf19676f7 (patch)
tree2606d627a67594a7146aa45e428052c596c99235
parent15ba70b5ff018ec2285e0459bf557d1f61240c41 (diff)
downloadqtlocation-mapboxgl-54f3dc961e3a9e668312d7210706cddcf19676f7.tar.gz
Relax type checking for "length"
-rw-r--r--cmake/core-files.cmake2
-rw-r--r--include/mbgl/style/expression/length.hpp32
-rw-r--r--src/mbgl/style/expression/compound_expression.cpp7
-rw-r--r--src/mbgl/style/expression/length.cpp66
-rw-r--r--src/mbgl/style/expression/parsing_context.cpp2
5 files changed, 102 insertions, 7 deletions
diff --git a/cmake/core-files.cmake b/cmake/core-files.cmake
index f24482e301..a915ffed69 100644
--- a/cmake/core-files.cmake
+++ b/cmake/core-files.cmake
@@ -456,6 +456,7 @@ set(MBGL_CORE_FILES
include/mbgl/style/expression/interpolate.hpp
include/mbgl/style/expression/is_constant.hpp
include/mbgl/style/expression/is_expression.hpp
+ include/mbgl/style/expression/length.hpp
include/mbgl/style/expression/let.hpp
include/mbgl/style/expression/literal.hpp
include/mbgl/style/expression/match.hpp
@@ -478,6 +479,7 @@ set(MBGL_CORE_FILES
src/mbgl/style/expression/interpolate.cpp
src/mbgl/style/expression/is_constant.cpp
src/mbgl/style/expression/is_expression.cpp
+ src/mbgl/style/expression/length.cpp
src/mbgl/style/expression/let.cpp
src/mbgl/style/expression/literal.cpp
src/mbgl/style/expression/match.cpp
diff --git a/include/mbgl/style/expression/length.hpp b/include/mbgl/style/expression/length.hpp
new file mode 100644
index 0000000000..1d754f1932
--- /dev/null
+++ b/include/mbgl/style/expression/length.hpp
@@ -0,0 +1,32 @@
+#pragma once
+
+#include <mbgl/style/expression/expression.hpp>
+#include <mbgl/style/conversion.hpp>
+#include <mbgl/style/expression/parsing_context.hpp>
+
+#include <memory>
+#include <vector>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+class Length : public Expression {
+public:
+ Length(std::unique_ptr<Expression> input);
+
+ static ParseResult parse(const mbgl::style::conversion::Convertible& value, ParsingContext& ctx);
+
+ EvaluationResult evaluate(const EvaluationContext& params) const override;
+ void eachChild(const std::function<void(const Expression&)>& visit) const override;
+ bool operator==(const Expression& e) const override;
+ std::vector<optional<Value>> possibleOutputs() const override;
+ std::string getOperator() const override { return "length"; }
+
+private:
+ std::unique_ptr<Expression> input;
+};
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/expression/compound_expression.cpp b/src/mbgl/style/expression/compound_expression.cpp
index 86d968c521..b1c2d74a9f 100644
--- a/src/mbgl/style/expression/compound_expression.cpp
+++ b/src/mbgl/style/expression/compound_expression.cpp
@@ -271,13 +271,6 @@ std::unordered_map<std::string, CompoundExpressionRegistry::Definition> initiali
return object.at(key);
});
- define("length", [](const std::vector<Value>& arr) -> Result<double> {
- return arr.size();
- });
- define("length", [] (const std::string s) -> Result<double> {
- return s.size();
- });
-
define("properties", [](const EvaluationContext& params) -> Result<std::unordered_map<std::string, Value>> {
if (!params.feature) {
return EvaluationError {
diff --git a/src/mbgl/style/expression/length.cpp b/src/mbgl/style/expression/length.cpp
new file mode 100644
index 0000000000..258353ae4e
--- /dev/null
+++ b/src/mbgl/style/expression/length.cpp
@@ -0,0 +1,66 @@
+#include <mbgl/style/expression/length.hpp>
+#include <mbgl/util/string.hpp>
+
+namespace mbgl {
+namespace style {
+namespace expression {
+
+Length::Length(std::unique_ptr<Expression> input_)
+ : Expression(type::Number),
+ input(std::move(input_)) {
+}
+
+EvaluationResult Length::evaluate(const EvaluationContext& params) const {
+ const EvaluationResult value = input->evaluate(params);
+ if (!value) return value;
+ return value->match(
+ [] (const std::string& s) {
+ return EvaluationResult { double(s.size()) };
+ },
+ [] (const std::vector<Value>& v) {
+ return EvaluationResult { double(v.size()) };
+ },
+ [&] (const auto&) -> EvaluationResult {
+ return EvaluationError { "Expected value to be of type string or array, but found " + toString(typeOf(*value)) + " instead." };
+ });
+}
+
+void Length::eachChild(const std::function<void(const Expression&)>& visit) const {
+ visit(*input);
+}
+
+bool Length::operator==(const Expression& e) const {
+ if (auto eq = dynamic_cast<const Length*>(&e)) {
+ return *eq->input == *input;
+ }
+ return false;
+}
+
+std::vector<optional<Value>> Length::possibleOutputs() const {
+ return { nullopt };
+}
+
+using namespace mbgl::style::conversion;
+ParseResult Length::parse(const Convertible& value, ParsingContext& ctx) {
+ std::size_t length = arrayLength(value);
+
+ if (length != 2) {
+ ctx.error("Expected one argument, but found " + util::toString(length) + " instead.");
+ return ParseResult();
+ }
+
+ ParseResult input = ctx.parse(arrayMember(value, 1), 1);
+ if (!input) return ParseResult();
+
+ type::Type type = (*input)->getType();
+ if (!type.is<type::Array>() && !type.is<type::StringType>() && !type.is<type::ValueType>()) {
+ ctx.error("Expected argument of type string or array, but found " + toString(type) + " instead.");
+ return ParseResult();
+ }
+
+ return ParseResult(std::make_unique<Length>(std::move(*input)));
+}
+
+} // namespace expression
+} // namespace style
+} // namespace mbgl
diff --git a/src/mbgl/style/expression/parsing_context.cpp b/src/mbgl/style/expression/parsing_context.cpp
index 880772d926..364c3f740a 100644
--- a/src/mbgl/style/expression/parsing_context.cpp
+++ b/src/mbgl/style/expression/parsing_context.cpp
@@ -15,6 +15,7 @@
#include <mbgl/style/expression/compound_expression.hpp>
#include <mbgl/style/expression/equals.hpp>
#include <mbgl/style/expression/interpolate.hpp>
+#include <mbgl/style/expression/length.hpp>
#include <mbgl/style/expression/let.hpp>
#include <mbgl/style/expression/literal.hpp>
#include <mbgl/style/expression/match.hpp>
@@ -89,6 +90,7 @@ const ExpressionRegistry& getExpressionRegistry() {
{"case", Case::parse},
{"coalesce", Coalesce::parse},
{"interpolate", parseInterpolate},
+ {"length", Length::parse},
{"let", Let::parse},
{"literal", Literal::parse},
{"match", parseMatch},