mirror of
https://github.com/zhigang1992/react-native.git
synced 2026-02-09 09:12:06 +08:00
Replaced RegExp method parser with recursive descent
Summary: public This diff replaces the RegEx module method parser with a handwritten recursive descent parser that's faster and easier to maintain. The new parser is ~8 times faster when tested on the UIManager.managerChildren() method, and uses ~1/10 as much RAM. The new parser also supports lightweight generics, and is more tolerant of white space. (This means that you now can – and should – use types like `NSArray<NSString *> *` for your exported properties and method arguments, instead of `NSStringArray`). Reviewed By: jspahrsummers Differential Revision: D2736636 fb-gh-sync-id: f6a11431935fa8acc8ac36f3471032ec9a1c8490
This commit is contained in:
committed by
facebook-github-bot-4
parent
ce7c0b735f
commit
88ac40666c
@@ -132,7 +132,7 @@ RCT_EXPORT_METHOD(test:(__unused NSString *)a
|
||||
{
|
||||
__weak RCTModuleMethod *weakMethod;
|
||||
@autoreleasepool {
|
||||
__autoreleasing RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:@"test:(NSString *)a :(nonnull NSNumber *)b :(RCTResponseSenderBlock)c :(RCTResponseErrorBlock)d" JSMethodName:@"" moduleClass:[AllocationTestModule class]];
|
||||
__autoreleasing RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithMethodSignature:@"test:(NSString *)a :(nonnull NSNumber *)b :(RCTResponseSenderBlock)c :(RCTResponseErrorBlock)d" JSMethodName:@"" moduleClass:[AllocationTestModule class]];
|
||||
weakMethod = method;
|
||||
XCTAssertNotNil(method, @"RCTModuleMethod should have been created");
|
||||
}
|
||||
|
||||
@@ -23,14 +23,14 @@
|
||||
|
||||
@implementation RCTMethodArgumentTests
|
||||
|
||||
extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes);
|
||||
extern SEL RCTParseMethodSignature(NSString *methodSignature, NSArray **argTypes);
|
||||
|
||||
- (void)testOneArgument
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo:(NSInteger)foo";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:");
|
||||
NSString *methodSignature = @"foo:(NSInteger)foo";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)1);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSInteger");
|
||||
}
|
||||
@@ -38,9 +38,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testTwoArguments
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo:(NSInteger)foo bar:(BOOL)bar";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:bar:");
|
||||
NSString *methodSignature = @"foo:(NSInteger)foo bar:(BOOL)bar";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)2);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSInteger");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"BOOL");
|
||||
@@ -49,9 +49,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testSpaces
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo : (NSInteger)foo bar : (BOOL) bar";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:bar:");
|
||||
NSString *methodSignature = @"foo : (NSInteger)foo bar : (BOOL) bar";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)2);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSInteger");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"BOOL");
|
||||
@@ -60,9 +60,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testNewlines
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo : (NSInteger)foo\nbar : (BOOL) bar";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:bar:");
|
||||
NSString *methodSignature = @"foo : (NSInteger)foo\nbar : (BOOL) bar";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)2);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSInteger");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"BOOL");
|
||||
@@ -71,9 +71,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testUnnamedArgs
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo:(NSInteger)foo:(BOOL)bar";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo::");
|
||||
NSString *methodSignature = @"foo:(NSInteger)foo:(BOOL)bar";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo::");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)2);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSInteger");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"BOOL");
|
||||
@@ -82,9 +82,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testUntypedUnnamedArgs
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo:foo:bar:bar";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:::");
|
||||
NSString *methodSignature = @"foo:foo:bar:bar";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:::");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)3);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"id");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"id");
|
||||
@@ -94,9 +94,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testAttributes
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo:(__attribute__((nonnull)) NSString *)foo bar:(__unused BOOL)bar";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:bar:");
|
||||
NSString *methodSignature = @"foo:(__attribute__((unused)) NSString *)foo bar:(__unused BOOL)bar";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)2);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSString");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"BOOL");
|
||||
@@ -105,9 +105,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testNullability
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo:(nullable NSString *)foo bar:(nonnull NSNumber *)bar baz:(id)baz";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:bar:baz:");
|
||||
NSString *methodSignature = @"foo:(nullable NSString *)foo bar:(nonnull NSNumber *)bar baz:(id)baz";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:baz:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)3);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSString");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"NSNumber");
|
||||
@@ -120,9 +120,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testSemicolonStripping
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo:(NSString *)foo bar:(BOOL)bar;";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:bar:");
|
||||
NSString *methodSignature = @"foo:(NSString *)foo bar:(BOOL)bar;";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)2);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSString");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"BOOL");
|
||||
@@ -131,9 +131,9 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
- (void)testUnused
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodName = @"foo:(__unused NSString *)foo bar:(NSNumber *)bar";
|
||||
RCTParseObjCMethodName(&methodName, &arguments);
|
||||
XCTAssertEqualObjects(methodName, @"foo:bar:");
|
||||
NSString *methodSignature = @"foo:(__unused NSString *)foo bar:(NSNumber *)bar";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:bar:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)2);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSString");
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[1]).type, @"NSNumber");
|
||||
@@ -141,4 +141,44 @@ extern void RCTParseObjCMethodName(NSString **objCMethodName, NSArray **argTypes
|
||||
XCTAssertFalse(((RCTMethodArgument *)arguments[1]).unused);
|
||||
}
|
||||
|
||||
- (void)testGenericArray
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodSignature = @"foo:(NSArray<NSString *> *)foo;";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)1);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSStringArray");
|
||||
}
|
||||
|
||||
- (void)testNestedGenericArray
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodSignature = @"foo:(NSArray<NSArray<NSString *> *> *)foo;";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)1);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSStringArrayArray");
|
||||
}
|
||||
|
||||
- (void)testGenericSet
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodSignature = @"foo:(NSSet<NSNumber *> *)foo;";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)1);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSNumberSet");
|
||||
}
|
||||
|
||||
- (void)testGenericDictionary
|
||||
{
|
||||
NSArray *arguments;
|
||||
NSString *methodSignature = @"foo:(NSDictionary<NSString *, NSNumber *> *)foo;";
|
||||
SEL selector = RCTParseMethodSignature(methodSignature, &arguments);
|
||||
XCTAssertEqualObjects(NSStringFromSelector(selector), @"foo:");
|
||||
XCTAssertEqual(arguments.count, (NSUInteger)1);
|
||||
XCTAssertEqualObjects(((RCTMethodArgument *)arguments[0]).type, @"NSNumberDictionary");
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@@ -47,10 +47,10 @@ static BOOL RCTLogsError(void (^block)(void))
|
||||
|
||||
- (void)testNonnull
|
||||
{
|
||||
NSString *methodName = @"doFooWithBar:(nonnull NSString *)bar";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
NSString *methodSignature = @"doFooWithBar:(nonnull NSString *)bar";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[@"Hello World"]];
|
||||
}));
|
||||
@@ -72,40 +72,40 @@ static BOOL RCTLogsError(void (^block)(void))
|
||||
{
|
||||
// Specifying an NSNumber param without nonnull isn't allowed
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
NSString *methodName = @"doFooWithNumber:(NSNumber *)n";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
NSString *methodSignature = @"doFooWithNumber:(NSNumber *)n";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
// Invoke method to trigger parsing
|
||||
[method invokeWithBridge:nil module:self arguments:@[@1]];
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
NSString *methodName = @"doFooWithNumber:(nonnull NSNumber *)n";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
NSString *methodSignature = @"doFooWithNumber:(nonnull NSNumber *)n";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
NSString *methodName = @"doFooWithDouble:(double)n";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
NSString *methodSignature = @"doFooWithDouble:(double)n";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
|
||||
}));
|
||||
}
|
||||
|
||||
{
|
||||
NSString *methodName = @"doFooWithInteger:(NSInteger)n";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
NSString *methodSignature = @"doFooWithInteger:(NSInteger)n";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
XCTAssertTrue(RCTLogsError(^{
|
||||
[method invokeWithBridge:nil module:self arguments:@[[NSNull null]]];
|
||||
}));
|
||||
@@ -114,10 +114,10 @@ static BOOL RCTLogsError(void (^block)(void))
|
||||
|
||||
- (void)testStructArgument
|
||||
{
|
||||
NSString *methodName = @"doFooWithCGRect:(CGRect)s";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
NSString *methodSignature = @"doFooWithCGRect:(CGRect)s";
|
||||
RCTModuleMethod *method = [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
|
||||
CGRect r = CGRectMake(10, 20, 30, 40);
|
||||
[method invokeWithBridge:nil module:self arguments:@[@[@10, @20, @30, @40]]];
|
||||
@@ -126,13 +126,13 @@ static BOOL RCTLogsError(void (^block)(void))
|
||||
|
||||
- (void)testWhitespaceTolerance
|
||||
{
|
||||
NSString *methodName = @"doFoo : \t (NSString *)foo";
|
||||
NSString *methodSignature = @"doFoo : \t (NSString *)foo";
|
||||
|
||||
__block RCTModuleMethod *method;
|
||||
XCTAssertFalse(RCTLogsError(^{
|
||||
method = [[RCTModuleMethod alloc] initWithObjCMethodName:methodName
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
method = [[RCTModuleMethod alloc] initWithMethodSignature:methodSignature
|
||||
JSMethodName:nil
|
||||
moduleClass:[self class]];
|
||||
}));
|
||||
|
||||
XCTAssertEqualObjects(method.JSMethodName, @"doFoo");
|
||||
|
||||
Reference in New Issue
Block a user