mirror of
https://github.com/dart-lang/sdk
synced 2024-10-03 00:09:20 +00:00
Completion. Issue 53964. Recovery after parsing almost PropertyAccess before 'await'.
Bug: https://github.com/dart-lang/sdk/issues/53964 Change-Id: Ia583243fefd190bb14d857f8547c88e74524d33f Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/357520 Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
parent
6270a46469
commit
e7a109c875
|
@ -55,6 +55,44 @@ suggestions
|
|||
''');
|
||||
}
|
||||
|
||||
Future<void> test_afterIdentifier_beforeAwait() async {
|
||||
await computeSuggestions('''
|
||||
void f(A a) async {
|
||||
a.^
|
||||
await a.foo();
|
||||
}
|
||||
|
||||
class A {
|
||||
void m01() {}
|
||||
}
|
||||
''');
|
||||
assertResponse(r'''
|
||||
suggestions
|
||||
m01
|
||||
kind: methodInvocation
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_afterIdentifier_beforeAwait_partial() async {
|
||||
await computeSuggestions('''
|
||||
void f(A a) async {
|
||||
a.m0^
|
||||
await 0;
|
||||
}
|
||||
|
||||
class A {
|
||||
void m01() {}
|
||||
}
|
||||
''');
|
||||
assertResponse(r'''
|
||||
replacement
|
||||
left: 2
|
||||
suggestions
|
||||
m01
|
||||
kind: methodInvocation
|
||||
''');
|
||||
}
|
||||
|
||||
Future<void> test_afterIdentifier_beforeIdentifier_partial() async {
|
||||
newFile('$testPackageLibPath/a.dart', r'''
|
||||
void v01() {}
|
||||
|
|
|
@ -3548,6 +3548,61 @@ class AstBuilder extends StackListener {
|
|||
var comment = _findComment(metadata, variables[0].beginToken);
|
||||
// var comment = _findComment(metadata,
|
||||
// variables[0].beginToken ?? type?.beginToken ?? modifiers.beginToken);
|
||||
|
||||
// https://github.com/dart-lang/sdk/issues/53964
|
||||
if (semicolon != null && semicolon.isSynthetic) {
|
||||
if (variables.singleOrNull case var variable?) {
|
||||
if (type is NamedTypeImpl) {
|
||||
var importPrefix = type.importPrefix;
|
||||
if (importPrefix != null) {
|
||||
// x.^
|
||||
// await y.foo();
|
||||
{
|
||||
var awaitToken = type.name2;
|
||||
if (awaitToken.type == Keyword.AWAIT) {
|
||||
push(
|
||||
ExpressionStatementImpl(
|
||||
expression: PrefixedIdentifierImpl(
|
||||
prefix: SimpleIdentifierImpl(importPrefix.name),
|
||||
period: importPrefix.period,
|
||||
identifier: SimpleIdentifierImpl(
|
||||
parser.rewriter.insertSyntheticIdentifier(
|
||||
importPrefix.period,
|
||||
),
|
||||
),
|
||||
),
|
||||
semicolon: semicolon,
|
||||
),
|
||||
);
|
||||
parser.rewriter.insertToken(semicolon, awaitToken);
|
||||
parser.rewriter.insertToken(awaitToken, variable.name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
// x.foo^
|
||||
// await y.bar();
|
||||
{
|
||||
var awaitToken = variable.name;
|
||||
if (awaitToken.type == Keyword.AWAIT) {
|
||||
push(
|
||||
ExpressionStatementImpl(
|
||||
expression: PrefixedIdentifierImpl(
|
||||
prefix: SimpleIdentifierImpl(importPrefix.name),
|
||||
period: importPrefix.period,
|
||||
identifier: SimpleIdentifierImpl(type.name2),
|
||||
),
|
||||
semicolon: semicolon,
|
||||
),
|
||||
);
|
||||
parser.rewriter.insertToken(semicolon, awaitToken);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
push(
|
||||
VariableDeclarationStatementImpl(
|
||||
variableList: VariableDeclarationListImpl(
|
||||
|
|
|
@ -10,6 +10,8 @@ import 'extension_type_test.dart' as extension_type;
|
|||
import 'mixin_test.dart' as mixin_;
|
||||
import 'top_level_function_test.dart' as top_level_function;
|
||||
import 'top_level_variable_test.dart' as top_level_variable;
|
||||
import 'variable_declaration_statement_test.dart'
|
||||
as variable_declaration_statement;
|
||||
|
||||
/// Utility for manually running all tests.
|
||||
main() {
|
||||
|
@ -20,5 +22,6 @@ main() {
|
|||
mixin_.main();
|
||||
top_level_function.main();
|
||||
top_level_variable.main();
|
||||
variable_declaration_statement.main();
|
||||
}, name: 'parser');
|
||||
}
|
||||
|
|
|
@ -0,0 +1,100 @@
|
|||
// Copyright (c) 2024, the Dart project authors. Please see the AUTHORS file
|
||||
// for details. All rights reserved. Use of this source code is governed by a
|
||||
// BSD-style license that can be found in the LICENSE file.
|
||||
|
||||
import 'package:analyzer/src/dart/error/syntactic_errors.dart';
|
||||
import 'package:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../diagnostics/parser_diagnostics.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(VariableDeclarationStatementParserTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class VariableDeclarationStatementParserTest extends ParserDiagnosticsTest {
|
||||
test_recovery_propertyAccess_beforeAwait_hasIdentifier() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
void f(x) async {
|
||||
x.foo
|
||||
await x.bar();
|
||||
}
|
||||
''');
|
||||
parseResult.assertErrors([
|
||||
error(ParserErrorCode.ASYNC_KEYWORD_USED_AS_IDENTIFIER, 28, 5),
|
||||
error(ParserErrorCode.EXPECTED_TOKEN, 28, 5),
|
||||
]);
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: PrefixedIdentifier
|
||||
prefix: SimpleIdentifier
|
||||
token: x
|
||||
period: .
|
||||
identifier: SimpleIdentifier
|
||||
token: foo
|
||||
semicolon: ; <synthetic>
|
||||
ExpressionStatement
|
||||
expression: AwaitExpression
|
||||
awaitKeyword: await
|
||||
expression: MethodInvocation
|
||||
target: SimpleIdentifier
|
||||
token: x
|
||||
operator: .
|
||||
methodName: SimpleIdentifier
|
||||
token: bar
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_recovery_propertyAccess_beforeAwait_noIdentifier() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
void f(x) async {
|
||||
x.
|
||||
await x.foo();
|
||||
}
|
||||
''');
|
||||
parseResult.assertErrors([
|
||||
error(ParserErrorCode.EXPECTED_TOKEN, 31, 1),
|
||||
]);
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: PrefixedIdentifier
|
||||
prefix: SimpleIdentifier
|
||||
token: x
|
||||
period: .
|
||||
identifier: SimpleIdentifier
|
||||
token: <empty> <synthetic>
|
||||
semicolon: ; <synthetic>
|
||||
ExpressionStatement
|
||||
expression: AwaitExpression
|
||||
awaitKeyword: await
|
||||
expression: MethodInvocation
|
||||
target: SimpleIdentifier
|
||||
token: x
|
||||
operator: .
|
||||
methodName: SimpleIdentifier
|
||||
token: foo
|
||||
argumentList: ArgumentList
|
||||
leftParenthesis: (
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue