From 7b1f811c84369d26c1e23035419c6362d1bcb673 Mon Sep 17 00:00:00 2001 From: James Ide Date: Tue, 30 Jun 2015 01:19:05 -0700 Subject: [PATCH] [Bridge] Support nullability annotations in bridged methods 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. Test Plan: Write 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. --- Libraries/RCTTest/RCTTestModule.m | 2 +- React/Base/RCTModuleMethod.m | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/Libraries/RCTTest/RCTTestModule.m b/Libraries/RCTTest/RCTTestModule.m index 54c44513e3206e..9ef60c61175e2c 100644 --- a/Libraries/RCTTest/RCTTestModule.m +++ b/Libraries/RCTTest/RCTTestModule.m @@ -55,7 +55,7 @@ - (instancetype)init }]; } -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]; } diff --git a/React/Base/RCTModuleMethod.m b/React/Base/RCTModuleMethod.m index aca8267b94f56f..f294085e2f10cd 100644 --- a/React/Base/RCTModuleMethod.m +++ b/React/Base/RCTModuleMethod.m @@ -40,10 +40,12 @@ - (instancetype)initWithObjCMethodName:(NSString *)objCMethodName 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];