summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFabian Guerra <fabian.guerra@mapbox.com>2018-03-21 15:17:11 -0400
committerFabian Guerra <fabian.guerra@mapbox.com>2018-03-23 16:09:09 -0400
commita832f826b5ebfd054a6266b8b9dc55e021e61b5f (patch)
tree5322c84978210d7297740792b3baec853debda2c
parent7439c428a59a6964228f0b0715e110df2b89f111 (diff)
downloadqtlocation-mapboxgl-upstream/fabian-conditionall-branching-11007.tar.gz
[ios, macos] Case operator now has iOS 8 support.upstream/fabian-conditionall-branching-11007
-rw-r--r--platform/darwin/src/NSExpression+MGLAdditions.mm54
-rw-r--r--platform/darwin/src/NSPredicate+MGLAdditions.h2
-rw-r--r--platform/darwin/src/NSPredicate+MGLAdditions.mm25
-rw-r--r--platform/darwin/test/MGLExpressionTests.mm57
4 files changed, 76 insertions, 62 deletions
diff --git a/platform/darwin/src/NSExpression+MGLAdditions.mm b/platform/darwin/src/NSExpression+MGLAdditions.mm
index 5493c59381..bd747dc97e 100644
--- a/platform/darwin/src/NSExpression+MGLAdditions.mm
+++ b/platform/darwin/src/NSExpression+MGLAdditions.mm
@@ -464,36 +464,22 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
} else if ([op isEqualToString:@"var"]) {
return [NSExpression expressionForVariable:argumentObjects.firstObject];
} else if ([op isEqualToString:@"case"]) {
- NSPredicate *conditional = [NSPredicate mgl_predicateWithJSONObject:argumentObjects.firstObject];
- NSExpression *trueExpression;
- NSInteger rightBranchIndex = 2;
-
- if ([argumentObjects[1] isKindOfClass:[NSArray class]] ) {
- NSInteger length = 1;
- for (NSInteger index = 1; index < argumentObjects.count - 2; index++) {
- length++;
- if (![argumentObjects[index] isKindOfClass:[NSArray class]] && ![argumentObjects[index + 1] isKindOfClass:[NSArray class]]) {
- break;
- }
- }
- NSArray *trueObjects = [@[@"case"] arrayByAddingObjectsFromArray:
- [argumentObjects subarrayWithRange:NSMakeRange(1, length)]];
- trueExpression = [NSExpression mgl_expressionWithJSONObject:trueObjects];
- rightBranchIndex = length + 1;
- } else {
- trueExpression = [NSExpression mgl_expressionWithJSONObject:argumentObjects[1]];
- }
+ NSArray *caseExpressions = argumentObjects;
+ NSExpression *firstConditional = [NSExpression expressionWithFormat:@"%@", [NSPredicate mgl_predicateWithJSONObject:caseExpressions[0]]];
+ NSMutableArray *arguments = [NSMutableArray array];
- NSExpression *falseExpression;
- if ([argumentObjects[rightBranchIndex] isKindOfClass:[NSArray class]] ) {
- NSArray *falseObjects = [@[@"case"] arrayByAddingObjectsFromArray:
- [argumentObjects subarrayWithRange:NSMakeRange(rightBranchIndex, argumentObjects.count - rightBranchIndex)]];
- falseExpression = [NSExpression mgl_expressionWithJSONObject:falseObjects];
- } else {
- falseExpression = [NSExpression mgl_expressionWithJSONObject:argumentObjects[rightBranchIndex]];
+ for (NSUInteger index = 1; index < caseExpressions.count; index++) {
+ if ([caseExpressions[index] isKindOfClass:[NSArray class]]) {
+ NSPredicate *conditional = [NSPredicate mgl_predicateWithJSONObject:caseExpressions[index]];
+ NSExpression *argument = [NSExpression expressionWithFormat:@"%@", conditional];
+ [arguments addObject:argument];
+ } else {
+ [arguments addObject:[NSExpression mgl_expressionWithJSONObject:caseExpressions[index]]];
+ }
+
}
- return [NSExpression expressionForConditional:conditional trueExpression:trueExpression falseExpression:falseExpression];
+ return [NSExpression expressionForFunction:firstConditional selectorName:@"mgl_case:" arguments:arguments];
} else {
[NSException raise:NSInvalidArgumentException
format:@"Expression operator %@ not yet implemented.", op];
@@ -685,6 +671,20 @@ NSArray *MGLSubexpressionsWithJSONObjects(NSArray *objects) {
}];
[expressionObject addObject:self.operand.mgl_jsonExpressionObject];
return expressionObject;
+ } else if ([function isEqualToString:@"mgl_case:"]) {
+ NSPredicate *firstConditional = (NSPredicate *)self.operand.constantValue;
+ NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"case", firstConditional.mgl_jsonExpressionObject, nil];
+
+ for (NSExpression *option in self.arguments) {
+ if ([option respondsToSelector:@selector(constantValue)] && [option.constantValue isKindOfClass:[NSComparisonPredicate class]]) {
+ NSPredicate *predicate = (NSPredicate *)option.constantValue;
+ [expressionObject addObject:predicate.mgl_jsonExpressionObject];
+ } else {
+ [expressionObject addObject:option.mgl_jsonExpressionObject];
+ }
+ }
+
+ return expressionObject;
} else if ([function isEqualToString:@"median:"] ||
[function isEqualToString:@"mode:"] ||
[function isEqualToString:@"stddev:"] ||
diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.h b/platform/darwin/src/NSPredicate+MGLAdditions.h
index 89e9e65c64..cce7561add 100644
--- a/platform/darwin/src/NSPredicate+MGLAdditions.h
+++ b/platform/darwin/src/NSPredicate+MGLAdditions.h
@@ -16,4 +16,6 @@
@property (nonatomic, readonly) id mgl_jsonExpressionObject;
+- (id)mgl_case:(id)firstValue, ...;
+
@end
diff --git a/platform/darwin/src/NSPredicate+MGLAdditions.mm b/platform/darwin/src/NSPredicate+MGLAdditions.mm
index 63c8307803..2d5b646ff2 100644
--- a/platform/darwin/src/NSPredicate+MGLAdditions.mm
+++ b/platform/darwin/src/NSPredicate+MGLAdditions.mm
@@ -324,4 +324,29 @@ NSArray *MGLSubpredicatesWithJSONObjects(NSArray *objects) {
return nil;
}
+- (id)mgl_case:(id)firstValue, ... {
+
+ if ([self evaluateWithObject:nil]) {
+ return firstValue;
+ }
+
+ id eachExpression;
+ va_list argumentList;
+ va_start(argumentList, firstValue);
+
+ while ((eachExpression = va_arg(argumentList, id))) {
+ if ([eachExpression isKindOfClass:[NSComparisonPredicate class]]) {
+ id valueExpression = va_arg(argumentList, id);
+ if ([eachExpression evaluateWithObject:nil]) {
+ return valueExpression;
+ }
+ } else {
+ return eachExpression;
+ }
+ }
+ va_end(argumentList);
+
+ return nil;
+}
+
@end
diff --git a/platform/darwin/test/MGLExpressionTests.mm b/platform/darwin/test/MGLExpressionTests.mm
index 2e1c0e80fa..3f36a0cf61 100644
--- a/platform/darwin/test/MGLExpressionTests.mm
+++ b/platform/darwin/test/MGLExpressionTests.mm
@@ -573,42 +573,29 @@ using namespace std::string_literals;
}
- (void)testConditionalExpressionObject {
- // FIXME: This test crashes because iOS 8 doesn't have `+[NSExpression expressionForConditional:trueExpression:falseExpression:]`.
- // https://github.com/mapbox/mapbox-gl-native/issues/11007
- if (@available(iOS 9.0, *)) {
- {
- NSPredicate *conditional = [NSPredicate predicateWithFormat:@"1 = 2"];
- NSExpression *trueExpression = [NSExpression expressionForConstantValue:@YES];
- NSExpression *falseExpression = [NSExpression expressionForConstantValue:@NO];
- NSExpression *expression = [NSExpression expressionForConditional:conditional trueExpression:trueExpression falseExpression:falseExpression];
- NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO];
- XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
- XCTAssertEqualObjects([NSExpression expressionWithFormat:@"TERNARY(1 = 2, TRUE, FALSE)"].mgl_jsonExpressionObject, jsonExpression);
- XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO);
- XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
- }
- {
- NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(0 = 1, TRUE, TERNARY(1 = 2, TRUE, FALSE))"];
- NSArray *jsonExpression = @[@"case", @[@"==", @0, @1], @YES, @[@"==", @1, @2], @YES, @NO];
- XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
- XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO);
- XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
- }
- {
- NSExpression *expression = [NSExpression expressionWithFormat:@"TERNARY(0 = 1, TERNARY(1 = 2, TRUE, FALSE), TRUE)"];
- NSArray *jsonExpression = @[@"case", @[@"==", @0, @1], @[@"==", @1, @2], @YES, @NO, @YES];
- XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
- XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES);
- XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
- }
- {
- NSExpression *nestedExpression = [NSExpression expressionWithFormat:@"TERNARY(1 == 2, TERNARY(0 == 1, FALSE, TERNARY(4 == 5, FALSE, FALSE)), TERNARY(1 == 1, TRUE, FALSE))"];
- NSArray *nestedJSONExpression = @[@"case", @[@"==", @1, @2], @[@"==", @0, @1], @NO, @[@"==", @4, @5], @NO, @NO, @[@"==", @1, @1], @YES, @NO];
- XCTAssertEqualObjects(nestedExpression.mgl_jsonExpressionObject, nestedJSONExpression);
- XCTAssertEqualObjects([nestedExpression expressionValueWithObject:nil context:nil], @YES);
- XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:nestedJSONExpression], nestedExpression);
- }
+ {
+ NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_case:', %@, %@)",
+ [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]],
+ MGLConstantExpression(@YES),
+ MGLConstantExpression(@NO)];
+ NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @NO];
+ XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
+ XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
+ XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @NO);
}
+ {
+ NSExpression *expression = [NSExpression expressionWithFormat:@"FUNCTION(%@, 'mgl_case:', %@, %@, %@, %@)",
+ [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 2"]],
+ MGLConstantExpression(@YES),
+ [NSExpression expressionWithFormat:@"%@", [NSPredicate predicateWithFormat:@"1 = 1"]],
+ MGLConstantExpression(@YES),
+ MGLConstantExpression(@NO)];
+ NSArray *jsonExpression = @[@"case", @[@"==", @1, @2], @YES, @[@"==", @1, @1], @YES, @NO];
+ XCTAssertEqualObjects(expression.mgl_jsonExpressionObject, jsonExpression);
+ XCTAssertEqualObjects([NSExpression mgl_expressionWithJSONObject:jsonExpression], expression);
+ XCTAssertEqualObjects([expression expressionValueWithObject:nil context:nil], @YES);
+ }
+
}
@end