Skip to content

Commit 67ead16

Browse files
jensjohaCommit Queue
authored andcommitted
[parser/CFE] Better recovery of partial missing type arguments on type; fix CFE crash
Change-Id: Ifd43ca5b5167e8bacf36e7b89ed8ab57362635b4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/399040 Reviewed-by: Johnni Winther <[email protected]> Commit-Queue: Jens Johansen <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent f53c758 commit 67ead16

File tree

24 files changed

+575
-1
lines changed

24 files changed

+575
-1
lines changed

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

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1327,7 +1327,10 @@ class ComplexTypeParamOrArgInfo extends TypeParamOrArgInfo {
13271327
typeInfo = computeType(next, /* required = */ true, inDeclaration);
13281328
}
13291329
if (typeInfo == noType) {
1330-
if (next == start && !inDeclaration && !isCloser(next.next!)) {
1330+
if (next == start &&
1331+
!inDeclaration &&
1332+
!isCloser(next.next!) &&
1333+
!next.next!.isA(TokenType.COMMA)) {
13311334
return noTypeParamOrArg;
13321335
}
13331336
if (!next.next!.isA(TokenType.COMMA)) {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
files:
2+
- missing_identifier_in_type_argument_ok.dart
3+
- missing_identifier_in_type_argument_bad_1.dart
4+
- missing_identifier_in_type_argument_bad_2.dart
5+
filters:
6+
- ignoreListenerArguments
7+
ignored:
8+
- handleRecoverableError
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
foo(bar) {
2+
Map<, int> b = {};
3+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
Problems reported:
2+
3+
parser/error_recovery/missing_identifier_in_type_argument_bad_1:2:7: Expected a type, but got ','.
4+
Map<, int> b = {};
5+
^
6+
7+
beginCompilationUnit(foo)
8+
beginMetadataStar(foo)
9+
endMetadataStar(0)
10+
beginTopLevelMember(foo)
11+
beginTopLevelMethod(, null, null)
12+
handleNoType()
13+
handleIdentifier(foo, topLevelFunctionDeclaration)
14+
handleNoTypeVariables(()
15+
beginFormalParameters((, MemberKind.TopLevelMethod)
16+
beginMetadataStar(bar)
17+
endMetadataStar(0)
18+
beginFormalParameter(bar, MemberKind.TopLevelMethod, null, null, null)
19+
handleNoType(()
20+
handleIdentifier(bar, formalParameterDeclaration)
21+
handleFormalParameterWithoutValue())
22+
endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
23+
endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
24+
handleAsyncModifier(null, null)
25+
beginBlockFunctionBody({)
26+
beginMetadataStar(Map)
27+
endMetadataStar(0)
28+
handleIdentifier(Map, typeReference)
29+
beginTypeArguments(<)
30+
handleRecoverableError(Message[ExpectedType, Expected a type, but got ','., null, {lexeme: ,}], ,, ,)
31+
handleIdentifier(, typeReference)
32+
handleNoTypeArguments(,)
33+
handleType(, null)
34+
handleIdentifier(int, typeReference)
35+
handleNoTypeArguments(>)
36+
handleType(int, null)
37+
endTypeArguments(2, <, >)
38+
handleType(Map, null)
39+
beginVariablesDeclaration(b, null, null)
40+
handleIdentifier(b, localVariableDeclaration)
41+
beginInitializedIdentifier(b)
42+
beginVariableInitializer(=)
43+
handleNoTypeArguments({)
44+
handleLiteralSetOrMap(0, {, null, }, false)
45+
endVariableInitializer(=)
46+
endInitializedIdentifier(b)
47+
endVariablesDeclaration(1, ;)
48+
endBlockFunctionBody(1, {, })
49+
endTopLevelMethod(foo, null, })
50+
endTopLevelDeclaration(})
51+
endCompilationUnit(1, )
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
parseUnit(foo)
2+
skipErrorTokens(foo)
3+
listener: beginCompilationUnit(foo)
4+
syntheticPreviousToken(foo)
5+
parseTopLevelDeclarationImpl(, DirectiveContext(DirectiveState.Unknown))
6+
parseMetadataStar()
7+
listener: beginMetadataStar(foo)
8+
listener: endMetadataStar(0)
9+
parseTopLevelMemberImpl()
10+
listener: beginTopLevelMember(foo)
11+
isReservedKeyword(()
12+
parseTopLevelMethod(, null, null, , NoType(), null, foo, false)
13+
listener: beginTopLevelMethod(, null, null)
14+
listener: handleNoType()
15+
ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
16+
listener: handleIdentifier(foo, topLevelFunctionDeclaration)
17+
parseMethodTypeVar(foo)
18+
listener: handleNoTypeVariables(()
19+
parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
20+
parseFormalParameters(foo, MemberKind.TopLevelMethod)
21+
parseFormalParametersRest((, MemberKind.TopLevelMethod)
22+
listener: beginFormalParameters((, MemberKind.TopLevelMethod)
23+
parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
24+
parseMetadataStar(()
25+
listener: beginMetadataStar(bar)
26+
listener: endMetadataStar(0)
27+
listener: beginFormalParameter(bar, MemberKind.TopLevelMethod, null, null, null)
28+
listener: handleNoType(()
29+
ensureIdentifier((, formalParameterDeclaration)
30+
listener: handleIdentifier(bar, formalParameterDeclaration)
31+
listener: handleFormalParameterWithoutValue())
32+
listener: endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
33+
listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
34+
parseAsyncModifierOpt())
35+
listener: handleAsyncModifier(null, null)
36+
inPlainSync()
37+
parseFunctionBody(), false, false)
38+
listener: beginBlockFunctionBody({)
39+
notEofOrValue(}, Map)
40+
parseStatement({)
41+
parseStatementX({)
42+
parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, null)
43+
looksLikeLocalFunction(b)
44+
listener: beginMetadataStar(Map)
45+
listener: endMetadataStar(0)
46+
ensureIdentifier({, typeReference)
47+
listener: handleIdentifier(Map, typeReference)
48+
listener: beginTypeArguments(<)
49+
reportRecoverableErrorWithToken(,, Template(ExpectedType))
50+
listener: handleRecoverableError(Message[ExpectedType, Expected a type, but got ','., null, {lexeme: ,}], ,, ,)
51+
rewriter()
52+
listener: handleIdentifier(, typeReference)
53+
listener: handleNoTypeArguments(,)
54+
listener: handleType(, null)
55+
listener: handleIdentifier(int, typeReference)
56+
listener: handleNoTypeArguments(>)
57+
listener: handleType(int, null)
58+
listener: endTypeArguments(2, <, >)
59+
listener: handleType(Map, null)
60+
listener: beginVariablesDeclaration(b, null, null)
61+
parseVariablesDeclarationRest(>, true)
62+
parseOptionallyInitializedIdentifier(>)
63+
ensureIdentifier(>, localVariableDeclaration)
64+
listener: handleIdentifier(b, localVariableDeclaration)
65+
listener: beginInitializedIdentifier(b)
66+
parseVariableInitializerOpt(b)
67+
listener: beginVariableInitializer(=)
68+
parseExpression(=)
69+
parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none)
70+
parseUnaryExpression(=, true, ConstantPatternContext.none)
71+
parsePrimary(=, expression, ConstantPatternContext.none)
72+
listener: handleNoTypeArguments({)
73+
parseLiteralSetOrMapSuffix(=, null)
74+
listener: handleLiteralSetOrMap(0, {, null, }, false)
75+
listener: endVariableInitializer(=)
76+
listener: endInitializedIdentifier(b)
77+
ensureSemicolon(})
78+
listener: endVariablesDeclaration(1, ;)
79+
notEofOrValue(}, })
80+
listener: endBlockFunctionBody(1, {, })
81+
listener: endTopLevelMethod(foo, null, })
82+
listener: endTopLevelDeclaration(})
83+
reportAllErrorTokens(foo)
84+
listener: endCompilationUnit(1, )
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
NOTICE: Stream was rewritten by parser!
2+
3+
foo(bar) {
4+
Map<*synthetic*, int> b = {};
5+
}
6+
7+
8+
foo[StringToken]([BeginToken]bar[StringToken])[SimpleToken] {[BeginToken]
9+
Map[StringToken]<[BeginToken][SyntheticStringToken],[SimpleToken] int[StringToken]>[SimpleToken] b[StringToken] =[SimpleToken] {[BeginToken]}[SimpleToken];[SimpleToken]
10+
}[SimpleToken]
11+
[SimpleToken]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
foo(bar) {
2+
Map<, int> b = {};
3+
}
4+
5+
6+
foo[StringToken]([BeginToken]bar[StringToken])[SimpleToken] {[BeginToken]
7+
Map[StringToken]<[BeginToken],[SimpleToken] int[StringToken]>[SimpleToken] b[StringToken] =[SimpleToken] {[BeginToken]}[SimpleToken];[SimpleToken]
8+
}[SimpleToken]
9+
[SimpleToken]
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
foo(bar) {
2+
Map<int, > c = {};
3+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
Problems reported:
2+
3+
parser/error_recovery/missing_identifier_in_type_argument_bad_2:2:12: Expected a type, but got '>'.
4+
Map<int, > c = {};
5+
^
6+
7+
beginCompilationUnit(foo)
8+
beginMetadataStar(foo)
9+
endMetadataStar(0)
10+
beginTopLevelMember(foo)
11+
beginTopLevelMethod(, null, null)
12+
handleNoType()
13+
handleIdentifier(foo, topLevelFunctionDeclaration)
14+
handleNoTypeVariables(()
15+
beginFormalParameters((, MemberKind.TopLevelMethod)
16+
beginMetadataStar(bar)
17+
endMetadataStar(0)
18+
beginFormalParameter(bar, MemberKind.TopLevelMethod, null, null, null)
19+
handleNoType(()
20+
handleIdentifier(bar, formalParameterDeclaration)
21+
handleFormalParameterWithoutValue())
22+
endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
23+
endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
24+
handleAsyncModifier(null, null)
25+
beginBlockFunctionBody({)
26+
beginMetadataStar(Map)
27+
endMetadataStar(0)
28+
handleIdentifier(Map, typeReference)
29+
beginTypeArguments(<)
30+
handleIdentifier(int, typeReference)
31+
handleNoTypeArguments(,)
32+
handleType(int, null)
33+
handleRecoverableError(Message[ExpectedType, Expected a type, but got '>'., null, {lexeme: >}], >, >)
34+
handleIdentifier(, typeReference)
35+
handleNoTypeArguments(>)
36+
handleType(, null)
37+
endTypeArguments(2, <, >)
38+
handleType(Map, null)
39+
beginVariablesDeclaration(c, null, null)
40+
handleIdentifier(c, localVariableDeclaration)
41+
beginInitializedIdentifier(c)
42+
beginVariableInitializer(=)
43+
handleNoTypeArguments({)
44+
handleLiteralSetOrMap(0, {, null, }, false)
45+
endVariableInitializer(=)
46+
endInitializedIdentifier(c)
47+
endVariablesDeclaration(1, ;)
48+
endBlockFunctionBody(1, {, })
49+
endTopLevelMethod(foo, null, })
50+
endTopLevelDeclaration(})
51+
endCompilationUnit(1, )
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
parseUnit(foo)
2+
skipErrorTokens(foo)
3+
listener: beginCompilationUnit(foo)
4+
syntheticPreviousToken(foo)
5+
parseTopLevelDeclarationImpl(, DirectiveContext(DirectiveState.Unknown))
6+
parseMetadataStar()
7+
listener: beginMetadataStar(foo)
8+
listener: endMetadataStar(0)
9+
parseTopLevelMemberImpl()
10+
listener: beginTopLevelMember(foo)
11+
isReservedKeyword(()
12+
parseTopLevelMethod(, null, null, , NoType(), null, foo, false)
13+
listener: beginTopLevelMethod(, null, null)
14+
listener: handleNoType()
15+
ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
16+
listener: handleIdentifier(foo, topLevelFunctionDeclaration)
17+
parseMethodTypeVar(foo)
18+
listener: handleNoTypeVariables(()
19+
parseGetterOrFormalParameters(foo, foo, false, MemberKind.TopLevelMethod)
20+
parseFormalParameters(foo, MemberKind.TopLevelMethod)
21+
parseFormalParametersRest((, MemberKind.TopLevelMethod)
22+
listener: beginFormalParameters((, MemberKind.TopLevelMethod)
23+
parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
24+
parseMetadataStar(()
25+
listener: beginMetadataStar(bar)
26+
listener: endMetadataStar(0)
27+
listener: beginFormalParameter(bar, MemberKind.TopLevelMethod, null, null, null)
28+
listener: handleNoType(()
29+
ensureIdentifier((, formalParameterDeclaration)
30+
listener: handleIdentifier(bar, formalParameterDeclaration)
31+
listener: handleFormalParameterWithoutValue())
32+
listener: endFormalParameter(null, null, null, bar, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
33+
listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
34+
parseAsyncModifierOpt())
35+
listener: handleAsyncModifier(null, null)
36+
inPlainSync()
37+
parseFunctionBody(), false, false)
38+
listener: beginBlockFunctionBody({)
39+
notEofOrValue(}, Map)
40+
parseStatement({)
41+
parseStatementX({)
42+
parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, null)
43+
looksLikeLocalFunction(c)
44+
listener: beginMetadataStar(Map)
45+
listener: endMetadataStar(0)
46+
ensureIdentifier({, typeReference)
47+
listener: handleIdentifier(Map, typeReference)
48+
listener: beginTypeArguments(<)
49+
listener: handleIdentifier(int, typeReference)
50+
listener: handleNoTypeArguments(,)
51+
listener: handleType(int, null)
52+
reportRecoverableErrorWithToken(>, Template(ExpectedType))
53+
listener: handleRecoverableError(Message[ExpectedType, Expected a type, but got '>'., null, {lexeme: >}], >, >)
54+
rewriter()
55+
listener: handleIdentifier(, typeReference)
56+
listener: handleNoTypeArguments(>)
57+
listener: handleType(, null)
58+
listener: endTypeArguments(2, <, >)
59+
listener: handleType(Map, null)
60+
listener: beginVariablesDeclaration(c, null, null)
61+
parseVariablesDeclarationRest(>, true)
62+
parseOptionallyInitializedIdentifier(>)
63+
ensureIdentifier(>, localVariableDeclaration)
64+
listener: handleIdentifier(c, localVariableDeclaration)
65+
listener: beginInitializedIdentifier(c)
66+
parseVariableInitializerOpt(c)
67+
listener: beginVariableInitializer(=)
68+
parseExpression(=)
69+
parsePrecedenceExpression(=, 1, true, ConstantPatternContext.none)
70+
parseUnaryExpression(=, true, ConstantPatternContext.none)
71+
parsePrimary(=, expression, ConstantPatternContext.none)
72+
listener: handleNoTypeArguments({)
73+
parseLiteralSetOrMapSuffix(=, null)
74+
listener: handleLiteralSetOrMap(0, {, null, }, false)
75+
listener: endVariableInitializer(=)
76+
listener: endInitializedIdentifier(c)
77+
ensureSemicolon(})
78+
listener: endVariablesDeclaration(1, ;)
79+
notEofOrValue(}, })
80+
listener: endBlockFunctionBody(1, {, })
81+
listener: endTopLevelMethod(foo, null, })
82+
listener: endTopLevelDeclaration(})
83+
reportAllErrorTokens(foo)
84+
listener: endCompilationUnit(1, )

0 commit comments

Comments
 (0)