-
Notifications
You must be signed in to change notification settings - Fork 1.3k
[ios, macos] Add match expressions support. #11464
[ios, macos] Add match expressions support. #11464
Conversation
290009d
to
7c8614b
Compare
@@ -665,6 +704,26 @@ - (id)mgl_jsonExpressionObject { | |||
[expressionObject addObject:obj.mgl_jsonExpressionObject]; | |||
}]; | |||
[expressionObject addObject:self.operand.mgl_jsonExpressionObject]; | |||
return expressionObject; | |||
} else if ([function isEqualToString:@"mgl_matchWithOptions:default:"]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, eventually everything here will need to be installed as aftermarket expressions. But we’d still need a selector-like function as backup, in case the approach in #11472 breaks for any reason.
|
||
[expressionObject addObject:[self.arguments[1] mgl_jsonExpressionObject]]; | ||
return expressionObject; | ||
} else if ([function isEqualToString:@"coalesce:"]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also this.
ede1ef6
to
e75bd22
Compare
|
||
[expressionObject addObject:[self.arguments[1] mgl_jsonExpressionObject]]; | ||
return expressionObject; | ||
} else if ([function isEqualToString:@"mgl_coalesce"]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This function needs a stub implementation in Objective-C, even if it’s just an assertion like the one for -[NSPredicate(MGLAdditions) mgl_matchWithOptions:default:]
. Even if we don’t fully implement these functions in Objective-C, the developer may expect to be able to call -expressionValueWithObject:context:
. As long as the function name allows for the right number of arguments, we can then raise an exception instead of allowing NSExpression’s parser to segfault.
@@ -665,6 +704,26 @@ - (id)mgl_jsonExpressionObject { | |||
[expressionObject addObject:obj.mgl_jsonExpressionObject]; | |||
}]; | |||
[expressionObject addObject:self.operand.mgl_jsonExpressionObject]; | |||
return expressionObject; | |||
} else if ([function isEqualToString:@"mgl_matchWithOptions:default:"]) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, eventually everything here will need to be installed as aftermarket expressions. But we’d still need a selector-like function as backup, in case the approach in #11472 breaks for any reason.
} else if ([function isEqualToString:@"mgl_matchWithOptions:default:"]) { | ||
NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"match", self.operand.mgl_jsonExpressionObject, nil]; | ||
NSArray *optionsArray = self.arguments[0].constantValue; | ||
for (NSDictionary<id, NSExpression*> *options in optionsArray) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike with coalescing, I think it could get quite inconvenient to have to specify all the cases for a match expression inside an aggregate expression. We can simplify the function name to mgl_match:
by supposing a vararg method signature for the underlying Objective-C method:
- (id)mgl_match:(NSExpression *)firstCase, ...;
Then the arguments to this expression would be firstCase
, firstValue
, secondCase
, secondValue
, …, defaultValue
.
(So far I’ve been taking cues from NSExpression’s built-in functions, not necessarily including all the nouns that an Objective-C method selector would, but still including prepositions.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Varargs are rare or nonexistent among NSExpression’s built-in functions, so when we implement the aftermarket version of this function, we should make it look like a control structure. Control structures like TERTIARY()
don’t have selectors, so the developer wouldn’t expect to call -expressionValueWithObject:context:
on them. Therefore, we could call the function MGL_MATCH:
and not need to explicitly name the arguments or add colons for each one. The call site would look like MGL_MATCH(input, firstCase, firstValue, secondCase, secondValue, …, defaultValue)
.
} else if ([function isEqualToString:@"mgl_coalesce"]) { | ||
NSMutableArray *expressionObject = [NSMutableArray arrayWithObjects:@"coalesce", nil]; | ||
|
||
for (NSExpression *expression in self.operand.constantValue) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It’s a bit awkward to say FUNCTION({1, 2, 3}, 'mgl_coalesce')
, since people normally think about coalescing an array, not telling the array to coelesce itself. Fortunately, built-in expressions don’t have operands (at least not publicly), so #11472 will implement an mgl_match:
function that takes a single argument. But this implementation should stay in case the aftermarket expression mechanism fails in the future.
90f984c
to
3daa566
Compare
3daa566
to
8cb51f4
Compare
Fixes #11009