Skip to content

Commit a066e2c

Browse files
jensjohaCommit Bot
authored and
Commit Bot
committed
[parser] Don't be overly aggressive when parsing 'on' in 'try'
Fixes #47541 Change-Id: Idb25f86801b14f75fe7bc06e5496c6fdd2cbe971 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/230243 Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent c28e52c commit a066e2c

File tree

64 files changed

+3101
-3
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

64 files changed

+3101
-3
lines changed

pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7488,19 +7488,33 @@ class Parser {
74887488

74897489
String? value = token.stringValue;
74907490
while (identical(value, 'catch') || identical(value, 'on')) {
7491-
listener.beginCatchClause(token);
7491+
bool didBeginCatchClause = false;
74927492
Token? onKeyword = null;
74937493
if (identical(value, 'on')) {
74947494
// 'on' type catchPart?
74957495
onKeyword = token;
7496-
lastConsumed = computeType(token, /* required = */ true)
7497-
.ensureTypeNotVoid(token, this);
7496+
TypeInfo typeInfo = computeType(token, /* required = */ true);
7497+
if (catchCount > 0 && (typeInfo == noType || typeInfo.recovered)) {
7498+
// Not a valid on-clause and we have enough catch counts to be a valid
7499+
// try block already.
7500+
// This could for instance be code like `on([...])` or `on = 42` after
7501+
// some actual catch/on as that could be a valid method call, local
7502+
// function, assignment etc.
7503+
break;
7504+
}
7505+
listener.beginCatchClause(token);
7506+
didBeginCatchClause = true;
7507+
lastConsumed = typeInfo.ensureTypeNotVoid(token, this);
74987508
token = lastConsumed.next!;
74997509
value = token.stringValue;
75007510
}
75017511
Token? catchKeyword = null;
75027512
Token? comma = null;
75037513
if (identical(value, 'catch')) {
7514+
if (!didBeginCatchClause) {
7515+
listener.beginCatchClause(token);
7516+
didBeginCatchClause = true;
7517+
}
75047518
catchKeyword = token;
75057519

75067520
Token openParens = catchKeyword.next!;
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
void main() {
2+
try {
3+
;
4+
} catch (e) {
5+
;
6+
} on Foo {
7+
;
8+
}
9+
10+
on();
11+
}
12+
13+
void on() {}
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
beginCompilationUnit(void)
2+
beginMetadataStar(void)
3+
endMetadataStar(0)
4+
beginTopLevelMember(void)
5+
beginTopLevelMethod(, null)
6+
handleVoidKeyword(void)
7+
handleIdentifier(main, topLevelFunctionDeclaration)
8+
handleNoTypeVariables(()
9+
beginFormalParameters((, MemberKind.TopLevelMethod)
10+
endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
11+
handleAsyncModifier(null, null)
12+
beginBlockFunctionBody({)
13+
beginTryStatement(try)
14+
beginBlock({, BlockKind(try statement))
15+
handleEmptyStatement(;)
16+
endBlock(1, {, }, BlockKind(try statement))
17+
beginCatchClause(catch)
18+
beginFormalParameters((, MemberKind.Catch)
19+
beginMetadataStar(e)
20+
endMetadataStar(0)
21+
beginFormalParameter(e, MemberKind.Catch, null, null, null)
22+
handleNoType(()
23+
handleIdentifier(e, formalParameterDeclaration)
24+
handleFormalParameterWithoutValue())
25+
endFormalParameter(null, null, null, e, null, null, FormalParameterKind.mandatory, MemberKind.Catch)
26+
endFormalParameters(1, (, ), MemberKind.Catch)
27+
endCatchClause({)
28+
beginBlock({, BlockKind(catch clause))
29+
handleEmptyStatement(;)
30+
endBlock(1, {, }, BlockKind(catch clause))
31+
handleCatchBlock(null, catch, null)
32+
beginCatchClause(on)
33+
handleIdentifier(Foo, typeReference)
34+
handleNoTypeArguments({)
35+
handleType(Foo, null)
36+
endCatchClause({)
37+
beginBlock({, BlockKind(catch clause))
38+
handleEmptyStatement(;)
39+
endBlock(1, {, }, BlockKind(catch clause))
40+
handleCatchBlock(on, null, null)
41+
endTryStatement(2, try, null)
42+
handleIdentifier(on, expression)
43+
handleNoTypeArguments(()
44+
beginArguments(()
45+
endArguments(0, (, ))
46+
handleSend(on, ;)
47+
handleExpressionStatement(;)
48+
endBlockFunctionBody(2, {, })
49+
endTopLevelMethod(void, null, })
50+
endTopLevelDeclaration(void)
51+
beginMetadataStar(void)
52+
endMetadataStar(0)
53+
beginTopLevelMember(void)
54+
beginTopLevelMethod(}, null)
55+
handleVoidKeyword(void)
56+
handleIdentifier(on, topLevelFunctionDeclaration)
57+
handleNoTypeVariables(()
58+
beginFormalParameters((, MemberKind.TopLevelMethod)
59+
endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
60+
handleAsyncModifier(null, null)
61+
beginBlockFunctionBody({)
62+
endBlockFunctionBody(0, {, })
63+
endTopLevelMethod(void, null, })
64+
endTopLevelDeclaration()
65+
endCompilationUnit(2, )
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
parseUnit(void)
2+
skipErrorTokens(void)
3+
listener: beginCompilationUnit(void)
4+
syntheticPreviousToken(void)
5+
parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
6+
parseMetadataStar()
7+
listener: beginMetadataStar(void)
8+
listener: endMetadataStar(0)
9+
parseTopLevelMemberImpl()
10+
listener: beginTopLevelMember(void)
11+
parseTopLevelMethod(, null, , Instance of 'VoidType', null, main, false)
12+
listener: beginTopLevelMethod(, null)
13+
listener: handleVoidKeyword(void)
14+
ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
15+
listener: handleIdentifier(main, topLevelFunctionDeclaration)
16+
parseMethodTypeVar(main)
17+
listener: handleNoTypeVariables(()
18+
parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
19+
parseFormalParameters(main, MemberKind.TopLevelMethod)
20+
parseFormalParametersRest((, MemberKind.TopLevelMethod)
21+
listener: beginFormalParameters((, MemberKind.TopLevelMethod)
22+
listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
23+
parseAsyncModifierOpt())
24+
listener: handleAsyncModifier(null, null)
25+
inPlainSync()
26+
parseFunctionBody(), false, false)
27+
listener: beginBlockFunctionBody({)
28+
notEofOrValue(}, try)
29+
parseStatement({)
30+
parseStatementX({)
31+
parseTryStatement({)
32+
listener: beginTryStatement(try)
33+
parseBlock(try, BlockKind(try statement))
34+
ensureBlock(try, null, try statement)
35+
listener: beginBlock({, BlockKind(try statement))
36+
notEofOrValue(}, ;)
37+
parseStatement({)
38+
parseStatementX({)
39+
parseEmptyStatement({)
40+
listener: handleEmptyStatement(;)
41+
notEofOrValue(}, })
42+
listener: endBlock(1, {, }, BlockKind(try statement))
43+
listener: beginCatchClause(catch)
44+
parseFormalParameters(catch, MemberKind.Catch)
45+
parseFormalParametersRest((, MemberKind.Catch)
46+
listener: beginFormalParameters((, MemberKind.Catch)
47+
parseFormalParameter((, FormalParameterKind.mandatory, MemberKind.Catch)
48+
parseMetadataStar(()
49+
listener: beginMetadataStar(e)
50+
listener: endMetadataStar(0)
51+
listener: beginFormalParameter(e, MemberKind.Catch, null, null, null)
52+
listener: handleNoType(()
53+
ensureIdentifier((, formalParameterDeclaration)
54+
listener: handleIdentifier(e, formalParameterDeclaration)
55+
listener: handleFormalParameterWithoutValue())
56+
listener: endFormalParameter(null, null, null, e, null, null, FormalParameterKind.mandatory, MemberKind.Catch)
57+
listener: endFormalParameters(1, (, ), MemberKind.Catch)
58+
listener: endCatchClause({)
59+
parseBlock(), BlockKind(catch clause))
60+
ensureBlock(), null, catch clause)
61+
listener: beginBlock({, BlockKind(catch clause))
62+
notEofOrValue(}, ;)
63+
parseStatement({)
64+
parseStatementX({)
65+
parseEmptyStatement({)
66+
listener: handleEmptyStatement(;)
67+
notEofOrValue(}, })
68+
listener: endBlock(1, {, }, BlockKind(catch clause))
69+
listener: handleCatchBlock(null, catch, null)
70+
listener: beginCatchClause(on)
71+
listener: handleIdentifier(Foo, typeReference)
72+
listener: handleNoTypeArguments({)
73+
listener: handleType(Foo, null)
74+
listener: endCatchClause({)
75+
parseBlock(Foo, BlockKind(catch clause))
76+
ensureBlock(Foo, null, catch clause)
77+
listener: beginBlock({, BlockKind(catch clause))
78+
notEofOrValue(}, ;)
79+
parseStatement({)
80+
parseStatementX({)
81+
parseEmptyStatement({)
82+
listener: handleEmptyStatement(;)
83+
notEofOrValue(}, })
84+
listener: endBlock(1, {, }, BlockKind(catch clause))
85+
listener: handleCatchBlock(on, null, null)
86+
listener: endTryStatement(2, try, null)
87+
notEofOrValue(}, on)
88+
parseStatement(})
89+
parseStatementX(})
90+
parseExpressionStatementOrDeclaration(}, false)
91+
parseExpressionStatementOrDeclarationAfterModifiers(}, }, null, null, null, false)
92+
looksLikeLocalFunction(on)
93+
parseExpressionStatement(})
94+
parseExpression(})
95+
parsePrecedenceExpression(}, 1, true)
96+
parseUnaryExpression(}, true)
97+
parsePrimary(}, expression)
98+
inPlainSync()
99+
parseSendOrFunctionLiteral(}, expression)
100+
looksLikeFunctionBody(;)
101+
parseSend(}, expression)
102+
isNextIdentifier(})
103+
ensureIdentifier(}, expression)
104+
inPlainSync()
105+
listener: handleIdentifier(on, expression)
106+
listener: handleNoTypeArguments(()
107+
parseArgumentsOpt(on)
108+
parseArguments(on)
109+
parseArgumentsRest(()
110+
listener: beginArguments(()
111+
listener: endArguments(0, (, ))
112+
listener: handleSend(on, ;)
113+
ensureSemicolon())
114+
listener: handleExpressionStatement(;)
115+
notEofOrValue(}, })
116+
listener: endBlockFunctionBody(2, {, })
117+
listener: endTopLevelMethod(void, null, })
118+
listener: endTopLevelDeclaration(void)
119+
parseTopLevelDeclarationImpl(}, Instance of 'DirectiveContext')
120+
parseMetadataStar(})
121+
listener: beginMetadataStar(void)
122+
listener: endMetadataStar(0)
123+
parseTopLevelMemberImpl(})
124+
listener: beginTopLevelMember(void)
125+
parseTopLevelMethod(}, null, }, Instance of 'VoidType', null, on, false)
126+
listener: beginTopLevelMethod(}, null)
127+
listener: handleVoidKeyword(void)
128+
ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
129+
listener: handleIdentifier(on, topLevelFunctionDeclaration)
130+
parseMethodTypeVar(on)
131+
listener: handleNoTypeVariables(()
132+
parseGetterOrFormalParameters(on, on, false, MemberKind.TopLevelMethod)
133+
parseFormalParameters(on, MemberKind.TopLevelMethod)
134+
parseFormalParametersRest((, MemberKind.TopLevelMethod)
135+
listener: beginFormalParameters((, MemberKind.TopLevelMethod)
136+
listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
137+
parseAsyncModifierOpt())
138+
listener: handleAsyncModifier(null, null)
139+
inPlainSync()
140+
parseFunctionBody(), false, false)
141+
listener: beginBlockFunctionBody({)
142+
notEofOrValue(}, })
143+
listener: endBlockFunctionBody(0, {, })
144+
listener: endTopLevelMethod(void, null, })
145+
listener: endTopLevelDeclaration()
146+
reportAllErrorTokens(void)
147+
listener: endCompilationUnit(2, )
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
void main() {
2+
try {
3+
;
4+
} catch (e) {
5+
;
6+
} on Foo {
7+
;
8+
}
9+
10+
on();
11+
}
12+
13+
void on() {}
14+
15+
16+
void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
17+
try[KeywordToken] {[BeginToken]
18+
;[SimpleToken]
19+
}[SimpleToken] catch[KeywordToken] ([BeginToken]e[StringToken])[SimpleToken] {[BeginToken]
20+
;[SimpleToken]
21+
}[SimpleToken] on[KeywordToken] Foo[StringToken] {[BeginToken]
22+
;[SimpleToken]
23+
}[SimpleToken]
24+
25+
on[KeywordToken]([BeginToken])[SimpleToken];[SimpleToken]
26+
}[SimpleToken]
27+
28+
void[KeywordToken] on[KeywordToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
29+
[SimpleToken]
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
void main() {
2+
try {
3+
;
4+
} catch (e) {
5+
;
6+
} on Foo {
7+
;
8+
}
9+
10+
on();
11+
}
12+
13+
void on() {}
14+
15+
16+
void[KeywordToken] main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
17+
try[KeywordToken] {[BeginToken]
18+
;[SimpleToken]
19+
}[SimpleToken] catch[KeywordToken] ([BeginToken]e[StringToken])[SimpleToken] {[BeginToken]
20+
;[SimpleToken]
21+
}[SimpleToken] on[KeywordToken] Foo[StringToken] {[BeginToken]
22+
;[SimpleToken]
23+
}[SimpleToken]
24+
25+
on[KeywordToken]([BeginToken])[SimpleToken];[SimpleToken]
26+
}[SimpleToken]
27+
28+
void[KeywordToken] on[KeywordToken]([BeginToken])[SimpleToken] {[BeginToken]}[SimpleToken]
29+
[SimpleToken]
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
files:
2+
- call_on_after_try_block.dart
3+
- call_on_after_try_block_prime.dart
4+
filters:
5+
- ignoreListenerArguments
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
void main() {
2+
try {
3+
;
4+
} catch (e) {
5+
;
6+
} on Foo {
7+
;
8+
}
9+
10+
on(e) {
11+
;
12+
}
13+
on("");
14+
}
15+

0 commit comments

Comments
 (0)