[Bridge] Support nullability annotations in bridged methods

Summary:
Fixes a crash due to the selector regex not knowing about the nullability annotations. Adds support for both the core annotations `__nullable` and `__nonnull` plus their shorthand counterparts `nullable` and `nonnull`.

Objective-C allows the shorthand versions only at the front of a parameter type declaration like `(nullable NSString *)` but the regex will pick up `(NSString * nullable)` too. This shouldn't cause any adverse effects and I left the code this way to keep the regex readable.

Fixes #1795

Closes https://github.com/facebook/react-native/pull/1796
Github Author: James Ide <ide@jameside.com>

Test Plan:
 Wrote a bridge method that uses a nullability annotation and verified that it didn't cause the app to crash:
```
RCT_EXPORT_METHOD(method:(nullable NSNumber *)reactTag)
{
}
```

Also added a nullable annotation to RCTTest.
This commit is contained in:
James Ide 2015-06-30 04:09:27 -07:00
parent 7d184adf1a
commit e3225f3403
2 changed files with 6 additions and 4 deletions

View File

@ -55,7 +55,7 @@ RCT_EXPORT_METHOD(verifySnapshot:(RCTResponseSenderBlock)callback)
}];
}
RCT_EXPORT_METHOD(sendAppEvent:(NSString *)name body:(id)body)
RCT_EXPORT_METHOD(sendAppEvent:(NSString *)name body:(nullable id)body)
{
[_bridge.eventDispatcher sendAppEventWithName:name body:body];
}

View File

@ -40,10 +40,12 @@
static NSRegularExpression *typeRegex;
static NSRegularExpression *selectorRegex;
if (!typeRegex) {
NSString *unusedPattern = @"(?:(?:__unused|__attribute__\\(\\(unused\\)\\)))";
NSString *unusedPattern = @"(?:__unused|__attribute__\\(\\(unused\\)\\))";
NSString *constPattern = @"(?:const)";
NSString *constUnusedPattern = [NSString stringWithFormat:@"(?:(?:%@|%@)\\s*)", unusedPattern, constPattern];
NSString *pattern = [NSString stringWithFormat:@"\\(%1$@?(\\w+?)(?:\\s*\\*)?%1$@?\\)", constUnusedPattern];
NSString *nullabilityPattern = @"(?:__nullable|__nonnull|nullable|nonnull)";
NSString *annotationPattern = [NSString stringWithFormat:@"(?:(?:%@|%@|%@)\\s*)",
unusedPattern, constPattern, nullabilityPattern];
NSString *pattern = [NSString stringWithFormat:@"\\(%1$@?(\\w+?)(?:\\s*\\*)?%1$@?\\)", annotationPattern];
typeRegex = [[NSRegularExpression alloc] initWithPattern:pattern options:0 error:NULL];
selectorRegex = [[NSRegularExpression alloc] initWithPattern:@"(?<=:).*?(?=[a-zA-Z_]+:|$)" options:0 error:NULL];