Skip to content

Commit a06e53b

Browse files
jensjohacommit-bot@chromium.org
authored andcommitted
[parser] Set forIn = true when recovering 'in' written as ':'
Before this change the CFE crashed with an assert error. Change-Id: Ide486388fbba8c6cda4bb75e5339ae3c10623351 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/161949 Reviewed-by: Johnni Winther <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Jens Johansen <[email protected]>
1 parent 343a696 commit a06e53b

12 files changed

+285
-1
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6248,7 +6248,7 @@ class Parser {
62486248
token =
62496249
parseVariablesDeclarationRest(token, /* endWithSemicolon = */ false);
62506250
listener.handleForInitializerLocalVariableDeclaration(
6251-
token, optional('in', token.next));
6251+
token, optional('in', token.next) || optional(':', token.next));
62526252
} else if (optional(';', token.next)) {
62536253
listener.handleForInitializerEmptyStatement(token.next);
62546254
} else {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
main() {
6+
for(int i : [1, 2, 3]) {
7+
print(i);
8+
}
9+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
Problems reported:
2+
3+
parser/error_recovery/for_in_with_colon:6:13: For-in loops use 'in' rather than a colon.
4+
for(int i : [1, 2, 3]) {
5+
^
6+
7+
beginCompilationUnit(main)
8+
beginMetadataStar(main)
9+
endMetadataStar(0)
10+
beginTopLevelMember(main)
11+
beginTopLevelMethod(, null)
12+
handleNoType()
13+
handleIdentifier(main, topLevelFunctionDeclaration)
14+
handleNoTypeVariables(()
15+
beginFormalParameters((, MemberKind.TopLevelMethod)
16+
endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
17+
handleAsyncModifier(null, null)
18+
beginBlockFunctionBody({)
19+
beginForStatement(for)
20+
beginMetadataStar(int)
21+
endMetadataStar(0)
22+
handleIdentifier(int, typeReference)
23+
handleNoTypeArguments(i)
24+
handleType(int, null)
25+
beginVariablesDeclaration(i, null, null)
26+
handleIdentifier(i, localVariableDeclaration)
27+
beginInitializedIdentifier(i)
28+
handleNoVariableInitializer(i)
29+
endInitializedIdentifier(i)
30+
endVariablesDeclaration(1, null)
31+
handleForInitializerLocalVariableDeclaration(i, true)
32+
handleRecoverableError(ColonInPlaceOfIn, :, :)
33+
beginForInExpression([)
34+
handleNoTypeArguments([)
35+
handleLiteralInt(1)
36+
handleLiteralInt(2)
37+
handleLiteralInt(3)
38+
handleLiteralList(3, [, null, ])
39+
endForInExpression())
40+
handleForInLoopParts(null, for, (, :)
41+
beginForInBody({)
42+
beginBlock({, BlockKind(statement))
43+
handleIdentifier(print, expression)
44+
handleNoTypeArguments(()
45+
beginArguments(()
46+
handleIdentifier(i, expression)
47+
handleNoTypeArguments())
48+
handleNoArguments())
49+
handleSend(i, ))
50+
endArguments(1, (, ))
51+
handleSend(print, ;)
52+
handleExpressionStatement(;)
53+
endBlock(1, {, }, BlockKind(statement))
54+
endForInBody(})
55+
endForIn(})
56+
endBlockFunctionBody(1, {, })
57+
endTopLevelMethod(main, null, })
58+
endTopLevelDeclaration()
59+
endCompilationUnit(1, )
Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
1+
parseUnit(main)
2+
skipErrorTokens(main)
3+
listener: beginCompilationUnit(main)
4+
syntheticPreviousToken(main)
5+
parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
6+
parseMetadataStar()
7+
listener: beginMetadataStar(main)
8+
listener: endMetadataStar(0)
9+
parseTopLevelMemberImpl()
10+
listener: beginTopLevelMember(main)
11+
isReservedKeyword(()
12+
parseTopLevelMethod(, null, , Instance of 'NoType', null, main, false)
13+
listener: beginTopLevelMethod(, null)
14+
listener: handleNoType()
15+
ensureIdentifierPotentiallyRecovered(, topLevelFunctionDeclaration, false)
16+
listener: handleIdentifier(main, topLevelFunctionDeclaration)
17+
parseMethodTypeVar(main)
18+
listener: handleNoTypeVariables(()
19+
parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod)
20+
parseFormalParameters(main, MemberKind.TopLevelMethod)
21+
parseFormalParametersRest((, MemberKind.TopLevelMethod)
22+
listener: beginFormalParameters((, MemberKind.TopLevelMethod)
23+
listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod)
24+
parseAsyncModifierOpt())
25+
listener: handleAsyncModifier(null, null)
26+
inPlainSync()
27+
parseFunctionBody(), false, false)
28+
listener: beginBlockFunctionBody({)
29+
notEofOrValue(}, for)
30+
parseStatement({)
31+
parseStatementX({)
32+
parseForStatement({, null)
33+
listener: beginForStatement(for)
34+
parseForLoopPartsStart(null, for)
35+
parseExpressionStatementOrDeclaration((, true)
36+
parseExpressionStatementOrDeclarationAfterModifiers((, (, null, null, null, true)
37+
listener: beginMetadataStar(int)
38+
listener: endMetadataStar(0)
39+
listener: handleIdentifier(int, typeReference)
40+
listener: handleNoTypeArguments(i)
41+
listener: handleType(int, null)
42+
listener: beginVariablesDeclaration(i, null, null)
43+
parseForLoopPartsMid(int, null, for)
44+
parseVariablesDeclarationRest(int, false)
45+
parseOptionallyInitializedIdentifier(int)
46+
ensureIdentifier(int, localVariableDeclaration)
47+
listener: handleIdentifier(i, localVariableDeclaration)
48+
listener: beginInitializedIdentifier(i)
49+
parseVariableInitializerOpt(i)
50+
listener: handleNoVariableInitializer(i)
51+
listener: endInitializedIdentifier(i)
52+
listener: endVariablesDeclaration(1, null)
53+
listener: handleForInitializerLocalVariableDeclaration(i, true)
54+
reportRecoverableError(:, ColonInPlaceOfIn)
55+
listener: handleRecoverableError(ColonInPlaceOfIn, :, :)
56+
parseForInRest(i, null, for, i)
57+
parseForInLoopPartsRest(i, null, for, i)
58+
listener: beginForInExpression([)
59+
parseExpression(:)
60+
parsePrecedenceExpression(:, 1, true)
61+
parseUnaryExpression(:, true)
62+
parsePrimary(:, expression)
63+
listener: handleNoTypeArguments([)
64+
parseLiteralListSuffix(:, null)
65+
parseExpression([)
66+
parsePrecedenceExpression([, 1, true)
67+
parseUnaryExpression([, true)
68+
parsePrimary([, expression)
69+
parseLiteralInt([)
70+
listener: handleLiteralInt(1)
71+
parseExpression(,)
72+
parsePrecedenceExpression(,, 1, true)
73+
parseUnaryExpression(,, true)
74+
parsePrimary(,, expression)
75+
parseLiteralInt(,)
76+
listener: handleLiteralInt(2)
77+
parseExpression(,)
78+
parsePrecedenceExpression(,, 1, true)
79+
parseUnaryExpression(,, true)
80+
parsePrimary(,, expression)
81+
parseLiteralInt(,)
82+
listener: handleLiteralInt(3)
83+
listener: handleLiteralList(3, [, null, ])
84+
ensureCloseParen(], ()
85+
listener: endForInExpression())
86+
listener: handleForInLoopParts(null, for, (, :)
87+
listener: beginForInBody({)
88+
parseStatement())
89+
parseStatementX())
90+
parseBlock(), BlockKind(statement))
91+
ensureBlock(), null, null)
92+
listener: beginBlock({, BlockKind(statement))
93+
notEofOrValue(}, print)
94+
parseStatement({)
95+
parseStatementX({)
96+
parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false)
97+
looksLikeLocalFunction(print)
98+
parseExpressionStatement({)
99+
parseExpression({)
100+
parsePrecedenceExpression({, 1, true)
101+
parseUnaryExpression({, true)
102+
parsePrimary({, expression)
103+
parseSendOrFunctionLiteral({, expression)
104+
looksLikeFunctionBody(;)
105+
parseSend({, expression)
106+
ensureIdentifier({, expression)
107+
listener: handleIdentifier(print, expression)
108+
listener: handleNoTypeArguments(()
109+
parseArgumentsOpt(print)
110+
parseArguments(print)
111+
parseArgumentsRest(()
112+
listener: beginArguments(()
113+
parseExpression(()
114+
parsePrecedenceExpression((, 1, true)
115+
parseUnaryExpression((, true)
116+
parsePrimary((, expression)
117+
parseSendOrFunctionLiteral((, expression)
118+
parseSend((, expression)
119+
ensureIdentifier((, expression)
120+
listener: handleIdentifier(i, expression)
121+
listener: handleNoTypeArguments())
122+
parseArgumentsOpt(i)
123+
listener: handleNoArguments())
124+
listener: handleSend(i, ))
125+
listener: endArguments(1, (, ))
126+
listener: handleSend(print, ;)
127+
ensureSemicolon())
128+
listener: handleExpressionStatement(;)
129+
notEofOrValue(}, })
130+
listener: endBlock(1, {, }, BlockKind(statement))
131+
listener: endForInBody(})
132+
listener: endForIn(})
133+
notEofOrValue(}, })
134+
listener: endBlockFunctionBody(1, {, })
135+
listener: endTopLevelMethod(main, null, })
136+
listener: endTopLevelDeclaration()
137+
reportAllErrorTokens(main)
138+
listener: endCompilationUnit(1, )
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
main() {
2+
for(int i : [1, 2, 3]) {
3+
print(i);
4+
}
5+
}
6+
7+
main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
8+
for[KeywordToken]([BeginToken]int[StringToken] i[StringToken] :[SimpleToken] [[BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] 3[StringToken]][SimpleToken])[SimpleToken] {[BeginToken]
9+
print[StringToken]([BeginToken]i[StringToken])[SimpleToken];[SimpleToken]
10+
}[SimpleToken]
11+
}[SimpleToken][SimpleToken]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
main() {
2+
for(int i : [1, 2, 3]) {
3+
print(i);
4+
}
5+
}
6+
7+
main[StringToken]([BeginToken])[SimpleToken] {[BeginToken]
8+
for[KeywordToken]([BeginToken]int[StringToken] i[StringToken] :[SimpleToken] [[BeginToken]1[StringToken],[SimpleToken] 2[StringToken],[SimpleToken] 3[StringToken]][SimpleToken])[SimpleToken] {[BeginToken]
9+
print[StringToken]([BeginToken]i[StringToken])[SimpleToken];[SimpleToken]
10+
}[SimpleToken]
11+
}[SimpleToken][SimpleToken]
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
main() {
6+
for(int i : [1, 2, 3]) {
7+
print(i);
8+
}
9+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
library;
2+
import self as self;
3+
4+
static method main() → dynamic
5+
;
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/error_recovery/for_in_with_colon.dart:6:13: Error: For-in loops use 'in' rather than a colon.
6+
// Try replacing the colon with the keyword 'in'.
7+
// for(int i : [1, 2, 3]) {
8+
// ^
9+
//
10+
import self as self;
11+
import "dart:core" as core;
12+
13+
static method main() → dynamic {
14+
for (core::int* i in <core::int*>[1, 2, 3]) {
15+
core::print(i);
16+
}
17+
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
library;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/error_recovery/for_in_with_colon.dart:6:13: Error: For-in loops use 'in' rather than a colon.
6+
// Try replacing the colon with the keyword 'in'.
7+
// for(int i : [1, 2, 3]) {
8+
// ^
9+
//
10+
import self as self;
11+
import "dart:core" as core;
12+
13+
static method main() → dynamic {
14+
{
15+
core::Iterator<core::int*>* :sync-for-iterator = <core::int*>[1, 2, 3].{core::Iterable::iterator};
16+
for (; :sync-for-iterator.{core::Iterator::moveNext}(); ) {
17+
core::int* i = :sync-for-iterator.{core::Iterator::current};
18+
{
19+
core::print(i);
20+
}
21+
}
22+
}
23+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
main() {}

0 commit comments

Comments
 (0)