Skip to content

Commit 6bb1de7

Browse files
author
Dart CI
committed
Version 2.19.0-427.0.dev
Merge 67015b7 into dev
2 parents 71241dd + 67015b7 commit 6bb1de7

File tree

77 files changed

+2151
-32
lines changed

Some content is hidden

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

77 files changed

+2151
-32
lines changed

pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10659,6 +10659,60 @@ Message _withArgumentsSdkSummaryNotFound(Uri uri_) {
1065910659
arguments: {'uri': uri_});
1066010660
}
1066110661

10662+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
10663+
const Template<
10664+
Message Function(
10665+
String
10666+
name)> templateSealedClassSubtypeOutsideOfLibrary = const Template<
10667+
Message Function(String name)>(
10668+
problemMessageTemplate:
10669+
r"""Sealed class '#name' can't be extended, implemented, or mixed in outside of its library.""",
10670+
withArguments: _withArgumentsSealedClassSubtypeOutsideOfLibrary);
10671+
10672+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
10673+
const Code<Message Function(String name)>
10674+
codeSealedClassSubtypeOutsideOfLibrary =
10675+
const Code<Message Function(String name)>(
10676+
"SealedClassSubtypeOutsideOfLibrary",
10677+
);
10678+
10679+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
10680+
Message _withArgumentsSealedClassSubtypeOutsideOfLibrary(String name) {
10681+
if (name.isEmpty) throw 'No name provided';
10682+
name = demangleMixinApplicationName(name);
10683+
return new Message(codeSealedClassSubtypeOutsideOfLibrary,
10684+
problemMessage:
10685+
"""Sealed class '${name}' can't be extended, implemented, or mixed in outside of its library.""",
10686+
arguments: {'name': name});
10687+
}
10688+
10689+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
10690+
const Template<
10691+
Message Function(
10692+
String
10693+
name)> templateSealedMixinSubtypeOutsideOfLibrary = const Template<
10694+
Message Function(String name)>(
10695+
problemMessageTemplate:
10696+
r"""Sealed mixin '#name' can't be mixed in outside of its library.""",
10697+
withArguments: _withArgumentsSealedMixinSubtypeOutsideOfLibrary);
10698+
10699+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
10700+
const Code<Message Function(String name)>
10701+
codeSealedMixinSubtypeOutsideOfLibrary =
10702+
const Code<Message Function(String name)>(
10703+
"SealedMixinSubtypeOutsideOfLibrary",
10704+
);
10705+
10706+
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
10707+
Message _withArgumentsSealedMixinSubtypeOutsideOfLibrary(String name) {
10708+
if (name.isEmpty) throw 'No name provided';
10709+
name = demangleMixinApplicationName(name);
10710+
return new Message(codeSealedMixinSubtypeOutsideOfLibrary,
10711+
problemMessage:
10712+
"""Sealed mixin '${name}' can't be mixed in outside of its library.""",
10713+
arguments: {'name': name});
10714+
}
10715+
1066210716
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
1066310717
const Code<Null> codeSetLiteralTooManyTypeArguments =
1066410718
messageSetLiteralTooManyTypeArguments;

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

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -454,16 +454,31 @@ class ForwardingListener implements Listener {
454454
listener?.beginSwitchBlock(token);
455455
}
456456

457+
@override
458+
void beginSwitchExpressionBlock(Token token) {
459+
listener?.beginSwitchExpressionBlock(token);
460+
}
461+
457462
@override
458463
void beginSwitchCase(int labelCount, int expressionCount, Token firstToken) {
459464
listener?.beginSwitchCase(labelCount, expressionCount, firstToken);
460465
}
461466

467+
@override
468+
void beginSwitchExpressionCase() {
469+
listener?.beginSwitchExpressionCase();
470+
}
471+
462472
@override
463473
void beginSwitchStatement(Token token) {
464474
listener?.beginSwitchStatement(token);
465475
}
466476

477+
@override
478+
void beginSwitchExpression(Token token) {
479+
listener?.beginSwitchExpression(token);
480+
}
481+
467482
@override
468483
void handleThenControlFlow(Token token) {
469484
listener?.handleThenControlFlow(token);
@@ -1146,6 +1161,12 @@ class ForwardingListener implements Listener {
11461161
listener?.endSwitchBlock(caseCount, beginToken, endToken);
11471162
}
11481163

1164+
@override
1165+
void endSwitchExpressionBlock(
1166+
int caseCount, Token beginToken, Token endToken) {
1167+
listener?.endSwitchExpressionBlock(caseCount, beginToken, endToken);
1168+
}
1169+
11491170
@override
11501171
void endSwitchCase(
11511172
int labelCount,
@@ -1159,11 +1180,21 @@ class ForwardingListener implements Listener {
11591180
colonAfterDefault, statementCount, firstToken, endToken);
11601181
}
11611182

1183+
@override
1184+
void endSwitchExpressionCase(Token? when, Token arrow, Token endToken) {
1185+
listener?.endSwitchExpressionCase(when, arrow, endToken);
1186+
}
1187+
11621188
@override
11631189
void endSwitchStatement(Token switchKeyword, Token endToken) {
11641190
listener?.endSwitchStatement(switchKeyword, endToken);
11651191
}
11661192

1193+
@override
1194+
void endSwitchExpression(Token switchKeyword, Token endToken) {
1195+
listener?.endSwitchExpression(switchKeyword, endToken);
1196+
}
1197+
11671198
@override
11681199
void endThenStatement(Token token) {
11691200
listener?.endThenStatement(token);

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

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1254,12 +1254,25 @@ class Listener implements UnescapeErrorListener {
12541254
logEvent("SwitchStatement");
12551255
}
12561256

1257+
void beginSwitchExpression(Token token) {}
1258+
1259+
void endSwitchExpression(Token switchKeyword, Token endToken) {
1260+
logEvent("SwitchExpression");
1261+
}
1262+
12571263
void beginSwitchBlock(Token token) {}
12581264

12591265
void endSwitchBlock(int caseCount, Token beginToken, Token endToken) {
12601266
logEvent("SwitchBlock");
12611267
}
12621268

1269+
void beginSwitchExpressionBlock(Token token) {}
1270+
1271+
void endSwitchExpressionBlock(
1272+
int caseCount, Token beginToken, Token endToken) {
1273+
logEvent("SwitchExpressionBlock");
1274+
}
1275+
12631276
void beginLiteralSymbol(Token token) {}
12641277

12651278
void endLiteralSymbol(Token hashToken, int identifierCount) {
@@ -1950,6 +1963,12 @@ class Listener implements UnescapeErrorListener {
19501963
logEvent("SwitchCase");
19511964
}
19521965

1966+
void beginSwitchExpressionCase() {}
1967+
1968+
void endSwitchExpressionCase(Token? when, Token arrow, Token endToken) {
1969+
logEvent("SwitchExpressionCase");
1970+
}
1971+
19531972
void handleThisExpression(Token token, IdentifierContext context) {
19541973
logEvent("ThisExpression");
19551974
}

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

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3958,6 +3958,17 @@ class Parser {
39583958
return rewriteAndRecover(token, message, newToken);
39593959
}
39603960

3961+
/// If the next token is a function arrow (`=>`), return it. Otherwise report
3962+
/// an error, insert a synthetic function arrow, and return the inserted
3963+
/// function arrow.
3964+
Token ensureFunctionArrow(Token token) {
3965+
Token next = token.next!;
3966+
if (optional('=>', next)) return next;
3967+
codes.Message message = codes.templateExpectedButGot.withArguments('=>');
3968+
Token newToken = new SyntheticToken(TokenType.FUNCTION, next.charOffset);
3969+
return rewriteAndRecover(token, message, newToken);
3970+
}
3971+
39613972
/// If the token after [token] is a not literal string,
39623973
/// then insert a synthetic literal string.
39633974
/// Call `parseLiteralString` and return the result.
@@ -6106,6 +6117,8 @@ class Parser {
61066117
// Fall through to the recovery code.
61076118
} else if (identical(value, "assert")) {
61086119
return parseAssert(token, Assert.Expression);
6120+
} else if (allowPatterns && identical(value, "switch")) {
6121+
return parseSwitchExpression(token);
61096122
} else if (token.next!.isIdentifier) {
61106123
return parseSendOrFunctionLiteral(token, context);
61116124
} else if (identical(value, "return")) {
@@ -9821,6 +9834,73 @@ class Parser {
98219834
keyword, equals, semicolon);
98229835
return semicolon;
98239836
}
9837+
9838+
/// switchExpression ::= 'switch' '(' expression ')' '{'
9839+
/// switchExpressionCase ( ',' switchExpressionCase )*
9840+
/// ','? '}'
9841+
/// switchExpressionCase ::= guardedPattern '=>' expression
9842+
Token parseSwitchExpression(Token token) {
9843+
Token switchKeyword = token.next!;
9844+
assert(optional('switch', switchKeyword));
9845+
listener.beginSwitchExpression(switchKeyword);
9846+
token = ensureParenthesizedCondition(switchKeyword, allowCase: false);
9847+
Token beginSwitch =
9848+
token = ensureBlock(token, /* template = */ null, 'switch expression');
9849+
listener.beginSwitchExpressionBlock(beginSwitch);
9850+
Token next = token.next!;
9851+
int caseCount = 0;
9852+
if (!optional('}', next)) {
9853+
while (true) {
9854+
listener.beginSwitchExpressionCase();
9855+
token = parsePattern(token, isRefutableContext: true);
9856+
Token? when;
9857+
next = token.next!;
9858+
if (optional('when', next)) {
9859+
when = token = next;
9860+
token = parseExpression(token);
9861+
}
9862+
Token arrow = token = ensureFunctionArrow(token);
9863+
token = parseExpression(token);
9864+
listener.endSwitchExpressionCase(when, arrow, token);
9865+
++caseCount;
9866+
next = token.next!;
9867+
9868+
Token? comma;
9869+
if (optional(',', next)) {
9870+
comma = token = next;
9871+
next = token.next!;
9872+
}
9873+
if (optional('}', next)) {
9874+
break;
9875+
}
9876+
9877+
if (comma == null) {
9878+
// TODO(paulberry): test this error recovery logic
9879+
// Recovery
9880+
if (looksLikePatternStart(next)) {
9881+
// If this looks like the start of a pattern, then report an error,
9882+
// insert the comma, and continue parsing.
9883+
SyntheticToken comma =
9884+
new SyntheticToken(TokenType.COMMA, next.offset);
9885+
codes.Message message =
9886+
codes.templateExpectedButGot.withArguments(',');
9887+
token = rewriteAndRecover(token, message, comma);
9888+
} else {
9889+
reportRecoverableError(
9890+
next, codes.templateExpectedButGot.withArguments('}'));
9891+
// Scanner guarantees a closing curly bracket
9892+
next = beginSwitch.endGroup!;
9893+
break;
9894+
}
9895+
}
9896+
}
9897+
}
9898+
listener.endSwitchExpressionBlock(caseCount, beginSwitch, next);
9899+
token = next;
9900+
assert(token.isEof || optional('}', token));
9901+
listener.endSwitchExpression(switchKeyword, token);
9902+
return token;
9903+
}
98249904
}
98259905

98269906
// TODO(ahe): Remove when analyzer supports generalized function syntax.

pkg/analyzer/lib/src/fasta/ast_builder.dart

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3040,6 +3040,61 @@ class AstBuilder extends StackListener {
30403040
push(members2);
30413041
}
30423042

3043+
@override
3044+
void endSwitchExpression(Token switchKeyword, Token endToken) {
3045+
assert(optional('switch', switchKeyword));
3046+
debugEvent("SwitchExpression");
3047+
3048+
var rightBracket = pop() as Token;
3049+
var cases = pop() as List<SwitchExpressionCaseImpl>;
3050+
var leftBracket = pop() as Token;
3051+
var condition = pop() as _ParenthesizedCondition;
3052+
push(
3053+
SwitchExpressionImpl(
3054+
switchKeyword: switchKeyword,
3055+
leftParenthesis: condition.leftParenthesis,
3056+
expression: condition.expression,
3057+
rightParenthesis: condition.rightParenthesis,
3058+
leftBracket: leftBracket,
3059+
cases: cases,
3060+
rightBracket: rightBracket,
3061+
),
3062+
);
3063+
}
3064+
3065+
@override
3066+
void endSwitchExpressionBlock(
3067+
int caseCount, Token leftBracket, Token rightBracket) {
3068+
assert(optional('{', leftBracket));
3069+
assert(optional('}', rightBracket));
3070+
debugEvent("SwitchExpressionBlock");
3071+
3072+
var cases = popTypedList2<SwitchExpressionCaseImpl>(caseCount);
3073+
3074+
push(leftBracket);
3075+
push(cases);
3076+
push(rightBracket);
3077+
}
3078+
3079+
@override
3080+
void endSwitchExpressionCase(Token? when, Token arrow, Token endToken) {
3081+
debugEvent("SwitchExpressionCase");
3082+
var expression = pop() as ExpressionImpl;
3083+
WhenClauseImpl? whenClause;
3084+
if (when != null) {
3085+
var expression = pop() as ExpressionImpl;
3086+
whenClause = WhenClauseImpl(whenKeyword: when, expression: expression);
3087+
}
3088+
var pattern = pop() as DartPatternImpl;
3089+
push(SwitchExpressionCaseImpl(
3090+
guardedPattern: GuardedPatternImpl(
3091+
pattern: pattern,
3092+
whenClause: whenClause,
3093+
),
3094+
arrow: arrow,
3095+
expression: expression));
3096+
}
3097+
30433098
@override
30443099
void endSwitchStatement(Token switchKeyword, Token endToken) {
30453100
assert(optional('switch', switchKeyword));

pkg/analyzer/lib/src/test_utilities/find_node.dart

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ class FindNode {
3939
}
4040
},
4141
switchPatternCase: (node) => nodes.add(node.guardedPattern),
42+
switchExpressionCase: (node) => nodes.add(node.guardedPattern),
4243
),
4344
);
4445
return nodes.single;

pkg/analyzer/lib/src/test_utilities/function_ast_visitor.dart

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ class FunctionAstVisitor extends RecursiveAstVisitor<void> {
1616
final void Function(Label)? label;
1717
final void Function(MethodInvocation)? methodInvocation;
1818
final void Function(SimpleIdentifier)? simpleIdentifier;
19+
final void Function(SwitchExpressionCase)? switchExpressionCase;
1920
final void Function(SwitchPatternCase)? switchPatternCase;
2021
final void Function(VariableDeclaration)? variableDeclaration;
2122

@@ -28,6 +29,7 @@ class FunctionAstVisitor extends RecursiveAstVisitor<void> {
2829
this.label,
2930
this.methodInvocation,
3031
this.simpleIdentifier,
32+
this.switchExpressionCase,
3133
this.switchPatternCase,
3234
this.variableDeclaration,
3335
});
@@ -94,6 +96,12 @@ class FunctionAstVisitor extends RecursiveAstVisitor<void> {
9496
super.visitSimpleIdentifier(node);
9597
}
9698

99+
@override
100+
void visitSwitchExpressionCase(SwitchExpressionCase node) {
101+
switchExpressionCase?.call(node);
102+
super.visitSwitchExpressionCase(node);
103+
}
104+
97105
@override
98106
void visitSwitchPatternCase(SwitchPatternCase node) {
99107
switchPatternCase?.call(node);

0 commit comments

Comments
 (0)