Patterns parsing: add support for guards.
Bug: https://github.com/dart-lang/sdk/issues/50035
Change-Id: I21db09c9d8c1d359e1b125eea2bae2749cdb72fd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/264101
Reviewed-by: Jens Johansen <jensj@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
index 807a3a6..3ad1953 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -6240,8 +6240,14 @@
if (allowPatterns && optional('case', next)) {
Token case_ = token = next;
token = parsePattern(token);
+ next = token.next!;
+ Token? when;
+ if (optional('when', next)) {
+ when = token = next;
+ token = parseExpression(token);
+ }
token = ensureCloseParen(token, begin);
- listener.handleParenthesizedCondition(begin, case_, null);
+ listener.handleParenthesizedCondition(begin, case_, when);
} else {
token = ensureCloseParen(token, begin);
listener.handleParenthesizedCondition(
@@ -8258,9 +8264,15 @@
} else {
token = parseExpression(caseKeyword);
}
+ Token? next = token.next!;
+ Token? when;
+ if (optional('when', next)) {
+ when = token = next;
+ token = parseExpression(token);
+ }
token = ensureColon(token);
- listener.endCaseExpression(null, token);
- listener.handleCaseMatch(caseKeyword, null, token);
+ listener.endCaseExpression(when, token);
+ listener.handleCaseMatch(caseKeyword, when, token);
expressionCount++;
peek = peekPastLabels(token.next!);
} else if (expressionCount > 0) {
diff --git a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
index ccbb40f..a3afcf2 100644
--- a/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/scanner/token.dart
@@ -327,14 +327,17 @@
static const Keyword VOID =
const Keyword(/* index = */ 145, "void", "VOID", KeywordStyle.reserved);
+ static const Keyword WHEN =
+ const Keyword(/* index = */ 146, "when", 'WHEN', KeywordStyle.pseudo);
+
static const Keyword WHILE =
- const Keyword(/* index = */ 146, "while", "WHILE", KeywordStyle.reserved);
+ const Keyword(/* index = */ 147, "while", "WHILE", KeywordStyle.reserved);
static const Keyword WITH =
- const Keyword(/* index = */ 147, "with", "WITH", KeywordStyle.reserved);
+ const Keyword(/* index = */ 148, "with", "WITH", KeywordStyle.reserved);
static const Keyword YIELD =
- const Keyword(/* index = */ 148, "yield", "YIELD", KeywordStyle.pseudo);
+ const Keyword(/* index = */ 149, "yield", "YIELD", KeywordStyle.pseudo);
static const List<Keyword> values = const <Keyword>[
ABSTRACT,
@@ -404,6 +407,7 @@
TYPEDEF,
VAR,
VOID,
+ WHEN,
WHILE,
WITH,
YIELD,
@@ -1978,6 +1982,7 @@
Keyword.TYPEDEF,
Keyword.VAR,
Keyword.VOID,
+ Keyword.WHEN,
Keyword.WHILE,
Keyword.WITH,
Keyword.YIELD,
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index 365fed9..d944173 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -1483,6 +1483,7 @@
required this.whenClause,
}) {
_becomeParentOf(pattern);
+ _becomeParentOf(whenClause);
}
@override
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 7b84143..95467fe 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -3282,12 +3282,17 @@
debugEvent("CaseMatch");
if (_featureSet.isEnabled(Feature.patterns)) {
+ WhenClauseImpl? whenClause;
+ if (when != null) {
+ var expression = pop() as ExpressionImpl;
+ whenClause = WhenClauseImpl(whenKeyword: when, expression: expression);
+ }
var pattern = pop() as DartPatternImpl;
push(SwitchPatternCaseImpl(
labels: <Label>[],
keyword: caseKeyword,
pattern: pattern,
- whenClause: null,
+ whenClause: whenClause,
colon: colon,
statements: <Statement>[]));
} else {
@@ -4561,10 +4566,14 @@
ExpressionImpl condition;
CaseClauseImpl? caseClause;
if (case_ != null) {
- // TODO(paulberry): what about a guard?
+ WhenClauseImpl? whenClause;
+ if (when != null) {
+ var expression = pop() as ExpressionImpl;
+ whenClause = WhenClauseImpl(whenKeyword: when, expression: expression);
+ }
var pattern = pop() as DartPatternImpl;
caseClause = CaseClauseImpl(
- caseKeyword: case_, pattern: pattern, whenClause: null);
+ caseKeyword: case_, pattern: pattern, whenClause: whenClause);
}
condition = pop() as ExpressionImpl;
push(_ParenthesizedCondition(leftParenthesis, condition, caseClause));
diff --git a/pkg/analyzer/test/generated/patterns_parser_test.dart b/pkg/analyzer/test/generated/patterns_parser_test.dart
index 0b11317..a5b6123 100644
--- a/pkg/analyzer/test/generated/patterns_parser_test.dart
+++ b/pkg/analyzer/test/generated/patterns_parser_test.dart
@@ -21,6 +21,238 @@
class PatternsTest extends ParserDiagnosticsTest {
late FindNode findNode;
+ test_caseHead_withClassicPattern_guarded_insideIfStatement() {
+ _parse('''
+void f(x) {
+ if (x case 0 when true) {}
+}
+''');
+ var node = findNode.ifStatement('case');
+ assertParsedNodeText(node, r'''
+IfStatement
+ ifKeyword: if
+ leftParenthesis: (
+ condition: SimpleIdentifier
+ token: x
+ caseClause: CaseClause
+ caseKeyword: case
+ pattern: ConstantPattern
+ expression: IntegerLiteral
+ literal: 0
+ whenClause: WhenClause
+ whenKeyword: when
+ expression: BooleanLiteral
+ literal: true
+ rightParenthesis: )
+ thenStatement: Block
+ leftBracket: {
+ rightBracket: }
+''');
+ }
+
+ test_caseHead_withClassicPattern_guarded_insideSwitchStatement() {
+ _parse('''
+void f(x) {
+ switch (x) {
+ case 0 when true:
+ break;
+ }
+}
+''');
+ var node = findNode.switchPatternCase('case');
+ assertParsedNodeText(node, r'''
+SwitchPatternCase
+ keyword: case
+ pattern: ConstantPattern
+ expression: IntegerLiteral
+ literal: 0
+ whenClause: WhenClause
+ whenKeyword: when
+ expression: BooleanLiteral
+ literal: true
+ colon: :
+ statements
+ BreakStatement
+ breakKeyword: break
+ semicolon: ;
+''');
+ }
+
+ test_caseHead_withClassicPattern_unguarded_insideIfStatement() {
+ _parse('''
+void f(x) {
+ if (x case 0) {}
+}
+''');
+ var node = findNode.ifStatement('case');
+ assertParsedNodeText(node, r'''
+IfStatement
+ ifKeyword: if
+ leftParenthesis: (
+ condition: SimpleIdentifier
+ token: x
+ caseClause: CaseClause
+ caseKeyword: case
+ pattern: ConstantPattern
+ expression: IntegerLiteral
+ literal: 0
+ rightParenthesis: )
+ thenStatement: Block
+ leftBracket: {
+ rightBracket: }
+''');
+ }
+
+ test_caseHead_withClassicPattern_unguarded_insideSwitchStatement() {
+ _parse('''
+void f(x) {
+ switch (x) {
+ case 0:
+ break;
+ }
+}
+''');
+ var node = findNode.switchPatternCase('case');
+ assertParsedNodeText(node, r'''
+SwitchPatternCase
+ keyword: case
+ pattern: ConstantPattern
+ expression: IntegerLiteral
+ literal: 0
+ colon: :
+ statements
+ BreakStatement
+ breakKeyword: break
+ semicolon: ;
+''');
+ }
+
+ test_caseHead_withNewPattern_guarded_insideIfStatement() {
+ _parse('''
+void f(x) {
+ if (x case 0 as int when true) {}
+}
+''');
+ var node = findNode.ifStatement('case');
+ assertParsedNodeText(node, r'''
+IfStatement
+ ifKeyword: if
+ leftParenthesis: (
+ condition: SimpleIdentifier
+ token: x
+ caseClause: CaseClause
+ caseKeyword: case
+ pattern: CastPattern
+ pattern: ConstantPattern
+ expression: IntegerLiteral
+ literal: 0
+ asToken: as
+ type: NamedType
+ name: SimpleIdentifier
+ token: int
+ whenClause: WhenClause
+ whenKeyword: when
+ expression: BooleanLiteral
+ literal: true
+ rightParenthesis: )
+ thenStatement: Block
+ leftBracket: {
+ rightBracket: }
+''');
+ }
+
+ test_caseHead_withNewPattern_guarded_insideSwitchStatement() {
+ _parse('''
+void f(x) {
+ switch (x) {
+ case 0 as int when true:
+ break;
+ }
+}
+''');
+ var node = findNode.switchPatternCase('case');
+ assertParsedNodeText(node, r'''
+SwitchPatternCase
+ keyword: case
+ pattern: CastPattern
+ pattern: ConstantPattern
+ expression: IntegerLiteral
+ literal: 0
+ asToken: as
+ type: NamedType
+ name: SimpleIdentifier
+ token: int
+ whenClause: WhenClause
+ whenKeyword: when
+ expression: BooleanLiteral
+ literal: true
+ colon: :
+ statements
+ BreakStatement
+ breakKeyword: break
+ semicolon: ;
+''');
+ }
+
+ test_caseHead_withNewPattern_unguarded_insideIfStatement() {
+ _parse('''
+void f(x) {
+ if (x case 0 as int) {}
+}
+''');
+ var node = findNode.ifStatement('case');
+ assertParsedNodeText(node, r'''
+IfStatement
+ ifKeyword: if
+ leftParenthesis: (
+ condition: SimpleIdentifier
+ token: x
+ caseClause: CaseClause
+ caseKeyword: case
+ pattern: CastPattern
+ pattern: ConstantPattern
+ expression: IntegerLiteral
+ literal: 0
+ asToken: as
+ type: NamedType
+ name: SimpleIdentifier
+ token: int
+ rightParenthesis: )
+ thenStatement: Block
+ leftBracket: {
+ rightBracket: }
+''');
+ }
+
+ test_caseHead_withNewPattern_unguarded_insideSwitchStatement() {
+ _parse('''
+void f(x) {
+ switch (x) {
+ case 0 as int:
+ break;
+ }
+}
+''');
+ var node = findNode.switchPatternCase('case');
+ assertParsedNodeText(node, r'''
+SwitchPatternCase
+ keyword: case
+ pattern: CastPattern
+ pattern: ConstantPattern
+ expression: IntegerLiteral
+ literal: 0
+ asToken: as
+ type: NamedType
+ name: SimpleIdentifier
+ token: int
+ colon: :
+ statements
+ BreakStatement
+ breakKeyword: break
+ semicolon: ;
+''');
+ }
+
test_cast_insideCase() {
_parse('''
void f(x) {
diff --git a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
index 6e742b2..dbdf688 100644
--- a/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
+++ b/pkg/analyzer/test/src/summary/resolved_ast_printer.dart
@@ -1439,6 +1439,14 @@
}
@override
+ void visitWhenClause(WhenClause node) {
+ _writeln('WhenClause');
+ _withIndent(() {
+ _writeNamedChildEntities(node);
+ });
+ }
+
+ @override
void visitWhileStatement(WhileStatement node) {
_writeln('WhileStatement');
_withIndent(() {
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index ba99d30..c7fc608 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -2281,6 +2281,28 @@
@override
void handleParenthesizedCondition(Token token, Token? case_, Token? when) {
if (case_ != null) {
+ // ignore: unused_local_variable
+ Expression? guard;
+ if (when != null) {
+ assert(checkState(token, [
+ unionOfKinds([
+ ValueKinds.Expression,
+ ValueKinds.Generator,
+ ValueKinds.ProblemBuilder,
+ ]),
+ unionOfKinds([
+ ValueKinds.Expression,
+ ValueKinds.Matcher,
+ ValueKinds.Binder,
+ ]),
+ unionOfKinds([
+ ValueKinds.Expression,
+ ValueKinds.Generator,
+ ValueKinds.ProblemBuilder,
+ ]),
+ ]));
+ guard = popForValue();
+ }
assert(checkState(token, [
unionOfKinds([
ValueKinds.Expression,
@@ -2508,6 +2530,26 @@
@override
void endCaseExpression(Token? when, Token colon) {
+ // ignore: unused_local_variable
+ Expression? guard;
+ if (when != null) {
+ assert(checkState(colon, [
+ unionOfKinds([
+ ValueKinds.Expression,
+ ValueKinds.Generator,
+ ValueKinds.ProblemBuilder,
+ ]),
+ unionOfKinds([
+ ValueKinds.Expression,
+ ValueKinds.Generator,
+ ValueKinds.ProblemBuilder,
+ ValueKinds.Matcher,
+ ValueKinds.Binder,
+ ]),
+ ValueKinds.ConstantContext,
+ ]));
+ guard = popForValue();
+ }
assert(checkState(colon, [
unionOfKinds([
ValueKinds.Expression,
@@ -2522,10 +2564,12 @@
Object? value = pop();
if (value is Matcher || value is Binder) {
constantContext = pop() as ConstantContext;
+ // TODO(paulberry): handle guard
super.push(toMatcher(value));
} else {
Expression expression = toValue(value);
constantContext = pop() as ConstantContext;
+ // TODO(paulberry): handle guard
super.push(expression);
}
assert(checkState(colon, [
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart
new file mode 100644
index 0000000..f1abcf1
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart
@@ -0,0 +1,3 @@
+void f(x) {
+ if (x case 0 when true) {}
+}
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.expect
new file mode 100644
index 0000000..791b439
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.expect
@@ -0,0 +1,37 @@
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null, null)
+ handleVoidKeyword(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ beginMetadataStar(x)
+ endMetadataStar(0)
+ beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ handleNoType(()
+ handleIdentifier(x, formalParameterDeclaration)
+ handleFormalParameterWithoutValue())
+ endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginIfStatement(if)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments(case)
+ handleNoArguments(case)
+ handleSend(x, case)
+ handleLiteralInt(0)
+ handleConstantPattern(null)
+ handleLiteralBool(true)
+ handleParenthesizedCondition((, case, when)
+ beginThenStatement({)
+ beginBlock({, BlockKind(statement))
+ endBlock(0, {, }, BlockKind(statement))
+ endThenStatement(})
+ endIfStatement(if, null)
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.intertwined.expect
new file mode 100644
index 0000000..8930d09
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.intertwined.expect
@@ -0,0 +1,89 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleVoidKeyword(void)
+ ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ parseMetadataStar(()
+ listener: beginMetadataStar(x)
+ listener: endMetadataStar(0)
+ listener: beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ listener: handleNoType(()
+ ensureIdentifier((, formalParameterDeclaration)
+ listener: handleIdentifier(x, formalParameterDeclaration)
+ listener: handleFormalParameterWithoutValue())
+ listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, if)
+ parseStatement({)
+ parseStatementX({)
+ parseIfStatement({)
+ listener: beginIfStatement(if)
+ ensureParenthesizedCondition(if, allowCase: true)
+ parseExpressionInParenthesisRest((, allowCase: true)
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ isNextIdentifier(()
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments(case)
+ parseArgumentsOpt(x)
+ listener: handleNoArguments(case)
+ listener: handleSend(x, case)
+ parsePattern(case, precedence: 1)
+ parsePrimaryPattern(case)
+ parsePrecedenceExpression(case, 18, false)
+ parseUnaryExpression(case, false)
+ parsePrimary(case, expression)
+ parseLiteralInt(case)
+ listener: handleLiteralInt(0)
+ listener: handleConstantPattern(null)
+ parseExpression(when)
+ parsePrecedenceExpression(when, 1, true)
+ parseUnaryExpression(when, true)
+ parsePrimary(when, expression)
+ parseLiteralBool(when)
+ listener: handleLiteralBool(true)
+ ensureCloseParen(true, ()
+ listener: handleParenthesizedCondition((, case, when)
+ listener: beginThenStatement({)
+ parseStatement())
+ parseStatementX())
+ parseBlock(), BlockKind(statement))
+ ensureBlock(), null, null)
+ listener: beginBlock({, BlockKind(statement))
+ notEofOrValue(}, })
+ listener: endBlock(0, {, }, BlockKind(statement))
+ listener: endThenStatement(})
+ listener: endIfStatement(if, null)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.parser.expect
new file mode 100644
index 0000000..de1f943
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.parser.expect
@@ -0,0 +1,9 @@
+void f(x) {
+if (x case 0 when true) {}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] case[KeywordToken] 0[StringToken] when[KeywordToken] true[KeywordToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.scanner.expect
new file mode 100644
index 0000000..de1f943
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideIfStatement.dart.scanner.expect
@@ -0,0 +1,9 @@
+void f(x) {
+if (x case 0 when true) {}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] case[KeywordToken] 0[StringToken] when[KeywordToken] true[KeywordToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart
new file mode 100644
index 0000000..b678211
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart
@@ -0,0 +1,6 @@
+void f(x) {
+ switch (x) {
+ case 0 when true:
+ break;
+ }
+}
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.expect
new file mode 100644
index 0000000..78ebb90
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.expect
@@ -0,0 +1,41 @@
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null, null)
+ handleVoidKeyword(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ beginMetadataStar(x)
+ endMetadataStar(0)
+ beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ handleNoType(()
+ handleIdentifier(x, formalParameterDeclaration)
+ handleFormalParameterWithoutValue())
+ endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginSwitchStatement(switch)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(x, ))
+ handleParenthesizedCondition((, null, null)
+ beginSwitchBlock({)
+ beginCaseExpression(case)
+ handleLiteralInt(0)
+ handleConstantPattern(null)
+ handleLiteralBool(true)
+ endCaseExpression(when, :)
+ handleCaseMatch(case, when, :)
+ beginSwitchCase(0, 1, case)
+ handleBreakStatement(false, break, ;)
+ endSwitchCase(0, 1, null, null, 1, case, })
+ endSwitchBlock(1, {, })
+ endSwitchStatement(switch, })
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.intertwined.expect
new file mode 100644
index 0000000..a8dfcbe
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.intertwined.expect
@@ -0,0 +1,102 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleVoidKeyword(void)
+ ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ parseMetadataStar(()
+ listener: beginMetadataStar(x)
+ listener: endMetadataStar(0)
+ listener: beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ listener: handleNoType(()
+ ensureIdentifier((, formalParameterDeclaration)
+ listener: handleIdentifier(x, formalParameterDeclaration)
+ listener: handleFormalParameterWithoutValue())
+ listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, switch)
+ parseStatement({)
+ parseStatementX({)
+ parseSwitchStatement({)
+ listener: beginSwitchStatement(switch)
+ ensureParenthesizedCondition(switch, allowCase: false)
+ parseExpressionInParenthesisRest((, allowCase: false)
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ isNextIdentifier(()
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(x)
+ listener: handleNoArguments())
+ listener: handleSend(x, ))
+ ensureCloseParen(x, ()
+ listener: handleParenthesizedCondition((, null, null)
+ parseSwitchBlock())
+ ensureBlock(), null, switch statement)
+ listener: beginSwitchBlock({)
+ notEofOrValue(}, case)
+ peekPastLabels(case)
+ listener: beginCaseExpression(case)
+ parsePattern(case, precedence: 1)
+ parsePrimaryPattern(case)
+ parsePrecedenceExpression(case, 18, false)
+ parseUnaryExpression(case, false)
+ parsePrimary(case, expression)
+ parseLiteralInt(case)
+ listener: handleLiteralInt(0)
+ listener: handleConstantPattern(null)
+ parseExpression(when)
+ parsePrecedenceExpression(when, 1, true)
+ parseUnaryExpression(when, true)
+ parsePrimary(when, expression)
+ parseLiteralBool(when)
+ listener: handleLiteralBool(true)
+ ensureColon(true)
+ listener: endCaseExpression(when, :)
+ listener: handleCaseMatch(case, when, :)
+ peekPastLabels(break)
+ parseStatementsInSwitchCase(:, break, case, 0, 1, null, null)
+ listener: beginSwitchCase(0, 1, case)
+ parseStatement(:)
+ parseStatementX(:)
+ parseBreakStatement(:)
+ isBreakAllowed()
+ ensureSemicolon(break)
+ listener: handleBreakStatement(false, break, ;)
+ peekPastLabels(})
+ listener: endSwitchCase(0, 1, null, null, 1, case, })
+ notEofOrValue(}, })
+ listener: endSwitchBlock(1, {, })
+ listener: endSwitchStatement(switch, })
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.parser.expect
new file mode 100644
index 0000000..b8edb2d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.parser.expect
@@ -0,0 +1,15 @@
+void f(x) {
+switch (x) {
+case 0 when true:
+break;
+}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+case[KeywordToken] 0[StringToken] when[KeywordToken] true[KeywordToken]:[SimpleToken]
+break[KeywordToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.scanner.expect
new file mode 100644
index 0000000..b8edb2d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_guarded_insideSwitchStatement.dart.scanner.expect
@@ -0,0 +1,15 @@
+void f(x) {
+switch (x) {
+case 0 when true:
+break;
+}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+case[KeywordToken] 0[StringToken] when[KeywordToken] true[KeywordToken]:[SimpleToken]
+break[KeywordToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart
new file mode 100644
index 0000000..d0632c7
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart
@@ -0,0 +1,3 @@
+void f(x) {
+ if (x case 0) {}
+}
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.expect
new file mode 100644
index 0000000..c9e3ad2
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.expect
@@ -0,0 +1,36 @@
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null, null)
+ handleVoidKeyword(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ beginMetadataStar(x)
+ endMetadataStar(0)
+ beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ handleNoType(()
+ handleIdentifier(x, formalParameterDeclaration)
+ handleFormalParameterWithoutValue())
+ endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginIfStatement(if)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments(case)
+ handleNoArguments(case)
+ handleSend(x, case)
+ handleLiteralInt(0)
+ handleConstantPattern(null)
+ handleParenthesizedCondition((, case, null)
+ beginThenStatement({)
+ beginBlock({, BlockKind(statement))
+ endBlock(0, {, }, BlockKind(statement))
+ endThenStatement(})
+ endIfStatement(if, null)
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.intertwined.expect
new file mode 100644
index 0000000..975d0ce
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.intertwined.expect
@@ -0,0 +1,83 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleVoidKeyword(void)
+ ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ parseMetadataStar(()
+ listener: beginMetadataStar(x)
+ listener: endMetadataStar(0)
+ listener: beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ listener: handleNoType(()
+ ensureIdentifier((, formalParameterDeclaration)
+ listener: handleIdentifier(x, formalParameterDeclaration)
+ listener: handleFormalParameterWithoutValue())
+ listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, if)
+ parseStatement({)
+ parseStatementX({)
+ parseIfStatement({)
+ listener: beginIfStatement(if)
+ ensureParenthesizedCondition(if, allowCase: true)
+ parseExpressionInParenthesisRest((, allowCase: true)
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ isNextIdentifier(()
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments(case)
+ parseArgumentsOpt(x)
+ listener: handleNoArguments(case)
+ listener: handleSend(x, case)
+ parsePattern(case, precedence: 1)
+ parsePrimaryPattern(case)
+ parsePrecedenceExpression(case, 18, false)
+ parseUnaryExpression(case, false)
+ parsePrimary(case, expression)
+ parseLiteralInt(case)
+ listener: handleLiteralInt(0)
+ listener: handleConstantPattern(null)
+ ensureCloseParen(0, ()
+ listener: handleParenthesizedCondition((, case, null)
+ listener: beginThenStatement({)
+ parseStatement())
+ parseStatementX())
+ parseBlock(), BlockKind(statement))
+ ensureBlock(), null, null)
+ listener: beginBlock({, BlockKind(statement))
+ notEofOrValue(}, })
+ listener: endBlock(0, {, }, BlockKind(statement))
+ listener: endThenStatement(})
+ listener: endIfStatement(if, null)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.parser.expect
new file mode 100644
index 0000000..4a4c785
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.parser.expect
@@ -0,0 +1,9 @@
+void f(x) {
+if (x case 0) {}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] case[KeywordToken] 0[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.scanner.expect
new file mode 100644
index 0000000..4a4c785
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideIfStatement.dart.scanner.expect
@@ -0,0 +1,9 @@
+void f(x) {
+if (x case 0) {}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] case[KeywordToken] 0[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart
new file mode 100644
index 0000000..9d25283
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart
@@ -0,0 +1,6 @@
+void f(x) {
+ switch (x) {
+ case 0:
+ break;
+ }
+}
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.expect
new file mode 100644
index 0000000..ac84fe9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.expect
@@ -0,0 +1,40 @@
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null, null)
+ handleVoidKeyword(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ beginMetadataStar(x)
+ endMetadataStar(0)
+ beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ handleNoType(()
+ handleIdentifier(x, formalParameterDeclaration)
+ handleFormalParameterWithoutValue())
+ endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginSwitchStatement(switch)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(x, ))
+ handleParenthesizedCondition((, null, null)
+ beginSwitchBlock({)
+ beginCaseExpression(case)
+ handleLiteralInt(0)
+ handleConstantPattern(null)
+ endCaseExpression(null, :)
+ handleCaseMatch(case, null, :)
+ beginSwitchCase(0, 1, case)
+ handleBreakStatement(false, break, ;)
+ endSwitchCase(0, 1, null, null, 1, case, })
+ endSwitchBlock(1, {, })
+ endSwitchStatement(switch, })
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.intertwined.expect
new file mode 100644
index 0000000..363a210
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.intertwined.expect
@@ -0,0 +1,96 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleVoidKeyword(void)
+ ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ parseMetadataStar(()
+ listener: beginMetadataStar(x)
+ listener: endMetadataStar(0)
+ listener: beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ listener: handleNoType(()
+ ensureIdentifier((, formalParameterDeclaration)
+ listener: handleIdentifier(x, formalParameterDeclaration)
+ listener: handleFormalParameterWithoutValue())
+ listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, switch)
+ parseStatement({)
+ parseStatementX({)
+ parseSwitchStatement({)
+ listener: beginSwitchStatement(switch)
+ ensureParenthesizedCondition(switch, allowCase: false)
+ parseExpressionInParenthesisRest((, allowCase: false)
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ isNextIdentifier(()
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(x)
+ listener: handleNoArguments())
+ listener: handleSend(x, ))
+ ensureCloseParen(x, ()
+ listener: handleParenthesizedCondition((, null, null)
+ parseSwitchBlock())
+ ensureBlock(), null, switch statement)
+ listener: beginSwitchBlock({)
+ notEofOrValue(}, case)
+ peekPastLabels(case)
+ listener: beginCaseExpression(case)
+ parsePattern(case, precedence: 1)
+ parsePrimaryPattern(case)
+ parsePrecedenceExpression(case, 18, false)
+ parseUnaryExpression(case, false)
+ parsePrimary(case, expression)
+ parseLiteralInt(case)
+ listener: handleLiteralInt(0)
+ listener: handleConstantPattern(null)
+ ensureColon(0)
+ listener: endCaseExpression(null, :)
+ listener: handleCaseMatch(case, null, :)
+ peekPastLabels(break)
+ parseStatementsInSwitchCase(:, break, case, 0, 1, null, null)
+ listener: beginSwitchCase(0, 1, case)
+ parseStatement(:)
+ parseStatementX(:)
+ parseBreakStatement(:)
+ isBreakAllowed()
+ ensureSemicolon(break)
+ listener: handleBreakStatement(false, break, ;)
+ peekPastLabels(})
+ listener: endSwitchCase(0, 1, null, null, 1, case, })
+ notEofOrValue(}, })
+ listener: endSwitchBlock(1, {, })
+ listener: endSwitchStatement(switch, })
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.parser.expect
new file mode 100644
index 0000000..14149d9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.parser.expect
@@ -0,0 +1,15 @@
+void f(x) {
+switch (x) {
+case 0:
+break;
+}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+case[KeywordToken] 0[StringToken]:[SimpleToken]
+break[KeywordToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.scanner.expect
new file mode 100644
index 0000000..14149d9
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withClassicPattern_unguarded_insideSwitchStatement.dart.scanner.expect
@@ -0,0 +1,15 @@
+void f(x) {
+switch (x) {
+case 0:
+break;
+}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+case[KeywordToken] 0[StringToken]:[SimpleToken]
+break[KeywordToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart
new file mode 100644
index 0000000..833315c
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart
@@ -0,0 +1,3 @@
+void f(x) {
+ if (x case 0 as int when true) {}
+}
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.expect
new file mode 100644
index 0000000..a28520f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.expect
@@ -0,0 +1,43 @@
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null, null)
+ handleVoidKeyword(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ beginMetadataStar(x)
+ endMetadataStar(0)
+ beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ handleNoType(()
+ handleIdentifier(x, formalParameterDeclaration)
+ handleFormalParameterWithoutValue())
+ endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginIfStatement(if)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments(case)
+ handleNoArguments(case)
+ handleSend(x, case)
+ handleLiteralInt(0)
+ handleConstantPattern(null)
+ beginAsOperatorType(as)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(when)
+ handleType(int, null)
+ endAsOperatorType(as)
+ handleCastPattern(as)
+ handleLiteralBool(true)
+ handleParenthesizedCondition((, case, when)
+ beginThenStatement({)
+ beginBlock({, BlockKind(statement))
+ endBlock(0, {, }, BlockKind(statement))
+ endThenStatement(})
+ endIfStatement(if, null)
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.intertwined.expect
new file mode 100644
index 0000000..9797f8b
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.intertwined.expect
@@ -0,0 +1,96 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleVoidKeyword(void)
+ ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ parseMetadataStar(()
+ listener: beginMetadataStar(x)
+ listener: endMetadataStar(0)
+ listener: beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ listener: handleNoType(()
+ ensureIdentifier((, formalParameterDeclaration)
+ listener: handleIdentifier(x, formalParameterDeclaration)
+ listener: handleFormalParameterWithoutValue())
+ listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, if)
+ parseStatement({)
+ parseStatementX({)
+ parseIfStatement({)
+ listener: beginIfStatement(if)
+ ensureParenthesizedCondition(if, allowCase: true)
+ parseExpressionInParenthesisRest((, allowCase: true)
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ isNextIdentifier(()
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments(case)
+ parseArgumentsOpt(x)
+ listener: handleNoArguments(case)
+ listener: handleSend(x, case)
+ parsePattern(case, precedence: 1)
+ parsePrimaryPattern(case)
+ parsePrecedenceExpression(case, 18, false)
+ parseUnaryExpression(case, false)
+ parsePrimary(case, expression)
+ parseLiteralInt(case)
+ listener: handleLiteralInt(0)
+ listener: handleConstantPattern(null)
+ listener: beginAsOperatorType(as)
+ computeTypeAfterIsOrAs(as)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(when)
+ listener: handleType(int, null)
+ listener: endAsOperatorType(as)
+ listener: handleCastPattern(as)
+ parseExpression(when)
+ parsePrecedenceExpression(when, 1, true)
+ parseUnaryExpression(when, true)
+ parsePrimary(when, expression)
+ parseLiteralBool(when)
+ listener: handleLiteralBool(true)
+ ensureCloseParen(true, ()
+ listener: handleParenthesizedCondition((, case, when)
+ listener: beginThenStatement({)
+ parseStatement())
+ parseStatementX())
+ parseBlock(), BlockKind(statement))
+ ensureBlock(), null, null)
+ listener: beginBlock({, BlockKind(statement))
+ notEofOrValue(}, })
+ listener: endBlock(0, {, }, BlockKind(statement))
+ listener: endThenStatement(})
+ listener: endIfStatement(if, null)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.parser.expect
new file mode 100644
index 0000000..708b554
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.parser.expect
@@ -0,0 +1,9 @@
+void f(x) {
+if (x case 0 as int when true) {}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] case[KeywordToken] 0[StringToken] as[KeywordToken] int[StringToken] when[KeywordToken] true[KeywordToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.scanner.expect
new file mode 100644
index 0000000..708b554
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideIfStatement.dart.scanner.expect
@@ -0,0 +1,9 @@
+void f(x) {
+if (x case 0 as int when true) {}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] case[KeywordToken] 0[StringToken] as[KeywordToken] int[StringToken] when[KeywordToken] true[KeywordToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart
new file mode 100644
index 0000000..7db6d2f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart
@@ -0,0 +1,6 @@
+void f(x) {
+ switch (x) {
+ case 0 as int when true:
+ break;
+ }
+}
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.expect
new file mode 100644
index 0000000..27defd71
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.expect
@@ -0,0 +1,47 @@
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null, null)
+ handleVoidKeyword(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ beginMetadataStar(x)
+ endMetadataStar(0)
+ beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ handleNoType(()
+ handleIdentifier(x, formalParameterDeclaration)
+ handleFormalParameterWithoutValue())
+ endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginSwitchStatement(switch)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(x, ))
+ handleParenthesizedCondition((, null, null)
+ beginSwitchBlock({)
+ beginCaseExpression(case)
+ handleLiteralInt(0)
+ handleConstantPattern(null)
+ beginAsOperatorType(as)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(when)
+ handleType(int, null)
+ endAsOperatorType(as)
+ handleCastPattern(as)
+ handleLiteralBool(true)
+ endCaseExpression(when, :)
+ handleCaseMatch(case, when, :)
+ beginSwitchCase(0, 1, case)
+ handleBreakStatement(false, break, ;)
+ endSwitchCase(0, 1, null, null, 1, case, })
+ endSwitchBlock(1, {, })
+ endSwitchStatement(switch, })
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.intertwined.expect
new file mode 100644
index 0000000..aef127f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.intertwined.expect
@@ -0,0 +1,109 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleVoidKeyword(void)
+ ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ parseMetadataStar(()
+ listener: beginMetadataStar(x)
+ listener: endMetadataStar(0)
+ listener: beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ listener: handleNoType(()
+ ensureIdentifier((, formalParameterDeclaration)
+ listener: handleIdentifier(x, formalParameterDeclaration)
+ listener: handleFormalParameterWithoutValue())
+ listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, switch)
+ parseStatement({)
+ parseStatementX({)
+ parseSwitchStatement({)
+ listener: beginSwitchStatement(switch)
+ ensureParenthesizedCondition(switch, allowCase: false)
+ parseExpressionInParenthesisRest((, allowCase: false)
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ isNextIdentifier(()
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(x)
+ listener: handleNoArguments())
+ listener: handleSend(x, ))
+ ensureCloseParen(x, ()
+ listener: handleParenthesizedCondition((, null, null)
+ parseSwitchBlock())
+ ensureBlock(), null, switch statement)
+ listener: beginSwitchBlock({)
+ notEofOrValue(}, case)
+ peekPastLabels(case)
+ listener: beginCaseExpression(case)
+ parsePattern(case, precedence: 1)
+ parsePrimaryPattern(case)
+ parsePrecedenceExpression(case, 18, false)
+ parseUnaryExpression(case, false)
+ parsePrimary(case, expression)
+ parseLiteralInt(case)
+ listener: handleLiteralInt(0)
+ listener: handleConstantPattern(null)
+ listener: beginAsOperatorType(as)
+ computeTypeAfterIsOrAs(as)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(when)
+ listener: handleType(int, null)
+ listener: endAsOperatorType(as)
+ listener: handleCastPattern(as)
+ parseExpression(when)
+ parsePrecedenceExpression(when, 1, true)
+ parseUnaryExpression(when, true)
+ parsePrimary(when, expression)
+ parseLiteralBool(when)
+ listener: handleLiteralBool(true)
+ ensureColon(true)
+ listener: endCaseExpression(when, :)
+ listener: handleCaseMatch(case, when, :)
+ peekPastLabels(break)
+ parseStatementsInSwitchCase(:, break, case, 0, 1, null, null)
+ listener: beginSwitchCase(0, 1, case)
+ parseStatement(:)
+ parseStatementX(:)
+ parseBreakStatement(:)
+ isBreakAllowed()
+ ensureSemicolon(break)
+ listener: handleBreakStatement(false, break, ;)
+ peekPastLabels(})
+ listener: endSwitchCase(0, 1, null, null, 1, case, })
+ notEofOrValue(}, })
+ listener: endSwitchBlock(1, {, })
+ listener: endSwitchStatement(switch, })
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.parser.expect
new file mode 100644
index 0000000..90e3346
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.parser.expect
@@ -0,0 +1,15 @@
+void f(x) {
+switch (x) {
+case 0 as int when true:
+break;
+}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+case[KeywordToken] 0[StringToken] as[KeywordToken] int[StringToken] when[KeywordToken] true[KeywordToken]:[SimpleToken]
+break[KeywordToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.scanner.expect
new file mode 100644
index 0000000..90e3346
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_guarded_insideSwitchStatement.dart.scanner.expect
@@ -0,0 +1,15 @@
+void f(x) {
+switch (x) {
+case 0 as int when true:
+break;
+}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+case[KeywordToken] 0[StringToken] as[KeywordToken] int[StringToken] when[KeywordToken] true[KeywordToken]:[SimpleToken]
+break[KeywordToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart
new file mode 100644
index 0000000..199154a
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart
@@ -0,0 +1,3 @@
+void f(x) {
+ if (x case 0 as int) {}
+}
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.expect
new file mode 100644
index 0000000..36db817
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.expect
@@ -0,0 +1,42 @@
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null, null)
+ handleVoidKeyword(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ beginMetadataStar(x)
+ endMetadataStar(0)
+ beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ handleNoType(()
+ handleIdentifier(x, formalParameterDeclaration)
+ handleFormalParameterWithoutValue())
+ endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginIfStatement(if)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments(case)
+ handleNoArguments(case)
+ handleSend(x, case)
+ handleLiteralInt(0)
+ handleConstantPattern(null)
+ beginAsOperatorType(as)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments())
+ handleType(int, null)
+ endAsOperatorType(as)
+ handleCastPattern(as)
+ handleParenthesizedCondition((, case, null)
+ beginThenStatement({)
+ beginBlock({, BlockKind(statement))
+ endBlock(0, {, }, BlockKind(statement))
+ endThenStatement(})
+ endIfStatement(if, null)
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.intertwined.expect
new file mode 100644
index 0000000..41bea34
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.intertwined.expect
@@ -0,0 +1,90 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleVoidKeyword(void)
+ ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ parseMetadataStar(()
+ listener: beginMetadataStar(x)
+ listener: endMetadataStar(0)
+ listener: beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ listener: handleNoType(()
+ ensureIdentifier((, formalParameterDeclaration)
+ listener: handleIdentifier(x, formalParameterDeclaration)
+ listener: handleFormalParameterWithoutValue())
+ listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, if)
+ parseStatement({)
+ parseStatementX({)
+ parseIfStatement({)
+ listener: beginIfStatement(if)
+ ensureParenthesizedCondition(if, allowCase: true)
+ parseExpressionInParenthesisRest((, allowCase: true)
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ isNextIdentifier(()
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments(case)
+ parseArgumentsOpt(x)
+ listener: handleNoArguments(case)
+ listener: handleSend(x, case)
+ parsePattern(case, precedence: 1)
+ parsePrimaryPattern(case)
+ parsePrecedenceExpression(case, 18, false)
+ parseUnaryExpression(case, false)
+ parsePrimary(case, expression)
+ parseLiteralInt(case)
+ listener: handleLiteralInt(0)
+ listener: handleConstantPattern(null)
+ listener: beginAsOperatorType(as)
+ computeTypeAfterIsOrAs(as)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments())
+ listener: handleType(int, null)
+ listener: endAsOperatorType(as)
+ listener: handleCastPattern(as)
+ ensureCloseParen(int, ()
+ listener: handleParenthesizedCondition((, case, null)
+ listener: beginThenStatement({)
+ parseStatement())
+ parseStatementX())
+ parseBlock(), BlockKind(statement))
+ ensureBlock(), null, null)
+ listener: beginBlock({, BlockKind(statement))
+ notEofOrValue(}, })
+ listener: endBlock(0, {, }, BlockKind(statement))
+ listener: endThenStatement(})
+ listener: endIfStatement(if, null)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.parser.expect
new file mode 100644
index 0000000..a1fc049
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.parser.expect
@@ -0,0 +1,9 @@
+void f(x) {
+if (x case 0 as int) {}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] case[KeywordToken] 0[StringToken] as[KeywordToken] int[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.scanner.expect
new file mode 100644
index 0000000..a1fc049
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideIfStatement.dart.scanner.expect
@@ -0,0 +1,9 @@
+void f(x) {
+if (x case 0 as int) {}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+if[KeywordToken] ([BeginToken]x[StringToken] case[KeywordToken] 0[StringToken] as[KeywordToken] int[StringToken])[SimpleToken] {[BeginToken]}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart
new file mode 100644
index 0000000..b3f6864
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart
@@ -0,0 +1,6 @@
+void f(x) {
+ switch (x) {
+ case 0 as int:
+ break;
+ }
+}
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.expect
new file mode 100644
index 0000000..be1a9a6
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.expect
@@ -0,0 +1,46 @@
+beginCompilationUnit(void)
+ beginMetadataStar(void)
+ endMetadataStar(0)
+ beginTopLevelMember(void)
+ beginTopLevelMethod(, null, null)
+ handleVoidKeyword(void)
+ handleIdentifier(f, topLevelFunctionDeclaration)
+ handleNoTypeVariables(()
+ beginFormalParameters((, MemberKind.TopLevelMethod)
+ beginMetadataStar(x)
+ endMetadataStar(0)
+ beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ handleNoType(()
+ handleIdentifier(x, formalParameterDeclaration)
+ handleFormalParameterWithoutValue())
+ endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ handleAsyncModifier(null, null)
+ beginBlockFunctionBody({)
+ beginSwitchStatement(switch)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(x, ))
+ handleParenthesizedCondition((, null, null)
+ beginSwitchBlock({)
+ beginCaseExpression(case)
+ handleLiteralInt(0)
+ handleConstantPattern(null)
+ beginAsOperatorType(as)
+ handleIdentifier(int, typeReference)
+ handleNoTypeArguments(:)
+ handleType(int, null)
+ endAsOperatorType(as)
+ handleCastPattern(as)
+ endCaseExpression(null, :)
+ handleCaseMatch(case, null, :)
+ beginSwitchCase(0, 1, case)
+ handleBreakStatement(false, break, ;)
+ endSwitchCase(0, 1, null, null, 1, case, })
+ endSwitchBlock(1, {, })
+ endSwitchStatement(switch, })
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(void, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.intertwined.expect
new file mode 100644
index 0000000..4b3aab4
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.intertwined.expect
@@ -0,0 +1,103 @@
+parseUnit(void)
+ skipErrorTokens(void)
+ listener: beginCompilationUnit(void)
+ syntheticPreviousToken(void)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(void)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(void)
+ parseTopLevelMethod(, null, null, , Instance of 'VoidType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleVoidKeyword(void)
+ ensureIdentifierPotentiallyRecovered(void, topLevelFunctionDeclaration, false)
+ listener: handleIdentifier(f, topLevelFunctionDeclaration)
+ parseMethodTypeVar(f)
+ listener: handleNoTypeVariables(()
+ parseGetterOrFormalParameters(f, f, false, MemberKind.TopLevelMethod)
+ parseFormalParameters(f, MemberKind.TopLevelMethod)
+ parseFormalParametersRest((, MemberKind.TopLevelMethod)
+ listener: beginFormalParameters((, MemberKind.TopLevelMethod)
+ parseFormalParameter((, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ parseMetadataStar(()
+ listener: beginMetadataStar(x)
+ listener: endMetadataStar(0)
+ listener: beginFormalParameter(x, MemberKind.TopLevelMethod, null, null, null)
+ listener: handleNoType(()
+ ensureIdentifier((, formalParameterDeclaration)
+ listener: handleIdentifier(x, formalParameterDeclaration)
+ listener: handleFormalParameterWithoutValue())
+ listener: endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod)
+ listener: endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
+ parseAsyncModifierOpt())
+ listener: handleAsyncModifier(null, null)
+ inPlainSync()
+ parseFunctionBody(), false, false)
+ listener: beginBlockFunctionBody({)
+ notEofOrValue(}, switch)
+ parseStatement({)
+ parseStatementX({)
+ parseSwitchStatement({)
+ listener: beginSwitchStatement(switch)
+ ensureParenthesizedCondition(switch, allowCase: false)
+ parseExpressionInParenthesisRest((, allowCase: false)
+ parseExpression(()
+ parsePrecedenceExpression((, 1, true)
+ parseUnaryExpression((, true)
+ parsePrimary((, expression)
+ parseSendOrFunctionLiteral((, expression)
+ parseSend((, expression)
+ isNextIdentifier(()
+ ensureIdentifier((, expression)
+ listener: handleIdentifier(x, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(x)
+ listener: handleNoArguments())
+ listener: handleSend(x, ))
+ ensureCloseParen(x, ()
+ listener: handleParenthesizedCondition((, null, null)
+ parseSwitchBlock())
+ ensureBlock(), null, switch statement)
+ listener: beginSwitchBlock({)
+ notEofOrValue(}, case)
+ peekPastLabels(case)
+ listener: beginCaseExpression(case)
+ parsePattern(case, precedence: 1)
+ parsePrimaryPattern(case)
+ parsePrecedenceExpression(case, 18, false)
+ parseUnaryExpression(case, false)
+ parsePrimary(case, expression)
+ parseLiteralInt(case)
+ listener: handleLiteralInt(0)
+ listener: handleConstantPattern(null)
+ listener: beginAsOperatorType(as)
+ computeTypeAfterIsOrAs(as)
+ listener: handleIdentifier(int, typeReference)
+ listener: handleNoTypeArguments(:)
+ listener: handleType(int, null)
+ listener: endAsOperatorType(as)
+ listener: handleCastPattern(as)
+ ensureColon(int)
+ listener: endCaseExpression(null, :)
+ listener: handleCaseMatch(case, null, :)
+ peekPastLabels(break)
+ parseStatementsInSwitchCase(:, break, case, 0, 1, null, null)
+ listener: beginSwitchCase(0, 1, case)
+ parseStatement(:)
+ parseStatementX(:)
+ parseBreakStatement(:)
+ isBreakAllowed()
+ ensureSemicolon(break)
+ listener: handleBreakStatement(false, break, ;)
+ peekPastLabels(})
+ listener: endSwitchCase(0, 1, null, null, 1, case, })
+ notEofOrValue(}, })
+ listener: endSwitchBlock(1, {, })
+ listener: endSwitchStatement(switch, })
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(void, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(void)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.parser.expect
new file mode 100644
index 0000000..e9cba66
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.parser.expect
@@ -0,0 +1,15 @@
+void f(x) {
+switch (x) {
+case 0 as int:
+break;
+}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+case[KeywordToken] 0[StringToken] as[KeywordToken] int[StringToken]:[SimpleToken]
+break[KeywordToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.scanner.expect
new file mode 100644
index 0000000..e9cba66
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/caseHead_withNewPattern_unguarded_insideSwitchStatement.dart.scanner.expect
@@ -0,0 +1,15 @@
+void f(x) {
+switch (x) {
+case 0 as int:
+break;
+}
+}
+
+
+void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+case[KeywordToken] 0[StringToken] as[KeywordToken] int[StringToken]:[SimpleToken]
+break[KeywordToken];[SimpleToken]
+}[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/test/token_test.dart b/pkg/front_end/test/token_test.dart
index 69f13b4..05c199b 100644
--- a/pkg/front_end/test/token_test.dart
+++ b/pkg/front_end/test/token_test.dart
@@ -182,6 +182,7 @@
Keyword.SHOW,
Keyword.SOURCE,
Keyword.SYNC,
+ Keyword.WHEN,
Keyword.YIELD,
]);
for (Keyword keyword in Keyword.values) {