Patterns parsing: improve error recovery for `late` in patternVariableDeclaration.
Bug: https://github.com/dart-lang/sdk/issues/50035
Change-Id: Id706ff0afab3f14d817fbf99112f772d1f1f7817
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/292800
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
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 3edbcd7..086992b 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -8346,6 +8346,18 @@
}
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeLatePatternVariableDeclaration =
+ messageLatePatternVariableDeclaration;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageLatePatternVariableDeclaration = const MessageCode(
+ "LatePatternVariableDeclaration",
+ index: 151,
+ problemMessage:
+ r"""A pattern variable declaration may not use the `late` keyword.""",
+ correctionMessage: r"""Try removing the keyword `late`.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Code<Null> codeLibraryDirectiveNotFirst = messageLibraryDirectiveNotFirst;
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
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 b5ec6f4..1fd4676 100644
--- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart
@@ -7792,10 +7792,7 @@
varFinalOrConst = context.varFinalOrConst;
}
- // TODO(paulberry): maybe some of the conditions in this `if` test should be
- // removed to allow for better error recovery.
if (allowPatterns &&
- lateToken == null &&
varFinalOrConst != null &&
(optional('var', varFinalOrConst) ||
optional('final', varFinalOrConst))) {
@@ -7804,6 +7801,10 @@
(optional('=', afterOuterPattern.next!) ||
(forPartsContext != null &&
optional('in', afterOuterPattern.next!)))) {
+ if (lateToken != null) {
+ reportRecoverableError(
+ lateToken, codes.messageLatePatternVariableDeclaration);
+ }
// If there was any metadata, then the caller was responsible for
// parsing it; if not, then we need to let the listener know there
// wasn't any.
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 7260bc4..5067849 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
@@ -2530,6 +2530,8 @@
status: needsEvaluation
ParserErrorCode.INVALID_USE_OF_COVARIANT_IN_EXTENSION:
status: needsEvaluation
+ParserErrorCode.LATE_PATTERN_VARIABLE_DECLARATION:
+ status: needsEvaluation
ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST:
status: needsEvaluation
ParserErrorCode.LITERAL_WITH_CLASS_AND_NEW:
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 821d4fb..9bcd01f 100644
--- a/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/syntactic_errors.g.dart
@@ -165,6 +165,7 @@
ParserErrorCode.SEALED_MIXIN,
ParserErrorCode.VARIABLE_PATTERN_KEYWORD_IN_DECLARATION_CONTEXT,
ParserErrorCode.INVALID_INSIDE_UNARY_PATTERN,
+ ParserErrorCode.LATE_PATTERN_VARIABLE_DECLARATION,
];
class ParserErrorCode extends ErrorCode {
@@ -1128,6 +1129,14 @@
hasPublishedDocs: true,
);
+ /// No parameters.
+ static const ParserErrorCode LATE_PATTERN_VARIABLE_DECLARATION =
+ ParserErrorCode(
+ 'LATE_PATTERN_VARIABLE_DECLARATION',
+ "A pattern variable declaration may not use the `late` keyword.",
+ correctionMessage: "Try removing the keyword `late`.",
+ );
+
static const ParserErrorCode LIBRARY_DIRECTIVE_NOT_FIRST = ParserErrorCode(
'LIBRARY_DIRECTIVE_NOT_FIRST',
"The library directive must appear before all other directives.",
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 3a7ecc8..50da53f 100644
--- a/pkg/analyzer/lib/src/error/error_code_values.g.dart
+++ b/pkg/analyzer/lib/src/error/error_code_values.g.dart
@@ -754,6 +754,7 @@
ParserErrorCode.INVALID_UNICODE_ESCAPE_U_NO_BRACKET,
ParserErrorCode.INVALID_UNICODE_ESCAPE_U_STARTED,
ParserErrorCode.INVALID_USE_OF_COVARIANT_IN_EXTENSION,
+ ParserErrorCode.LATE_PATTERN_VARIABLE_DECLARATION,
ParserErrorCode.LIBRARY_DIRECTIVE_NOT_FIRST,
ParserErrorCode.LITERAL_WITH_CLASS,
ParserErrorCode.LITERAL_WITH_CLASS_AND_NEW,
diff --git a/pkg/analyzer/test/generated/patterns_parser_test.dart b/pkg/analyzer/test/generated/patterns_parser_test.dart
index 11a490b..2fbf973 100644
--- a/pkg/analyzer/test/generated/patterns_parser_test.dart
+++ b/pkg/analyzer/test/generated/patterns_parser_test.dart
@@ -7538,20 +7538,43 @@
''');
}
- test_patternVariableDeclarationStatement_disallowsLate() {
+ test_patternVariableDeclarationStatement_disallowsConst() {
// TODO(paulberry): do better error recovery.
_parse('''
f(x) {
+ const (_) = x;
+}
+''', errors: [
+ error(ParserErrorCode.MISSING_ASSIGNABLE_SELECTOR, 9, 9),
+ error(ParserErrorCode.ILLEGAL_ASSIGNMENT_TO_NON_ASSIGNABLE, 9, 9),
+ error(ParserErrorCode.RECORD_LITERAL_ONE_POSITIONAL_NO_TRAILING_COMMA, 17,
+ 1),
+ ]);
+ }
+
+ test_patternVariableDeclarationStatement_disallowsLate() {
+ _parse('''
+f(x) {
late var (_) = x;
}
''', errors: [
- error(ParserErrorCode.MISSING_IDENTIFIER, 18, 1),
- error(ParserErrorCode.EXPECTED_TOKEN, 18, 1),
- error(ParserErrorCode.EXPECTED_TOKEN, 19, 1),
- error(ParserErrorCode.MISSING_IDENTIFIER, 20, 1),
- error(ParserErrorCode.UNEXPECTED_TOKEN, 20, 1),
- error(ParserErrorCode.MISSING_IDENTIFIER, 22, 1),
+ error(ParserErrorCode.LATE_PATTERN_VARIABLE_DECLARATION, 9, 4),
]);
+ var node = findNode.patternVariableDeclarationStatement('= x');
+ assertParsedNodeText(node, r'''
+PatternVariableDeclarationStatement
+ declaration: PatternVariableDeclaration
+ keyword: var
+ pattern: ParenthesizedPattern
+ leftParenthesis: (
+ pattern: WildcardPattern
+ name: _
+ rightParenthesis: )
+ equals: =
+ expression: SimpleIdentifier
+ token: x
+ semicolon: ;
+''');
}
test_patternVariableDeclarationStatement_noMetadata_final_extractor() {
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 633fff6..608df3a 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -6720,6 +6720,18 @@
if (x case _ as int as num) {}
}
+LatePatternVariableDeclaration:
+ problemMessage: A pattern variable declaration may not use the `late` keyword.
+ correctionMessage: Try removing the keyword `late`.
+ analyzerCode: ParserErrorCode.LATE_PATTERN_VARIABLE_DECLARATION
+ index: 151
+ experiments: patterns
+ comment: No parameters.
+ script: |
+ void f(x) {
+ late var (y, z) = x;
+ }
+
WeakReferenceNotStatic:
problemMessage: "Weak reference pragma can be used on a static method only."
diff --git a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart
new file mode 100644
index 0000000..aa293ef
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart
@@ -0,0 +1,3 @@
+f(x) {
+ const (_) = x;
+}
diff --git a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.expect b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.expect
new file mode 100644
index 0000000..c7ffe1f
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.expect
@@ -0,0 +1,44 @@
+Problems reported:
+
+parser/patterns/patternVariableDeclarationStatement_disallowsConst:2:11: A record literal with exactly one positional field requires a trailing comma.
+ const (_) = x;
+ ^
+
+beginCompilationUnit(f)
+ beginMetadataStar(f)
+ endMetadataStar(0)
+ beginTopLevelMember(f)
+ beginTopLevelMethod(, null, null)
+ handleNoType()
+ 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({)
+ beginConstLiteral(()
+ beginParenthesizedExpressionOrRecordLiteral(()
+ handleIdentifier(_, expression)
+ handleNoTypeArguments())
+ handleNoArguments())
+ handleSend(_, ))
+ handleRecoverableError(RecordLiteralOnePositionalFieldNoTrailingComma, ), ))
+ endRecordLiteral((, 1, const)
+ endConstLiteral(=)
+ handleIdentifier(x, expression)
+ handleNoTypeArguments(;)
+ handleNoArguments(;)
+ handleSend(x, ;)
+ handleAssignmentExpression(=)
+ handleExpressionStatement(;)
+ endBlockFunctionBody(1, {, })
+ endTopLevelMethod(f, null, })
+ endTopLevelDeclaration()
+endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.intertwined.expect
new file mode 100644
index 0000000..69803ba
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.intertwined.expect
@@ -0,0 +1,95 @@
+parseUnit(f)
+ skipErrorTokens(f)
+ listener: beginCompilationUnit(f)
+ syntheticPreviousToken(f)
+ parseTopLevelDeclarationImpl(, Instance of 'DirectiveContext')
+ parseMetadataStar()
+ listener: beginMetadataStar(f)
+ listener: endMetadataStar(0)
+ parseTopLevelMemberImpl()
+ listener: beginTopLevelMember(f)
+ isReservedKeyword(()
+ parseTopLevelMethod(, null, null, , Instance of 'NoType', null, f, false)
+ listener: beginTopLevelMethod(, null, null)
+ listener: handleNoType()
+ ensureIdentifierPotentiallyRecovered(, 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(}, const)
+ parseStatement({)
+ parseStatementX({)
+ parseExpressionStatementOrConstDeclaration({)
+ parseExpressionStatement({)
+ parseExpression({)
+ looksLikeOuterPatternEquals({)
+ skipOuterPattern({)
+ parsePrecedenceExpression({, 1, true, ConstantPatternContext.none)
+ parseUnaryExpression({, true, ConstantPatternContext.none)
+ parsePrimary({, expression, ConstantPatternContext.none)
+ parseConstExpression({)
+ listener: beginConstLiteral(()
+ parseParenthesizedExpressionOrRecordLiteral(const, const, ConstantPatternContext.none)
+ listener: beginParenthesizedExpressionOrRecordLiteral(()
+ parseExpression(()
+ looksLikeOuterPatternEquals(()
+ skipOuterPattern(()
+ skipObjectPatternRest(_)
+ 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(_, expression)
+ listener: handleNoTypeArguments())
+ parseArgumentsOpt(_)
+ listener: handleNoArguments())
+ listener: handleSend(_, ))
+ ensureCloseParen(_, ()
+ reportRecoverableError(), RecordLiteralOnePositionalFieldNoTrailingComma)
+ listener: handleRecoverableError(RecordLiteralOnePositionalFieldNoTrailingComma, ), ))
+ listener: endRecordLiteral((, 1, const)
+ listener: endConstLiteral(=)
+ 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: handleAssignmentExpression(=)
+ ensureSemicolon(x)
+ listener: handleExpressionStatement(;)
+ notEofOrValue(}, })
+ listener: endBlockFunctionBody(1, {, })
+ listener: endTopLevelMethod(f, null, })
+ listener: endTopLevelDeclaration()
+ reportAllErrorTokens(f)
+ listener: endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.parser.expect
new file mode 100644
index 0000000..79f293d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.parser.expect
@@ -0,0 +1,9 @@
+f(x) {
+const (_) = x;
+}
+
+
+f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+const[KeywordToken] ([BeginToken]_[StringToken])[SimpleToken] =[SimpleToken] x[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.scanner.expect
new file mode 100644
index 0000000..79f293d
--- /dev/null
+++ b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsConst.dart.scanner.expect
@@ -0,0 +1,9 @@
+f(x) {
+const (_) = x;
+}
+
+
+f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
+const[KeywordToken] ([BeginToken]_[StringToken])[SimpleToken] =[SimpleToken] x[StringToken];[SimpleToken]
+}[SimpleToken]
+[SimpleToken]
diff --git a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.expect b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.expect
index b11f423..6a64cb8 100644
--- a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.expect
+++ b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.expect
@@ -1,32 +1,8 @@
Problems reported:
-parser/patterns/patternVariableDeclarationStatement_disallowsLate:2:12: Expected an identifier, but got '('.
+parser/patterns/patternVariableDeclarationStatement_disallowsLate:2:3: A pattern variable declaration may not use the `late` keyword.
late var (_) = x;
- ^
-
-parser/patterns/patternVariableDeclarationStatement_disallowsLate:2:12: Expected ';' after this.
- late var (_) = x;
- ^
-
-parser/patterns/patternVariableDeclarationStatement_disallowsLate:2:13: Expected ';' after this.
- late var (_) = x;
- ^
-
-parser/patterns/patternVariableDeclarationStatement_disallowsLate:2:14: Expected an identifier, but got ')'.
- late var (_) = x;
- ^
-
-parser/patterns/patternVariableDeclarationStatement_disallowsLate:2:13: Expected ';' after this.
- late var (_) = x;
- ^
-
-parser/patterns/patternVariableDeclarationStatement_disallowsLate:2:14: Unexpected token ';'.
- late var (_) = x;
- ^
-
-parser/patterns/patternVariableDeclarationStatement_disallowsLate:2:16: Expected an identifier, but got '='.
- late var (_) = x;
- ^
+ ^^^^
beginCompilationUnit(f)
beginMetadataStar(f)
@@ -47,43 +23,18 @@
endFormalParameters(1, (, ), MemberKind.TopLevelMethod)
handleAsyncModifier(null, null)
beginBlockFunctionBody({)
+ handleRecoverableError(LatePatternVariableDeclaration, late, late)
beginMetadataStar(late)
endMetadataStar(0)
- handleNoType(var)
- beginVariablesDeclaration((, late, var)
- handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}], (, ()
- handleIdentifier(, localVariableDeclaration)
- beginInitializedIdentifier()
- handleNoVariableInitializer()
- endInitializedIdentifier()
- handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], (, ()
- endVariablesDeclaration(1, ;)
- handleIdentifier(_, expression)
- handleNoTypeArguments())
- handleNoArguments())
- handleSend(_, ))
- handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], _, _)
- handleExpressionStatement(;)
- handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., Try inserting an identifier before ')'., {lexeme: )}], ), ))
- handleIdentifier(, expression)
- handleNoTypeArguments())
- handleNoArguments())
- handleSend(, ))
- handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], _, _)
- handleExpressionStatement(;)
- handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {lexeme: ;}], ), ))
- handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '='., Try inserting an identifier before '='., {lexeme: =}], =, =)
- handleIdentifier(, expression)
- handleNoTypeArguments(=)
- handleNoArguments(=)
- handleSend(, =)
+ handleNoType(_)
+ handleWildcardPattern(null, _)
+ handleParenthesizedPattern(()
handleIdentifier(x, expression)
handleNoTypeArguments(;)
handleNoArguments(;)
handleSend(x, ;)
- handleAssignmentExpression(=)
- handleExpressionStatement(;)
- endBlockFunctionBody(4, {, })
+ handlePatternVariableDeclarationStatement(var, =, ;)
+ endBlockFunctionBody(1, {, })
endTopLevelMethod(f, null, })
endTopLevelDeclaration()
endCompilationUnit(1, )
diff --git a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.intertwined.expect
index 5dadf33..07a2084 100644
--- a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.intertwined.expect
+++ b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.intertwined.expect
@@ -41,126 +41,42 @@
parseStatementX({)
parseExpressionStatementOrDeclaration({, null)
parseExpressionStatementOrDeclarationAfterModifiers(var, {, late, var, null, null)
- looksLikeLocalFunction(()
+ skipOuterPattern(var)
+ reportRecoverableError(late, LatePatternVariableDeclaration)
+ listener: handleRecoverableError(LatePatternVariableDeclaration, late, late)
listener: beginMetadataStar(late)
listener: endMetadataStar(0)
- listener: handleNoType(var)
- listener: beginVariablesDeclaration((, late, var)
- parseVariablesDeclarationRest(var, true)
- parseOptionallyInitializedIdentifier(var)
- ensureIdentifier(var, localVariableDeclaration)
- reportRecoverableErrorWithToken((, Instance of 'Template<(Token) => Message>')
- listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '('., Try inserting an identifier before '('., {lexeme: (}], (, ()
- rewriter()
- listener: handleIdentifier(, localVariableDeclaration)
- listener: beginInitializedIdentifier()
- parseVariableInitializerOpt()
- listener: handleNoVariableInitializer()
- listener: endInitializedIdentifier()
- ensureSemicolon()
- reportRecoverableError((, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
- listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], (, ()
- rewriter()
- listener: endVariablesDeclaration(1, ;)
- notEofOrValue(}, _)
- parseStatement(;)
- parseStatementX(;)
- parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
- looksLikeLocalFunction(_)
- parseExpressionStatement(;)
- parseExpression(;)
- looksLikeOuterPatternEquals(;)
- skipOuterPattern(;)
- skipObjectPatternRest(_)
- 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(_, expression)
- listener: handleNoTypeArguments())
- parseArgumentsOpt(_)
- listener: handleNoArguments())
- listener: handleSend(_, ))
- ensureSemicolon(_)
- reportRecoverableError(_, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
- listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], _, _)
- rewriter()
- listener: handleExpressionStatement(;)
- notEofOrValue(}, ))
- parseStatement(;)
- parseStatementX(;)
- parseExpressionStatementOrDeclaration(;, null)
- parseExpressionStatementOrDeclarationAfterModifiers(;, ;, null, null, null, null)
- looksLikeLocalFunction())
- parseExpressionStatement(;)
- parseExpression(;)
- looksLikeOuterPatternEquals(;)
- skipOuterPattern(;)
- parsePrecedenceExpression(;, 1, true, ConstantPatternContext.none)
- parseUnaryExpression(;, true, ConstantPatternContext.none)
- parsePrimary(;, expression, ConstantPatternContext.none)
- parseSend(;, expression, ConstantPatternContext.none)
- isNextIdentifier(;)
- ensureIdentifier(;, expression)
- reportRecoverableErrorWithToken(), Instance of 'Template<(Token) => Message>')
- listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got ')'., Try inserting an identifier before ')'., {lexeme: )}], ), ))
- rewriter()
- listener: handleIdentifier(, expression)
- listener: handleNoTypeArguments())
- parseArgumentsOpt()
- listener: handleNoArguments())
- listener: handleSend(, ))
- ensureSemicolon()
- reportRecoverableError(_, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}])
- listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], _, _)
- rewriter()
- listener: handleExpressionStatement(;)
- reportRecoverableError(;, Message[UnexpectedToken, Unexpected token ';'., null, {lexeme: ;}])
- listener: handleRecoverableError(Message[UnexpectedToken, Unexpected token ';'., null, {lexeme: ;}], ), ))
- notEofOrValue(}, =)
- parseStatement())
- parseStatementX())
- parseExpressionStatementOrDeclaration(), null)
- parseExpressionStatementOrDeclarationAfterModifiers(), ), null, null, null, null)
- looksLikeLocalFunction(=)
- parseExpressionStatement())
- parseExpression())
- looksLikeOuterPatternEquals())
- skipOuterPattern())
- parsePrecedenceExpression(), 1, true, ConstantPatternContext.none)
- parseUnaryExpression(), true, ConstantPatternContext.none)
- parsePrimary(), expression, ConstantPatternContext.none)
- parseSend(), expression, ConstantPatternContext.none)
- isNextIdentifier())
- ensureIdentifier(), expression)
- reportRecoverableErrorWithToken(=, Instance of 'Template<(Token) => Message>')
- listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '='., Try inserting an identifier before '='., {lexeme: =}], =, =)
- rewriter()
- listener: handleIdentifier(, expression)
- listener: handleNoTypeArguments(=)
- parseArgumentsOpt()
- listener: handleNoArguments(=)
- listener: handleSend(, =)
- 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: handleAssignmentExpression(=)
+ parsePatternVariableDeclarationStatement(var, {, var)
+ parsePattern(var, PatternContext.declaration, precedence: 1)
+ parsePrimaryPattern(var, PatternContext.declaration)
+ parseParenthesizedPatternOrRecordPattern(var, PatternContext.declaration)
+ parsePattern((, PatternContext.declaration, precedence: 1)
+ parsePrimaryPattern((, PatternContext.declaration)
+ parseVariablePattern((, PatternContext.declaration, typeInfo: Instance of 'NoType')
+ listener: handleNoType(_)
+ listener: handleWildcardPattern(null, _)
+ ensureCloseParen(_, ()
+ 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, ;)
ensureSemicolon(x)
- listener: handleExpressionStatement(;)
+ listener: handlePatternVariableDeclarationStatement(var, =, ;)
notEofOrValue(}, })
- listener: endBlockFunctionBody(4, {, })
+ listener: endBlockFunctionBody(1, {, })
listener: endTopLevelMethod(f, null, })
listener: endTopLevelDeclaration()
reportAllErrorTokens(f)
diff --git a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.parser.expect
index 5878358..50323ff 100644
--- a/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.parser.expect
+++ b/pkg/front_end/parser_testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.parser.expect
@@ -1,11 +1,9 @@
-NOTICE: Stream was rewritten by parser!
-
f(x) {
-late var (*synthetic*;_;*synthetic*;) *synthetic*= x;
+late var (_) = x;
}
f[StringToken]([BeginToken]x[StringToken])[SimpleToken] {[BeginToken]
-late[KeywordToken] var[KeywordToken] ([BeginToken][SyntheticStringToken];[SyntheticToken]_[StringToken];[SyntheticToken][SyntheticStringToken];[SyntheticToken])[SimpleToken] [SyntheticStringToken]=[SimpleToken] x[StringToken];[SimpleToken]
+late[KeywordToken] var[KeywordToken] ([BeginToken]_[StringToken])[SimpleToken] =[SimpleToken] x[StringToken];[SimpleToken]
}[SimpleToken]
[SimpleToken]
diff --git a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.strong.expect b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.strong.expect
index cbacc5d..1332fa1 100644
--- a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.strong.expect
+++ b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.strong.expect
@@ -2,37 +2,18 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected an identifier, but got '('.
-// Try inserting an identifier before '('.
+// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:3: Error: A pattern variable declaration may not use the `late` keyword.
+// Try removing the keyword `late`.
// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Undefined name '_'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Expected an identifier, but got ')'.
-// Try inserting an identifier before ')'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Unexpected token ';'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:16: Error: Expected an identifier, but got '='.
-// Try inserting an identifier before '='.
-// late var (_) = x;
-// ^
+// ^^^^
//
import self as self;
+import "dart:core" as core;
-static method f(dynamic x) → dynamic {}
+static method f(dynamic x) → dynamic {
+ {
+ final synthesized dynamic #0#0 = x;
+ if(!true)
+ throw new core::StateError::•("Pattern matching error");
+ }
+}
diff --git a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.strong.transformed.expect b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.strong.transformed.expect
index cbacc5d..81a3665 100644
--- a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.strong.transformed.expect
@@ -2,37 +2,23 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected an identifier, but got '('.
-// Try inserting an identifier before '('.
+// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:3: Error: A pattern variable declaration may not use the `late` keyword.
+// Try removing the keyword `late`.
// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Undefined name '_'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Expected an identifier, but got ')'.
-// Try inserting an identifier before ')'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Unexpected token ';'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:16: Error: Expected an identifier, but got '='.
-// Try inserting an identifier before '='.
-// late var (_) = x;
-// ^
+// ^^^^
//
import self as self;
+import "dart:core" as core;
-static method f(dynamic x) → dynamic {}
+static method f(dynamic x) → dynamic {
+ {
+ final synthesized dynamic #0#0 = x;
+ if(!true)
+ throw new core::StateError::•("Pattern matching error");
+ }
+}
+
+
+Extra constant evaluation status:
+Evaluated: Not @ org-dartlang-testcase:///patternVariableDeclarationStatement_disallowsLate.dart:6:13 -> BoolConstant(false)
+Extra constant evaluation: evaluated: 4, effectively constant: 1
diff --git a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.expect b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.expect
index cbacc5d..1332fa1 100644
--- a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.expect
+++ b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.expect
@@ -2,37 +2,18 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected an identifier, but got '('.
-// Try inserting an identifier before '('.
+// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:3: Error: A pattern variable declaration may not use the `late` keyword.
+// Try removing the keyword `late`.
// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Undefined name '_'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Expected an identifier, but got ')'.
-// Try inserting an identifier before ')'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Unexpected token ';'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:16: Error: Expected an identifier, but got '='.
-// Try inserting an identifier before '='.
-// late var (_) = x;
-// ^
+// ^^^^
//
import self as self;
+import "dart:core" as core;
-static method f(dynamic x) → dynamic {}
+static method f(dynamic x) → dynamic {
+ {
+ final synthesized dynamic #0#0 = x;
+ if(!true)
+ throw new core::StateError::•("Pattern matching error");
+ }
+}
diff --git a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.modular.expect b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.modular.expect
index cbacc5d..1332fa1 100644
--- a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.modular.expect
@@ -2,37 +2,18 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected an identifier, but got '('.
-// Try inserting an identifier before '('.
+// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:3: Error: A pattern variable declaration may not use the `late` keyword.
+// Try removing the keyword `late`.
// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Undefined name '_'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Expected an identifier, but got ')'.
-// Try inserting an identifier before ')'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Unexpected token ';'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:16: Error: Expected an identifier, but got '='.
-// Try inserting an identifier before '='.
-// late var (_) = x;
-// ^
+// ^^^^
//
import self as self;
+import "dart:core" as core;
-static method f(dynamic x) → dynamic {}
+static method f(dynamic x) → dynamic {
+ {
+ final synthesized dynamic #0#0 = x;
+ if(!true)
+ throw new core::StateError::•("Pattern matching error");
+ }
+}
diff --git a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.transformed.expect b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.transformed.expect
index cbacc5d..81a3665 100644
--- a/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart.weak.transformed.expect
@@ -2,37 +2,23 @@
//
// Problems in library:
//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected an identifier, but got '('.
-// Try inserting an identifier before '('.
+// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:3: Error: A pattern variable declaration may not use the `late` keyword.
+// Try removing the keyword `late`.
// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:12: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Expected ';' after this.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:13: Error: Undefined name '_'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Expected an identifier, but got ')'.
-// Try inserting an identifier before ')'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:14: Error: Unexpected token ';'.
-// late var (_) = x;
-// ^
-//
-// pkg/front_end/testcases/patterns/patternVariableDeclarationStatement_disallowsLate.dart:6:16: Error: Expected an identifier, but got '='.
-// Try inserting an identifier before '='.
-// late var (_) = x;
-// ^
+// ^^^^
//
import self as self;
+import "dart:core" as core;
-static method f(dynamic x) → dynamic {}
+static method f(dynamic x) → dynamic {
+ {
+ final synthesized dynamic #0#0 = x;
+ if(!true)
+ throw new core::StateError::•("Pattern matching error");
+ }
+}
+
+
+Extra constant evaluation status:
+Evaluated: Not @ org-dartlang-testcase:///patternVariableDeclarationStatement_disallowsLate.dart:6:13 -> BoolConstant(false)
+Extra constant evaluation: evaluated: 4, effectively constant: 1