From 8d2b2a197d178fa8dd189480dfa85807e4e4a993 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Fri, 12 May 2023 18:43:39 +0000 Subject: [PATCH] [parser] Ensure that list and map pattern parsing always makes progress. In rare circumstances involving syntax errors, the `parsePattern` method inserts a synthetic token but does not consume any tokens. Usually when this happens it's not a problem, because whatever method is calling `parsePattern` consumes some tokens, so the parser always makes progress. However, when parsing list patterns, after calling `parsePattern`, the parser would look for a `,`, and if it didn't find one, it would supply a synthetic `,` and call `parsePattern` again, resulting in an infinite loop. A similar situation happened with map patterns, though the situation was more complex because in between the calls to `parsePattern`, the parser would also create synthetic key expressions and `:`s. To fix the problem, when parsing a list or map pattern, after the call to `parsePattern`, the parser checks whether any tokens were consumed. If no tokens were consumed, it ignores the next token from the input stream in order to make progress. I also investigated whether there were similar issues with parenthesized/record patterns and switch expressions, since those constructs also consist of a sequence of patterns separated by tokens and other things that could in principle be supplied synthetically. Fortunately, parser recovery doesn't get into an infinite loop in those cases, so I didn't make any further changes. But I did include test cases to make sure. Fixes #52352. Bug: https://github.com/dart-lang/sdk/issues/52352 Change-Id: Idc8140236f6054deb1fd3c862036fe47dd84f30b Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/302803 Reviewed-by: Konstantin Shcheglov Commit-Queue: Paul Berry --- .../lib/src/parser/parser_impl.dart | 12 ++ .../test/generated/patterns_parser_test.dart | 152 +++++++++++++++ ...syntheticIdentifier_insideListPattern.dart | 5 + ...icIdentifier_insideListPattern.dart.expect | 59 ++++++ ..._insideListPattern.dart.intertwined.expect | 119 ++++++++++++ ...ifier_insideListPattern.dart.parser.expect | 15 ++ ...fier_insideListPattern.dart.scanner.expect | 13 ++ .../syntheticIdentifier_insideMapPattern.dart | 5 + ...ticIdentifier_insideMapPattern.dart.expect | 94 ++++++++++ ...r_insideMapPattern.dart.intertwined.expect | 176 ++++++++++++++++++ ...tifier_insideMapPattern.dart.parser.expect | 15 ++ ...ifier_insideMapPattern.dart.scanner.expect | 13 ++ ...Identifier_insideParenthesizedPattern.dart | 5 + ...ier_insideParenthesizedPattern.dart.expect | 63 +++++++ ...renthesizedPattern.dart.intertwined.expect | 121 ++++++++++++ ...ideParenthesizedPattern.dart.parser.expect | 15 ++ ...deParenthesizedPattern.dart.scanner.expect | 13 ++ ...ntheticIdentifier_insideRecordPattern.dart | 5 + ...Identifier_insideRecordPattern.dart.expect | 69 +++++++ ...nsideRecordPattern.dart.intertwined.expect | 130 +++++++++++++ ...ier_insideRecordPattern.dart.parser.expect | 15 ++ ...er_insideRecordPattern.dart.scanner.expect | 13 ++ ...eticIdentifier_insideSwitchExpression.dart | 1 + ...ntifier_insideSwitchExpression.dart.expect | 70 +++++++ ...deSwitchExpression.dart.intertwined.expect | 129 +++++++++++++ ..._insideSwitchExpression.dart.parser.expect | 7 + ...insideSwitchExpression.dart.scanner.expect | 5 + 27 files changed, 1339 insertions(+) create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.scanner.expect 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 a7c0212e07a..9352d61fa0e 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart @@ -10061,6 +10061,12 @@ class Parser { listener.handleRestPattern(dots, hasSubPattern: hasSubPattern); } else { token = parsePattern(token, patternContext); + if (identical(next, token.next)) { + // No tokens were consumed (though it's possible that a synthetic + // token was inserted). If this happens, go ahead and skip the next + // token to ensure that progress is made. + token = token.next!; + } } next = token.next!; ++count; @@ -10136,6 +10142,12 @@ class Parser { new SyntheticToken(TokenType.COLON, next.charOffset)); } token = parsePattern(colon, patternContext); + if (identical(next, token.next)) { + // No tokens were consumed (though it's possible that a synthetic + // token was inserted). If this happens, go ahead and skip the next + // token to ensure that progress is made. + token = token.next!; + } listener.handleMapPatternEntry(colon, token.next!); } ++count; diff --git a/pkg/analyzer/test/generated/patterns_parser_test.dart b/pkg/analyzer/test/generated/patterns_parser_test.dart index 9d3a75b40bd..9eee522fe5d 100644 --- a/pkg/analyzer/test/generated/patterns_parser_test.dart +++ b/pkg/analyzer/test/generated/patterns_parser_test.dart @@ -9730,6 +9730,158 @@ SwitchExpression '''); } + test_syntheticIdentifier_insideListPattern() { + _parse(''' +void f(Object? x) { + switch (x) { + case [if]: + }; +} +''', errors: [ + error(ParserErrorCode.MISSING_IDENTIFIER, 45, 2), + ]); + var node = findNode.switchPatternCase('case'); + assertParsedNodeText(node, r''' +SwitchPatternCase + keyword: case + guardedPattern: GuardedPattern + pattern: ListPattern + leftBracket: [ + elements + ConstantPattern + expression: SimpleIdentifier + token: + rightBracket: ] + colon: : +'''); + } + + test_syntheticIdentifier_insideMapPattern() { + _parse(''' +void f(Object? x) { + switch (x) { + case {0: if}: + }; +} +''', errors: [ + error(ParserErrorCode.MISSING_IDENTIFIER, 48, 2), + error(ParserErrorCode.EXPECTED_TOKEN, 48, 2), + error(ParserErrorCode.EXPECTED_TOKEN, 48, 2), + ]); + var node = findNode.switchPatternCase('case'); + assertParsedNodeText(node, r''' +SwitchPatternCase + keyword: case + guardedPattern: GuardedPattern + pattern: MapPattern + leftBracket: { + elements + MapPatternEntry + key: IntegerLiteral + literal: 0 + separator: : + value: ConstantPattern + expression: SimpleIdentifier + token: + MapPatternEntry + key: SimpleIdentifier + token: + separator: : + value: ConstantPattern + expression: SimpleIdentifier + token: + rightBracket: } + colon: : +'''); + } + + test_syntheticIdentifier_insideParenthesizedPattern() { + _parse(''' +void f(Object? x) { + switch (x) { + case (if): + }; +} +''', errors: [ + error(ParserErrorCode.MISSING_IDENTIFIER, 45, 2), + error(ParserErrorCode.EXPECTED_TOKEN, 45, 2), + ]); + var node = findNode.switchPatternCase('case'); + assertParsedNodeText(node, r''' +SwitchPatternCase + keyword: case + guardedPattern: GuardedPattern + pattern: ParenthesizedPattern + leftParenthesis: ( + pattern: ConstantPattern + expression: SimpleIdentifier + token: + rightParenthesis: ) + colon: : +'''); + } + + test_syntheticIdentifier_insideRecordPattern() { + _parse(''' +void f(Object? x) { + switch (x) { + case (_, if): + }; +} +''', errors: [ + error(ParserErrorCode.MISSING_IDENTIFIER, 48, 2), + error(ParserErrorCode.EXPECTED_TOKEN, 48, 2), + ]); + var node = findNode.switchPatternCase('case'); + assertParsedNodeText(node, r''' +SwitchPatternCase + keyword: case + guardedPattern: GuardedPattern + pattern: RecordPattern + leftParenthesis: ( + fields + PatternField + pattern: WildcardPattern + name: _ + PatternField + pattern: ConstantPattern + expression: SimpleIdentifier + token: + rightParenthesis: ) + colon: : +'''); + } + + test_syntheticIdentifier_insideSwitchExpression() { + _parse(''' +void f(Object? x) => switch (x) {if}; +''', errors: [ + error(ParserErrorCode.MISSING_IDENTIFIER, 33, 2), + error(ParserErrorCode.EXPECTED_TOKEN, 33, 2), + error(ParserErrorCode.EXPECTED_TOKEN, 33, 2), + ]); + var node = findNode.switchExpression('if'); + assertParsedNodeText(node, r''' +SwitchExpression + switchKeyword: switch + leftParenthesis: ( + expression: SimpleIdentifier + token: x + rightParenthesis: ) + leftBracket: { + cases + SwitchExpressionCase + guardedPattern: GuardedPattern + pattern: ConstantPattern + expression: SimpleIdentifier + token: + arrow: => + expression: SimpleIdentifier + token: + rightBracket: } +'''); + } + test_typeQuestionBeforeWhen_conditional() { // The logic for parsing types has special disambiguation rules for deciding // whether a trailing `?` should be included in the type; these rules are diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart new file mode 100644 index 00000000000..72630b0ad1e --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart @@ -0,0 +1,5 @@ +void f(Object? x) { + switch (x) { + case [if]: + }; +} diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.expect new file mode 100644 index 00000000000..d045d7d29da --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.expect @@ -0,0 +1,59 @@ +Problems reported: + +parser/patterns/syntheticIdentifier_insideListPattern:3:11: Expected an identifier, but got 'if'. + case [if]: + ^^ + +beginCompilationUnit(void) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(, null, null) + handleVoidKeyword(void) + handleIdentifier(f, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + beginMetadataStar(Object) + endMetadataStar(0) + beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + handleIdentifier(Object, typeReference) + handleNoTypeArguments(?) + handleType(Object, ?) + 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) + beginPattern(case) + handleNoTypeArguments([) + beginPattern([) + beginConstantPattern(null) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + handleIdentifier(, expression) + handleNoTypeArguments(if) + handleNoArguments(if) + handleSend(, if) + endConstantPattern(null) + endPattern() + handleListPattern(1, [, ]) + endPattern(]) + handleSwitchCaseNoWhenClause(]) + endCaseExpression(case, null, :) + beginSwitchCase(0, 1, case) + endSwitchCase(0, 1, null, null, 0, case, }) + endSwitchBlock(1, {, }) + endSwitchStatement(switch, }) + handleEmptyStatement(;) + endBlockFunctionBody(2, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.intertwined.expect new file mode 100644 index 00000000000..4a7bb8db29f --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.intertwined.expect @@ -0,0 +1,119 @@ +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(Object) + listener: endMetadataStar(0) + listener: beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + listener: handleIdentifier(Object, typeReference) + listener: handleNoTypeArguments(?) + listener: handleType(Object, ?) + 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(() + looksLikeOuterPatternEquals(() + skipOuterPattern(() + skipObjectPatternRest(x) + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + parseSendOrFunctionLiteral((, expression, ConstantPatternContext.none) + parseSend((, expression, ConstantPatternContext.none) + 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, PatternContext.matching, precedence: 1) + listener: beginPattern(case) + parsePrimaryPattern(case, PatternContext.matching) + listener: handleNoTypeArguments([) + parseListPatternSuffix(case, PatternContext.matching) + parsePattern([, PatternContext.matching, precedence: 1) + listener: beginPattern([) + parsePrimaryPattern([, PatternContext.matching) + listener: beginConstantPattern(null) + parsePrecedenceExpression([, 7, false, ConstantPatternContext.implicit) + parseUnaryExpression([, false, ConstantPatternContext.implicit) + parsePrimary([, expression, ConstantPatternContext.implicit) + inPlainSync() + parseSend([, expression, ConstantPatternContext.implicit) + isNextIdentifier([) + ensureIdentifier([, expression) + reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>') + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + rewriter() + listener: handleIdentifier(, expression) + listener: handleNoTypeArguments(if) + parseArgumentsOpt() + listener: handleNoArguments(if) + listener: handleSend(, if) + listener: endConstantPattern(null) + listener: endPattern() + listener: handleListPattern(1, [, ]) + listener: endPattern(]) + listener: handleSwitchCaseNoWhenClause(]) + ensureColon(]) + listener: endCaseExpression(case, null, :) + peekPastLabels(}) + parseStatementsInSwitchCase(:, }, case, 0, 1, null, null) + listener: beginSwitchCase(0, 1, case) + listener: endSwitchCase(0, 1, null, null, 0, case, }) + notEofOrValue(}, }) + listener: endSwitchBlock(1, {, }) + listener: endSwitchStatement(switch, }) + notEofOrValue(}, ;) + parseStatement(}) + parseStatementX(}) + parseEmptyStatement(}) + listener: handleEmptyStatement(;) + notEofOrValue(}, }) + listener: endBlockFunctionBody(2, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.parser.expect new file mode 100644 index 00000000000..3aee7e775a6 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.parser.expect @@ -0,0 +1,15 @@ +NOTICE: Stream was rewritten by parser! + +void f(Object? x) { +switch (x) { +case [*synthetic*if]: +}; +} + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] [[BeginToken][SyntheticStringToken]if[KeywordToken]][SimpleToken]:[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.scanner.expect new file mode 100644 index 00000000000..4e08a5a0270 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideListPattern.dart.scanner.expect @@ -0,0 +1,13 @@ +void f(Object? x) { +switch (x) { +case [if]: +}; +} + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] [[BeginToken]if[KeywordToken]][SimpleToken]:[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart new file mode 100644 index 00000000000..1320bbdb0a3 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart @@ -0,0 +1,5 @@ +void f(Object? x) { + switch (x) { + case {0: if}: + }; +} diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.expect new file mode 100644 index 00000000000..8fe0648f447 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.expect @@ -0,0 +1,94 @@ +Problems reported: + +parser/patterns/syntheticIdentifier_insideMapPattern:3:14: Expected an identifier, but got 'if'. + case {0: if}: + ^^ + +parser/patterns/syntheticIdentifier_insideMapPattern:3:14: Expected ',' before this. + case {0: if}: + ^^ + +parser/patterns/syntheticIdentifier_insideMapPattern:3:14: Expected an identifier, but got 'if'. + case {0: if}: + ^^ + +parser/patterns/syntheticIdentifier_insideMapPattern:3:14: Expected ':' before this. + case {0: if}: + ^^ + +parser/patterns/syntheticIdentifier_insideMapPattern:3:14: Expected an identifier, but got 'if'. + case {0: if}: + ^^ + +beginCompilationUnit(void) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(, null, null) + handleVoidKeyword(void) + handleIdentifier(f, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + beginMetadataStar(Object) + endMetadataStar(0) + beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + handleIdentifier(Object, typeReference) + handleNoTypeArguments(?) + handleType(Object, ?) + 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) + beginPattern(case) + handleNoTypeArguments({) + handleLiteralInt(0) + beginPattern(:) + beginConstantPattern(null) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + handleIdentifier(, expression) + handleNoTypeArguments(if) + handleNoArguments(if) + handleSend(, if) + endConstantPattern(null) + endPattern() + handleMapPatternEntry(:, if) + handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], if, if) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + handleIdentifier(, expression) + handleNoTypeArguments(if) + handleNoArguments(if) + handleSend(, if) + handleRecoverableError(Message[ExpectedButGot, Expected ':' before this., null, {string: :}], if, if) + beginPattern(:) + beginConstantPattern(null) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + handleIdentifier(, expression) + handleNoTypeArguments(if) + handleNoArguments(if) + handleSend(, if) + endConstantPattern(null) + endPattern() + handleMapPatternEntry(:, }) + handleMapPattern(2, {, }) + endPattern(}) + handleSwitchCaseNoWhenClause(}) + endCaseExpression(case, null, :) + beginSwitchCase(0, 1, case) + endSwitchCase(0, 1, null, null, 0, case, }) + endSwitchBlock(1, {, }) + endSwitchStatement(switch, }) + handleEmptyStatement(;) + endBlockFunctionBody(2, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.intertwined.expect new file mode 100644 index 00000000000..080590cf195 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.intertwined.expect @@ -0,0 +1,176 @@ +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(Object) + listener: endMetadataStar(0) + listener: beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + listener: handleIdentifier(Object, typeReference) + listener: handleNoTypeArguments(?) + listener: handleType(Object, ?) + 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(() + looksLikeOuterPatternEquals(() + skipOuterPattern(() + skipObjectPatternRest(x) + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + parseSendOrFunctionLiteral((, expression, ConstantPatternContext.none) + parseSend((, expression, ConstantPatternContext.none) + 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, PatternContext.matching, precedence: 1) + listener: beginPattern(case) + parsePrimaryPattern(case, PatternContext.matching) + listener: handleNoTypeArguments({) + parseMapPatternSuffix(case, PatternContext.matching) + parseExpression({) + looksLikeOuterPatternEquals({) + skipOuterPattern({) + parsePrecedenceExpression({, 1, true, ConstantPatternContext.none) + parseUnaryExpression({, true, ConstantPatternContext.none) + parsePrimary({, expression, ConstantPatternContext.none) + parseLiteralInt({) + listener: handleLiteralInt(0) + parsePattern(:, PatternContext.matching, precedence: 1) + listener: beginPattern(:) + parsePrimaryPattern(:, PatternContext.matching) + listener: beginConstantPattern(null) + parsePrecedenceExpression(:, 7, false, ConstantPatternContext.implicit) + parseUnaryExpression(:, false, ConstantPatternContext.implicit) + parsePrimary(:, expression, ConstantPatternContext.implicit) + inPlainSync() + parseSend(:, expression, ConstantPatternContext.implicit) + isNextIdentifier(:) + ensureIdentifier(:, expression) + reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>') + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + rewriter() + listener: handleIdentifier(, expression) + listener: handleNoTypeArguments(if) + parseArgumentsOpt() + listener: handleNoArguments(if) + listener: handleSend(, if) + listener: endConstantPattern(null) + listener: endPattern() + listener: handleMapPatternEntry(:, if) + rewriteAndRecover(, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], ,) + reportRecoverableError(if, Message[ExpectedButGot, Expected ',' before this., null, {string: ,}]) + listener: handleRecoverableError(Message[ExpectedButGot, Expected ',' before this., null, {string: ,}], if, if) + rewriter() + parseExpression(,) + looksLikeOuterPatternEquals(,) + skipOuterPattern(,) + parsePrecedenceExpression(,, 1, true, ConstantPatternContext.none) + parseUnaryExpression(,, true, ConstantPatternContext.none) + parsePrimary(,, expression, ConstantPatternContext.none) + inPlainSync() + parseSend(,, expression, ConstantPatternContext.none) + isNextIdentifier(,) + ensureIdentifier(,, expression) + reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>') + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + rewriter() + listener: handleIdentifier(, expression) + listener: handleNoTypeArguments(if) + parseArgumentsOpt() + listener: handleNoArguments(if) + listener: handleSend(, if) + rewriteAndRecover(, Message[ExpectedButGot, Expected ':' before this., null, {string: :}], :) + reportRecoverableError(if, Message[ExpectedButGot, Expected ':' before this., null, {string: :}]) + listener: handleRecoverableError(Message[ExpectedButGot, Expected ':' before this., null, {string: :}], if, if) + rewriter() + parsePattern(:, PatternContext.matching, precedence: 1) + listener: beginPattern(:) + parsePrimaryPattern(:, PatternContext.matching) + listener: beginConstantPattern(null) + parsePrecedenceExpression(:, 7, false, ConstantPatternContext.implicit) + parseUnaryExpression(:, false, ConstantPatternContext.implicit) + parsePrimary(:, expression, ConstantPatternContext.implicit) + inPlainSync() + parseSend(:, expression, ConstantPatternContext.implicit) + isNextIdentifier(:) + ensureIdentifier(:, expression) + reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>') + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + rewriter() + listener: handleIdentifier(, expression) + listener: handleNoTypeArguments(if) + parseArgumentsOpt() + listener: handleNoArguments(if) + listener: handleSend(, if) + listener: endConstantPattern(null) + listener: endPattern() + listener: handleMapPatternEntry(:, }) + listener: handleMapPattern(2, {, }) + listener: endPattern(}) + listener: handleSwitchCaseNoWhenClause(}) + ensureColon(}) + listener: endCaseExpression(case, null, :) + peekPastLabels(}) + parseStatementsInSwitchCase(:, }, case, 0, 1, null, null) + listener: beginSwitchCase(0, 1, case) + listener: endSwitchCase(0, 1, null, null, 0, case, }) + notEofOrValue(}, }) + listener: endSwitchBlock(1, {, }) + listener: endSwitchStatement(switch, }) + notEofOrValue(}, ;) + parseStatement(}) + parseStatementX(}) + parseEmptyStatement(}) + listener: handleEmptyStatement(;) + notEofOrValue(}, }) + listener: endBlockFunctionBody(2, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.parser.expect new file mode 100644 index 00000000000..f972a215636 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.parser.expect @@ -0,0 +1,15 @@ +NOTICE: Stream was rewritten by parser! + +void f(Object? x) { +switch (x) { +case {0: *synthetic*,*synthetic*:*synthetic*if}: +}; +} + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] {[BeginToken]0[StringToken]:[SimpleToken] [SyntheticStringToken],[SyntheticToken][SyntheticStringToken]:[SyntheticToken][SyntheticStringToken]if[KeywordToken]}[SimpleToken]:[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.scanner.expect new file mode 100644 index 00000000000..b5f304e7596 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideMapPattern.dart.scanner.expect @@ -0,0 +1,13 @@ +void f(Object? x) { +switch (x) { +case {0: if}: +}; +} + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] {[BeginToken]0[StringToken]:[SimpleToken] if[KeywordToken]}[SimpleToken]:[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart new file mode 100644 index 00000000000..c3adda9dce9 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart @@ -0,0 +1,5 @@ +void f(Object? x) { + switch (x) { + case (if): + }; +} diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.expect new file mode 100644 index 00000000000..82983e2d484 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.expect @@ -0,0 +1,63 @@ +Problems reported: + +parser/patterns/syntheticIdentifier_insideParenthesizedPattern:3:11: Expected an identifier, but got 'if'. + case (if): + ^^ + +parser/patterns/syntheticIdentifier_insideParenthesizedPattern:3:11: Expected ')' before this. + case (if): + ^^ + +beginCompilationUnit(void) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(, null, null) + handleVoidKeyword(void) + handleIdentifier(f, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + beginMetadataStar(Object) + endMetadataStar(0) + beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + handleIdentifier(Object, typeReference) + handleNoTypeArguments(?) + handleType(Object, ?) + 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) + beginPattern(case) + beginPattern(() + beginConstantPattern(null) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + handleIdentifier(, expression) + handleNoTypeArguments(if) + handleNoArguments(if) + handleSend(, if) + endConstantPattern(null) + endPattern() + handleRecoverableError(Message[ExpectedButGot, Expected ')' before this., null, {string: )}], if, if) + handleParenthesizedPattern(() + endPattern()) + handleSwitchCaseNoWhenClause()) + endCaseExpression(case, null, :) + beginSwitchCase(0, 1, case) + endSwitchCase(0, 1, null, null, 0, case, }) + endSwitchBlock(1, {, }) + endSwitchStatement(switch, }) + handleEmptyStatement(;) + endBlockFunctionBody(2, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.intertwined.expect new file mode 100644 index 00000000000..f473acb4d56 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.intertwined.expect @@ -0,0 +1,121 @@ +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(Object) + listener: endMetadataStar(0) + listener: beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + listener: handleIdentifier(Object, typeReference) + listener: handleNoTypeArguments(?) + listener: handleType(Object, ?) + 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(() + looksLikeOuterPatternEquals(() + skipOuterPattern(() + skipObjectPatternRest(x) + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + parseSendOrFunctionLiteral((, expression, ConstantPatternContext.none) + parseSend((, expression, ConstantPatternContext.none) + 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, PatternContext.matching, precedence: 1) + listener: beginPattern(case) + parsePrimaryPattern(case, PatternContext.matching) + parseParenthesizedPatternOrRecordPattern(case, PatternContext.matching) + parsePattern((, PatternContext.matching, precedence: 1) + listener: beginPattern(() + parsePrimaryPattern((, PatternContext.matching) + listener: beginConstantPattern(null) + parsePrecedenceExpression((, 7, false, ConstantPatternContext.implicit) + parseUnaryExpression((, false, ConstantPatternContext.implicit) + parsePrimary((, expression, ConstantPatternContext.implicit) + inPlainSync() + parseSend((, expression, ConstantPatternContext.implicit) + isNextIdentifier(() + ensureIdentifier((, expression) + reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>') + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + rewriter() + listener: handleIdentifier(, expression) + listener: handleNoTypeArguments(if) + parseArgumentsOpt() + listener: handleNoArguments(if) + listener: handleSend(, if) + listener: endConstantPattern(null) + listener: endPattern() + ensureCloseParen(, () + reportRecoverableError(if, Message[ExpectedButGot, Expected ')' before this., null, {string: )}]) + listener: handleRecoverableError(Message[ExpectedButGot, Expected ')' before this., null, {string: )}], if, if) + listener: handleParenthesizedPattern(() + listener: endPattern()) + listener: handleSwitchCaseNoWhenClause()) + ensureColon()) + listener: endCaseExpression(case, null, :) + peekPastLabels(}) + parseStatementsInSwitchCase(:, }, case, 0, 1, null, null) + listener: beginSwitchCase(0, 1, case) + listener: endSwitchCase(0, 1, null, null, 0, case, }) + notEofOrValue(}, }) + listener: endSwitchBlock(1, {, }) + listener: endSwitchStatement(switch, }) + notEofOrValue(}, ;) + parseStatement(}) + parseStatementX(}) + parseEmptyStatement(}) + listener: handleEmptyStatement(;) + notEofOrValue(}, }) + listener: endBlockFunctionBody(2, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.parser.expect new file mode 100644 index 00000000000..e59b42fecb1 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.parser.expect @@ -0,0 +1,15 @@ +NOTICE: Stream was rewritten by parser! + +void f(Object? x) { +switch (x) { +case (*synthetic*if): +}; +} + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] ([BeginToken][SyntheticStringToken]if[KeywordToken])[SimpleToken]:[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.scanner.expect new file mode 100644 index 00000000000..5de601c2ff2 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideParenthesizedPattern.dart.scanner.expect @@ -0,0 +1,13 @@ +void f(Object? x) { +switch (x) { +case (if): +}; +} + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] ([BeginToken]if[KeywordToken])[SimpleToken]:[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart new file mode 100644 index 00000000000..0f31dfcbd22 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart @@ -0,0 +1,5 @@ +void f(Object? x) { + switch (x) { + case (_, if): + }; +} diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.expect new file mode 100644 index 00000000000..e5789027ef2 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.expect @@ -0,0 +1,69 @@ +Problems reported: + +parser/patterns/syntheticIdentifier_insideRecordPattern:3:14: Expected an identifier, but got 'if'. + case (_, if): + ^^ + +parser/patterns/syntheticIdentifier_insideRecordPattern:3:14: Expected ')' before this. + case (_, if): + ^^ + +beginCompilationUnit(void) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(, null, null) + handleVoidKeyword(void) + handleIdentifier(f, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + beginMetadataStar(Object) + endMetadataStar(0) + beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + handleIdentifier(Object, typeReference) + handleNoTypeArguments(?) + handleType(Object, ?) + 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) + beginPattern(case) + beginPattern(() + handleNoType(_) + handleWildcardPattern(null, _) + endPattern(_) + handlePatternField(null) + beginPattern(,) + beginConstantPattern(null) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + handleIdentifier(, expression) + handleNoTypeArguments(if) + handleNoArguments(if) + handleSend(, if) + endConstantPattern(null) + endPattern() + handlePatternField(null) + handleRecoverableError(Message[ExpectedButGot, Expected ')' before this., null, {string: )}], if, if) + handleRecordPattern((, 2) + endPattern()) + handleSwitchCaseNoWhenClause()) + endCaseExpression(case, null, :) + beginSwitchCase(0, 1, case) + endSwitchCase(0, 1, null, null, 0, case, }) + endSwitchBlock(1, {, }) + endSwitchStatement(switch, }) + handleEmptyStatement(;) + endBlockFunctionBody(2, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.intertwined.expect new file mode 100644 index 00000000000..5931936c785 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.intertwined.expect @@ -0,0 +1,130 @@ +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(Object) + listener: endMetadataStar(0) + listener: beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + listener: handleIdentifier(Object, typeReference) + listener: handleNoTypeArguments(?) + listener: handleType(Object, ?) + 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(() + looksLikeOuterPatternEquals(() + skipOuterPattern(() + skipObjectPatternRest(x) + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + parseSendOrFunctionLiteral((, expression, ConstantPatternContext.none) + parseSend((, expression, ConstantPatternContext.none) + 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, PatternContext.matching, precedence: 1) + listener: beginPattern(case) + parsePrimaryPattern(case, PatternContext.matching) + parseParenthesizedPatternOrRecordPattern(case, PatternContext.matching) + parsePattern((, PatternContext.matching, precedence: 1) + listener: beginPattern(() + parsePrimaryPattern((, PatternContext.matching) + parseVariablePattern((, PatternContext.matching, typeInfo: Instance of 'NoType') + listener: handleNoType(_) + listener: handleWildcardPattern(null, _) + listener: endPattern(_) + listener: handlePatternField(null) + parsePattern(,, PatternContext.matching, precedence: 1) + listener: beginPattern(,) + parsePrimaryPattern(,, PatternContext.matching) + listener: beginConstantPattern(null) + parsePrecedenceExpression(,, 7, false, ConstantPatternContext.implicit) + parseUnaryExpression(,, false, ConstantPatternContext.implicit) + parsePrimary(,, expression, ConstantPatternContext.implicit) + inPlainSync() + parseSend(,, expression, ConstantPatternContext.implicit) + isNextIdentifier(,) + ensureIdentifier(,, expression) + reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>') + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + rewriter() + listener: handleIdentifier(, expression) + listener: handleNoTypeArguments(if) + parseArgumentsOpt() + listener: handleNoArguments(if) + listener: handleSend(, if) + listener: endConstantPattern(null) + listener: endPattern() + listener: handlePatternField(null) + ensureCloseParen(, () + reportRecoverableError(if, Message[ExpectedButGot, Expected ')' before this., null, {string: )}]) + listener: handleRecoverableError(Message[ExpectedButGot, Expected ')' before this., null, {string: )}], if, if) + listener: handleRecordPattern((, 2) + listener: endPattern()) + listener: handleSwitchCaseNoWhenClause()) + ensureColon()) + listener: endCaseExpression(case, null, :) + peekPastLabels(}) + parseStatementsInSwitchCase(:, }, case, 0, 1, null, null) + listener: beginSwitchCase(0, 1, case) + listener: endSwitchCase(0, 1, null, null, 0, case, }) + notEofOrValue(}, }) + listener: endSwitchBlock(1, {, }) + listener: endSwitchStatement(switch, }) + notEofOrValue(}, ;) + parseStatement(}) + parseStatementX(}) + parseEmptyStatement(}) + listener: handleEmptyStatement(;) + notEofOrValue(}, }) + listener: endBlockFunctionBody(2, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.parser.expect new file mode 100644 index 00000000000..f43d17ee1a5 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.parser.expect @@ -0,0 +1,15 @@ +NOTICE: Stream was rewritten by parser! + +void f(Object? x) { +switch (x) { +case (_, *synthetic*if): +}; +} + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] ([BeginToken]_[StringToken],[SimpleToken] [SyntheticStringToken]if[KeywordToken])[SimpleToken]:[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.scanner.expect new file mode 100644 index 00000000000..9cff154f576 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideRecordPattern.dart.scanner.expect @@ -0,0 +1,13 @@ +void f(Object? x) { +switch (x) { +case (_, if): +}; +} + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] ([BeginToken]_[StringToken],[SimpleToken] if[KeywordToken])[SimpleToken]:[SimpleToken] +}[SimpleToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart new file mode 100644 index 00000000000..e9309430c16 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart @@ -0,0 +1 @@ +void f(Object? x) => switch (x) {if}; diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.expect new file mode 100644 index 00000000000..7ca5f38e77b --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.expect @@ -0,0 +1,70 @@ +Problems reported: + +parser/patterns/syntheticIdentifier_insideSwitchExpression:1:34: Expected an identifier, but got 'if'. +void f(Object? x) => switch (x) {if}; + ^^ + +parser/patterns/syntheticIdentifier_insideSwitchExpression:1:34: Expected '=>' before this. +void f(Object? x) => switch (x) {if}; + ^^ + +parser/patterns/syntheticIdentifier_insideSwitchExpression:1:34: Expected an identifier, but got 'if'. +void f(Object? x) => switch (x) {if}; + ^^ + +parser/patterns/syntheticIdentifier_insideSwitchExpression:1:34: Expected '}' before this. +void f(Object? x) => switch (x) {if}; + ^^ + +beginCompilationUnit(void) + beginMetadataStar(void) + endMetadataStar(0) + beginTopLevelMember(void) + beginTopLevelMethod(, null, null) + handleVoidKeyword(void) + handleIdentifier(f, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + beginMetadataStar(Object) + endMetadataStar(0) + beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + handleIdentifier(Object, typeReference) + handleNoTypeArguments(?) + handleType(Object, ?) + handleIdentifier(x, formalParameterDeclaration) + handleFormalParameterWithoutValue()) + endFormalParameter(null, null, null, x, null, null, FormalParameterKind.requiredPositional, MemberKind.TopLevelMethod) + endFormalParameters(1, (, ), MemberKind.TopLevelMethod) + handleAsyncModifier(null, null) + beginSwitchExpression(switch) + handleIdentifier(x, expression) + handleNoTypeArguments()) + handleNoArguments()) + handleSend(x, )) + handleParenthesizedCondition((, null, null) + beginSwitchExpressionBlock({) + beginSwitchExpressionCase() + beginPattern({) + beginConstantPattern(null) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + handleIdentifier(, expression) + handleNoTypeArguments(if) + handleNoArguments(if) + handleSend(, if) + endConstantPattern(null) + endPattern() + handleSwitchExpressionCasePattern() + handleRecoverableError(Message[ExpectedButGot, Expected '=>' before this., null, {string: =>}], if, if) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + handleIdentifier(, expression) + handleNoTypeArguments(if) + handleNoArguments(if) + handleSend(, if) + endSwitchExpressionCase(null, =>, ) + handleRecoverableError(Message[ExpectedButGot, Expected '}' before this., null, {string: }}], if, if) + endSwitchExpressionBlock(1, {, }) + endSwitchExpression(switch, }) + handleExpressionFunctionBody(=>, ;) + endTopLevelMethod(void, null, ;) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.intertwined.expect new file mode 100644 index 00000000000..fd180e4d85e --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.intertwined.expect @@ -0,0 +1,129 @@ +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(Object) + listener: endMetadataStar(0) + listener: beginFormalParameter(Object, MemberKind.TopLevelMethod, null, null, null) + listener: handleIdentifier(Object, typeReference) + listener: handleNoTypeArguments(?) + listener: handleType(Object, ?) + 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) + parseExpressionFunctionBody(=>, false) + parseExpression(=>) + looksLikeOuterPatternEquals(=>) + skipOuterPattern(=>) + parsePrecedenceExpression(=>, 1, true, ConstantPatternContext.none) + parseUnaryExpression(=>, true, ConstantPatternContext.none) + parsePrimary(=>, expression, ConstantPatternContext.none) + inPlainSync() + parseSwitchExpression(=>) + listener: beginSwitchExpression(switch) + ensureParenthesizedCondition(switch, allowCase: false) + parseExpressionInParenthesisRest((, allowCase: false) + parseExpression(() + looksLikeOuterPatternEquals(() + skipOuterPattern(() + skipObjectPatternRest(x) + parsePrecedenceExpression((, 1, true, ConstantPatternContext.none) + parseUnaryExpression((, true, ConstantPatternContext.none) + parsePrimary((, expression, ConstantPatternContext.none) + parseSendOrFunctionLiteral((, expression, ConstantPatternContext.none) + parseSend((, expression, ConstantPatternContext.none) + isNextIdentifier(() + ensureIdentifier((, expression) + listener: handleIdentifier(x, expression) + listener: handleNoTypeArguments()) + parseArgumentsOpt(x) + listener: handleNoArguments()) + listener: handleSend(x, )) + ensureCloseParen(x, () + listener: handleParenthesizedCondition((, null, null) + ensureBlock(), null, switch expression) + listener: beginSwitchExpressionBlock({) + listener: beginSwitchExpressionCase() + parsePattern({, PatternContext.matching, precedence: 1) + listener: beginPattern({) + parsePrimaryPattern({, PatternContext.matching) + listener: beginConstantPattern(null) + parsePrecedenceExpression({, 7, false, ConstantPatternContext.implicit) + parseUnaryExpression({, false, ConstantPatternContext.implicit) + parsePrimary({, expression, ConstantPatternContext.implicit) + inPlainSync() + parseSend({, expression, ConstantPatternContext.implicit) + isNextIdentifier({) + ensureIdentifier({, expression) + reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>') + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + rewriter() + listener: handleIdentifier(, expression) + listener: handleNoTypeArguments(if) + parseArgumentsOpt() + listener: handleNoArguments(if) + listener: handleSend(, if) + listener: endConstantPattern(null) + listener: endPattern() + listener: handleSwitchExpressionCasePattern() + ensureFunctionArrow() + rewriteAndRecover(, Message[ExpectedButGot, Expected '=>' before this., null, {string: =>}], =>) + reportRecoverableError(if, Message[ExpectedButGot, Expected '=>' before this., null, {string: =>}]) + listener: handleRecoverableError(Message[ExpectedButGot, Expected '=>' before this., null, {string: =>}], if, if) + rewriter() + parseExpression(=>) + looksLikeOuterPatternEquals(=>) + skipOuterPattern(=>) + parsePrecedenceExpression(=>, 1, true, ConstantPatternContext.none) + parseUnaryExpression(=>, true, ConstantPatternContext.none) + parsePrimary(=>, expression, ConstantPatternContext.none) + inPlainSync() + parseSend(=>, expression, ConstantPatternContext.none) + isNextIdentifier(=>) + ensureIdentifier(=>, expression) + reportRecoverableErrorWithToken(if, Instance of 'Template<(Token) => Message>') + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got 'if'., Try inserting an identifier before 'if'., {lexeme: if}], if, if) + rewriter() + listener: handleIdentifier(, expression) + listener: handleNoTypeArguments(if) + parseArgumentsOpt() + listener: handleNoArguments(if) + listener: handleSend(, if) + listener: endSwitchExpressionCase(null, =>, ) + findNextCommaOrSemicolon(if, }) + reportRecoverableError(if, Message[ExpectedButGot, Expected '}' before this., null, {string: }}]) + listener: handleRecoverableError(Message[ExpectedButGot, Expected '}' before this., null, {string: }}], if, if) + listener: endSwitchExpressionBlock(1, {, }) + listener: endSwitchExpression(switch, }) + ensureSemicolon(}) + listener: handleExpressionFunctionBody(=>, ;) + inGenerator() + listener: endTopLevelMethod(void, null, ;) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.parser.expect new file mode 100644 index 00000000000..3ab030ad951 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.parser.expect @@ -0,0 +1,7 @@ +NOTICE: Stream was rewritten by parser! + +void f(Object? x) => switch (x) {*synthetic*=>*synthetic*if}; + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] =>[SimpleToken] switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken][SyntheticStringToken]=>[SyntheticToken][SyntheticStringToken]if[KeywordToken]}[SimpleToken];[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.scanner.expect new file mode 100644 index 00000000000..4a2d1ce2a4a --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/syntheticIdentifier_insideSwitchExpression.dart.scanner.expect @@ -0,0 +1,5 @@ +void f(Object? x) => switch (x) {if}; + + +void[KeywordToken] f[StringToken]([BeginToken]Object[StringToken]?[SimpleToken] x[StringToken])[SimpleToken] =>[SimpleToken] switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]if[KeywordToken]}[SimpleToken];[SimpleToken] +[SimpleToken]