Replace exported method registration with statically allocated struct

Reviewed By: fromcelticpark

Differential Revision: D5389383

fbshipit-source-id: 9eb29b254b616574966b43ad24aa880d44589652
This commit is contained in:
Pieter De Baets 2017-07-24 06:46:01 -07:00 committed by Facebook Github Bot
parent d94f3e4b98
commit cb12080179
15 changed files with 161 additions and 143 deletions

View File

@ -15,16 +15,17 @@
#define FB_REFERENCE_IMAGE_DIR "" #define FB_REFERENCE_IMAGE_DIR ""
#endif #endif
#define RCT_RUN_RUNLOOP_WHILE(CONDITION) \ #define RCT_RUN_RUNLOOP_WHILE(CONDITION) \
{ \ { \
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:5]; \ NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:5]; \
while ((CONDITION)) { \ NSRunLoop *runloop = [NSRunLoop mainRunLoop]; \
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; \ while ((CONDITION)) { \
if ([timeout timeIntervalSinceNow] <= 0) { \ [runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; \
XCTFail(@"Runloop timed out before condition was met"); \ if ([timeout timeIntervalSinceNow] <= 0) { \
break; \ XCTFail(@"Runloop timed out before condition was met"); \
} \ break; \
} \ } \
} \
} }
/** /**

View File

@ -112,9 +112,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
AllocationTestModule *module = [AllocationTestModule new]; AllocationTestModule *module = [AllocationTestModule new];
@autoreleasepool { @autoreleasepool {
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
moduleProvider:^{ moduleProvider:^{ return @[module]; }
return @[module];
}
launchOptions:nil]; launchOptions:nil];
XCTAssertTrue(module.isValid, @"AllocationTestModule should be valid"); XCTAssertTrue(module.isValid, @"AllocationTestModule should be valid");
(void)bridge; (void)bridge;
@ -130,12 +128,10 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
@autoreleasepool { @autoreleasepool {
AllocationTestModule *module = [AllocationTestModule new]; AllocationTestModule *module = [AllocationTestModule new];
RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL RCTBridge *bridge = [[RCTBridge alloc] initWithBundleURL:_bundleURL
moduleProvider:^{ moduleProvider:^{ return @[module]; }
return @[module];
}
launchOptions:nil]; launchOptions:nil];
XCTAssertNotNil(module, @"AllocationTestModule should have been created");
weakModule = module; weakModule = module;
XCTAssertNotNil(weakModule, @"AllocationTestModule should have been created");
(void)bridge; (void)bridge;
} }
@ -145,11 +141,18 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
- (void)testModuleMethodsAreDeallocated - (void)testModuleMethodsAreDeallocated
{ {
static RCTMethodInfo methodInfo = {
.objcName = "test:(NSString *)a :(nonnull NSNumber *)b :(RCTResponseSenderBlock)c :(RCTResponseErrorBlock)d",
.jsName = "",
.isSync = false
};
__weak RCTModuleMethod *weakMethod; __weak RCTModuleMethod *weakMethod;
@autoreleasepool { @autoreleasepool {
__autoreleasing RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithMethodSignature:@"test:(NSString *)a :(nonnull NSNumber *)b :(RCTResponseSenderBlock)c :(RCTResponseErrorBlock)d" JSMethodName:@"" isSync:NO moduleClass:[AllocationTestModule class]]; __autoreleasing RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithExportedMethod:&methodInfo
weakMethod = method; moduleClass:[AllocationTestModule class]];
XCTAssertNotNil(method, @"RCTModuleMethod should have been created"); XCTAssertNotNil(method, @"RCTModuleMethod should have been created");
weakMethod = method;
} }
RCT_RUN_RUNLOOP_WHILE(weakMethod) RCT_RUN_RUNLOOP_WHILE(weakMethod)
@ -172,7 +175,6 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
#if !TARGET_OS_TV // userInteractionEnabled is true for Apple TV views #if !TARGET_OS_TV // userInteractionEnabled is true for Apple TV views
XCTAssertFalse(rootContentView.userInteractionEnabled, @"RCTContentView should have been invalidated"); XCTAssertFalse(rootContentView.userInteractionEnabled, @"RCTContentView should have been invalidated");
#endif #endif
} }
- (void)testUnderlyingBridgeIsDeallocated - (void)testUnderlyingBridgeIsDeallocated

View File

@ -19,12 +19,12 @@
@implementation RCTMethodArgumentTests @implementation RCTMethodArgumentTests
extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes); extern SEL RCTParseMethodSignature(const char *methodSignature, NSArray **argTypes);
- (void)testOneArgument - (void)testOneArgument
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(NSInteger)foo"; const char *methodSignature = "foo:(NSInteger)foo";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
XCTAssertEqual(arguments.count, (NSUInteger)1); XCTAssertEqual(arguments.count, (NSUInteger)1);
@ -34,7 +34,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testTwoArguments - (void)testTwoArguments
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(NSInteger)foo bar:(BOOL)bar"; const char *methodSignature = "foo:(NSInteger)foo bar:(BOOL)bar";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
XCTAssertEqual(arguments.count, (NSUInteger)2); XCTAssertEqual(arguments.count, (NSUInteger)2);
@ -45,7 +45,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testSpaces - (void)testSpaces
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo : (NSInteger)foo bar : (BOOL) bar"; const char *methodSignature = "foo : (NSInteger)foo bar : (BOOL) bar";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
XCTAssertEqual(arguments.count, (NSUInteger)2); XCTAssertEqual(arguments.count, (NSUInteger)2);
@ -56,7 +56,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testNewlines - (void)testNewlines
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo : (NSInteger)foo\nbar : (BOOL) bar"; const char *methodSignature = "foo : (NSInteger)foo\nbar : (BOOL) bar";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
XCTAssertEqual(arguments.count, (NSUInteger)2); XCTAssertEqual(arguments.count, (NSUInteger)2);
@ -67,7 +67,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testUnnamedArgs - (void)testUnnamedArgs
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(NSInteger)foo:(BOOL)bar"; const char *methodSignature = "foo:(NSInteger)foo:(BOOL)bar";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo::"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo::");
XCTAssertEqual(arguments.count, (NSUInteger)2); XCTAssertEqual(arguments.count, (NSUInteger)2);
@ -78,7 +78,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testUntypedUnnamedArgs - (void)testUntypedUnnamedArgs
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:foo:bar:bar"; const char *methodSignature = "foo:foo:bar:bar";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:::"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:::");
XCTAssertEqual(arguments.count, (NSUInteger)3); XCTAssertEqual(arguments.count, (NSUInteger)3);
@ -90,7 +90,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testAttributes - (void)testAttributes
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(__attribute__((unused)) NSString *)foo bar:(__unused BOOL)bar"; const char *methodSignature = "foo:(__attribute__((unused)) NSString *)foo bar:(__unused BOOL)bar";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
XCTAssertEqual(arguments.count, (NSUInteger)2); XCTAssertEqual(arguments.count, (NSUInteger)2);
@ -101,7 +101,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testNullability - (void)testNullability
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(nullable NSString *)foo bar:(nonnull NSNumber *)bar baz:(id)baz"; const char *methodSignature = "foo:(nullable NSString *)foo bar:(nonnull NSNumber *)bar baz:(id)baz";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:baz:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:baz:");
XCTAssertEqual(arguments.count, (NSUInteger)3); XCTAssertEqual(arguments.count, (NSUInteger)3);
@ -116,7 +116,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testSemicolonStripping - (void)testSemicolonStripping
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(NSString *)foo bar:(BOOL)bar;"; const char *methodSignature = "foo:(NSString *)foo bar:(BOOL)bar;";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
XCTAssertEqual(arguments.count, (NSUInteger)2); XCTAssertEqual(arguments.count, (NSUInteger)2);
@ -127,7 +127,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testUnused - (void)testUnused
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(__unused NSString *)foo bar:(NSNumber *)bar"; const char *methodSignature = "foo:(__unused NSString *)foo bar:(NSNumber *)bar";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
XCTAssertEqual(arguments.count, (NSUInteger)2); XCTAssertEqual(arguments.count, (NSUInteger)2);
@ -140,7 +140,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testGenericArray - (void)testGenericArray
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(NSArray<NSString *> *)foo;"; const char *methodSignature = "foo:(NSArray<NSString *> *)foo;";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
XCTAssertEqual(arguments.count, (NSUInteger)1); XCTAssertEqual(arguments.count, (NSUInteger)1);
@ -150,7 +150,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testNestedGenericArray - (void)testNestedGenericArray
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(NSArray<NSArray<NSString *> *> *)foo;"; const char *methodSignature = "foo:(NSArray<NSArray<NSString *> *> *)foo;";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
XCTAssertEqual(arguments.count, (NSUInteger)1); XCTAssertEqual(arguments.count, (NSUInteger)1);
@ -160,7 +160,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testGenericSet - (void)testGenericSet
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(NSSet<NSNumber *> *)foo;"; const char *methodSignature = "foo:(NSSet<NSNumber *> *)foo;";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
XCTAssertEqual(arguments.count, (NSUInteger)1); XCTAssertEqual(arguments.count, (NSUInteger)1);
@ -170,7 +170,7 @@ extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes
- (void)testGenericDictionary - (void)testGenericDictionary
{ {
NSArray *arguments; NSArray *arguments;
NSString *methodSignature = @"foo:(NSDictionary<NSString *, NSNumber *> *)foo;"; const char *methodSignature = "foo:(NSDictionary<NSString *, NSNumber *> *)foo;";
SEL selector = RCTParseMethodSignature(methodSignature, &arguments); SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:"); XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
XCTAssertEqual(arguments.count, (NSUInteger)1); XCTAssertEqual(arguments.count, (NSUInteger)1);

View File

@ -37,18 +37,18 @@ static BOOL RCTLogsError(void (^block)(void))
CGRect _s; CGRect _s;
} }
static RCTModuleMethod *buildDefaultMethodWithMethodSignature(NSString *methodSignature) { static RCTModuleMethod *buildDefaultMethodWithMethodSignature(const char *methodSignature)
return [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature {
JSMethodName:nil // This leaks a RCTMethodInfo, but it's a test, so...
isSync:NO RCTMethodInfo *methodInfo = new RCTMethodInfo {.objcName = methodSignature, .isSync = NO};
moduleClass:[RCTModuleMethodTests class]]; return [[RCTModuleMethod alloc] initWithExportedMethod:methodInfo moduleClass:[RCTModuleMethodTests class]];
} }
static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSignature) { static RCTModuleMethod *buildSyncMethodWithMethodSignature(const char *methodSignature)
return [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature {
JSMethodName:nil // This leaks a RCTMethodInfo, but it's a test, so...
isSync:YES RCTMethodInfo *methodInfo = new RCTMethodInfo {.objcName = methodSignature, .isSync = YES};
moduleClass:[RCTModuleMethodTests class]]; return [[RCTModuleMethod alloc] initWithExportedMethod:methodInfo moduleClass:[RCTModuleMethodTests class]];
} }
+ (NSString *)moduleName { return nil; } + (NSString *)moduleName { return nil; }
@ -62,7 +62,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
- (void)testNonnull - (void)testNonnull
{ {
NSString *methodSignature = @"doFooWithBar:(nonnull NSString *)bar"; const char *methodSignature = "doFooWithBar:(nonnull NSString *)bar";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
XCTAssertFalse(RCTLogsError(^{ XCTAssertFalse(RCTLogsError(^{
[method invokeWithBridge:nil module:self arguments:@[@"Hello World"]]; [method invokeWithBridge:nil module:self arguments:@[@"Hello World"]];
@ -85,7 +85,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
{ {
// Specifying an NSNumber param without nonnull isn't allowed // Specifying an NSNumber param without nonnull isn't allowed
XCTAssertTrue(RCTLogsError(^{ XCTAssertTrue(RCTLogsError(^{
NSString *methodSignature = @"doFooWithNumber:(NSNumber *)n"; const char *methodSignature = "doFooWithNumber:(NSNumber *)n";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
// Invoke method to trigger parsing // Invoke method to trigger parsing
[method invokeWithBridge:nil module:self arguments:@[@1]]; [method invokeWithBridge:nil module:self arguments:@[@1]];
@ -93,7 +93,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
} }
{ {
NSString *methodSignature = @"doFooWithNumber:(nonnull NSNumber *)n"; const char *methodSignature = "doFooWithNumber:(nonnull NSNumber *)n";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
XCTAssertTrue(RCTLogsError(^{ XCTAssertTrue(RCTLogsError(^{
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]]; [method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
@ -101,7 +101,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
} }
{ {
NSString *methodSignature = @"doFooWithDouble:(double)n"; const char *methodSignature = "doFooWithDouble:(double)n";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
XCTAssertTrue(RCTLogsError(^{ XCTAssertTrue(RCTLogsError(^{
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]]; [method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
@ -109,7 +109,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
} }
{ {
NSString *methodSignature = @"doFooWithInteger:(NSInteger)n"; const char *methodSignature = "doFooWithInteger:(NSInteger)n";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
XCTAssertTrue(RCTLogsError(^{ XCTAssertTrue(RCTLogsError(^{
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]]; [method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
@ -119,7 +119,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
- (void)testStructArgument - (void)testStructArgument
{ {
NSString *methodSignature = @"doFooWithCGRect:(CGRect)s"; const char *methodSignature = "doFooWithCGRect:(CGRect)s";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
CGRect r = CGRectMake(10, 20, 30, 40); CGRect r = CGRectMake(10, 20, 30, 40);
@ -129,7 +129,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
- (void)testWhitespaceTolerance - (void)testWhitespaceTolerance
{ {
NSString *methodSignature = @"doFoo : \t (NSString *)foo"; const char *methodSignature = "doFoo : \t (NSString *)foo";
__block RCTModuleMethod *method; __block RCTModuleMethod *method;
XCTAssertFalse(RCTLogsError(^{ XCTAssertFalse(RCTLogsError(^{
@ -146,19 +146,19 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
- (void)testFunctionType - (void)testFunctionType
{ {
{ {
NSString *methodSignature = @"doFoo"; const char *methodSignature = "doFoo";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
XCTAssertTrue(method.functionType == RCTFunctionTypeNormal); XCTAssertTrue(method.functionType == RCTFunctionTypeNormal);
} }
{ {
NSString *methodSignature = @"openURL:(NSURL *)URL resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject"; const char *methodSignature = "openURL:(NSURL *)URL resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
XCTAssertTrue(method.functionType == RCTFunctionTypePromise); XCTAssertTrue(method.functionType == RCTFunctionTypePromise);
} }
{ {
NSString *methodSignature = @"echoString:(NSString *)input"; const char *methodSignature = "echoString:(NSString *)input";
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
XCTAssertTrue(method.functionType == RCTFunctionTypeSync); XCTAssertTrue(method.functionType == RCTFunctionTypeSync);
} }
@ -167,14 +167,14 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
- (void)testReturnsValueForSyncFunction - (void)testReturnsValueForSyncFunction
{ {
{ {
NSString *methodSignature = @"echoString:(NSString *)input"; const char *methodSignature = "echoString:(NSString *)input";
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
id result = [method invokeWithBridge:nil module:self arguments:@[@"Test String Value"]]; id result = [method invokeWithBridge:nil module:self arguments:@[@"Test String Value"]];
XCTAssertEqualObjects(result, @"Test String Value"); XCTAssertEqualObjects(result, @"Test String Value");
} }
{ {
NSString *methodSignature = @"methodThatReturnsNil"; const char *methodSignature = "methodThatReturnsNil";
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
id result = [method invokeWithBridge:nil module:self arguments:@[]]; id result = [method invokeWithBridge:nil module:self arguments:@[]];
XCTAssertNil(result); XCTAssertNil(result);
@ -183,7 +183,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
- (void)testReturnsNilForDefaultFunction - (void)testReturnsNilForDefaultFunction
{ {
NSString *methodSignature = @"doFoo"; const char *methodSignature = "doFoo";
RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildDefaultMethodWithMethodSignature(methodSignature);
id result = [method invokeWithBridge:nil module:self arguments:@[]]; id result = [method invokeWithBridge:nil module:self arguments:@[]];
XCTAssertNil(result); XCTAssertNil(result);
@ -192,7 +192,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
- (void)testReturnTypeForSyncFunction - (void)testReturnTypeForSyncFunction
{ {
{ {
NSString *methodSignature = @"methodThatReturnsNil"; const char *methodSignature = "methodThatReturnsNil";
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
XCTAssertFalse(RCTLogsError(^{ XCTAssertFalse(RCTLogsError(^{
// Invoke method to trigger parsing // Invoke method to trigger parsing
@ -201,7 +201,7 @@ static RCTModuleMethod *buildSyncMethodWithMethodSignature(NSString *methodSigna
} }
{ {
NSString *methodSignature = @"doFoo"; const char *methodSignature = "doFoo";
RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature); RCTModuleMethod *method = buildSyncMethodWithMethodSignature(methodSignature);
XCTAssertTrue(RCTLogsError(^{ XCTAssertTrue(RCTLogsError(^{
// Invoke method to trigger parsing // Invoke method to trigger parsing

View File

@ -1067,7 +1067,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithBundleURL:(__unused NSURL *)bundleUR
} }
NSString *message = [NSString stringWithFormat: NSString *message = [NSString stringWithFormat:
@"Exception '%@' was thrown while invoking %@ on target %@ with params %@", @"Exception '%@' was thrown while invoking %s on target %@ with params %@",
exception, method.JSMethodName, moduleData.name, params]; exception, method.JSMethodName, moduleData.name, params];
RCTFatal(RCTErrorWithMessage(message)); RCTFatal(RCTErrorWithMessage(message));
return nil; return nil;

View File

@ -30,7 +30,7 @@ static inline const char *RCTFunctionDescriptorFromType(RCTFunctionType type) {
@protocol RCTBridgeMethod <NSObject> @protocol RCTBridgeMethod <NSObject>
@property (nonatomic, copy, readonly) NSString *JSMethodName; @property (nonatomic, readonly) const char *JSMethodName;
@property (nonatomic, readonly) RCTFunctionType functionType; @property (nonatomic, readonly) RCTFunctionType functionType;
- (id)invokeWithBridge:(RCTBridge *)bridge - (id)invokeWithBridge:(RCTBridge *)bridge

View File

@ -47,7 +47,17 @@ typedef void (^RCTPromiseRejectBlock)(NSString *code, NSString *message, NSError
* *
* NOTE: RCTJSThread is not a real libdispatch queue * NOTE: RCTJSThread is not a real libdispatch queue
*/ */
extern dispatch_queue_t RCTJSThread; RCT_EXTERN dispatch_queue_t RCTJSThread;
RCT_EXTERN_C_BEGIN
typedef struct RCTMethodInfo {
const char *const jsName;
const char *const objcName;
const BOOL isSync;
} RCTMethodInfo;
RCT_EXTERN_C_END
/** /**
* Provides the interface needed to register a bridge module. * Provides the interface needed to register a bridge module.
@ -248,9 +258,9 @@ RCT_EXTERN void RCTRegisterModule(Class); \
* and also whether this method is synchronous. * and also whether this method is synchronous.
*/ */
#define _RCT_EXTERN_REMAP_METHOD(js_name, method, is_blocking_synchronous_method) \ #define _RCT_EXTERN_REMAP_METHOD(js_name, method, is_blocking_synchronous_method) \
+ (NSArray *)RCT_CONCAT(__rct_export__, \ + (const RCTMethodInfo *)RCT_CONCAT(__rct_export__, RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \
RCT_CONCAT(js_name, RCT_CONCAT(__LINE__, __COUNTER__))) { \ static RCTMethodInfo config = {#js_name, #method, is_blocking_synchronous_method}; \
return @[@#js_name, @#method, @is_blocking_synchronous_method]; \ return &config; \
} }
/** /**

View File

@ -16,8 +16,12 @@
*/ */
#if defined(__cplusplus) #if defined(__cplusplus)
#define RCT_EXTERN extern "C" __attribute__((visibility("default"))) #define RCT_EXTERN extern "C" __attribute__((visibility("default")))
#define RCT_EXTERN_C_BEGIN extern "C" {
#define RCT_EXTERN_C_END }
#else #else
#define RCT_EXTERN extern __attribute__((visibility("default"))) #define RCT_EXTERN extern __attribute__((visibility("default")))
#define RCT_EXTERN_C_BEGIN
#define RCT_EXTERN_C_END
#endif #endif
/** /**

View File

@ -270,14 +270,9 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
SEL selector = method_getName(method); SEL selector = method_getName(method);
if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) { if ([NSStringFromSelector(selector) hasPrefix:@"__rct_export__"]) {
IMP imp = method_getImplementation(method); IMP imp = method_getImplementation(method);
NSArray *entries = auto exportedMethod = ((const RCTMethodInfo *(*)(id, SEL))imp)(_moduleClass, selector);
((NSArray *(*)(id, SEL))imp)(_moduleClass, selector); id<RCTBridgeMethod> moduleMethod = [[RCTModuleMethod alloc] initWithExportedMethod:exportedMethod
id<RCTBridgeMethod> moduleMethod = moduleClass:_moduleClass];
[[RCTModuleMethod alloc] initWithMethodSignature:entries[1]
JSMethodName:entries[0]
isSync:((NSNumber *)entries[2]).boolValue
moduleClass:_moduleClass];
[moduleMethods addObject:moduleMethod]; [moduleMethods addObject:moduleMethod];
} }
} }
@ -345,7 +340,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init);
} }
[syncMethods addObject:@(methods.count)]; [syncMethods addObject:@(methods.count)];
} }
[methods addObject:method.JSMethodName]; [methods addObject:@(method.JSMethodName)];
} }
NSArray *config = @[ NSArray *config = @[

View File

@ -10,6 +10,7 @@
#import <Foundation/Foundation.h> #import <Foundation/Foundation.h>
#import <React/RCTBridgeMethod.h> #import <React/RCTBridgeMethod.h>
#import <React/RCTBridgeModule.h>
#import <React/RCTNullability.h> #import <React/RCTNullability.h>
@class RCTBridge; @class RCTBridge;
@ -27,9 +28,7 @@
@property (nonatomic, readonly) Class moduleClass; @property (nonatomic, readonly) Class moduleClass;
@property (nonatomic, readonly) SEL selector; @property (nonatomic, readonly) SEL selector;
- (instancetype)initWithMethodSignature:(NSString *)objCMethodName - (instancetype)initWithExportedMethod:(const RCTMethodInfo *)exportMethod
JSMethodName:(NSString *)JSMethodName
isSync:(BOOL)isSync
moduleClass:(Class)moduleClass NS_DESIGNATED_INITIALIZER; moduleClass:(Class)moduleClass NS_DESIGNATED_INITIALIZER;
@end @end

View File

@ -41,21 +41,20 @@ typedef BOOL (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
@implementation RCTModuleMethod @implementation RCTModuleMethod
{ {
Class _moduleClass; Class _moduleClass;
const RCTMethodInfo *_methodInfo;
NSString *_JSMethodName;
SEL _selector;
NSInvocation *_invocation; NSInvocation *_invocation;
NSArray<RCTArgumentBlock> *_argumentBlocks; NSArray<RCTArgumentBlock> *_argumentBlocks;
NSString *_methodSignature;
SEL _selector;
BOOL _isSync;
} }
@synthesize JSMethodName = _JSMethodName;
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index, static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index,
id valueOrType, const char *issue) id valueOrType, const char *issue)
{ {
RCTLogError(@"Argument %tu (%@) of %@.%@ %s", index, valueOrType, RCTLogError(@"Argument %tu (%@) of %@.%s %s", index, valueOrType,
RCTBridgeModuleNameForClass(method->_moduleClass), RCTBridgeModuleNameForClass(method->_moduleClass),
method->_JSMethodName, issue); method.JSMethodName, issue);
} }
RCT_NOT_IMPLEMENTED(- (instancetype)init) RCT_NOT_IMPLEMENTED(- (instancetype)init)
@ -114,10 +113,9 @@ static BOOL RCTCheckCallbackMultipleInvocations(BOOL *didInvoke) {
} }
} }
SEL RCTParseMethodSignature(NSString *, NSArray<RCTMethodArgument *> **); SEL RCTParseMethodSignature(const char *, NSArray<RCTMethodArgument *> **);
SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument *> **arguments) SEL RCTParseMethodSignature(const char *input, NSArray<RCTMethodArgument *> **arguments)
{ {
const char *input = methodSignature.UTF8String;
RCTSkipWhitespace(&input); RCTSkipWhitespace(&input);
NSMutableArray *args; NSMutableArray *args;
@ -164,30 +162,25 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
return NSSelectorFromString(selector); return NSSelectorFromString(selector);
} }
- (instancetype)initWithMethodSignature:(NSString *)methodSignature - (instancetype)initWithExportedMethod:(const RCTMethodInfo *)exportedMethod
JSMethodName:(NSString *)JSMethodName moduleClass:(Class)moduleClass
isSync:(BOOL)isSync
moduleClass:(Class)moduleClass
{ {
if (self = [super init]) { if (self = [super init]) {
_moduleClass = moduleClass; _moduleClass = moduleClass;
_methodSignature = [methodSignature copy]; _methodInfo = exportedMethod;
_JSMethodName = [JSMethodName copy];
_isSync = isSync;
} }
return self; return self;
} }
- (void)processMethodSignature - (void)processMethodSignature
{ {
NSArray<RCTMethodArgument *> *arguments; NSArray<RCTMethodArgument *> *arguments;
_selector = RCTParseMethodSignature(_methodSignature, &arguments); _selector = RCTParseMethodSignature(_methodInfo->objcName, &arguments);
RCTAssert(_selector, @"%@ is not a valid selector", _methodSignature); RCTAssert(_selector, @"%s is not a valid selector", _methodInfo->objcName);
// Create method invocation // Create method invocation
NSMethodSignature *methodSignature = [_moduleClass instanceMethodSignatureForSelector:_selector]; NSMethodSignature *methodSignature = [_moduleClass instanceMethodSignatureForSelector:_selector];
RCTAssert(methodSignature, @"%@ is not a recognized Objective-C method.", _methodSignature); RCTAssert(methodSignature, @"%s is not a recognized Objective-C method.", sel_getName(_selector));
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature]; NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:methodSignature];
invocation.selector = _selector; invocation.selector = _selector;
_invocation = invocation; _invocation = invocation;
@ -328,8 +321,8 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
) )
} else if ([typeName isEqualToString:@"RCTPromiseResolveBlock"]) { } else if ([typeName isEqualToString:@"RCTPromiseResolveBlock"]) {
RCTAssert(i == numberOfArguments - 2, RCTAssert(i == numberOfArguments - 2,
@"The RCTPromiseResolveBlock must be the second to last parameter in -[%@ %@]", @"The RCTPromiseResolveBlock must be the second to last parameter in %@",
_moduleClass, _methodSignature); [self methodName]);
RCT_ARG_BLOCK( RCT_ARG_BLOCK(
if (RCT_DEBUG && ![json isKindOfClass:[NSNumber class]]) { if (RCT_DEBUG && ![json isKindOfClass:[NSNumber class]]) {
RCTLogArgumentError(weakSelf, index, json, "should be a promise resolver function"); RCTLogArgumentError(weakSelf, index, json, "should be a promise resolver function");
@ -345,8 +338,8 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
) )
} else if ([typeName isEqualToString:@"RCTPromiseRejectBlock"]) { } else if ([typeName isEqualToString:@"RCTPromiseRejectBlock"]) {
RCTAssert(i == numberOfArguments - 1, RCTAssert(i == numberOfArguments - 1,
@"The RCTPromiseRejectBlock must be the last parameter in -[%@ %@]", @"The RCTPromiseRejectBlock must be the last parameter in %@",
_moduleClass, _methodSignature); [self methodName]);
RCT_ARG_BLOCK( RCT_ARG_BLOCK(
if (RCT_DEBUG && ![json isKindOfClass:[NSNumber class]]) { if (RCT_DEBUG && ![json isKindOfClass:[NSNumber class]]) {
RCTLogArgumentError(weakSelf, index, json, "should be a promise rejecter function"); RCTLogArgumentError(weakSelf, index, json, "should be a promise rejecter function");
@ -422,9 +415,9 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
if (RCT_DEBUG) { if (RCT_DEBUG) {
const char *objcType = _invocation.methodSignature.methodReturnType; const char *objcType = _invocation.methodSignature.methodReturnType;
if (_isSync && objcType[0] != _C_ID) if (_methodInfo->isSync && objcType[0] != _C_ID)
RCTLogError(@"Return type of %@.%@ should be (id) as the method is \"sync\"", RCTLogError(@"Return type of %@.%s should be (id) as the method is \"sync\"",
RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName); RCTBridgeModuleNameForClass(_moduleClass), self.JSMethodName);
} }
_argumentBlocks = [argumentBlocks copy]; _argumentBlocks = [argumentBlocks copy];
@ -434,36 +427,41 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
{ {
if (_selector == NULL) { if (_selector == NULL) {
RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"", (@{ @"module": NSStringFromClass(_moduleClass), RCT_PROFILE_BEGIN_EVENT(RCTProfileTagAlways, @"", (@{ @"module": NSStringFromClass(_moduleClass),
@"method": _methodSignature })); @"method": @(_methodInfo->objcName) }));
[self processMethodSignature]; [self processMethodSignature];
RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @""); RCT_PROFILE_END_EVENT(RCTProfileTagAlways, @"");
} }
return _selector; return _selector;
} }
- (NSString *)JSMethodName - (const char *)JSMethodName
{ {
NSString *methodName = _JSMethodName; NSString *methodName = _JSMethodName;
if (methodName.length == 0) { if (!methodName) {
methodName = _methodSignature; const char *jsName = _methodInfo->jsName;
NSRange colonRange = [methodName rangeOfString:@":"]; if (jsName && strlen(jsName) > 0) {
if (colonRange.location != NSNotFound) { methodName = @(jsName);
methodName = [methodName substringToIndex:colonRange.location]; } else {
methodName = @(_methodInfo->objcName);
NSRange colonRange = [methodName rangeOfString:@":"];
if (colonRange.location != NSNotFound) {
methodName = [methodName substringToIndex:colonRange.location];
}
methodName = [methodName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
RCTAssert(methodName.length, @"%s is not a valid JS function name, please"
" supply an alternative using RCT_REMAP_METHOD()", _methodInfo->objcName);
} }
methodName = [methodName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; _JSMethodName = methodName;
RCTAssert(methodName.length, @"%@ is not a valid JS function name, please"
" supply an alternative using RCT_REMAP_METHOD()", _methodSignature);
} }
return methodName; return methodName.UTF8String;
} }
- (RCTFunctionType)functionType - (RCTFunctionType)functionType
{ {
if ([_methodSignature rangeOfString:@"RCTPromise"].length) { if (strstr(_methodInfo->objcName, "RCTPromise") != NULL) {
RCTAssert(!_isSync, @"Promises cannot be used in sync functions"); RCTAssert(!_methodInfo->isSync, @"Promises cannot be used in sync functions");
return RCTFunctionTypePromise; return RCTFunctionTypePromise;
} else if (_isSync) { } else if (_methodInfo->isSync) {
return RCTFunctionTypeSync; return RCTFunctionTypeSync;
} else { } else {
return RCTFunctionTypeNormal; return RCTFunctionTypeNormal;
@ -494,11 +492,11 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
expectedCount -= 2; expectedCount -= 2;
} }
RCTLogError(@"%@.%@ was called with %zd arguments but expects %zd arguments. " RCTLogError(@"%@.%s was called with %zd arguments but expects %zd arguments. "
@"If you haven\'t changed this method yourself, this usually means that " @"If you haven\'t changed this method yourself, this usually means that "
@"your versions of the native code and JavaScript code are out of sync. " @"your versions of the native code and JavaScript code are out of sync. "
@"Updating both should make this error go away.", @"Updating both should make this error go away.",
RCTBridgeModuleNameForClass(_moduleClass), _JSMethodName, RCTBridgeModuleNameForClass(_moduleClass), self.JSMethodName,
actualCount, expectedCount); actualCount, expectedCount);
return nil; return nil;
} }
@ -540,7 +538,7 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
} }
id result = nil; id result = nil;
if (_isSync) { if (_methodInfo->isSync) {
void *pointer; void *pointer;
[_invocation getReturnValue:&pointer]; [_invocation getReturnValue:&pointer];
result = (__bridge id)pointer; result = (__bridge id)pointer;
@ -554,13 +552,12 @@ SEL RCTParseMethodSignature(NSString *methodSignature, NSArray<RCTMethodArgument
if (_selector == NULL) { if (_selector == NULL) {
[self processMethodSignature]; [self processMethodSignature];
} }
return [NSString stringWithFormat:@"-[%@ %@]", _moduleClass, return [NSString stringWithFormat:@"-[%@ %s]", _moduleClass, sel_getName(_selector)];
NSStringFromSelector(_selector)];
} }
- (NSString *)description - (NSString *)description
{ {
return [NSString stringWithFormat:@"<%@: %p; exports %@ as %@(); type: %s>", return [NSString stringWithFormat:@"<%@: %p; exports %@ as %s(); type: %s>",
[self class], self, [self methodName], self.JSMethodName, RCTFunctionDescriptorFromType(self.functionType)]; [self class], self, [self methodName], self.JSMethodName, RCTFunctionDescriptorFromType(self.functionType)];
} }

View File

@ -26,17 +26,31 @@ using namespace facebook::react;
std::unique_ptr<CxxModule::Method> _method; std::unique_ptr<CxxModule::Method> _method;
} }
@synthesize JSMethodName = _JSMethodName;
- (instancetype)initWithCxxMethod:(const CxxModule::Method &)method - (instancetype)initWithCxxMethod:(const CxxModule::Method &)method
{ {
if ((self = [super init])) { if ((self = [super init])) {
_JSMethodName = @(method.name.c_str());
_method = folly::make_unique<CxxModule::Method>(method); _method = folly::make_unique<CxxModule::Method>(method);
} }
return self; return self;
} }
- (const char *)JSMethodName
{
return _method->name.c_str();
}
- (RCTFunctionType)functionType
{
std::string type(_method->getType());
if (type == "sync") {
return RCTFunctionTypeSync;
} else if (type == "async") {
return RCTFunctionTypeNormal;
} else {
return RCTFunctionTypePromise;
}
}
- (id)invokeWithBridge:(RCTBridge *)bridge - (id)invokeWithBridge:(RCTBridge *)bridge
module:(id)module module:(id)module
arguments:(NSArray *)arguments arguments:(NSArray *)arguments
@ -110,16 +124,9 @@ using namespace facebook::react;
} }
} }
- (RCTFunctionType)functionType
{
// TODO: support promise-style APIs
return _method->syncFunc ? RCTFunctionTypeSync : RCTFunctionTypeNormal;
}
- (NSString *)description - (NSString *)description
{ {
return [NSString stringWithFormat:@"<%@: %p; name = %@>", return [NSString stringWithFormat:@"<%@: %p; name = %s>", [self class], self, self.JSMethodName];
[self class], self, self.JSMethodName];
} }
@end @end

View File

@ -38,7 +38,7 @@ std::vector<MethodDescriptor> RCTNativeModule::getMethods() {
for (id<RCTBridgeMethod> method in m_moduleData.methods) { for (id<RCTBridgeMethod> method in m_moduleData.methods) {
descs.emplace_back( descs.emplace_back(
method.JSMethodName.UTF8String, method.JSMethodName,
RCTFunctionDescriptorFromType(method.functionType) RCTFunctionDescriptorFromType(method.functionType)
); );
} }
@ -103,7 +103,7 @@ MethodCallResult RCTNativeModule::invokeInner(unsigned int methodId, const folly
} }
NSString *message = [NSString stringWithFormat: NSString *message = [NSString stringWithFormat:
@"Exception '%@' was thrown while invoking %@ on target %@ with params %@", @"Exception '%@' was thrown while invoking %s on target %@ with params %@",
exception, method.JSMethodName, m_moduleData.name, objcParams]; exception, method.JSMethodName, m_moduleData.name, objcParams];
RCTFatal(RCTErrorWithMessage(message)); RCTFatal(RCTErrorWithMessage(message));
} }

View File

@ -68,6 +68,11 @@ public:
std::function<folly::dynamic(folly::dynamic)> syncFunc; std::function<folly::dynamic(folly::dynamic)> syncFunc;
const char *getType() {
assert(func || syncFunc);
return func ? (callbacks == 2 ? "promise" : "async") : "sync";
}
// std::function/lambda ctors // std::function/lambda ctors
Method(std::string aname, Method(std::string aname,

View File

@ -57,9 +57,7 @@ std::vector<MethodDescriptor> CxxNativeModule::getMethods() {
std::vector<MethodDescriptor> descs; std::vector<MethodDescriptor> descs;
for (auto& method : methods_) { for (auto& method : methods_) {
assert(method.func || method.syncFunc); descs.emplace_back(method.name, method.getType());
auto methodType = method.func ? (method.callbacks == 2 ? "promise" : "async") : "sync";
descs.emplace_back(method.name, methodType);
} }
return descs; return descs;
} }