Fixed method invoke when both nullable and __unused exist (#23726)

Summary:
We have parse code to try to support exported method parameter annotated `__unused` and `nullable`, but actually, seems we don't support it entirely, for example, we parse `__unused` firstly, then we parse `nullable`, actually, this case not exist, because `nullable` macro must appear right after `(`, before `__unused`, so we can't parse success, leads to error signature and crash.

[iOS] [Fixed] - Fixed method invoke when both nullable and __unused exist
Pull Request resolved: https://github.com/facebook/react-native/pull/23726

Differential Revision: D14298563

Pulled By: cpojer

fbshipit-source-id: 934e1d384a5d67b7bbf117fd2dec51f50979c979
This commit is contained in:
zhongwuzw 2019-03-03 20:36:55 -08:00 коммит произвёл Facebook Github Bot
Родитель 1ed2b82693
Коммит 17ae61e14c
1 изменённых файлов: 23 добавлений и 6 удалений

Просмотреть файл

@ -90,8 +90,8 @@ static BOOL RCTParseSelectorPart(const char **input, NSMutableString *selector)
static BOOL RCTParseUnused(const char **input)
{
return RCTReadString(input, "__unused") ||
RCTReadString(input, "__attribute__((unused))");
return RCTReadString(input, "__attribute__((unused))") ||
RCTReadString(input, "__unused");
}
static RCTNullability RCTParseNullability(const char **input)
@ -145,16 +145,33 @@ NSString *RCTParseMethodSignature(const char *input, NSArray<RCTMethodArgument *
if (RCTReadChar(&input, '(')) {
RCTSkipWhitespace(&input);
BOOL unused = RCTParseUnused(&input);
// 5 cases that both nullable and __unused exist
// 1: foo:(nullable __unused id)foo 2: foo:(nullable id __unused)foo
// 3: foo:(__unused id _Nullable)foo 4: foo:(id __unused _Nullable)foo
// 5: foo:(id _Nullable __unused)foo
RCTNullability nullability = RCTParseNullability(&input);
RCTSkipWhitespace(&input);
RCTNullability nullability = RCTParseNullability(&input);
BOOL unused = RCTParseUnused(&input);
RCTSkipWhitespace(&input);
NSString *type = RCTParseType(&input);
RCTSkipWhitespace(&input);
if (nullability == RCTNullabilityUnspecified) {
nullability = RCTParseNullabilityPostfix(&input);
RCTSkipWhitespace(&input);
if (!unused) {
unused = RCTParseUnused(&input);
RCTSkipWhitespace(&input);
if (unused && nullability == RCTNullabilityUnspecified) {
nullability = RCTParseNullabilityPostfix(&input);
RCTSkipWhitespace(&input);
}
}
} else if (!unused) {
unused = RCTParseUnused(&input);
RCTSkipWhitespace(&input);
}
[args addObject:[[RCTMethodArgument alloc] initWithType:type
nullability:nullability