mirror of
https://github.com/status-im/react-native.git
synced 2025-02-05 06:04:15 +00:00
Implemented lazy parsing of method signatures to improve TTI
This commit is contained in:
parent
57a6a02dff
commit
a5e9f83a0a
@ -162,8 +162,8 @@
|
||||
- (void)testFamilyStyleAndWeight
|
||||
{
|
||||
{
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-UltraLightItalic" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue", @"fontStyle": @"italic", @"fontWeight": @"100"}];
|
||||
UIFont *expected = [UIFont fontWithName:@"HelveticaNeue-LightItalic" size:14];
|
||||
UIFont *result = [RCTConvert UIFont:@{@"fontFamily": @"Helvetica Neue", @"fontStyle": @"italic", @"fontWeight": @"300"}];
|
||||
RCTAssertEqualFonts(expected, result);
|
||||
}
|
||||
{
|
||||
|
@ -63,9 +63,11 @@ static BOOL RCTLogsError(void (^block)(void))
|
||||
// Specifying an NSNumber param without nonnull isn't allowed
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
NSString *methodName = @"doFooWithNumber:(NSNumber *)n";
|
||||
(void)[[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
// Invoke method to trigger parsing
|
||||
[method invokeWithBridge:nil module:self arguments:@[@1]];
|
||||
}));
|
||||
}
|
||||
|
||||
|
@ -88,7 +88,7 @@ RCT_NOT_IMPLEMENTED(-init);
|
||||
[self.methods enumerateObjectsUsingBlock:^(RCTModuleMethod *method, NSUInteger idx, __unused BOOL *stop) {
|
||||
methodconfig[method.JSMethodName] = @{
|
||||
@"methodID": @(idx),
|
||||
@"type": method.functionKind == RCTJavaScriptFunctionKindAsync ? @"remoteAsync" : @"remote",
|
||||
@"type": method.functionType == RCTFunctionTypePromise ? @"remoteAsync" : @"remote",
|
||||
};
|
||||
}];
|
||||
config[@"methods"] = [methodconfig copy];
|
||||
|
@ -11,9 +11,9 @@
|
||||
|
||||
@class RCTBridge;
|
||||
|
||||
typedef NS_ENUM(NSUInteger, RCTJavaScriptFunctionKind) {
|
||||
RCTJavaScriptFunctionKindNormal,
|
||||
RCTJavaScriptFunctionKindAsync,
|
||||
typedef NS_ENUM(NSUInteger, RCTFunctionType) {
|
||||
RCTFunctionTypeNormal,
|
||||
RCTFunctionTypePromise,
|
||||
};
|
||||
|
||||
typedef NS_ENUM(NSUInteger, RCTNullability) {
|
||||
@ -35,7 +35,7 @@ typedef NS_ENUM(NSUInteger, RCTNullability) {
|
||||
@property (nonatomic, copy, readonly) NSString *JSMethodName;
|
||||
@property (nonatomic, readonly) Class moduleClass;
|
||||
@property (nonatomic, readonly) SEL selector;
|
||||
@property (nonatomic, readonly) RCTJavaScriptFunctionKind functionKind;
|
||||
@property (nonatomic, readonly) RCTFunctionType functionType;
|
||||
|
||||
- (instancetype)initWithObjCMethodName:(NSString *)objCMethodName
|
||||
JSMethodName:(NSString *)JSMethodName
|
||||
|
@ -46,9 +46,10 @@ typedef void (^RCTArgumentBlock)(RCTBridge *, NSUInteger, id);
|
||||
@implementation RCTModuleMethod
|
||||
{
|
||||
Class _moduleClass;
|
||||
SEL _selector;
|
||||
NSInvocation *_invocation;
|
||||
NSArray *_argumentBlocks;
|
||||
NSString *_objCMethodName;
|
||||
SEL _selector;
|
||||
}
|
||||
|
||||
static void RCTLogArgumentError(RCTModuleMethod *method, NSUInteger index,
|
||||
@ -117,13 +118,8 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
{
|
||||
if ((self = [super init])) {
|
||||
|
||||
NSArray *arguments;
|
||||
RCTParseObjCMethodName(&objCMethodName, &arguments);
|
||||
|
||||
_moduleClass = moduleClass;
|
||||
_selector = NSSelectorFromString(objCMethodName);
|
||||
RCTAssert(_selector, @"%@ is not a valid selector", objCMethodName);
|
||||
|
||||
_objCMethodName = [objCMethodName copy];
|
||||
_JSMethodName = JSMethodName.length > 0 ? JSMethodName : ({
|
||||
NSString *methodName = objCMethodName;
|
||||
NSRange colonRange = [methodName rangeOfString:@":"];
|
||||
@ -135,6 +131,25 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
methodName;
|
||||
});
|
||||
|
||||
if ([_objCMethodName rangeOfString:@"RCTPromise"].length) {
|
||||
_functionType = RCTFunctionTypePromise;
|
||||
} else {
|
||||
_functionType = RCTFunctionTypeNormal;
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)processMethodSignature
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *objCMethodName = _objCMethodName;
|
||||
RCTParseObjCMethodName(&objCMethodName, &arguments);
|
||||
|
||||
_selector = NSSelectorFromString(objCMethodName);
|
||||
RCTAssert(_selector, @"%@ is not a valid selector", objCMethodName);
|
||||
|
||||
// Create method invocation
|
||||
NSMethodSignature *methodSignature = [_moduleClass instanceMethodSignatureForSelector:_selector];
|
||||
RCTAssert(methodSignature, @"%@ is not a recognized Objective-C method.", objCMethodName);
|
||||
@ -148,10 +163,10 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
NSMutableArray *argumentBlocks = [[NSMutableArray alloc] initWithCapacity:numberOfArguments - 2];
|
||||
|
||||
#define RCT_ARG_BLOCK(_logic) \
|
||||
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) { \
|
||||
[argumentBlocks addObject:^(__unused RCTBridge *bridge, NSUInteger index, id json) { \
|
||||
_logic \
|
||||
[invocation setArgument:&value atIndex:(index) + 2]; \
|
||||
}];
|
||||
}];
|
||||
|
||||
__weak RCTModuleMethod *weakSelf = self;
|
||||
void (^addBlockArgument)(void) = ^{
|
||||
@ -280,7 +295,6 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
arguments:@[json, result ? @[result] : @[]]];
|
||||
});
|
||||
)
|
||||
_functionKind = RCTJavaScriptFunctionKindAsync;
|
||||
} else if ([typeName isEqualToString:@"RCTPromiseRejectBlock"]) {
|
||||
RCTAssert(i == numberOfArguments - 1,
|
||||
@"The RCTPromiseRejectBlock must be the last parameter in -[%@ %@]",
|
||||
@ -299,7 +313,6 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
arguments:@[json, @[errorJSON]]];
|
||||
});
|
||||
)
|
||||
_functionKind = RCTJavaScriptFunctionKindAsync;
|
||||
} else {
|
||||
|
||||
// Unknown argument type
|
||||
@ -350,15 +363,24 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
}
|
||||
|
||||
_argumentBlocks = [argumentBlocks copy];
|
||||
}
|
||||
}
|
||||
|
||||
return self;
|
||||
- (SEL)selector
|
||||
{
|
||||
if (_selector == NULL) {
|
||||
[self processMethodSignature];
|
||||
}
|
||||
return _selector;
|
||||
}
|
||||
|
||||
- (void)invokeWithBridge:(RCTBridge *)bridge
|
||||
module:(id)module
|
||||
arguments:(NSArray *)arguments
|
||||
{
|
||||
if (_argumentBlocks == nil) {
|
||||
[self processMethodSignature];
|
||||
}
|
||||
|
||||
if (RCT_DEBUG) {
|
||||
|
||||
// Sanity check
|
||||
@ -371,7 +393,7 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
NSInteger expectedCount = _argumentBlocks.count;
|
||||
|
||||
// Subtract the implicit Promise resolver and rejecter functions for implementations of async functions
|
||||
if (_functionKind == RCTJavaScriptFunctionKindAsync) {
|
||||
if (_functionType == RCTFunctionTypePromise) {
|
||||
actualCount -= 2;
|
||||
expectedCount -= 2;
|
||||
}
|
||||
@ -398,6 +420,9 @@ void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **arguments)
|
||||
|
||||
- (NSString *)methodName
|
||||
{
|
||||
if (_selector == NULL) {
|
||||
[self processMethodSignature];
|
||||
}
|
||||
return [NSString stringWithFormat:@"-[%@ %@]", _moduleClass,
|
||||
NSStringFromSelector(_selector)];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user