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 17826384dbf..3f3f8f6e839 100644 --- a/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart +++ b/pkg/_fe_analyzer_shared/lib/src/parser/parser_impl.dart @@ -9803,7 +9803,8 @@ class Parser { // Record or parenthesized pattern return next.endGroup; } - throw new UnimplementedError('TODO(paulberry)'); + // Not an outer pattern + return null; } /// Tries to advance through an object pattern, where [token] is the last diff --git a/pkg/analyzer/test/generated/patterns_parser_test.dart b/pkg/analyzer/test/generated/patterns_parser_test.dart index 7e98ff3ab50..71dc55c0af6 100644 --- a/pkg/analyzer/test/generated/patterns_parser_test.dart +++ b/pkg/analyzer/test/generated/patterns_parser_test.dart @@ -6734,6 +6734,18 @@ ListPattern '''); } + test_skipOuterPattern_eof() { + // See https://github.com/dart-lang/sdk/issues/50563 + _parse(''' +main() { + int var = 0; +''', errors: [ + error(ParserErrorCode.EXPECTED_TOKEN, 11, 3), + error(ParserErrorCode.MISSING_IDENTIFIER, 19, 1), + error(ScannerErrorCode.EXPECTED_TOKEN, 24, 1), + ]); + } + test_switchExpression_empty() { // Even though an empty switch expression is illegal (because it's not // exhaustive), it should be accepted by the parser to enable analyzer code diff --git a/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart new file mode 100644 index 00000000000..1c9e97f05c6 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart @@ -0,0 +1,2 @@ +main() { + int var = 0; diff --git a/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.expect b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.expect new file mode 100644 index 00000000000..ac4e93d5455 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.expect @@ -0,0 +1,50 @@ +Problems reported: + +parser/patterns/skipOuterPattern_eof:2:3: Expected ';' after this. + int var = 0; + ^^^ + +parser/patterns/skipOuterPattern_eof:2:11: Expected an identifier, but got '='. + int var = 0; + ^ + +parser/patterns/skipOuterPattern_eof:1:8: Can't find '}' to match '{'. +main() { + ^ + +beginCompilationUnit(main) + beginMetadataStar(main) + endMetadataStar(0) + beginTopLevelMember(main) + beginTopLevelMethod(UnmatchedToken({), null, null) + handleNoType(UnmatchedToken({)) + handleIdentifier(main, topLevelFunctionDeclaration) + handleNoTypeVariables(() + beginFormalParameters((, MemberKind.TopLevelMethod) + endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + handleAsyncModifier(null, null) + beginBlockFunctionBody({) + handleIdentifier(int, expression) + handleNoTypeArguments(var) + handleNoArguments(var) + handleSend(int, var) + handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int) + handleExpressionStatement(;) + beginMetadataStar(var) + endMetadataStar(0) + handleNoType(var) + beginVariablesDeclaration(=, null, var) + handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '='., Try inserting an identifier before '='., {lexeme: =}], =, =) + handleIdentifier(, localVariableDeclaration) + beginInitializedIdentifier() + beginVariableInitializer(=) + handleLiteralInt(0) + endVariableInitializer(=) + endInitializedIdentifier() + endVariablesDeclaration(1, ;) + endBlockFunctionBody(2, {, }) + endTopLevelMethod(main, null, }) + endTopLevelDeclaration() + handleErrorToken(UnmatchedToken({)) + handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({)) +endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.intertwined.expect b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.intertwined.expect new file mode 100644 index 00000000000..7b348e16bb7 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.intertwined.expect @@ -0,0 +1,92 @@ +parseUnit(UnmatchedToken({)) + skipErrorTokens(UnmatchedToken({)) + listener: beginCompilationUnit(main) + syntheticPreviousToken(main) + parseTopLevelDeclarationImpl(UnmatchedToken({), Instance of 'DirectiveContext') + parseMetadataStar(UnmatchedToken({)) + listener: beginMetadataStar(main) + listener: endMetadataStar(0) + parseTopLevelMemberImpl(UnmatchedToken({)) + listener: beginTopLevelMember(main) + isReservedKeyword(() + parseTopLevelMethod(UnmatchedToken({), null, null, UnmatchedToken({), Instance of 'NoType', null, main, false) + listener: beginTopLevelMethod(UnmatchedToken({), null, null) + listener: handleNoType(UnmatchedToken({)) + ensureIdentifierPotentiallyRecovered(UnmatchedToken({), topLevelFunctionDeclaration, false) + listener: handleIdentifier(main, topLevelFunctionDeclaration) + parseMethodTypeVar(main) + listener: handleNoTypeVariables(() + parseGetterOrFormalParameters(main, main, false, MemberKind.TopLevelMethod) + parseFormalParameters(main, MemberKind.TopLevelMethod) + parseFormalParametersRest((, MemberKind.TopLevelMethod) + listener: beginFormalParameters((, MemberKind.TopLevelMethod) + listener: endFormalParameters(0, (, ), MemberKind.TopLevelMethod) + parseAsyncModifierOpt()) + listener: handleAsyncModifier(null, null) + inPlainSync() + parseFunctionBody(), false, false) + listener: beginBlockFunctionBody({) + notEofOrValue(}, int) + parseStatement({) + parseStatementX({) + parseExpressionStatementOrDeclarationAfterModifiers({, {, null, null, null, false) + looksLikeLocalFunction(int) + parseExpressionStatement({) + parseExpression({) + parsePrecedenceExpression({, 1, true) + parseUnaryExpression({, true) + parsePrimary({, expression) + parseSendOrFunctionLiteral({, expression) + parseSend({, expression) + isNextIdentifier({) + ensureIdentifier({, expression) + listener: handleIdentifier(int, expression) + listener: handleNoTypeArguments(var) + parseArgumentsOpt(int) + listener: handleNoArguments(var) + listener: handleSend(int, var) + ensureSemicolon(int) + reportRecoverableError(int, Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}]) + listener: handleRecoverableError(Message[ExpectedAfterButGot, Expected ';' after this., null, {string: ;}], int, int) + rewriter() + listener: handleExpressionStatement(;) + notEofOrValue(}, var) + parseStatement(;) + parseStatementX(;) + parseExpressionStatementOrDeclarationAfterModifiers(var, ;, null, var, null, false) + looksLikePatternVariableDeclaration(var) + skipOuterPattern(var) + looksLikeLocalFunction(=) + listener: beginMetadataStar(var) + listener: endMetadataStar(0) + listener: handleNoType(var) + listener: beginVariablesDeclaration(=, null, var) + parseVariablesDeclarationRest(var, true) + parseOptionallyInitializedIdentifier(var) + ensureIdentifier(var, localVariableDeclaration) + insertSyntheticIdentifier(var, localVariableDeclaration, message: Message[ExpectedIdentifier, Expected an identifier, but got '='., Try inserting an identifier before '='., {lexeme: =}], messageOnToken: null) + reportRecoverableError(=, Message[ExpectedIdentifier, Expected an identifier, but got '='., Try inserting an identifier before '='., {lexeme: =}]) + listener: handleRecoverableError(Message[ExpectedIdentifier, Expected an identifier, but got '='., Try inserting an identifier before '='., {lexeme: =}], =, =) + rewriter() + listener: handleIdentifier(, localVariableDeclaration) + listener: beginInitializedIdentifier() + parseVariableInitializerOpt() + listener: beginVariableInitializer(=) + parseExpression(=) + parsePrecedenceExpression(=, 1, true) + parseUnaryExpression(=, true) + parsePrimary(=, expression) + parseLiteralInt(=) + listener: handleLiteralInt(0) + listener: endVariableInitializer(=) + listener: endInitializedIdentifier() + ensureSemicolon(0) + listener: endVariablesDeclaration(1, ;) + notEofOrValue(}, }) + listener: endBlockFunctionBody(2, {, }) + listener: endTopLevelMethod(main, null, }) + listener: endTopLevelDeclaration() + reportAllErrorTokens(UnmatchedToken({)) + listener: handleErrorToken(UnmatchedToken({)) + listener: handleRecoverableError(Message[UnmatchedToken, Can't find '}' to match '{'., null, {string: }, lexeme: {}], UnmatchedToken({), UnmatchedToken({)) + listener: endCompilationUnit(1, ) diff --git a/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.parser.expect b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.parser.expect new file mode 100644 index 00000000000..4a4b576a18f --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.parser.expect @@ -0,0 +1,9 @@ +NOTICE: Stream was rewritten by parser! + +main() { +int ;var *synthetic*= 0; +} + +[UnmatchedToken]main[StringToken]([BeginToken])[SimpleToken] {[BeginToken] +int[StringToken] ;[SyntheticToken]var[KeywordToken] [SyntheticStringToken]=[SimpleToken] 0[StringToken];[SimpleToken] +}[SyntheticToken][SimpleToken] diff --git a/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.scanner.expect b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.scanner.expect new file mode 100644 index 00000000000..892c1fa5771 --- /dev/null +++ b/pkg/front_end/parser_testcases/patterns/skipOuterPattern_eof.dart.scanner.expect @@ -0,0 +1,7 @@ +main() { +int var = 0; +} + +[UnmatchedToken]main[StringToken]([BeginToken])[SimpleToken] {[BeginToken] +int[StringToken] var[KeywordToken] =[SimpleToken] 0[StringToken];[SimpleToken] +}[SyntheticToken][SimpleToken]