From 2f11564d670836b7d1e37d7f0450e0ca1e7569f9 Mon Sep 17 00:00:00 2001 From: Paul Berry Date: Fri, 12 May 2023 15:49:05 +0000 Subject: [PATCH] [stable] Patterns parser: prohibit variable/identifier patterns named when/as. In https://dart-review.googlesource.com/c/sdk/+/299400, the parser was adjusted so that it no longer accepts `when` and `as` as the names for variable patterns in cases where there is a possible ambiguity (e.g. `int when` is not accepted as a pattern because `int` is a legitimate pattern, therefore `when` could introduce a guard clause). This change further prohibits `when` and `as` from being the names of variable patterns or identifier patterns even in the case where there is no ambiguity. This is in line with the discussion at https://github.com/dart-lang/sdk/issues/52199#issuecomment-1526297771, and the spec change at https://github.com/dart-lang/language/pull/3033. Three new error codes are introduced, to cover the three circumstances in which `when` or `as` might be used illegally: in a declared variable pattern, in an assigned variable pattern, or in an identifier pattern. I've also added analyzer tests to ensure that the parser recovers from these errors nicely. Unfortunately, nice error recovery is only feasible in the non-ambiguous cases. I've also updated the language test expectations in `tests/language/patterns/version_2_32_changes_error_test.dart` to reflect the new error messages, and added a few more examples of uses of `when` and `as` that are still permitted. Fixes: https://github.com/dart-lang/sdk/issues/52311 Bug: https://github.com/dart-lang/sdk/issues/52260 Change-Id: I30cb3a1ca627c6db3d281740fb59de74c4118c2b Cherry-pick: https://dart-review.googlesource.com/c/sdk/+/301482 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/302100 Reviewed-by: Konstantin Shcheglov Reviewed-by: Jens Johansen Commit-Queue: Paul Berry --- .../lib/src/messages/codes_generated.dart | 78 +++++++++++++ .../lib/src/parser/parser_impl.dart | 19 +++- .../lib/src/parser/type_info.dart | 5 + .../services/correction/error_fix_status.yaml | 6 + .../src/dart/error/syntactic_errors.g.dart | 29 +++++ .../lib/src/error/error_code_values.g.dart | 3 + .../test/generated/patterns_parser_test.dart | 102 +++++++++++++++++ pkg/front_end/messages.yaml | 48 ++++++++ .../patterns/assignedVariable_namedAs.dart | 4 + .../assignedVariable_namedAs.dart.expect | 49 ++++++++ ...edVariable_namedAs.dart.intertwined.expect | 107 ++++++++++++++++++ ...ssignedVariable_namedAs.dart.parser.expect | 11 ++ ...signedVariable_namedAs.dart.scanner.expect | 11 ++ .../patterns/assignedVariable_namedWhen.dart | 4 + .../assignedVariable_namedWhen.dart.expect | 49 ++++++++ ...Variable_namedWhen.dart.intertwined.expect | 107 ++++++++++++++++++ ...ignedVariable_namedWhen.dart.parser.expect | 11 ++ ...gnedVariable_namedWhen.dart.scanner.expect | 11 ++ .../patterns/constant_identifier_namedAs.dart | 5 + .../constant_identifier_namedAs.dart.expect | 50 ++++++++ ...identifier_namedAs.dart.intertwined.expect | 104 +++++++++++++++++ ...tant_identifier_namedAs.dart.parser.expect | 13 +++ ...ant_identifier_namedAs.dart.scanner.expect | 13 +++ .../constant_identifier_namedWhen.dart | 5 + .../constant_identifier_namedWhen.dart.expect | 50 ++++++++ ...entifier_namedWhen.dart.intertwined.expect | 104 +++++++++++++++++ ...nt_identifier_namedWhen.dart.parser.expect | 13 +++ ...t_identifier_namedWhen.dart.scanner.expect | 13 +++ .../patterns/variable_namedAs.dart | 5 + .../patterns/variable_namedAs.dart.expect | 46 ++++++++ .../variable_namedAs.dart.intertwined.expect | 91 +++++++++++++++ .../variable_namedAs.dart.parser.expect | 13 +++ .../variable_namedAs.dart.scanner.expect | 13 +++ .../patterns/variable_namedWhen.dart | 5 + .../patterns/variable_namedWhen.dart.expect | 46 ++++++++ ...variable_namedWhen.dart.intertwined.expect | 91 +++++++++++++++ .../variable_namedWhen.dart.parser.expect | 13 +++ .../variable_namedWhen.dart.scanner.expect | 13 +++ 38 files changed, 1359 insertions(+), 1 deletion(-) create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedAs.dart create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.scanner.expect create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.expect create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.intertwined.expect create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.parser.expect create mode 100644 pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.scanner.expect diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart index 4e927ada85b9..d9901aadea14 100644 --- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart +++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart @@ -5684,6 +5684,84 @@ Message _withArgumentsIllegalMixinDueToConstructorsCause(String name) { arguments: {'name': name}); } +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template< + Message Function( + Token + token)> templateIllegalPatternAssignmentVariableName = const Template< + Message Function(Token token)>( + problemMessageTemplate: + r"""A variable assigned by a pattern assignment can't be named '#lexeme'.""", + correctionMessageTemplate: r"""Choose a different name.""", + withArguments: _withArgumentsIllegalPatternAssignmentVariableName); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code + codeIllegalPatternAssignmentVariableName = + const Code( + "IllegalPatternAssignmentVariableName", + index: 155); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsIllegalPatternAssignmentVariableName(Token token) { + String lexeme = token.lexeme; + return new Message(codeIllegalPatternAssignmentVariableName, + problemMessage: + """A variable assigned by a pattern assignment can't be named '${lexeme}'.""", + correctionMessage: """Choose a different name.""", + arguments: {'lexeme': token}); +} + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template + templateIllegalPatternIdentifierName = + const Template( + problemMessageTemplate: + r"""A pattern can't refer to an identifier named '#lexeme'.""", + correctionMessageTemplate: r"""Match the identifier using '==""", + withArguments: _withArgumentsIllegalPatternIdentifierName); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeIllegalPatternIdentifierName = + const Code("IllegalPatternIdentifierName", + index: 156); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsIllegalPatternIdentifierName(Token token) { + String lexeme = token.lexeme; + return new Message(codeIllegalPatternIdentifierName, + problemMessage: + """A pattern can't refer to an identifier named '${lexeme}'.""", + correctionMessage: """Match the identifier using '==""", + arguments: {'lexeme': token}); +} + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Template< + Message Function( + Token + token)> templateIllegalPatternVariableName = const Template< + Message Function(Token token)>( + problemMessageTemplate: + r"""The variable declared by a variable pattern can't be named '#lexeme'.""", + correctionMessageTemplate: r"""Choose a different name.""", + withArguments: _withArgumentsIllegalPatternVariableName); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +const Code codeIllegalPatternVariableName = + const Code("IllegalPatternVariableName", + index: 154); + +// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. +Message _withArgumentsIllegalPatternVariableName(Token token) { + String lexeme = token.lexeme; + return new Message(codeIllegalPatternVariableName, + problemMessage: + """The variable declared by a variable pattern can't be named '${lexeme}'.""", + correctionMessage: """Choose a different name.""", + arguments: {'lexeme': token}); +} + // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE. const Code codeIllegalSyncGeneratorReturnType = messageIllegalSyncGeneratorReturnType; 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 9cb384b17ba2..99aca4a97181 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart @@ -117,6 +117,7 @@ import 'type_info.dart' computeType, computeTypeParamOrArg, computeVariablePatternType, + illegalPatternIdentifiers, isValidNonRecordTypeReference, noType, noTypeParamOrArg; @@ -9874,12 +9875,18 @@ class Parser { } else if (dot == null) { // It's a single identifier. If it's a wildcard pattern or we're in an // irrefutable context, parse it as a variable pattern. - if (!patternContext.isRefutable || firstIdentifier.lexeme == '_') { + String name = firstIdentifier.lexeme; + if (!patternContext.isRefutable || name == '_') { // It's a wildcard pattern with no preceding type, so parse it as a // variable pattern. isLastPatternAllowedInsideUnaryPattern = true; return parseVariablePattern(beforeFirstIdentifier, patternContext, typeInfo: typeInfo); + } else if (illegalPatternIdentifiers.contains(name)) { + reportRecoverableError( + firstIdentifier, + codes.templateIllegalPatternIdentifierName + .withArguments(firstIdentifier)); } } // It's not an object pattern so parse it as an expression. @@ -9963,8 +9970,18 @@ class Parser { } listener.handleWildcardPattern(keyword, token); } else if (inAssignmentPattern && isBareIdentifier) { + if (illegalPatternIdentifiers.contains(variableName)) { + reportRecoverableError( + token, + codes.templateIllegalPatternAssignmentVariableName + .withArguments(token)); + } listener.handleAssignedVariablePattern(token); } else { + if (illegalPatternIdentifiers.contains(variableName)) { + reportRecoverableError(token, + codes.templateIllegalPatternVariableName.withArguments(token)); + } if (isBareIdentifier) { listener.handleNoType(token); } diff --git a/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart b/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart index 39d1406effa8..241b1ef9853c 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/type_info.dart @@ -433,6 +433,11 @@ TypeParamOrArgInfo computeMethodTypeArguments(Token token) { : noTypeParamOrArg; } +/// The set of identifiers that are illegal to use as the name of a variable in +/// a variable pattern, or as the name of an identifier in an identifier +/// pattern. +const Set illegalPatternIdentifiers = {'when', 'as'}; + /// Indicates whether the given [token] is allowed to follow a list of type /// arguments used as a selector after an expression. /// diff --git a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml index c8b28514494c..0af9ed028ae2 100644 --- a/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml +++ b/pkg/analysis_server/lib/src/services/correction/error_fix_status.yaml @@ -2686,6 +2686,12 @@ ParserErrorCode.GETTER_WITH_PARAMETERS: status: hasFix ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE: status: needsEvaluation +ParserErrorCode.ILLEGAL_PATTERN_ASSIGNMENT_VARIABLE_NAME: + status: needsEvaluation +ParserErrorCode.ILLEGAL_PATTERN_IDENTIFIER_NAME: + status: needsEvaluation +ParserErrorCode.ILLEGAL_PATTERN_VARIABLE_NAME: + status: needsEvaluation ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS: status: needsEvaluation ParserErrorCode.IMPLEMENTS_BEFORE_ON: diff --git a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart index e84a404c0b2e..fcb4f263f227 100644 --- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart +++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart @@ -168,6 +168,9 @@ final fastaAnalyzerErrorCodes = [ ParserErrorCode.LATE_PATTERN_VARIABLE_DECLARATION, ParserErrorCode.PATTERN_VARIABLE_DECLARATION_OUTSIDE_FUNCTION_OR_METHOD, ParserErrorCode.DEFAULT_IN_SWITCH_EXPRESSION, + ParserErrorCode.ILLEGAL_PATTERN_VARIABLE_NAME, + ParserErrorCode.ILLEGAL_PATTERN_ASSIGNMENT_VARIABLE_NAME, + ParserErrorCode.ILLEGAL_PATTERN_IDENTIFIER_NAME, ]; class ParserErrorCode extends ErrorCode { @@ -896,6 +899,32 @@ class ParserErrorCode extends ErrorCode { "Illegal assignment to non-assignable expression.", ); + /// Parameters: + /// 0: the illegal name + static const ParserErrorCode ILLEGAL_PATTERN_ASSIGNMENT_VARIABLE_NAME = + ParserErrorCode( + 'ILLEGAL_PATTERN_ASSIGNMENT_VARIABLE_NAME', + "A variable assigned by a pattern assignment can't be named '{0}'.", + correctionMessage: "Choose a different name.", + ); + + /// Parameters: + /// 0: the illegal name + static const ParserErrorCode ILLEGAL_PATTERN_IDENTIFIER_NAME = + ParserErrorCode( + 'ILLEGAL_PATTERN_IDENTIFIER_NAME', + "A pattern can't refer to an identifier named '{0}'.", + correctionMessage: "Match the identifier using '==", + ); + + /// Parameters: + /// 0: the illegal name + static const ParserErrorCode ILLEGAL_PATTERN_VARIABLE_NAME = ParserErrorCode( + 'ILLEGAL_PATTERN_VARIABLE_NAME', + "The variable declared by a variable pattern can't be named '{0}'.", + correctionMessage: "Choose a different name.", + ); + static const ParserErrorCode IMPLEMENTS_BEFORE_EXTENDS = ParserErrorCode( 'IMPLEMENTS_BEFORE_EXTENDS', "The extends clause must be before the implements clause.", diff --git a/pkg/analyzer/lib/src/error/error_code_values.g.dart b/pkg/analyzer/lib/src/error/error_code_values.g.dart index cebde45e14d3..4f2129c5d9c1 100644 --- a/pkg/analyzer/lib/src/error/error_code_values.g.dart +++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart @@ -722,6 +722,9 @@ const List errorCodeValues = [ ParserErrorCode.GETTER_IN_FUNCTION, ParserErrorCode.GETTER_WITH_PARAMETERS, ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, + ParserErrorCode.ILLEGAL_PATTERN_ASSIGNMENT_VARIABLE_NAME, + ParserErrorCode.ILLEGAL_PATTERN_IDENTIFIER_NAME, + ParserErrorCode.ILLEGAL_PATTERN_VARIABLE_NAME, ParserErrorCode.IMPLEMENTS_BEFORE_EXTENDS, ParserErrorCode.IMPLEMENTS_BEFORE_ON, ParserErrorCode.IMPLEMENTS_BEFORE_WITH, diff --git a/pkg/analyzer/test/generated/patterns_parser_test.dart b/pkg/analyzer/test/generated/patterns_parser_test.dart index 559d8c20670a..60125bce3495 100644 --- a/pkg/analyzer/test/generated/patterns_parser_test.dart +++ b/pkg/analyzer/test/generated/patterns_parser_test.dart @@ -21,6 +21,44 @@ main() { class PatternsTest extends ParserDiagnosticsTest { late FindNode findNode; + test_assignedVariable_namedAs() { + _parse(''' +void f(x) { + dynamic as; + (as) = x; +} +''', errors: [ + error(ParserErrorCode.ILLEGAL_PATTERN_ASSIGNMENT_VARIABLE_NAME, 29, 2) + ]); + var node = findNode.singlePatternAssignment.pattern; + assertParsedNodeText(node, r''' +ParenthesizedPattern + leftParenthesis: ( + pattern: AssignedVariablePattern + name: as + rightParenthesis: ) +'''); + } + + test_assignedVariable_namedWhen() { + _parse(''' +void f(x) { + dynamic when; + (when) = x; +} +''', errors: [ + error(ParserErrorCode.ILLEGAL_PATTERN_ASSIGNMENT_VARIABLE_NAME, 31, 4) + ]); + var node = findNode.singlePatternAssignment.pattern; + assertParsedNodeText(node, r''' +ParenthesizedPattern + leftParenthesis: ( + pattern: AssignedVariablePattern + name: when + rightParenthesis: ) +'''); + } + test_case_identifier_dot_incomplete() { // Based on the repro from // https://github.com/Dart-Code/Dart-Code/issues/4407. @@ -1305,6 +1343,38 @@ ConstantPattern '''); } + test_constant_identifier_namedAs() { + _parse(''' +void f(x) { + switch (x) { + case as: + } +} +''', errors: [error(ParserErrorCode.ILLEGAL_PATTERN_IDENTIFIER_NAME, 36, 2)]); + var node = findNode.singleGuardedPattern.pattern; + assertParsedNodeText(node, r''' +ConstantPattern + expression: SimpleIdentifier + token: as +'''); + } + + test_constant_identifier_namedWhen() { + _parse(''' +void f(x) { + switch (x) { + case when: + } +} +''', errors: [error(ParserErrorCode.ILLEGAL_PATTERN_IDENTIFIER_NAME, 36, 4)]); + var node = findNode.singleGuardedPattern.pattern; + assertParsedNodeText(node, r''' +ConstantPattern + expression: SimpleIdentifier + token: when +'''); + } + test_constant_identifier_prefixed_builtin() { _parse(''' void f(x) { @@ -10022,6 +10092,38 @@ NullCheckPattern '''); } + test_variable_namedAs() { + _parse(''' +void f(x) { + switch (x) { + case var as: + } +} +''', errors: [error(ParserErrorCode.ILLEGAL_PATTERN_VARIABLE_NAME, 40, 2)]); + var node = findNode.singleGuardedPattern.pattern; + assertParsedNodeText(node, r''' +DeclaredVariablePattern + keyword: var + name: as +'''); + } + + test_variable_namedWhen() { + _parse(''' +void f(x) { + switch (x) { + case var when: + } +} +''', errors: [error(ParserErrorCode.ILLEGAL_PATTERN_VARIABLE_NAME, 40, 4)]); + var node = findNode.singleGuardedPattern.pattern; + assertParsedNodeText(node, r''' +DeclaredVariablePattern + keyword: var + name: when +'''); + } + test_variable_type_record_empty_inDeclarationContext() { _parse(''' void f(x) { diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml index b7b1875b4473..53c8b18b41c5 100644 --- a/pkg/front_end/messages.yaml +++ b/pkg/front_end/messages.yaml @@ -6719,6 +6719,54 @@ VariablePatternKeywordInDeclarationContext: } ``` +IllegalPatternVariableName: + problemMessage: The variable declared by a variable pattern can't be named '#lexeme'. + correctionMessage: Choose a different name. + analyzerCode: ParserErrorCode.ILLEGAL_PATTERN_VARIABLE_NAME + index: 154 + experiments: patterns + comment: |- + Parameters: + 0: the illegal name + script: | + void f(x) { + switch (x) { + case var when: + } + } + +IllegalPatternAssignmentVariableName: + problemMessage: A variable assigned by a pattern assignment can't be named '#lexeme'. + correctionMessage: Choose a different name. + analyzerCode: ParserErrorCode.ILLEGAL_PATTERN_ASSIGNMENT_VARIABLE_NAME + index: 155 + experiments: patterns + comment: |- + Parameters: + 0: the illegal name + script: | + void f(x) { + dynamic when; + (when) = x; + } + +IllegalPatternIdentifierName: + problemMessage: A pattern can't refer to an identifier named '#lexeme'. + correctionMessage: Match the identifier using '== #lexeme'. + analyzerCode: ParserErrorCode.ILLEGAL_PATTERN_IDENTIFIER_NAME + index: 156 + experiments: patterns + comment: |- + Parameters: + 0: the illegal name + script: | + void f(x) { + const when = 0; + switch (x) { + case when: + } + } + InvalidInsideUnaryPattern: problemMessage: This pattern cannot appear inside a unary pattern (cast pattern, null check pattern, or null assert pattern) without parentheses. correctionMessage: Try combining into a single pattern if possible, or enclose the inner pattern in parentheses. diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart new file mode 100644 index 000000000000..5c0363d02751 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart @@ -0,0 +1,4 @@ +void f(x) { + dynamic as; + (as) = x; +} diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.expect b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.expect new file mode 100644 index 000000000000..8a3f4fadbfdb --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.expect @@ -0,0 +1,49 @@ +Problems reported: + +parser/patterns/assignedVariable_namedAs:3:4: A variable assigned by a pattern assignment can't be named 'as'. + (as) = x; + ^^ + +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({) + beginMetadataStar(dynamic) + endMetadataStar(0) + handleIdentifier(dynamic, typeReference) + handleNoTypeArguments(as) + handleType(dynamic, null) + beginVariablesDeclaration(as, null, null) + handleIdentifier(as, localVariableDeclaration) + beginInitializedIdentifier(as) + handleNoVariableInitializer(as) + endInitializedIdentifier(as) + endVariablesDeclaration(1, ;) + handleRecoverableError(Message[IllegalPatternAssignmentVariableName, A variable assigned by a pattern assignment can't be named 'as'., Choose a different name., {lexeme: as}], as, as) + handleAssignedVariablePattern(as) + handleParenthesizedPattern(() + handleIdentifier(x, expression) + handleNoTypeArguments(;) + handleNoArguments(;) + handleSend(x, ;) + handlePatternAssignment(=) + handleExpressionStatement(;) + endBlockFunctionBody(2, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.intertwined.expect new file mode 100644 index 000000000000..77f71b131cda --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.intertwined.expect @@ -0,0 +1,107 @@ +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(}, dynamic) + parseStatement({) + parseStatementX({) + parseExpressionStatementOrDeclaration({, null) + parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, null) + looksLikeLocalFunction(as) + listener: beginMetadataStar(dynamic) + listener: endMetadataStar(0) + listener: handleIdentifier(dynamic, typeReference) + listener: handleNoTypeArguments(as) + listener: handleType(dynamic, null) + listener: beginVariablesDeclaration(as, null, null) + parseVariablesDeclarationRest(dynamic, true) + parseOptionallyInitializedIdentifier(dynamic) + ensureIdentifier(dynamic, localVariableDeclaration) + inPlainSync() + listener: handleIdentifier(as, localVariableDeclaration) + listener: beginInitializedIdentifier(as) + parseVariableInitializerOpt(as) + listener: handleNoVariableInitializer(as) + listener: endInitializedIdentifier(as) + ensureSemicolon(as) + listener: endVariablesDeclaration(1, ;) + notEofOrValue(}, () + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclaration(;, null) + parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null) + looksLikeLocalFunction(() + parseExpressionStatement(;) + parseExpression(;) + looksLikeOuterPatternEquals(;) + skipOuterPattern(;) + parsePatternAssignment(;) + parsePattern(;, PatternContext.assignment, precedence: 1) + parsePrimaryPattern(;, PatternContext.assignment) + parseParenthesizedPatternOrRecordPattern(;, PatternContext.assignment) + parsePattern((, PatternContext.assignment, precedence: 1) + parsePrimaryPattern((, PatternContext.assignment) + parseVariablePattern((, PatternContext.assignment, typeInfo: Instance of 'NoType') + reportRecoverableError(as, Message[IllegalPatternAssignmentVariableName, A variable assigned by a pattern assignment can't be named 'as'., Choose a different name., {lexeme: as}]) + listener: handleRecoverableError(Message[IllegalPatternAssignmentVariableName, A variable assigned by a pattern assignment can't be named 'as'., Choose a different name., {lexeme: as}], as, as) + listener: handleAssignedVariablePattern(as) + ensureCloseParen(as, () + listener: handleParenthesizedPattern(() + 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, ;) + listener: handlePatternAssignment(=) + ensureSemicolon(x) + listener: handleExpressionStatement(;) + notEofOrValue(}, }) + listener: endBlockFunctionBody(2, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.parser.expect new file mode 100644 index 000000000000..155f79101265 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.parser.expect @@ -0,0 +1,11 @@ +void f(x) { +dynamic as; +(as) = x; +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +dynamic[KeywordToken] as[KeywordToken];[SimpleToken] +([BeginToken]as[KeywordToken])[SimpleToken] =[SimpleToken] x[StringToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.scanner.expect new file mode 100644 index 000000000000..155f79101265 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedAs.dart.scanner.expect @@ -0,0 +1,11 @@ +void f(x) { +dynamic as; +(as) = x; +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +dynamic[KeywordToken] as[KeywordToken];[SimpleToken] +([BeginToken]as[KeywordToken])[SimpleToken] =[SimpleToken] x[StringToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart new file mode 100644 index 000000000000..15c44fe25c4d --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart @@ -0,0 +1,4 @@ +void f(x) { + dynamic when; + (when) = x; +} diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.expect b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.expect new file mode 100644 index 000000000000..0394137c455e --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.expect @@ -0,0 +1,49 @@ +Problems reported: + +parser/patterns/assignedVariable_namedWhen:3:4: A variable assigned by a pattern assignment can't be named 'when'. + (when) = x; + ^^^^ + +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({) + beginMetadataStar(dynamic) + endMetadataStar(0) + handleIdentifier(dynamic, typeReference) + handleNoTypeArguments(when) + handleType(dynamic, null) + beginVariablesDeclaration(when, null, null) + handleIdentifier(when, localVariableDeclaration) + beginInitializedIdentifier(when) + handleNoVariableInitializer(when) + endInitializedIdentifier(when) + endVariablesDeclaration(1, ;) + handleRecoverableError(Message[IllegalPatternAssignmentVariableName, A variable assigned by a pattern assignment can't be named 'when'., Choose a different name., {lexeme: when}], when, when) + handleAssignedVariablePattern(when) + handleParenthesizedPattern(() + handleIdentifier(x, expression) + handleNoTypeArguments(;) + handleNoArguments(;) + handleSend(x, ;) + handlePatternAssignment(=) + handleExpressionStatement(;) + endBlockFunctionBody(2, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.intertwined.expect new file mode 100644 index 000000000000..0c0e5ff61631 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.intertwined.expect @@ -0,0 +1,107 @@ +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(}, dynamic) + parseStatement({) + parseStatementX({) + parseExpressionStatementOrDeclaration({, null) + parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, null) + looksLikeLocalFunction(when) + listener: beginMetadataStar(dynamic) + listener: endMetadataStar(0) + listener: handleIdentifier(dynamic, typeReference) + listener: handleNoTypeArguments(when) + listener: handleType(dynamic, null) + listener: beginVariablesDeclaration(when, null, null) + parseVariablesDeclarationRest(dynamic, true) + parseOptionallyInitializedIdentifier(dynamic) + ensureIdentifier(dynamic, localVariableDeclaration) + inPlainSync() + listener: handleIdentifier(when, localVariableDeclaration) + listener: beginInitializedIdentifier(when) + parseVariableInitializerOpt(when) + listener: handleNoVariableInitializer(when) + listener: endInitializedIdentifier(when) + ensureSemicolon(when) + listener: endVariablesDeclaration(1, ;) + notEofOrValue(}, () + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclaration(;, null) + parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null) + looksLikeLocalFunction(() + parseExpressionStatement(;) + parseExpression(;) + looksLikeOuterPatternEquals(;) + skipOuterPattern(;) + parsePatternAssignment(;) + parsePattern(;, PatternContext.assignment, precedence: 1) + parsePrimaryPattern(;, PatternContext.assignment) + parseParenthesizedPatternOrRecordPattern(;, PatternContext.assignment) + parsePattern((, PatternContext.assignment, precedence: 1) + parsePrimaryPattern((, PatternContext.assignment) + parseVariablePattern((, PatternContext.assignment, typeInfo: Instance of 'NoType') + reportRecoverableError(when, Message[IllegalPatternAssignmentVariableName, A variable assigned by a pattern assignment can't be named 'when'., Choose a different name., {lexeme: when}]) + listener: handleRecoverableError(Message[IllegalPatternAssignmentVariableName, A variable assigned by a pattern assignment can't be named 'when'., Choose a different name., {lexeme: when}], when, when) + listener: handleAssignedVariablePattern(when) + ensureCloseParen(when, () + listener: handleParenthesizedPattern(() + 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, ;) + listener: handlePatternAssignment(=) + ensureSemicolon(x) + listener: handleExpressionStatement(;) + notEofOrValue(}, }) + listener: endBlockFunctionBody(2, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.parser.expect new file mode 100644 index 000000000000..06d4f425d26d --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.parser.expect @@ -0,0 +1,11 @@ +void f(x) { +dynamic when; +(when) = x; +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +dynamic[KeywordToken] when[KeywordToken];[SimpleToken] +([BeginToken]when[KeywordToken])[SimpleToken] =[SimpleToken] x[StringToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.scanner.expect new file mode 100644 index 000000000000..06d4f425d26d --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/assignedVariable_namedWhen.dart.scanner.expect @@ -0,0 +1,11 @@ +void f(x) { +dynamic when; +(when) = x; +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +dynamic[KeywordToken] when[KeywordToken];[SimpleToken] +([BeginToken]when[KeywordToken])[SimpleToken] =[SimpleToken] x[StringToken];[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart new file mode 100644 index 000000000000..44753b8aa17e --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart @@ -0,0 +1,5 @@ +void f(x) { + switch (x) { + case as: + } +} diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.expect b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.expect new file mode 100644 index 000000000000..83023bd1a930 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.expect @@ -0,0 +1,50 @@ +Problems reported: + +parser/patterns/constant_identifier_namedAs:3:10: A pattern can't refer to an identifier named 'as'. + case as: + ^^ + +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) + handleRecoverableError(Message[IllegalPatternIdentifierName, A pattern can't refer to an identifier named 'as'., Match the identifier using '==, {lexeme: as}], as, as) + beginConstantPattern(null) + handleIdentifier(as, expression) + handleNoTypeArguments(:) + handleNoArguments(:) + handleSend(as, :) + endConstantPattern(null) + handleSwitchCaseNoWhenClause(as) + endCaseExpression(case, null, :) + beginSwitchCase(0, 1, case) + endSwitchCase(0, 1, null, null, 0, case, }) + endSwitchBlock(1, {, }) + endSwitchStatement(switch, }) + endBlockFunctionBody(1, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.intertwined.expect new file mode 100644 index 000000000000..02d65f2e3745 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.intertwined.expect @@ -0,0 +1,104 @@ +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(() + 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) + parsePrimaryPattern(case, PatternContext.matching) + reportRecoverableError(as, Message[IllegalPatternIdentifierName, A pattern can't refer to an identifier named 'as'., Match the identifier using '==, {lexeme: as}]) + listener: handleRecoverableError(Message[IllegalPatternIdentifierName, A pattern can't refer to an identifier named 'as'., Match the identifier using '==, {lexeme: as}], as, as) + listener: beginConstantPattern(null) + parsePrecedenceExpression(case, 7, false, ConstantPatternContext.implicit) + parseUnaryExpression(case, false, ConstantPatternContext.implicit) + parsePrimary(case, expression, ConstantPatternContext.implicit) + inPlainSync() + parseSendOrFunctionLiteral(case, expression, ConstantPatternContext.implicit) + parseSend(case, expression, ConstantPatternContext.implicit) + isNextIdentifier(case) + ensureIdentifier(case, expression) + inPlainSync() + listener: handleIdentifier(as, expression) + listener: handleNoTypeArguments(:) + parseArgumentsOpt(as) + listener: handleNoArguments(:) + listener: handleSend(as, :) + listener: endConstantPattern(null) + listener: handleSwitchCaseNoWhenClause(as) + ensureColon(as) + 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(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.parser.expect new file mode 100644 index 000000000000..0d082e986939 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.parser.expect @@ -0,0 +1,13 @@ +void f(x) { +switch (x) { +case as: +} +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] as[KeywordToken]:[SimpleToken] +}[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.scanner.expect new file mode 100644 index 000000000000..0d082e986939 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedAs.dart.scanner.expect @@ -0,0 +1,13 @@ +void f(x) { +switch (x) { +case as: +} +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] as[KeywordToken]:[SimpleToken] +}[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart new file mode 100644 index 000000000000..690db36fe178 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart @@ -0,0 +1,5 @@ +void f(x) { + switch (x) { + case when: + } +} diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.expect b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.expect new file mode 100644 index 000000000000..ade496ebf6e4 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.expect @@ -0,0 +1,50 @@ +Problems reported: + +parser/patterns/constant_identifier_namedWhen:3:10: A pattern can't refer to an identifier named 'when'. + case when: + ^^^^ + +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) + handleRecoverableError(Message[IllegalPatternIdentifierName, A pattern can't refer to an identifier named 'when'., Match the identifier using '==, {lexeme: when}], when, when) + beginConstantPattern(null) + handleIdentifier(when, expression) + handleNoTypeArguments(:) + handleNoArguments(:) + handleSend(when, :) + endConstantPattern(null) + handleSwitchCaseNoWhenClause(when) + endCaseExpression(case, null, :) + beginSwitchCase(0, 1, case) + endSwitchCase(0, 1, null, null, 0, case, }) + endSwitchBlock(1, {, }) + endSwitchStatement(switch, }) + endBlockFunctionBody(1, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.intertwined.expect new file mode 100644 index 000000000000..5df79dd742b2 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.intertwined.expect @@ -0,0 +1,104 @@ +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(() + 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) + parsePrimaryPattern(case, PatternContext.matching) + reportRecoverableError(when, Message[IllegalPatternIdentifierName, A pattern can't refer to an identifier named 'when'., Match the identifier using '==, {lexeme: when}]) + listener: handleRecoverableError(Message[IllegalPatternIdentifierName, A pattern can't refer to an identifier named 'when'., Match the identifier using '==, {lexeme: when}], when, when) + listener: beginConstantPattern(null) + parsePrecedenceExpression(case, 7, false, ConstantPatternContext.implicit) + parseUnaryExpression(case, false, ConstantPatternContext.implicit) + parsePrimary(case, expression, ConstantPatternContext.implicit) + inPlainSync() + parseSendOrFunctionLiteral(case, expression, ConstantPatternContext.implicit) + parseSend(case, expression, ConstantPatternContext.implicit) + isNextIdentifier(case) + ensureIdentifier(case, expression) + inPlainSync() + listener: handleIdentifier(when, expression) + listener: handleNoTypeArguments(:) + parseArgumentsOpt(when) + listener: handleNoArguments(:) + listener: handleSend(when, :) + listener: endConstantPattern(null) + listener: handleSwitchCaseNoWhenClause(when) + ensureColon(when) + 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(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.parser.expect new file mode 100644 index 000000000000..477a730d196a --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.parser.expect @@ -0,0 +1,13 @@ +void f(x) { +switch (x) { +case when: +} +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] when[KeywordToken]:[SimpleToken] +}[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.scanner.expect new file mode 100644 index 000000000000..477a730d196a --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/constant_identifier_namedWhen.dart.scanner.expect @@ -0,0 +1,13 @@ +void f(x) { +switch (x) { +case when: +} +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] when[KeywordToken]:[SimpleToken] +}[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart new file mode 100644 index 000000000000..66a6cd216744 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart @@ -0,0 +1,5 @@ +void f(x) { + switch (x) { + case var as: + } +} diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.expect b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.expect new file mode 100644 index 000000000000..886f9f44cc94 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.expect @@ -0,0 +1,46 @@ +Problems reported: + +parser/patterns/variable_namedAs:3:14: The variable declared by a variable pattern can't be named 'as'. + case var as: + ^^ + +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) + handleNoType(var) + handleRecoverableError(Message[IllegalPatternVariableName, The variable declared by a variable pattern can't be named 'as'., Choose a different name., {lexeme: as}], as, as) + handleDeclaredVariablePattern(var, as, false) + handleSwitchCaseNoWhenClause(as) + endCaseExpression(case, null, :) + beginSwitchCase(0, 1, case) + endSwitchCase(0, 1, null, null, 0, case, }) + endSwitchBlock(1, {, }) + endSwitchStatement(switch, }) + endBlockFunctionBody(1, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.intertwined.expect new file mode 100644 index 000000000000..18137b7ed373 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.intertwined.expect @@ -0,0 +1,91 @@ +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(() + 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) + parsePrimaryPattern(case, PatternContext.matching) + parseVariablePattern(case, PatternContext.matching, typeInfo: Instance of 'NoType') + listener: handleNoType(var) + reportRecoverableError(as, Message[IllegalPatternVariableName, The variable declared by a variable pattern can't be named 'as'., Choose a different name., {lexeme: as}]) + listener: handleRecoverableError(Message[IllegalPatternVariableName, The variable declared by a variable pattern can't be named 'as'., Choose a different name., {lexeme: as}], as, as) + listener: handleDeclaredVariablePattern(var, as, false) + listener: handleSwitchCaseNoWhenClause(as) + ensureColon(as) + 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(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.parser.expect new file mode 100644 index 000000000000..e37dc341667b --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.parser.expect @@ -0,0 +1,13 @@ +void f(x) { +switch (x) { +case var as: +} +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] var[KeywordToken] as[KeywordToken]:[SimpleToken] +}[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.scanner.expect new file mode 100644 index 000000000000..e37dc341667b --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedAs.dart.scanner.expect @@ -0,0 +1,13 @@ +void f(x) { +switch (x) { +case var as: +} +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] var[KeywordToken] as[KeywordToken]:[SimpleToken] +}[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart new file mode 100644 index 000000000000..41dcf2d4dd4b --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart @@ -0,0 +1,5 @@ +void f(x) { + switch (x) { + case var when: + } +} diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.expect b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.expect new file mode 100644 index 000000000000..a645502bde4a --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.expect @@ -0,0 +1,46 @@ +Problems reported: + +parser/patterns/variable_namedWhen:3:14: The variable declared by a variable pattern can't be named 'when'. + case var when: + ^^^^ + +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) + handleNoType(var) + handleRecoverableError(Message[IllegalPatternVariableName, The variable declared by a variable pattern can't be named 'when'., Choose a different name., {lexeme: when}], when, when) + handleDeclaredVariablePattern(var, when, false) + handleSwitchCaseNoWhenClause(when) + endCaseExpression(case, null, :) + beginSwitchCase(0, 1, case) + endSwitchCase(0, 1, null, null, 0, case, }) + endSwitchBlock(1, {, }) + endSwitchStatement(switch, }) + endBlockFunctionBody(1, {, }) + endTopLevelMethod(void, null, }) + endTopLevelDeclaration() +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.intertwined.expect new file mode 100644 index 000000000000..662d92be08d9 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.intertwined.expect @@ -0,0 +1,91 @@ +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(() + 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) + parsePrimaryPattern(case, PatternContext.matching) + parseVariablePattern(case, PatternContext.matching, typeInfo: Instance of 'NoType') + listener: handleNoType(var) + reportRecoverableError(when, Message[IllegalPatternVariableName, The variable declared by a variable pattern can't be named 'when'., Choose a different name., {lexeme: when}]) + listener: handleRecoverableError(Message[IllegalPatternVariableName, The variable declared by a variable pattern can't be named 'when'., Choose a different name., {lexeme: when}], when, when) + listener: handleDeclaredVariablePattern(var, when, false) + listener: handleSwitchCaseNoWhenClause(when) + ensureColon(when) + 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(}, }) + listener: endBlockFunctionBody(1, {, }) + listener: endTopLevelMethod(void, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(void) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.parser.expect new file mode 100644 index 000000000000..962f0324e0d3 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.parser.expect @@ -0,0 +1,13 @@ +void f(x) { +switch (x) { +case var when: +} +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] var[KeywordToken] when[KeywordToken]:[SimpleToken] +}[SimpleToken] +}[SimpleToken] +[SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.scanner.expect new file mode 100644 index 000000000000..962f0324e0d3 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/variable_namedWhen.dart.scanner.expect @@ -0,0 +1,13 @@ +void f(x) { +switch (x) { +case var when: +} +} + + +void[KeywordToken] f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +switch[KeywordToken] ([BeginToken]x[StringToken])[SimpleToken] {[BeginToken] +case[KeywordToken] var[KeywordToken] when[KeywordToken]:[SimpleToken] +}[SimpleToken] +}[SimpleToken] +[SimpleToken]