summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Guerra Soto <fabian.guerra@mapbox.com>2018-05-17 14:47:01 -0400
committerGitHub <noreply@github.com>2018-05-17 14:47:01 -0400
commit1aa5c67837a19d5f8ba8f7336f183da83e68441c (patch)
tree9185feeb7da4f0890b150367b138c7b81783cd4d
parent4ceb687f6c7bdb4cd768310eeae558d826dcf506 (diff)
downloadqtlocation-mapboxgl-1aa5c67837a19d5f8ba8f7336f183da83e68441c.tar.gz
[ios, macos] Support array values in match expressions. (#11866)android-v6.2.0-alpha.1
* [ios, macos] Support array values in match expressions. * [ios, macos] Update mgl_match documentation. * [ios, macos] Update changelogs. * [ios, macos] Clarify match expressions documentation.
-rw-r--r--platform/darwin/docs/guides/Predicates and Expressions.md4
-rw-r--r--platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm17
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm25
-rw-r--r--platform/darwin/test/MGLExpressionTests.mm6
-rw-r--r--platform/darwin/test/MGLPredicateTests.mm30
-rw-r--r--platform/ios/CHANGELOG.md4
-rw-r--r--platform/macos/CHANGELOG.md4
7 files changed, 62 insertions, 28 deletions
diff --git a/platform/darwin/docs/guides/Predicates and Expressions.md b/platform/darwin/docs/guides/Predicates and Expressions.md
index 18eccda569..e0d4755d4a 100644
--- a/platform/darwin/docs/guides/Predicates and Expressions.md
+++ b/platform/darwin/docs/guides/Predicates and Expressions.md
@@ -536,6 +536,10 @@ expression that contains references to those variables.
An input expression, then any number of argument pairs, followed by a default
expression. Each argument pair consists of a constant value followed by an
expression to produce as a result of matching that constant value.
+ If the input value is an aggregate expression, then any of the constant values within
+ that aggregate expression result in the following argument. This is shorthand for
+ specifying an argument pair for each of the constant values within that aggregate
+ expression. It is not possible to match the aggregate expression itself.
</dd>
</dl>
diff --git a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
index 380215ff32..15aa71419d 100644
--- a/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSComparisonPredicate+MGLAdditions.mm
@@ -115,15 +115,14 @@
return @[op, leftHandPredicate.mgl_jsonExpressionObject, rightHandPredicate.mgl_jsonExpressionObject];
}
case NSInPredicateOperatorType: {
- NSMutableArray *elements = [NSMutableArray arrayWithObjects:@"match", self.leftExpression.mgl_jsonExpressionObject, nil];
- NSArray *optionsExpressions = self.rightExpression.constantValue;
- for (id object in optionsExpressions) {
- id option = ((NSExpression *)object).mgl_jsonExpressionObject;
- [elements addObject:option];
- [elements addObject:@YES];
- }
- [elements addObject:@NO];
- return elements;
+
+ NSExpression *matchExpression = [NSExpression expressionForFunction:@"MGL_MATCH"
+ arguments:@[self.leftExpression,
+ self.rightExpression,
+ [NSExpression expressionForConstantValue:@YES],
+ [NSExpression expressionForConstantValue:@NO]]];
+
+ return matchExpression.mgl_jsonExpressionObject;
}
case NSContainsPredicateOperatorType: {
NSPredicate *inPredicate = [NSComparisonPredicate predicateWithLeftExpression:self.rightExpression
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm
index be93b13f3c..af4a197662 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.mm
+++ b/platform/darwin/src/NSExpression+MGLAdditions.mm
@@ -763,6 +763,11 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
NSArray *array = (NSArray *)object;
NSString *op = array.firstObject;
+ if (![op isKindOfClass:[NSString class]]) {
+ NSArray *subexpressions = MGLSubexpressionsWithJSONObjects(array);
+ return [NSExpression expressionForFunction:@"MGL_FUNCTION" arguments:subexpressions];
+ }
+
NSArray *argumentObjects = [array subarrayWithRange:NSMakeRange(1, array.count - 1)];
NSString *functionName = MGLFunctionNamesByExpressionOperator[op];
@@ -940,9 +945,13 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
return [NSExpression expressionForFunction:@"MGL_IF" arguments:arguments];
} else if ([op isEqualToString:@"match"]) {
NSMutableArray *optionsArray = [NSMutableArray array];
- NSEnumerator *optionsEnumerator = argumentObjects.objectEnumerator;
- while (id object = optionsEnumerator.nextObject) {
- NSExpression *option = [NSExpression expressionWithMGLJSONObject:object];
+
+ for (NSUInteger index = 0; index < argumentObjects.count; index++) {
+ NSExpression *option = [NSExpression expressionWithMGLJSONObject:argumentObjects[index]];
+ // match operators with arrays as matching values should not parse arrays as generic functions.
+ if (index > 0 && index < argumentObjects.count - 1 && !(index % 2 == 0) && [argumentObjects[index] isKindOfClass:[NSArray class]]) {
+ option = [NSExpression expressionForAggregate:MGLSubexpressionsWithJSONObjects(argumentObjects[index])];
+ }
[optionsArray addObject:option];
}
@@ -1346,7 +1355,15 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
NSArray<NSExpression *> *arguments = isAftermarketFunction ? self.arguments : self.arguments[minimumIndex].constantValue;
for (NSUInteger index = minimumIndex; index < arguments.count; index++) {
- [expressionObject addObject:arguments[index].mgl_jsonExpressionObject];
+ NSArray *argumentObject = arguments[index].mgl_jsonExpressionObject;
+ // match operators with arrays as matching values should not parse arrays using the literal operator.
+ if (index > 0 && index < arguments.count - 1 && !(index % 2 == 0)
+ && (arguments[index].expressionType == NSAggregateExpressionType ||
+ (arguments[index].expressionType == NSConstantValueExpressionType && [arguments[index].constantValue isKindOfClass:[NSArray class]]))) {
+
+ argumentObject = argumentObject.count == 2 ? argumentObject[1] : argumentObject;
+ }
+ [expressionObject addObject:argumentObject];
}
return expressionObject;
diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm
index e514ec22a7..dbdad2ed13 100644
--- a/platform/darwin/test/MGLExpressionTests.mm
+++ b/platform/darwin/test/MGLExpressionTests.mm
@@ -777,6 +777,12 @@ using namespace std::string_literals;
XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression);
}
+ {
+ NSExpression *expression = [NSExpression expressionWithFormat:@"MGL_MATCH(x, {'a', 'A'}, 'Apple', {'b', 'B'}, 'Banana', 'Kumquat')"];
+ NSArray *jsonExpression = @[@"match", @[@"get", @"x"], @[@"a", @"A"], @"Apple", @[@"b", @"B"], @"Banana", @"Kumquat"];
+ XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
+ XCTAssertEqualObjects([NSExpression expressionWithMGLJSONObject:jsonExpression], expression);
+ }
}
- (void)testCoalesceExpressionObject {
diff --git a/platform/darwin/test/MGLPredicateTests.mm b/platform/darwin/test/MGLPredicateTests.mm
index 4e7b3e7e4b..a21774a8f3 100644
--- a/platform/darwin/test/MGLPredicateTests.mm
+++ b/platform/darwin/test/MGLPredicateTests.mm
@@ -216,64 +216,64 @@
mustRoundTrip:NO];
}
{
- NSArray *expected = @[@"match", @[@"id"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO];
+ NSArray *expected = @[@"match", @[@"id"], @[@6, @5, @4, @3], @YES, @NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"$featureIdentifier IN { 6, 5, 4, 3}"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST($featureIdentifier, 'NSNumber'), 3, YES, 4, YES, 5, YES, 6, YES, NO) == YES"];
+ NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST($featureIdentifier, 'NSNumber'), { 3, 4, 5, 6 }, YES, NO) == YES"];
auto forwardFilter = [NSPredicate predicateWithMGLJSONObject:expected].mgl_filter;
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter);
}
{
- NSArray *expected = @[@"!", @[@"match", @[@"get", @"x"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO]];
+ NSArray *expected = @[@"!", @[@"match", @[@"get", @"x"], @[@6, @5, @4, @3], @YES, @NO]];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"NOT x IN { 6, 5, 4, 3}"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"NOT MGL_MATCH(CAST(x, 'NSNumber'), 3, YES, 4, YES, 5, YES, 6, YES, NO) == YES"];
+ NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"NOT MGL_MATCH(CAST(x, 'NSNumber'), { 3, 4, 5, 6 }, YES, NO) == YES"];
auto forwardFilter = [NSPredicate predicateWithMGLJSONObject:expected].mgl_filter;
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter);
}
{
- NSArray *expected = @[@"match", @[@"get", @"a"], @"b", @YES, @"c", @YES, @NO];
+ NSArray *expected = @[@"match", @[@"get", @"a"], @[@"b", @"c"], @YES, @NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"a IN { 'b', 'c' }"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST(a, 'NSString'), 'b', YES, 'c', YES, NO) == YES"];
+ NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST(a, 'NSString'), { 'b', 'c' }, YES, NO) == YES"];
auto forwardFilter = [NSPredicate predicateWithMGLJSONObject:expected].mgl_filter;
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter);
}
{
- NSArray *expected = @[@"match", @[@"geometry-type"], @"LineString", @YES, @"Polygon", @YES, @NO];
+ NSArray *expected = @[@"match", @[@"geometry-type"], @[@"LineString", @"Polygon"], @YES, @NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ IN %@", [NSExpression expressionForVariable:@"geometryType"], @[@"LineString", @"Polygon"]];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH($geometryType, 'LineString', YES, 'Polygon', YES, NO) == YES"];
+ NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH($geometryType, { 'LineString', 'Polygon' }, YES, NO) == YES"];
auto forwardFilter = [NSPredicate predicateWithMGLJSONObject:expected].mgl_filter;
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter);
}
{
- NSArray *expected = @[@"match", @[@"get", @"x"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO];
- NSPredicate *predicate = [NSPredicate predicateWithFormat:@"{ 6, 5, 4, 3} CONTAINS x"];
+ NSArray *expected = @[@"match", @[@"get", @"x"], @[@6, @5, @4, @3], @YES, @NO];
+ NSPredicate *predicate = [NSPredicate predicateWithFormat:@"{ 6, 5, 4, 3 } CONTAINS x"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST(x, 'NSNumber'), 3, YES, 4, YES, 5, YES, 6, YES, NO) == YES"];
+ NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST(x, 'NSNumber'), { 3, 4, 5, 6 }, YES, NO) == YES"];
auto forwardFilter = [NSPredicate predicateWithMGLJSONObject:expected].mgl_filter;
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter);
}
{
- NSArray *expected = @[@"match", @[@"geometry-type"], @"LineString", @YES, @"Polygon", @YES, @NO];
+ NSArray *expected = @[@"match", @[@"geometry-type"], @[@"LineString", @"Polygon"], @YES, @NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"%@ CONTAINS %@", @[@"LineString", @"Polygon"], [NSExpression expressionForVariable:@"geometryType"]];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH($geometryType, 'LineString', YES, 'Polygon', YES, NO) == YES"];
+ NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH($geometryType, { 'LineString', 'Polygon' }, YES, NO) == YES"];
auto forwardFilter = [NSPredicate predicateWithMGLJSONObject:expected].mgl_filter;
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter);
}
{
- NSArray *expected = @[@"match", @[@"id"], @6, @YES, @5, @YES, @4, @YES, @3, @YES, @NO];
+ NSArray *expected = @[@"match", @[@"id"], @[@6, @5, @4, @3], @YES, @NO];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"{ 6, 5, 4, 3} CONTAINS $featureIdentifier"];
XCTAssertEqualObjects(predicate.mgl_jsonExpressionObject, expected);
- NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST($featureIdentifier, 'NSNumber'), 3, YES, 4, YES, 5, YES, 6, YES, NO) == YES"];
+ NSPredicate *predicateAfter = [NSPredicate predicateWithFormat:@"MGL_MATCH(CAST($featureIdentifier, 'NSNumber'), { 3, 4, 5, 6 }, YES, NO) == YES"];
auto forwardFilter = [NSPredicate predicateWithMGLJSONObject:expected].mgl_filter;
NSPredicate *forwardPredicateAfter = [NSPredicate mgl_predicateWithFilter:forwardFilter];
XCTAssertEqualObjects(predicateAfter, forwardPredicateAfter);
diff --git a/platform/ios/CHANGELOG.md b/platform/ios/CHANGELOG.md
index f70330300b..27ade8b4b0 100644
--- a/platform/ios/CHANGELOG.md
+++ b/platform/ios/CHANGELOG.md
@@ -8,6 +8,10 @@ Mapbox welcomes participation and contributions from everyone. Please read [CONT
* The minimum deployment target for this SDK is now iOS 9.0. ([#11776](https://github.com/mapbox/mapbox-gl-native/pull/11776))
+### Style layers
+
+* Added support for aggregate expressions as input values to `MGL_MATCH` expressions. ([#11866](https://github.com/mapbox/mapbox-gl-native/pull/11866))
+
## 4.0.1 - May 14, 2018
### Packaging
diff --git a/platform/macos/CHANGELOG.md b/platform/macos/CHANGELOG.md
index ab71e62ec6..08093f2415 100644
--- a/platform/macos/CHANGELOG.md
+++ b/platform/macos/CHANGELOG.md
@@ -6,6 +6,10 @@
* The minimum deployment target for this SDK is now macOS 10.11.0. ([#11776](https://github.com/mapbox/mapbox-gl-native/pull/11776))
+### Style layers
+
+* Added support for aggregate expressions as input values to `MGL_MATCH` expressions. ([#11866](https://github.com/mapbox/mapbox-gl-native/pull/11866))
+
## 0.7.1
### Style layers