Replace exported method registration with statically allocated struct
Reviewed By: fromcelticpark Differential Revision: D5389383 fbshipit-source-id: 9eb29b254b616574966b43ad24aa880d44589652
This commit is contained in:
parent
d94f3e4b98
commit
cb12080179
|
@ -18,8 +18,9 @@
|
||||||
#define RCT_RUN_RUNLOOP_WHILE(CONDITION) \
|
#define RCT_RUN_RUNLOOP_WHILE(CONDITION) \
|
||||||
{ \
|
{ \
|
||||||
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:5]; \
|
NSDate *timeout = [NSDate dateWithTimeIntervalSinceNow:5]; \
|
||||||
|
NSRunLoop *runloop = [NSRunLoop mainRunLoop]; \
|
||||||
while ((CONDITION)) { \
|
while ((CONDITION)) { \
|
||||||
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]]; \
|
[runloop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.01]]; \
|
||||||
if ([timeout timeIntervalSinceNow] <= 0) { \
|
if ([timeout timeIntervalSinceNow] <= 0) { \
|
||||||
XCTFail(@"Runloop timed out before condition was met"); \
|
XCTFail(@"Runloop timed out before condition was met"); \
|
||||||
break; \
|
break; \
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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 =
|
|
||||||
[[RCTModuleMethod alloc] initWithMethodSignature:entries[1]
|
|
||||||
JSMethodName:entries[0]
|
|
||||||
isSync:((NSNumber *)entries[2]).boolValue
|
|
||||||
moduleClass:_moduleClass];
|
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 = @[
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
|
||||||
isSync:(BOOL)isSync
|
|
||||||
moduleClass:(Class)moduleClass
|
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;
|
||||||
|
if (jsName && strlen(jsName) > 0) {
|
||||||
|
methodName = @(jsName);
|
||||||
|
} else {
|
||||||
|
methodName = @(_methodInfo->objcName);
|
||||||
NSRange colonRange = [methodName rangeOfString:@":"];
|
NSRange colonRange = [methodName rangeOfString:@":"];
|
||||||
if (colonRange.location != NSNotFound) {
|
if (colonRange.location != NSNotFound) {
|
||||||
methodName = [methodName substringToIndex:colonRange.location];
|
methodName = [methodName substringToIndex:colonRange.location];
|
||||||
}
|
}
|
||||||
methodName = [methodName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
methodName = [methodName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
|
||||||
RCTAssert(methodName.length, @"%@ is not a valid JS function name, please"
|
RCTAssert(methodName.length, @"%s is not a valid JS function name, please"
|
||||||
" supply an alternative using RCT_REMAP_METHOD()", _methodSignature);
|
" supply an alternative using RCT_REMAP_METHOD()", _methodInfo->objcName);
|
||||||
}
|
}
|
||||||
return methodName;
|
_JSMethodName = 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)];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue