From 84e15e9efb67c7d6cc14c021c0a9a323d64525ac Mon Sep 17 00:00:00 2001 From: Konstantin Shcheglov Date: Tue, 29 Oct 2024 20:12:41 +0000 Subject: [PATCH] Issue 56355. Fix token cycle via 'previous'. Bug: https://github.com/dart-lang/sdk/issues/56355 Change-Id: I1ee7f837dc8beed9bb2ed1f27c45108345e7cceb Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/392460 Reviewed-by: Brian Wilkerson Reviewed-by: Phil Quitslund Commit-Queue: Konstantin Shcheglov --- pkg/analyzer/lib/src/fasta/ast_builder.dart | 11 ++++- .../dart/parser/top_level_function_test.dart | 28 +++-------- .../variable_declaration_statement_test.dart | 49 +++++++++---------- 3 files changed, 39 insertions(+), 49 deletions(-) diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart index 0e26e9a61929..c8752dc293fe 100644 --- a/pkg/analyzer/lib/src/fasta/ast_builder.dart +++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart @@ -3636,6 +3636,14 @@ class AstBuilder extends StackListener { var awaitToken = variable.name; if (awaitToken.type == Keyword.AWAIT || awaitToken.type == TokenType.IDENTIFIER) { + // We see `x.foo await;`, where `;` is synthetic. + // It is followed by `y.bar()`. + // Insert a new `;`, and (unfortunately) drop `await;`. + type.name2.setNext(semicolon.next!); + var semicolon2 = parser.rewriter.insertSyntheticToken( + type.name2, + TokenType.SEMICOLON, + ); push( ExpressionStatementImpl( expression: PrefixedIdentifierImpl( @@ -3643,10 +3651,9 @@ class AstBuilder extends StackListener { period: importPrefix.period, identifier: SimpleIdentifierImpl(type.name2), ), - semicolon: semicolon, + semicolon: semicolon2, ), ); - parser.rewriter.insertToken(semicolon, awaitToken); return; } } diff --git a/pkg/analyzer/test/src/dart/parser/top_level_function_test.dart b/pkg/analyzer/test/src/dart/parser/top_level_function_test.dart index 96fee849a033..ee278a0db719 100644 --- a/pkg/analyzer/test/src/dart/parser/top_level_function_test.dart +++ b/pkg/analyzer/test/src/dart/parser/top_level_function_test.dart @@ -65,7 +65,7 @@ FunctionDeclaration // https://github.com/dart-lang/sdk/issues/56355 var parseResult = parseStringWithErrors(r''' void get() { - http.Response response = http + http.Response response = http2 } '''); @@ -109,25 +109,13 @@ FunctionDeclaration identifier: SimpleIdentifier token: T7 Response @20 previous: T6 |.| - next: T8 |response| - semicolon: T9 ; @45 - previousX: T10 http @40 - previousX: T11 = @38 - previous: T8 |response| - next: T10 |http| - next: T9 |;| - next: T8 |response| - ExpressionStatement - expression: SimpleIdentifier - token: T8 response @29 - previous: T9 |;| - next: T12 |;| - semicolon: T12 ; @45 - previous: T8 |response| - next: T13 |}| - rightBracket: T13 } @45 - previous: T12 |;| - next: T14 || + next: T8 |;| + semicolon: T8 ; @46 + previous: T7 |Response| + next: T9 |}| + rightBracket: T9 } @46 + previous: T8 |;| + next: T10 || ''', ); } diff --git a/pkg/analyzer/test/src/dart/parser/variable_declaration_statement_test.dart b/pkg/analyzer/test/src/dart/parser/variable_declaration_statement_test.dart index 3e7974775e7f..3501aaf38e9c 100644 --- a/pkg/analyzer/test/src/dart/parser/variable_declaration_statement_test.dart +++ b/pkg/analyzer/test/src/dart/parser/variable_declaration_statement_test.dart @@ -17,14 +17,14 @@ main() { class VariableDeclarationStatementParserTest extends ParserDiagnosticsTest { test_recovery_propertyAccess_beforeAwait_hasIdentifier() { var parseResult = parseStringWithErrors(r''' -void f(x) async { +void f() async { x.foo - await x.bar(); + await y.bar(); } '''); parseResult.assertErrors([ - error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 28, 5), - error(ParserErrorCode.EXPECTED_TOKEN, 28, 5), + error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 27, 5), + error(ParserErrorCode.EXPECTED_TOKEN, 27, 5), ]); var node = parseResult.findNode.singleBlock; @@ -41,17 +41,15 @@ Block token: foo semicolon: ; ExpressionStatement - expression: AwaitExpression - awaitKeyword: await - expression: MethodInvocation - target: SimpleIdentifier - token: x - operator: . - methodName: SimpleIdentifier - token: bar - argumentList: ArgumentList - leftParenthesis: ( - rightParenthesis: ) + expression: MethodInvocation + target: SimpleIdentifier + token: y + operator: . + methodName: SimpleIdentifier + token: bar + argumentList: ArgumentList + leftParenthesis: ( + rightParenthesis: ) semicolon: ; rightBracket: } '''); @@ -59,13 +57,13 @@ Block test_recovery_propertyAccess_beforeAwait_noIdentifier() { var parseResult = parseStringWithErrors(r''' -void f(x) async { +void f() async { x. - await x.foo(); + await y.foo(); } '''); parseResult.assertErrors([ - error(ParserErrorCode.EXPECTED_TOKEN, 31, 1), + error(ParserErrorCode.EXPECTED_TOKEN, 30, 1), ]); var node = parseResult.findNode.singleBlock; @@ -86,7 +84,7 @@ Block awaitKeyword: await expression: MethodInvocation target: SimpleIdentifier - token: x + token: y operator: . methodName: SimpleIdentifier token: foo @@ -100,13 +98,13 @@ Block test_recovery_propertyAccess_beforeIdentifier_hasIdentifier() { var parseResult = parseStringWithErrors(r''' -void f(x) { +void f() { x.foo bar(); } '''); parseResult.assertErrors([ - error(ParserErrorCode.EXPECTED_TOKEN, 22, 3), + error(ParserErrorCode.EXPECTED_TOKEN, 21, 3), ]); var node = parseResult.findNode.singleBlock; @@ -123,12 +121,9 @@ Block token: foo semicolon: ; ExpressionStatement - expression: MethodInvocation - methodName: SimpleIdentifier - token: bar - argumentList: ArgumentList - leftParenthesis: ( - rightParenthesis: ) + expression: RecordLiteral + leftParenthesis: ( + rightParenthesis: ) semicolon: ; rightBracket: } ''');