@@ -219,20 +219,22 @@ @implementation RCTModuleMethod
219219
220220static Class _globalExecutorClass;
221221
222- NS_INLINE NSString *RCTStringUpToFirstArgument (NSString *methodName) {
222+ static NSString *RCTStringUpToFirstArgument (NSString *methodName)
223+ {
223224 NSRange colonRange = [methodName rangeOfString: @" :" ];
224225 if (colonRange.length ) {
225226 methodName = [methodName substringToIndex: colonRange.location];
226227 }
227228 return methodName;
228229}
229230
230- - (instancetype )initWithMethodName : (NSString *)methodName
231- JSMethodName : (NSString *)JSMethodName
231+ - (instancetype )initWithReactMethodName : (NSString *)reactMethodName
232+ objCMethodName : (NSString *)objCMethodName
233+ JSMethodName : (NSString *)JSMethodName
232234{
233235 if ((self = [super init ])) {
234- _methodName = methodName ;
235- NSArray *parts = [[methodName substringWithRange: (NSRange ){2 , methodName .length - 3 }] componentsSeparatedByString: @" " ];
236+ _methodName = reactMethodName ;
237+ NSArray *parts = [[reactMethodName substringWithRange: (NSRange ){2 , reactMethodName .length - 3 }] componentsSeparatedByString: @" " ];
236238
237239 // Parse class and method
238240 _moduleClassName = parts[0 ];
@@ -246,7 +248,7 @@ - (instancetype)initWithMethodName:(NSString *)methodName
246248 // New format
247249 NSString *selectorString = [parts[1 ] substringFromIndex: 14 ];
248250 _selector = NSSelectorFromString (selectorString);
249- _JSMethodName = RCTStringUpToFirstArgument (selectorString);
251+ _JSMethodName = JSMethodName ?: RCTStringUpToFirstArgument (selectorString);
250252
251253 static NSRegularExpression *regExp;
252254 if (!regExp) {
@@ -258,8 +260,8 @@ - (instancetype)initWithMethodName:(NSString *)methodName
258260 }
259261
260262 argumentNames = [NSMutableArray array ];
261- [regExp enumerateMatchesInString: JSMethodName options: 0 range: NSMakeRange (0 , JSMethodName .length) usingBlock: ^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
262- NSString *argumentName = [JSMethodName substringWithRange: [result rangeAtIndex: 1 ]];
263+ [regExp enumerateMatchesInString: objCMethodName options: 0 range: NSMakeRange (0 , objCMethodName .length) usingBlock: ^(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop) {
264+ NSString *argumentName = [objCMethodName substringWithRange: [result rangeAtIndex: 1 ]];
263265 [(NSMutableArray *)argumentNames addObject: argumentName];
264266 }];
265267 } else {
@@ -270,14 +272,15 @@ - (instancetype)initWithMethodName:(NSString *)methodName
270272 }
271273
272274 // Extract class and method details
273- _isClassMethod = [methodName characterAtIndex: 0 ] == ' +' ;
275+ _isClassMethod = [reactMethodName characterAtIndex: 0 ] == ' +' ;
274276 _moduleClass = NSClassFromString (_moduleClassName);
275277
276278#if DEBUG
279+
277280 // Sanity check
278281 RCTAssert ([_moduleClass conformsToProtocol: @protocol (RCTBridgeModule)],
279282 @" You are attempting to export the method %@ , but %@ does not \
280- conform to the RCTBridgeModule Protocol" , methodName , _moduleClassName);
283+ conform to the RCTBridgeModule Protocol" , objCMethodName , _moduleClassName);
281284#endif
282285
283286 // Get method signature
@@ -290,26 +293,26 @@ - (instancetype)initWithMethodName:(NSString *)methodName
290293 NSMutableArray *argumentBlocks = [[NSMutableArray alloc ] initWithCapacity: numberOfArguments - 2 ];
291294
292295#define RCT_ARG_BLOCK (_logic ) \
293- [argumentBlocks addObject: ^(RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
294- _logic \
295- [invocation setArgument: &value atIndex: index]; \
296- }]; \
296+ [argumentBlocks addObject: ^(RCTBridge *bridge, NSInvocation *invocation, NSUInteger index, id json) { \
297+ _logic \
298+ [invocation setArgument: &value atIndex: index]; \
299+ }]; \
297300
298301 void (^addBlockArgument)(void ) = ^{
299302 RCT_ARG_BLOCK (
300- if (json && ![json isKindOfClass: [NSNumber class ]]) {
301- RCTLogError (@" Argument %tu (%@ ) of %@ .%@ should be a number" , index,
302- json, RCTBridgeModuleNameForClass (_moduleClass), _JSMethodName);
303- return ;
304- }
305-
306- // Marked as autoreleasing, because NSInvocation doesn't retain arguments
307- __autoreleasing id value = (json ? ^(NSArray *args) {
308- [bridge _invokeAndProcessModule: @" BatchedBridge"
309- method: @" invokeCallbackAndReturnFlushedQueue"
310- arguments: @[json, args]];
311- } : ^(NSArray *unused) {});
312- )
303+ if (json && ![json isKindOfClass: [NSNumber class ]]) {
304+ RCTLogError (@" Argument %tu (%@ ) of %@ .%@ should be a number" , index,
305+ json, RCTBridgeModuleNameForClass (_moduleClass), _JSMethodName);
306+ return ;
307+ }
308+
309+ // Marked as autoreleasing, because NSInvocation doesn't retain arguments
310+ __autoreleasing id value = (json ? ^(NSArray *args) {
311+ [bridge _invokeAndProcessModule: @" BatchedBridge"
312+ method: @" invokeCallbackAndReturnFlushedQueue"
313+ arguments: @[json, args]];
314+ } : ^(NSArray *unused) {});
315+ )
313316 };
314317
315318 void (^defaultCase)(const char *) = ^(const char *argumentType) {
@@ -333,11 +336,11 @@ - (instancetype)initWithMethodName:(NSString *)methodName
333336 switch (argumentType[0 ]) {
334337
335338#define RCT_CONVERT_CASE (_value, _type ) \
336- case _value: { \
337- _type (*convert)(id , SEL , id ) = (typeof (convert))[RCTConvert methodForSelector: selector]; \
338- RCT_ARG_BLOCK ( _type value = convert ([RCTConvert class ], selector, json); ) \
339- break ; \
340- }
339+ case _value: { \
340+ _type (*convert)(id , SEL , id ) = (typeof (convert))[RCTConvert methodForSelector: selector]; \
341+ RCT_ARG_BLOCK ( _type value = convert ([RCTConvert class ], selector, json); ) \
342+ break ; \
343+ }
341344
342345 RCT_CONVERT_CASE (' :' , SEL )
343346 RCT_CONVERT_CASE (' *' , const char *)
@@ -371,33 +374,33 @@ - (instancetype)initWithMethodName:(NSString *)methodName
371374 switch (argumentType[0 ]) {
372375
373376#define RCT_CASE (_value, _class, _logic ) \
374- case _value: { \
375- RCT_ARG_BLOCK ( \
376- if (json && ![json isKindOfClass: [_class class ]]) { \
377- RCTLogError (@" Argument %tu (%@ ) of %@ .%@ should be of type %@ " , index, \
378- json, RCTBridgeModuleNameForClass (_moduleClass), _JSMethodName, [_class class ]); \
379- return ; \
380- } \
381- _logic \
382- ) \
383- break ; \
384- }
377+ case _value: { \
378+ RCT_ARG_BLOCK ( \
379+ if (json && ![json isKindOfClass: [_class class ]]) { \
380+ RCTLogError (@" Argument %tu (%@ ) of %@ .%@ should be of type %@ " , index, \
381+ json, RCTBridgeModuleNameForClass (_moduleClass), _JSMethodName, [_class class ]); \
382+ return ; \
383+ } \
384+ _logic \
385+ ) \
386+ break ; \
387+ }
385388
386389 RCT_CASE (' :' , NSString , SEL value = NSSelectorFromString (json); )
387390 RCT_CASE (' *' , NSString , const char *value = [json UTF8String ]; )
388391
389392#define RCT_SIMPLE_CASE (_value, _type, _selector ) \
390- case _value: { \
391- RCT_ARG_BLOCK ( \
392- if (json && ![json respondsToSelector: @selector (_selector )]) { \
393- RCTLogError (@" Argument %tu (%@ ) of %@ .%@ does not respond to selector: %@ " , \
394- index, json, RCTBridgeModuleNameForClass (_moduleClass), _JSMethodName, @#_selector); \
395- return ; \
396- } \
397- _type value = [json _selector ]; \
398- ) \
399- break ; \
400- }
393+ case _value: { \
394+ RCT_ARG_BLOCK ( \
395+ if (json && ![json respondsToSelector: @selector (_selector )]) { \
396+ RCTLogError (@" Argument %tu (%@ ) of %@ .%@ does not respond to selector: %@ " , \
397+ index, json, RCTBridgeModuleNameForClass (_moduleClass), _JSMethodName, @#_selector); \
398+ return ; \
399+ } \
400+ _type value = [json _selector ]; \
401+ ) \
402+ break ; \
403+ }
401404
402405 RCT_SIMPLE_CASE (' c' , char , charValue)
403406 RCT_SIMPLE_CASE (' C' , unsigned char , unsignedCharValue)
@@ -432,6 +435,7 @@ - (void)invokeWithBridge:(RCTBridge *)bridge
432435{
433436
434437#if DEBUG
438+
435439 // Sanity check
436440 RCTAssert ([module class ] == _moduleClass, @" Attempted to invoke method \
437441 %@ on a module of class %@ " , _methodName, [module class ]);
@@ -496,15 +500,24 @@ - (NSString *)description
496500
497501 for (RCTHeaderValue addr = section->offset ;
498502 addr < section->offset + section->size ;
499- addr += sizeof (const char **) * 2 ) {
503+ addr += sizeof (const char **) * 3 ) {
500504
501505 // Get data entry
502506 const char **entries = (const char **)(mach_header + addr);
503507
504508 // Create method
505- RCTModuleMethod *moduleMethod =
506- [[RCTModuleMethod alloc ] initWithMethodName: @(entries[0 ])
507- JSMethodName: strlen (entries[1 ]) ? @(entries[1 ]) : nil ];
509+ RCTModuleMethod *moduleMethod;
510+ if (entries[2 ] == NULL ) {
511+
512+ // Legacy support for RCT_EXPORT()
513+ moduleMethod = [[RCTModuleMethod alloc ] initWithReactMethodName: @(entries[0 ])
514+ objCMethodName: @(entries[0 ])
515+ JSMethodName: strlen (entries[1 ]) ? @(entries[1 ]) : nil ];
516+ } else {
517+ moduleMethod = [[RCTModuleMethod alloc ] initWithReactMethodName: @(entries[0 ])
518+ objCMethodName: strlen (entries[1 ]) ? @(entries[1 ]) : nil
519+ JSMethodName: strlen (entries[2 ]) ? @(entries[2 ]) : nil ];
520+ }
508521
509522 // Cache method
510523 NSArray *methods = methodsByModuleClassName[moduleMethod.moduleClassName];
@@ -560,15 +573,15 @@ - (NSString *)description
560573 NSMutableDictionary *methodsByName = [NSMutableDictionary dictionaryWithCapacity: methods.count];
561574 [methods enumerateObjectsUsingBlock: ^(RCTModuleMethod *method, NSUInteger methodID, BOOL *_stop) {
562575 methodsByName[method.JSMethodName] = @{
563- @" methodID" : @(methodID),
564- @" type" : @" remote" ,
565- };
576+ @" methodID" : @(methodID),
577+ @" type" : @" remote" ,
578+ };
566579 }];
567580
568581 NSDictionary *module = @{
569- @" moduleID" : @(moduleID),
570- @" methods" : methodsByName
571- };
582+ @" moduleID" : @(moduleID),
583+ @" methods" : methodsByName
584+ };
572585
573586 remoteModuleConfigByClassName[NSStringFromClass (moduleClass)] = module;
574587 }];
@@ -639,9 +652,9 @@ - (NSString *)description
639652 NSDictionary *module = localModules[moduleName];
640653 if (!module) {
641654 module = @{
642- @" moduleID" : @(localModules.count ),
643- @" methods" : [[NSMutableDictionary alloc ] init ]
644- };
655+ @" moduleID" : @(localModules.count ),
656+ @" methods" : [[NSMutableDictionary alloc ] init ]
657+ };
645658 localModules[moduleName] = module;
646659 }
647660
@@ -650,9 +663,9 @@ - (NSString *)description
650663 NSMutableDictionary *methods = module[@" methods" ];
651664 if (!methods[methodName]) {
652665 methods[methodName] = @{
653- @" methodID" : @(methods.count ),
654- @" type" : @" local"
655- };
666+ @" methodID" : @(methods.count ),
667+ @" type" : @" local"
668+ };
656669 }
657670
658671 // Add module and method lookup
@@ -741,9 +754,9 @@ - (void)setUp
741754
742755 // Inject module data into JS context
743756 NSString *configJSON = RCTJSONStringify (@{
744- @" remoteModuleConfig" : RCTRemoteModulesConfig (_modulesByName),
745- @" localModulesConfig" : RCTLocalModulesConfig ()
746- }, NULL );
757+ @" remoteModuleConfig" : RCTRemoteModulesConfig (_modulesByName),
758+ @" localModulesConfig" : RCTLocalModulesConfig ()
759+ }, NULL );
747760 dispatch_semaphore_t semaphore = dispatch_semaphore_create (0 );
748761 [_javaScriptExecutor injectJSONText: configJSON
749762 asGlobalObjectNamed: @" __fbBatchedBridgeConfig" callback: ^(id err) {
0 commit comments