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:
Nick Lockwood
2015-12-10 10:09:04 -08:00
committed by facebook-github-bot-4
parent ce7c0b735f
commit 88ac40666c
20 changed files with 413 additions and 170 deletions

View File

@@ -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");