Skip to content

Commit a975bf0

Browse files
stereotype441Commit Queue
authored and
Commit Queue
committed
Parser API changes in preparation for supporting patternVariableDeclaration.
Bug: #50035 Change-Id: I2661b7cbe60815b6232a165d56a478d8975aa6c2 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/270228 Reviewed-by: Jens Johansen <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Paul Berry <[email protected]>
1 parent ac1ad9f commit a975bf0

File tree

272 files changed

+917
-873
lines changed

Some content is hidden

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

272 files changed

+917
-873
lines changed

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

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6274,7 +6274,7 @@ class Parser {
62746274
Token next = token.next!;
62756275
if (allowPatterns && optional('case', next)) {
62766276
Token case_ = token = next;
6277-
token = parsePattern(token);
6277+
token = parsePattern(token, isRefutableContext: true);
62786278
next = token.next!;
62796279
Token? when;
62806280
if (optional('when', next)) {
@@ -8295,7 +8295,7 @@ class Parser {
82958295
}
82968296
listener.beginCaseExpression(caseKeyword);
82978297
if (allowPatterns) {
8298-
token = parsePattern(caseKeyword);
8298+
token = parsePattern(caseKeyword, isRefutableContext: true);
82998299
} else {
83008300
token = parseExpression(caseKeyword);
83018301
}
@@ -9157,10 +9157,21 @@ class Parser {
91579157
/// castPattern ::= primaryPattern 'as' type
91589158
/// nullAssertPattern ::= primaryPattern '!'
91599159
/// nullCheckPattern ::= primaryPattern '?'
9160-
Token parsePattern(Token token, {int precedence = 1}) {
9160+
///
9161+
/// [isRefutableContext] should be `true` if the pattern occurs in a
9162+
/// `guardedPattern` or any of its sub-patterns (i.e. in a
9163+
/// `switchStatementCase`, `switchExpressionCase`, or `ifCondition`); these
9164+
/// are contexts where a pattern match might be expected to fail, and bare
9165+
/// identifiers are treated as constant patterns. It should be `false` if the
9166+
/// pattern occurs in a `localVariableDeclaration`, `forLoopParts`, or
9167+
/// `patternAssignment`; these are contexts where a pattern match failure is
9168+
/// either prohibited statically or causes a runtime exception, and bare
9169+
/// identifiers are treated as variable patterns.
9170+
Token parsePattern(Token token,
9171+
{int precedence = 1, required bool isRefutableContext}) {
91619172
assert(precedence >= 1);
91629173
assert(precedence <= SELECTOR_PRECEDENCE);
9163-
token = parsePrimaryPattern(token);
9174+
token = parsePrimaryPattern(token, isRefutableContext: isRefutableContext);
91649175
while (true) {
91659176
Token next = token.next!;
91669177
int tokenLevel = _computePrecedence(next, forPattern: true);
@@ -9191,7 +9202,9 @@ class Parser {
91919202
case '|':
91929203
listener.beginBinaryPattern(next);
91939204
// Left associative so we parse the RHS one precedence level higher
9194-
token = parsePattern(next, precedence: tokenLevel + 1);
9205+
token = parsePattern(next,
9206+
precedence: tokenLevel + 1,
9207+
isRefutableContext: isRefutableContext);
91959208
listener.endBinaryPattern(next);
91969209
break;
91979210
default:
@@ -9229,7 +9242,7 @@ class Parser {
92299242
/// extractorPattern ::= extractorName typeArguments?
92309243
/// '(' patternFields? ')'
92319244
/// extractorName ::= typeIdentifier | qualifiedName
9232-
Token parsePrimaryPattern(Token token) {
9245+
Token parsePrimaryPattern(Token token, {required bool isRefutableContext}) {
92339246
TypeParamOrArgInfo typeArg =
92349247
computeTypeParamOrArg(token, /* inDeclaration = */ true);
92359248
Token next = typeArg.skip(token).next!;
@@ -9238,13 +9251,15 @@ class Parser {
92389251
case '[':
92399252
// listPattern ::= typeArguments? '[' patterns? ']'
92409253
token = typeArg.parseArguments(token, this);
9241-
return parseListPatternSuffix(token);
9254+
return parseListPatternSuffix(token,
9255+
isRefutableContext: isRefutableContext);
92429256
case '{':
92439257
// mapPattern ::= typeArguments? '{' mapPatternEntries? '}'
92449258
// mapPatternEntries ::= mapPatternEntry ( ',' mapPatternEntry )* ','?
92459259
// mapPatternEntry ::= expression ':' pattern
92469260
token = typeArg.parseArguments(token, this);
9247-
return parseMapPatternSuffix(token);
9261+
return parseMapPatternSuffix(token,
9262+
isRefutableContext: isRefutableContext);
92489263
}
92499264
// Whatever was after the optional type arguments didn't parse as a pattern
92509265
// that can start with type arguments, so back up and reparse assuming that
@@ -9265,7 +9280,8 @@ class Parser {
92659280
listener.handleRecordPattern(next, /* count = */ 0);
92669281
return nextNext;
92679282
} else {
9268-
return parseParenthesizedPatternOrRecordPattern(token);
9283+
return parseParenthesizedPatternOrRecordPattern(token,
9284+
isRefutableContext: isRefutableContext);
92699285
}
92709286
case 'const':
92719287
// constantPattern ::= booleanLiteral
@@ -9335,7 +9351,8 @@ class Parser {
93359351
if (optional('(', afterToken) && !potentialTypeArg.recovered) {
93369352
TypeParamOrArgInfo typeArg = potentialTypeArg;
93379353
token = typeArg.parseArguments(token, this);
9338-
token = parseExtractorPatternRest(token);
9354+
token = parseExtractorPatternRest(token,
9355+
isRefutableContext: isRefutableContext);
93399356
listener.handleExtractorPattern(firstIdentifier, dot, secondIdentifier);
93409357
return token;
93419358
} else if (firstIdentifier.lexeme == '_' && dot == null) {
@@ -9393,7 +9410,8 @@ class Parser {
93939410
/// bracket.
93949411
///
93959412
/// listPattern ::= typeArguments? '[' patterns? ']'
9396-
Token parseListPatternSuffix(Token token) {
9413+
Token parseListPatternSuffix(Token token,
9414+
{required bool isRefutableContext}) {
93979415
Token beforeToken = token;
93989416
Token beginToken = token = token.next!;
93999417
assert(optional('[', token) || optional('[]', token));
@@ -9413,7 +9431,7 @@ class Parser {
94139431
token = next;
94149432
break;
94159433
}
9416-
token = parsePattern(token);
9434+
token = parsePattern(token, isRefutableContext: isRefutableContext);
94179435
next = token.next!;
94189436
++count;
94199437
if (!optional(',', next)) {
@@ -9455,7 +9473,7 @@ class Parser {
94559473
/// mapPattern ::= typeArguments? '{' mapPatternEntries? '}'
94569474
/// mapPatternEntries ::= mapPatternEntry ( ',' mapPatternEntry )* ','?
94579475
/// mapPatternEntry ::= expression ':' pattern
9458-
Token parseMapPatternSuffix(Token token) {
9476+
Token parseMapPatternSuffix(Token token, {required bool isRefutableContext}) {
94599477
Token leftBrace = token = token.next!;
94609478
assert(optional('{', leftBrace));
94619479
Token next = token.next!;
@@ -9476,7 +9494,7 @@ class Parser {
94769494
codes.templateExpectedButGot.withArguments(':'),
94779495
new SyntheticToken(TokenType.PERIOD, next.charOffset));
94789496
}
9479-
token = parsePattern(colon);
9497+
token = parsePattern(colon, isRefutableContext: isRefutableContext);
94809498
listener.handleMapPatternEntry(colon, token.next!);
94819499
++count;
94829500
next = token.next!;
@@ -9520,7 +9538,8 @@ class Parser {
95209538
/// recordPattern ::= '(' patternFields? ')'
95219539
/// patternFields ::= patternField ( ',' patternField )* ','?
95229540
/// patternField ::= ( identifier? ':' )? pattern
9523-
Token parseParenthesizedPatternOrRecordPattern(Token token) {
9541+
Token parseParenthesizedPatternOrRecordPattern(Token token,
9542+
{required bool isRefutableContext}) {
95249543
Token begin = token.next!;
95259544
assert(optional('(', begin));
95269545

@@ -9551,7 +9570,7 @@ class Parser {
95519570
colon = token;
95529571
wasValidRecord = true;
95539572
}
9554-
token = parsePattern(token);
9573+
token = parsePattern(token, isRefutableContext: isRefutableContext);
95559574
next = token.next!;
95569575
if (wasRecord || colon != null) {
95579576
listener.handlePatternField(colon);
@@ -9594,7 +9613,8 @@ class Parser {
95949613
///
95959614
/// extractorPattern ::= extractorName typeArguments?
95969615
/// '(' patternFields? ')'
9597-
Token parseExtractorPatternRest(Token token) {
9616+
Token parseExtractorPatternRest(Token token,
9617+
{required bool isRefutableContext}) {
95989618
Token begin = token = token.next!;
95999619
assert(optional('(', begin));
96009620
int argumentCount = 0;
@@ -9616,7 +9636,7 @@ class Parser {
96169636
.next!;
96179637
colon = token;
96189638
}
9619-
token = parsePattern(token);
9639+
token = parsePattern(token, isRefutableContext: isRefutableContext);
96209640
next = token.next!;
96219641
listener.handlePatternField(colon);
96229642
++argumentCount;

pkg/front_end/parser_testcases/patterns/boolean_literal_inside_case.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ parseUnit(test)
6666
notEofOrValue(}, case)
6767
peekPastLabels(case)
6868
listener: beginCaseExpression(case)
69-
parsePattern(case, precedence: 1)
70-
parsePrimaryPattern(case)
69+
parsePattern(case, precedence: 1, isRefutableContext: true)
70+
parsePrimaryPattern(case, isRefutableContext: true)
7171
parsePrecedenceExpression(case, 18, false)
7272
parseUnaryExpression(case, false)
7373
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/boolean_literal_inside_cast.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ parseUnit(test)
6666
notEofOrValue(}, case)
6767
peekPastLabels(case)
6868
listener: beginCaseExpression(case)
69-
parsePattern(case, precedence: 1)
70-
parsePrimaryPattern(case)
69+
parsePattern(case, precedence: 1, isRefutableContext: true)
70+
parsePrimaryPattern(case, isRefutableContext: true)
7171
parsePrecedenceExpression(case, 18, false)
7272
parseUnaryExpression(case, false)
7373
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/boolean_literal_inside_if_case.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ parseUnit(test)
5858
parseArgumentsOpt(x)
5959
listener: handleNoArguments(case)
6060
listener: handleSend(x, case)
61-
parsePattern(case, precedence: 1)
62-
parsePrimaryPattern(case)
61+
parsePattern(case, precedence: 1, isRefutableContext: true)
62+
parsePrimaryPattern(case, isRefutableContext: true)
6363
parsePrecedenceExpression(case, 18, false)
6464
parseUnaryExpression(case, false)
6565
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/boolean_literal_inside_null_assert.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ parseUnit(test)
6666
notEofOrValue(}, case)
6767
peekPastLabels(case)
6868
listener: beginCaseExpression(case)
69-
parsePattern(case, precedence: 1)
70-
parsePrimaryPattern(case)
69+
parsePattern(case, precedence: 1, isRefutableContext: true)
70+
parsePrimaryPattern(case, isRefutableContext: true)
7171
parsePrecedenceExpression(case, 18, false)
7272
parseUnaryExpression(case, false)
7373
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/boolean_literal_inside_null_check.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ parseUnit(test)
6666
notEofOrValue(}, case)
6767
peekPastLabels(case)
6868
listener: beginCaseExpression(case)
69-
parsePattern(case, precedence: 1)
70-
parsePrimaryPattern(case)
69+
parsePattern(case, precedence: 1, isRefutableContext: true)
70+
parsePrimaryPattern(case, isRefutableContext: true)
7171
parsePrecedenceExpression(case, 18, false)
7272
parseUnaryExpression(case, false)
7373
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ parseUnit(void)
5555
parseArgumentsOpt(x)
5656
listener: handleNoArguments(case)
5757
listener: handleSend(x, case)
58-
parsePattern(case, precedence: 1)
59-
parsePrimaryPattern(case)
58+
parsePattern(case, precedence: 1, isRefutableContext: true)
59+
parsePrimaryPattern(case, isRefutableContext: true)
6060
parsePrecedenceExpression(case, 18, false)
6161
parseUnaryExpression(case, false)
6262
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ parseUnit(void)
6363
notEofOrValue(}, case)
6464
peekPastLabels(case)
6565
listener: beginCaseExpression(case)
66-
parsePattern(case, precedence: 1)
67-
parsePrimaryPattern(case)
66+
parsePattern(case, precedence: 1, isRefutableContext: true)
67+
parsePrimaryPattern(case, isRefutableContext: true)
6868
parsePrecedenceExpression(case, 18, false)
6969
parseUnaryExpression(case, false)
7070
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ parseUnit(void)
5555
parseArgumentsOpt(x)
5656
listener: handleNoArguments(case)
5757
listener: handleSend(x, case)
58-
parsePattern(case, precedence: 1)
59-
parsePrimaryPattern(case)
58+
parsePattern(case, precedence: 1, isRefutableContext: true)
59+
parsePrimaryPattern(case, isRefutableContext: true)
6060
parsePrecedenceExpression(case, 18, false)
6161
parseUnaryExpression(case, false)
6262
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ parseUnit(void)
6363
notEofOrValue(}, case)
6464
peekPastLabels(case)
6565
listener: beginCaseExpression(case)
66-
parsePattern(case, precedence: 1)
67-
parsePrimaryPattern(case)
66+
parsePattern(case, precedence: 1, isRefutableContext: true)
67+
parsePrimaryPattern(case, isRefutableContext: true)
6868
parsePrecedenceExpression(case, 18, false)
6969
parseUnaryExpression(case, false)
7070
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ parseUnit(void)
5555
parseArgumentsOpt(x)
5656
listener: handleNoArguments(case)
5757
listener: handleSend(x, case)
58-
parsePattern(case, precedence: 1)
59-
parsePrimaryPattern(case)
58+
parsePattern(case, precedence: 1, isRefutableContext: true)
59+
parsePrimaryPattern(case, isRefutableContext: true)
6060
parsePrecedenceExpression(case, 18, false)
6161
parseUnaryExpression(case, false)
6262
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ parseUnit(void)
6363
notEofOrValue(}, case)
6464
peekPastLabels(case)
6565
listener: beginCaseExpression(case)
66-
parsePattern(case, precedence: 1)
67-
parsePrimaryPattern(case)
66+
parsePattern(case, precedence: 1, isRefutableContext: true)
67+
parsePrimaryPattern(case, isRefutableContext: true)
6868
parsePrecedenceExpression(case, 18, false)
6969
parseUnaryExpression(case, false)
7070
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ parseUnit(void)
5555
parseArgumentsOpt(x)
5656
listener: handleNoArguments(case)
5757
listener: handleSend(x, case)
58-
parsePattern(case, precedence: 1)
59-
parsePrimaryPattern(case)
58+
parsePattern(case, precedence: 1, isRefutableContext: true)
59+
parsePrimaryPattern(case, isRefutableContext: true)
6060
parsePrecedenceExpression(case, 18, false)
6161
parseUnaryExpression(case, false)
6262
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,8 +63,8 @@ parseUnit(void)
6363
notEofOrValue(}, case)
6464
peekPastLabels(case)
6565
listener: beginCaseExpression(case)
66-
parsePattern(case, precedence: 1)
67-
parsePrimaryPattern(case)
66+
parsePattern(case, precedence: 1, isRefutableContext: true)
67+
parsePrimaryPattern(case, isRefutableContext: true)
6868
parsePrecedenceExpression(case, 18, false)
6969
parseUnaryExpression(case, false)
7070
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/cast_inside_case.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ parseUnit(test)
9393
notEofOrValue(}, case)
9494
peekPastLabels(case)
9595
listener: beginCaseExpression(case)
96-
parsePattern(case, precedence: 1)
97-
parsePrimaryPattern(case)
96+
parsePattern(case, precedence: 1, isRefutableContext: true)
97+
parsePrimaryPattern(case, isRefutableContext: true)
9898
parsePrecedenceExpression(case, 18, false)
9999
parseUnaryExpression(case, false)
100100
parsePrimary(case, expression)

pkg/front_end/parser_testcases/patterns/cast_inside_extractor_pattern.dart.intertwined.expect

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,14 +110,14 @@ parseUnit(class)
110110
notEofOrValue(}, case)
111111
peekPastLabels(case)
112112
listener: beginCaseExpression(case)
113-
parsePattern(case, precedence: 1)
114-
parsePrimaryPattern(case)
113+
parsePattern(case, precedence: 1, isRefutableContext: true)
114+
parsePrimaryPattern(case, isRefutableContext: true)
115115
listener: handleNoTypeArguments(()
116-
parseExtractorPatternRest(C)
116+
parseExtractorPatternRest(C, isRefutableContext: true)
117117
ensureIdentifier((, namedArgumentReference)
118118
listener: handleIdentifier(f, namedArgumentReference)
119-
parsePattern(:, precedence: 1)
120-
parsePrimaryPattern(:)
119+
parsePattern(:, precedence: 1, isRefutableContext: true)
120+
parsePrimaryPattern(:, isRefutableContext: true)
121121
parsePrecedenceExpression(:, 18, false)
122122
parseUnaryExpression(:, false)
123123
parsePrimary(:, expression)

pkg/front_end/parser_testcases/patterns/cast_inside_extractor_pattern_implicitly_named.dart.intertwined.expect

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,13 @@ parseUnit(class)
110110
notEofOrValue(}, case)
111111
peekPastLabels(case)
112112
listener: beginCaseExpression(case)
113-
parsePattern(case, precedence: 1)
114-
parsePrimaryPattern(case)
113+
parsePattern(case, precedence: 1, isRefutableContext: true)
114+
parsePrimaryPattern(case, isRefutableContext: true)
115115
listener: handleNoTypeArguments(()
116-
parseExtractorPatternRest(C)
116+
parseExtractorPatternRest(C, isRefutableContext: true)
117117
listener: handleNoName(()
118-
parsePattern(:, precedence: 1)
119-
parsePrimaryPattern(:)
118+
parsePattern(:, precedence: 1, isRefutableContext: true)
119+
parsePrimaryPattern(:, isRefutableContext: true)
120120
parseVariablePattern(:, typeInfo: Instance of 'NoType')
121121
listener: handleNoType(var)
122122
listener: handleVariablePattern(var, f)

pkg/front_end/parser_testcases/patterns/cast_inside_if_case.dart.intertwined.expect

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ parseUnit(test)
5858
parseArgumentsOpt(x)
5959
listener: handleNoArguments(case)
6060
listener: handleSend(x, case)
61-
parsePattern(case, precedence: 1)
62-
parsePrimaryPattern(case)
61+
parsePattern(case, precedence: 1, isRefutableContext: true)
62+
parsePrimaryPattern(case, isRefutableContext: true)
6363
parseVariablePattern(case, typeInfo: Instance of 'NoType')
6464
listener: handleNoType(var)
6565
listener: handleVariablePattern(var, y)

0 commit comments

Comments
 (0)