mirror of
https://github.com/dart-lang/sdk
synced 2024-10-06 16:19:07 +00:00
Augment. Add AugmentedExpression, AugmentedInvocation.
Change-Id: I15ec8a3bed5ad66600c3b51bf8109ff2089590f3 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/361002 Reviewed-by: Brian Wilkerson <brianwilkerson@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
parent
df707ac85e
commit
240d60c06b
|
@ -51,6 +51,8 @@ export 'package:analyzer/src/dart/ast/ast.dart'
|
|||
AstNode,
|
||||
AstVisitor,
|
||||
AugmentationImportDirective,
|
||||
AugmentedExpression,
|
||||
AugmentedInvocation,
|
||||
AwaitExpression,
|
||||
BinaryExpression,
|
||||
Block,
|
||||
|
|
|
@ -163,6 +163,14 @@ class GeneralizingAstVisitor<R> implements AstVisitor<R> {
|
|||
R? visitAugmentationImportDirective(AugmentationImportDirective node) =>
|
||||
visitUriBasedDirective(node);
|
||||
|
||||
@override
|
||||
R? visitAugmentedExpression(AugmentedExpression node) =>
|
||||
visitExpression(node);
|
||||
|
||||
@override
|
||||
R? visitAugmentedInvocation(AugmentedInvocation node) =>
|
||||
visitExpression(node);
|
||||
|
||||
@override
|
||||
R? visitAwaitExpression(AwaitExpression node) => visitExpression(node);
|
||||
|
||||
|
@ -857,6 +865,18 @@ class RecursiveAstVisitor<R> implements AstVisitor<R> {
|
|||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
R? visitAugmentedExpression(AugmentedExpression node) {
|
||||
node.visitChildren(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
R? visitAugmentedInvocation(AugmentedInvocation node) {
|
||||
node.visitChildren(this);
|
||||
return null;
|
||||
}
|
||||
|
||||
@override
|
||||
R? visitAwaitExpression(AwaitExpression node) {
|
||||
node.visitChildren(this);
|
||||
|
@ -1878,6 +1898,12 @@ class SimpleAstVisitor<R> implements AstVisitor<R> {
|
|||
@override
|
||||
R? visitAugmentationImportDirective(AugmentationImportDirective node) => null;
|
||||
|
||||
@override
|
||||
R? visitAugmentedExpression(AugmentedExpression node) => null;
|
||||
|
||||
@override
|
||||
R? visitAugmentedInvocation(AugmentedInvocation node) => null;
|
||||
|
||||
@override
|
||||
R? visitAwaitExpression(AwaitExpression node) => null;
|
||||
|
||||
|
@ -2427,6 +2453,12 @@ class ThrowingAstVisitor<R> implements AstVisitor<R> {
|
|||
R? visitAugmentationImportDirective(AugmentationImportDirective node) =>
|
||||
_throw(node);
|
||||
|
||||
@override
|
||||
R? visitAugmentedExpression(AugmentedExpression node) => _throw(node);
|
||||
|
||||
@override
|
||||
R? visitAugmentedInvocation(AugmentedInvocation node) => _throw(node);
|
||||
|
||||
@override
|
||||
R? visitAwaitExpression(AwaitExpression node) => _throw(node);
|
||||
|
||||
|
@ -3042,6 +3074,22 @@ class TimedAstVisitor<T> implements AstVisitor<T> {
|
|||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
T? visitAugmentedExpression(AugmentedExpression node) {
|
||||
stopwatch.start();
|
||||
T? result = _baseVisitor.visitAugmentedExpression(node);
|
||||
stopwatch.stop();
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
T? visitAugmentedInvocation(AugmentedInvocation node) {
|
||||
stopwatch.start();
|
||||
T? result = _baseVisitor.visitAugmentedInvocation(node);
|
||||
stopwatch.stop();
|
||||
return result;
|
||||
}
|
||||
|
||||
@override
|
||||
T? visitAwaitExpression(AwaitExpression node) {
|
||||
stopwatch.start();
|
||||
|
@ -4394,6 +4442,12 @@ class UnifyingAstVisitor<R> implements AstVisitor<R> {
|
|||
R? visitAugmentationImportDirective(AugmentationImportDirective node) =>
|
||||
visitNode(node);
|
||||
|
||||
@override
|
||||
R? visitAugmentedExpression(AugmentedExpression node) => visitNode(node);
|
||||
|
||||
@override
|
||||
R? visitAugmentedInvocation(AugmentedInvocation node) => visitNode(node);
|
||||
|
||||
@override
|
||||
R? visitAwaitExpression(AwaitExpression node) => visitNode(node);
|
||||
|
||||
|
|
|
@ -1227,6 +1227,10 @@ abstract class AstVisitor<R> {
|
|||
|
||||
R? visitAugmentationImportDirective(AugmentationImportDirective node);
|
||||
|
||||
R? visitAugmentedExpression(AugmentedExpression node);
|
||||
|
||||
R? visitAugmentedInvocation(AugmentedInvocation node);
|
||||
|
||||
R? visitAwaitExpression(AwaitExpression node);
|
||||
|
||||
R? visitBinaryExpression(BinaryExpression node);
|
||||
|
@ -1623,6 +1627,166 @@ final class AugmentationImportDirectiveImpl extends UriBasedDirectiveImpl
|
|||
}
|
||||
}
|
||||
|
||||
/// The augmented expression.
|
||||
///
|
||||
/// It is created only inside an augmentation.
|
||||
/// The exact meaning depends on what is augmented, and where it is used.
|
||||
///
|
||||
/// Augmenting getters: `augmented` invokes the getter and evaluates to the
|
||||
/// return value.
|
||||
/// The [element] is the augmented getter.
|
||||
/// The [staticType] is the return type of the getter.
|
||||
///
|
||||
/// Augmenting setters: `augmented` must be followed by an `=`, and will
|
||||
/// directly invoke the augmented setter.
|
||||
/// The [element] is the augmented setter.
|
||||
/// The [staticType] is meaningless, and set to `null`.
|
||||
///
|
||||
/// Augmenting fields: `augmented` can only be used in an initializer
|
||||
/// expression, and refers to the original field's initializer expression.
|
||||
/// The [element] is the augmented field.
|
||||
/// The [staticType] is the type of the field.
|
||||
///
|
||||
/// Augmenting binary operators: `augmented` must be the LHS, and followed by
|
||||
/// the argument, e.g. `augmented + 1`.
|
||||
/// The [element] is the augmented [MethodElement].
|
||||
/// The [staticType] is the type of `this`.
|
||||
///
|
||||
/// Augmenting index operators: `augmented` must be the index target,
|
||||
/// e.g. `augmented[0]`.
|
||||
/// The [element] is the augmented [MethodElement].
|
||||
/// The [staticType] is the type of `this`.
|
||||
///
|
||||
/// Augmenting prefix operators: `augmented` must be the target, e.g.
|
||||
/// `~augmented`.
|
||||
/// The [element] is the augmented [MethodElement].
|
||||
/// The [staticType] is the type of `this`.
|
||||
abstract final class AugmentedExpression implements Expression {
|
||||
/// The 'augmented' keyword.
|
||||
Token get augmentedKeyword;
|
||||
|
||||
/// The referenced augmented element: getter, setter, variable.
|
||||
Element? get element;
|
||||
}
|
||||
|
||||
final class AugmentedExpressionImpl extends ExpressionImpl
|
||||
implements AugmentedExpression {
|
||||
@override
|
||||
final Token augmentedKeyword;
|
||||
|
||||
@override
|
||||
Element? element;
|
||||
|
||||
AugmentedExpressionImpl({
|
||||
required this.augmentedKeyword,
|
||||
});
|
||||
|
||||
@override
|
||||
Token get beginToken => augmentedKeyword;
|
||||
|
||||
@override
|
||||
Token get endToken => augmentedKeyword;
|
||||
|
||||
@override
|
||||
bool get isAssignable => true;
|
||||
|
||||
@override
|
||||
Precedence get precedence => Precedence.primary;
|
||||
|
||||
@override
|
||||
ChildEntities get _childEntities =>
|
||||
ChildEntities()..addToken('augmentedKeyword', augmentedKeyword);
|
||||
|
||||
@override
|
||||
E? accept<E>(AstVisitor<E> visitor) => visitor.visitAugmentedExpression(this);
|
||||
|
||||
@override
|
||||
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
|
||||
resolver.visitAugmentedExpression(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitChildren(AstVisitor visitor) {
|
||||
// There are no children to visit.
|
||||
}
|
||||
}
|
||||
|
||||
/// Invocation of the augmented function, constructor, or method.
|
||||
///
|
||||
/// augmentedInvocation ::=
|
||||
/// 'augmented' [TypeArgumentList]? [ArgumentList]
|
||||
abstract final class AugmentedInvocation implements Expression {
|
||||
/// The list of value arguments.
|
||||
ArgumentList get arguments;
|
||||
|
||||
/// The 'augmented' keyword.
|
||||
Token get augmentedKeyword;
|
||||
|
||||
/// The referenced augmented element: function, constructor, or method.
|
||||
ExecutableElement? get element;
|
||||
|
||||
/// The list of type arguments.
|
||||
///
|
||||
/// In valid code cannot be provided for augmented constructor invocation.
|
||||
TypeArgumentList? get typeArguments;
|
||||
}
|
||||
|
||||
final class AugmentedInvocationImpl extends ExpressionImpl
|
||||
implements AugmentedInvocation {
|
||||
@override
|
||||
final Token augmentedKeyword;
|
||||
|
||||
@override
|
||||
ExecutableElement? element;
|
||||
|
||||
@override
|
||||
final TypeArgumentListImpl? typeArguments;
|
||||
|
||||
@override
|
||||
final ArgumentListImpl arguments;
|
||||
|
||||
AugmentedInvocationImpl({
|
||||
required this.augmentedKeyword,
|
||||
required this.typeArguments,
|
||||
required this.arguments,
|
||||
}) {
|
||||
_becomeParentOf(typeArguments);
|
||||
_becomeParentOf(arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
Token get beginToken => augmentedKeyword;
|
||||
|
||||
@override
|
||||
Token get endToken => arguments.endToken;
|
||||
|
||||
@override
|
||||
Precedence get precedence => Precedence.postfix;
|
||||
|
||||
@override
|
||||
ChildEntities get _childEntities => ChildEntities()
|
||||
..addToken('augmentedKeyword', augmentedKeyword)
|
||||
..addNode('typeArguments', typeArguments)
|
||||
..addNode('arguments', arguments);
|
||||
|
||||
@override
|
||||
E? accept<E>(AstVisitor<E> visitor) {
|
||||
return visitor.visitAugmentedInvocation(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void resolveExpression(ResolverVisitor resolver, DartType contextType) {
|
||||
// TODO(scheglov): implement
|
||||
throw UnimplementedError();
|
||||
}
|
||||
|
||||
@override
|
||||
void visitChildren(AstVisitor visitor) {
|
||||
typeArguments?.accept(visitor);
|
||||
arguments.accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
/// An await expression.
|
||||
///
|
||||
/// awaitExpression ::=
|
||||
|
|
|
@ -89,6 +89,18 @@ class ToSourceVisitor implements AstVisitor<void> {
|
|||
sink.write(';');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAugmentedExpression(AugmentedExpression node) {
|
||||
sink.write('augmented');
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAugmentedInvocation(AugmentedInvocation node) {
|
||||
_visitToken(node.augmentedKeyword);
|
||||
_visitNode(node.typeArguments);
|
||||
_visitNode(node.arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAwaitExpression(AwaitExpression node) {
|
||||
sink.write('await ');
|
||||
|
|
|
@ -175,6 +175,20 @@ class AstComparator implements AstVisitor<bool> {
|
|||
isEqualTokens(node.semicolon, other.semicolon);
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitAugmentedExpression(AugmentedExpression node) {
|
||||
final other = _other as AugmentedExpression;
|
||||
return isEqualTokens(node.augmentedKeyword, other.augmentedKeyword);
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitAugmentedInvocation(AugmentedInvocation node) {
|
||||
final other = _other as AugmentedInvocation;
|
||||
return isEqualTokens(node.augmentedKeyword, other.augmentedKeyword) &&
|
||||
isEqualNodes(node.typeArguments, other.typeArguments) &&
|
||||
isEqualNodes(node.arguments, other.arguments);
|
||||
}
|
||||
|
||||
@override
|
||||
bool visitAwaitExpression(AwaitExpression node) {
|
||||
AwaitExpression other = _other as AwaitExpression;
|
||||
|
|
|
@ -156,6 +156,8 @@ class AstBuilder extends StackListener {
|
|||
|
||||
final LineInfo _lineInfo;
|
||||
|
||||
Token? _enclosingDeclarationAugmentToken;
|
||||
|
||||
AstBuilder(ErrorReporter? errorReporter, this.fileUri, this.isFullAst,
|
||||
this._featureSet, this._lineInfo,
|
||||
[Uri? uri])
|
||||
|
@ -361,6 +363,33 @@ class AstBuilder extends StackListener {
|
|||
..finalConstOrVarKeyword = constToken);
|
||||
}
|
||||
|
||||
@override
|
||||
void beginFields(
|
||||
DeclarationKind declarationKind,
|
||||
Token? abstractToken,
|
||||
Token? augmentToken,
|
||||
Token? externalToken,
|
||||
Token? staticToken,
|
||||
Token? covariantToken,
|
||||
Token? lateToken,
|
||||
Token? varFinalOrConst,
|
||||
Token lastConsumed,
|
||||
) {
|
||||
_enclosingDeclarationAugmentToken = augmentToken;
|
||||
|
||||
super.beginFields(
|
||||
declarationKind,
|
||||
abstractToken,
|
||||
augmentToken,
|
||||
externalToken,
|
||||
staticToken,
|
||||
covariantToken,
|
||||
lateToken,
|
||||
varFinalOrConst,
|
||||
lastConsumed,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void beginFormalParameter(Token token, MemberKind kind, Token? requiredToken,
|
||||
Token? covariantToken, Token? varFinalOrConst) {
|
||||
|
@ -411,6 +440,7 @@ class AstBuilder extends StackListener {
|
|||
if (augmentToken != null) {
|
||||
assert(augmentToken.isModifier);
|
||||
modifiers.augmentKeyword = augmentToken;
|
||||
_enclosingDeclarationAugmentToken = augmentToken;
|
||||
}
|
||||
if (externalToken != null) {
|
||||
assert(externalToken.isModifier);
|
||||
|
@ -554,6 +584,7 @@ class AstBuilder extends StackListener {
|
|||
@override
|
||||
void beginTopLevelMethod(
|
||||
Token lastConsumed, Token? augmentToken, Token? externalToken) {
|
||||
_enclosingDeclarationAugmentToken = augmentToken;
|
||||
push(_Modifiers()
|
||||
..augmentKeyword = augmentToken
|
||||
..externalKeyword = externalToken);
|
||||
|
@ -823,20 +854,29 @@ class AstBuilder extends StackListener {
|
|||
void doInvocation(
|
||||
TypeArgumentListImpl? typeArguments, MethodInvocationImpl arguments) {
|
||||
var receiver = pop() as ExpressionImpl;
|
||||
if (receiver is SimpleIdentifierImpl) {
|
||||
arguments.methodName = receiver;
|
||||
if (typeArguments != null) {
|
||||
arguments.typeArguments = typeArguments;
|
||||
}
|
||||
push(arguments);
|
||||
} else {
|
||||
push(
|
||||
FunctionExpressionInvocationImpl(
|
||||
function: receiver,
|
||||
typeArguments: typeArguments,
|
||||
argumentList: arguments.argumentList,
|
||||
),
|
||||
);
|
||||
switch (receiver) {
|
||||
case AugmentedExpressionImpl():
|
||||
push(
|
||||
AugmentedInvocationImpl(
|
||||
augmentedKeyword: receiver.augmentedKeyword,
|
||||
typeArguments: typeArguments,
|
||||
arguments: arguments.argumentList,
|
||||
),
|
||||
);
|
||||
case SimpleIdentifierImpl():
|
||||
arguments.methodName = receiver;
|
||||
if (typeArguments != null) {
|
||||
arguments.typeArguments = typeArguments;
|
||||
}
|
||||
push(arguments);
|
||||
default:
|
||||
push(
|
||||
FunctionExpressionInvocationImpl(
|
||||
function: receiver,
|
||||
typeArguments: typeArguments,
|
||||
argumentList: arguments.argumentList,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1151,6 +1191,7 @@ class AstBuilder extends StackListener {
|
|||
endToken: endToken,
|
||||
),
|
||||
);
|
||||
_enclosingDeclarationAugmentToken = null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1247,6 +1288,7 @@ class AstBuilder extends StackListener {
|
|||
semicolon: semicolon,
|
||||
),
|
||||
);
|
||||
_enclosingDeclarationAugmentToken = null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1318,6 +1360,7 @@ class AstBuilder extends StackListener {
|
|||
body: body,
|
||||
),
|
||||
);
|
||||
_enclosingDeclarationAugmentToken = null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -1347,6 +1390,8 @@ class AstBuilder extends StackListener {
|
|||
void endCompilationUnit(int count, Token endToken) {
|
||||
debugEvent("CompilationUnit");
|
||||
|
||||
assert(_enclosingDeclarationAugmentToken == null);
|
||||
|
||||
var beginToken = pop() as Token;
|
||||
checkEmpty(endToken.charOffset);
|
||||
|
||||
|
@ -3348,6 +3393,7 @@ class AstBuilder extends StackListener {
|
|||
semicolon: semicolon,
|
||||
),
|
||||
);
|
||||
_enclosingDeclarationAugmentToken = null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -3385,6 +3431,7 @@ class AstBuilder extends StackListener {
|
|||
),
|
||||
),
|
||||
);
|
||||
_enclosingDeclarationAugmentToken = null;
|
||||
}
|
||||
|
||||
@override
|
||||
|
@ -4377,6 +4424,17 @@ class AstBuilder extends StackListener {
|
|||
return;
|
||||
}
|
||||
|
||||
if (_enclosingDeclarationAugmentToken != null) {
|
||||
if (token.lexeme == 'augmented') {
|
||||
push(
|
||||
AugmentedExpressionImpl(
|
||||
augmentedKeyword: token,
|
||||
),
|
||||
);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final identifier = SimpleIdentifierImpl(token);
|
||||
if (context.inLibraryOrPartOfDeclaration) {
|
||||
if (!context.isContinuation) {
|
||||
|
|
|
@ -77,6 +77,18 @@ class LinterVisitor implements AstVisitor<void> {
|
|||
node.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAugmentedExpression(AugmentedExpression node) {
|
||||
_runSubscriptions(node, registry._forAugmentedExpression);
|
||||
node.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAugmentedInvocation(AugmentedInvocation node) {
|
||||
_runSubscriptions(node, registry._forAugmentedInvocation);
|
||||
node.visitChildren(this);
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAwaitExpression(AwaitExpression node) {
|
||||
_runSubscriptions(node, registry._forAwaitExpression);
|
||||
|
@ -1094,6 +1106,8 @@ class NodeLintRegistry {
|
|||
final List<_Subscription<AssignmentExpression>> _forAssignmentExpression = [];
|
||||
final List<_Subscription<AugmentationImportDirective>>
|
||||
_forAugmentationImportDirective = [];
|
||||
final List<_Subscription<AugmentedExpression>> _forAugmentedExpression = [];
|
||||
final List<_Subscription<AugmentedInvocation>> _forAugmentedInvocation = [];
|
||||
final List<_Subscription<AwaitExpression>> _forAwaitExpression = [];
|
||||
final List<_Subscription<BinaryExpression>> _forBinaryExpression = [];
|
||||
final List<_Subscription<Block>> _forBlock = [];
|
||||
|
@ -1335,6 +1349,16 @@ class NodeLintRegistry {
|
|||
.add(_Subscription(linter, visitor, _getTimer(linter)));
|
||||
}
|
||||
|
||||
void addAugmentedExpression(LintRule linter, AstVisitor visitor) {
|
||||
_forAugmentedExpression
|
||||
.add(_Subscription(linter, visitor, _getTimer(linter)));
|
||||
}
|
||||
|
||||
void addAugmentedInvocation(LintRule linter, AstVisitor visitor) {
|
||||
_forAugmentedInvocation
|
||||
.add(_Subscription(linter, visitor, _getTimer(linter)));
|
||||
}
|
||||
|
||||
void addAwaitExpression(LintRule linter, AstVisitor visitor) {
|
||||
_forAwaitExpression.add(_Subscription(linter, visitor, _getTimer(linter)));
|
||||
}
|
||||
|
|
|
@ -39,6 +39,10 @@ class FindNode {
|
|||
AugmentationImportDirective get singleAugmentationImportDirective =>
|
||||
_single();
|
||||
|
||||
AugmentedExpression get singleAugmentedExpression => _single();
|
||||
|
||||
AugmentedInvocation get singleAugmentedInvocation => _single();
|
||||
|
||||
AwaitExpression get singleAwaitExpression => _single();
|
||||
|
||||
BinaryExpression get singleBinaryExpression => _single();
|
||||
|
|
783
pkg/analyzer/test/src/dart/parser/augmented_expression_test.dart
Normal file
783
pkg/analyzer/test/src/dart/parser/augmented_expression_test.dart
Normal file
|
@ -0,0 +1,783 @@
|
|||
// 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:test_reflective_loader/test_reflective_loader.dart';
|
||||
|
||||
import '../../diagnostics/parser_diagnostics.dart';
|
||||
|
||||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
defineReflectiveTests(AugmentedExpressionParserTest);
|
||||
});
|
||||
}
|
||||
|
||||
@reflectiveTest
|
||||
class AugmentedExpressionParserTest extends ParserDiagnosticsTest {
|
||||
test_class_constructor() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment A(int a) {
|
||||
augmented(0);
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AugmentedInvocation
|
||||
augmentedKeyword: augmented
|
||||
arguments: ArgumentList
|
||||
leftParenthesis: (
|
||||
arguments
|
||||
IntegerLiteral
|
||||
literal: 0
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_field() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment int foo = augmented + 1;
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBinaryExpression;
|
||||
assertParsedNodeText(node, r'''
|
||||
BinaryExpression
|
||||
leftOperand: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: +
|
||||
rightOperand: IntegerLiteral
|
||||
literal: 1
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_getter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment int get foo {
|
||||
return augmented;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_method() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment void foo<T>(T a) {
|
||||
augmented<int>(0);
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AugmentedInvocation
|
||||
augmentedKeyword: augmented
|
||||
typeArguments: TypeArgumentList
|
||||
leftBracket: <
|
||||
arguments
|
||||
NamedType
|
||||
name: int
|
||||
rightBracket: >
|
||||
arguments: ArgumentList
|
||||
leftParenthesis: (
|
||||
arguments
|
||||
IntegerLiteral
|
||||
literal: 0
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_operatorBinary() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment int operator+(int a) {
|
||||
return augmented + 1;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: BinaryExpression
|
||||
leftOperand: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: +
|
||||
rightOperand: IntegerLiteral
|
||||
literal: 1
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_operatorIndexRead() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment int operator[](int index) {
|
||||
return augmented[0];
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: IndexExpression
|
||||
target: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
leftBracket: [
|
||||
index: IntegerLiteral
|
||||
literal: 0
|
||||
rightBracket: ]
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_operatorIndexWrite() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment void operator[]=(int index, Object value) {
|
||||
augmented[0] = value;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AssignmentExpression
|
||||
leftHandSide: IndexExpression
|
||||
target: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
leftBracket: [
|
||||
index: IntegerLiteral
|
||||
literal: 0
|
||||
rightBracket: ]
|
||||
operator: =
|
||||
rightHandSide: SimpleIdentifier
|
||||
token: value
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_operatorPrefix() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment int operator-() {
|
||||
return -augmented;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: PrefixExpression
|
||||
operator: -
|
||||
operand: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_setter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment class A {
|
||||
augment set foo(int _) {
|
||||
augmented = 0;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AssignmentExpression
|
||||
leftHandSide: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: =
|
||||
rightHandSide: IntegerLiteral
|
||||
literal: 0
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_enum_getter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment enum A {
|
||||
bar;
|
||||
|
||||
augment int get foo {
|
||||
return augmented;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_enum_method() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment enum A {
|
||||
bar;
|
||||
|
||||
augment void foo<T>(T a) {
|
||||
augmented<int>(0);
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AugmentedInvocation
|
||||
augmentedKeyword: augmented
|
||||
typeArguments: TypeArgumentList
|
||||
leftBracket: <
|
||||
arguments
|
||||
NamedType
|
||||
name: int
|
||||
rightBracket: >
|
||||
arguments: ArgumentList
|
||||
leftParenthesis: (
|
||||
arguments
|
||||
IntegerLiteral
|
||||
literal: 0
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_enum_setter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment enum A {
|
||||
bar;
|
||||
|
||||
augment set foo(int _) {
|
||||
augmented = 0;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AssignmentExpression
|
||||
leftHandSide: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: =
|
||||
rightHandSide: IntegerLiteral
|
||||
literal: 0
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_extension_getter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment extension A {
|
||||
augment int get foo {
|
||||
return augmented;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_extension_method() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment extension A {
|
||||
augment void foo<T>(T a) {
|
||||
augmented<int>(0);
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AugmentedInvocation
|
||||
augmentedKeyword: augmented
|
||||
typeArguments: TypeArgumentList
|
||||
leftBracket: <
|
||||
arguments
|
||||
NamedType
|
||||
name: int
|
||||
rightBracket: >
|
||||
arguments: ArgumentList
|
||||
leftParenthesis: (
|
||||
arguments
|
||||
IntegerLiteral
|
||||
literal: 0
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_extension_setter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment extension A {
|
||||
augment set foo(int _) {
|
||||
augmented = 0;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AssignmentExpression
|
||||
leftHandSide: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: =
|
||||
rightHandSide: IntegerLiteral
|
||||
literal: 0
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_extensionType_getter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment extension type A(int it) {
|
||||
augment int get foo {
|
||||
return augmented;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_extensionType_method() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment extension type A(int it) {
|
||||
augment void foo<T>(T a) {
|
||||
augmented<int>(0);
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AugmentedInvocation
|
||||
augmentedKeyword: augmented
|
||||
typeArguments: TypeArgumentList
|
||||
leftBracket: <
|
||||
arguments
|
||||
NamedType
|
||||
name: int
|
||||
rightBracket: >
|
||||
arguments: ArgumentList
|
||||
leftParenthesis: (
|
||||
arguments
|
||||
IntegerLiteral
|
||||
literal: 0
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_extensionType_setter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment extension type A(int it) {
|
||||
augment set foo(int _) {
|
||||
augmented = 0;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AssignmentExpression
|
||||
leftHandSide: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: =
|
||||
rightHandSide: IntegerLiteral
|
||||
literal: 0
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_mixin_field() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment mixin A {
|
||||
augment int foo = augmented + 1;
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBinaryExpression;
|
||||
assertParsedNodeText(node, r'''
|
||||
BinaryExpression
|
||||
leftOperand: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: +
|
||||
rightOperand: IntegerLiteral
|
||||
literal: 1
|
||||
''');
|
||||
}
|
||||
|
||||
test_mixin_getter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment mixin A {
|
||||
augment int get foo {
|
||||
return augmented;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_mixin_method() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment mixin A {
|
||||
augment void foo<T>(T a) {
|
||||
augmented<int>(0);
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AugmentedInvocation
|
||||
augmentedKeyword: augmented
|
||||
typeArguments: TypeArgumentList
|
||||
leftBracket: <
|
||||
arguments
|
||||
NamedType
|
||||
name: int
|
||||
rightBracket: >
|
||||
arguments: ArgumentList
|
||||
leftParenthesis: (
|
||||
arguments
|
||||
IntegerLiteral
|
||||
literal: 0
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_mixin_setter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment mixin A {
|
||||
augment set foo(int _) {
|
||||
augmented = 0;
|
||||
}
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AssignmentExpression
|
||||
leftHandSide: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: =
|
||||
rightHandSide: IntegerLiteral
|
||||
literal: 0
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_function() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment void foo<T>(T a) {
|
||||
augmented<int>(0);
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AugmentedInvocation
|
||||
augmentedKeyword: augmented
|
||||
typeArguments: TypeArgumentList
|
||||
leftBracket: <
|
||||
arguments
|
||||
NamedType
|
||||
name: int
|
||||
rightBracket: >
|
||||
arguments: ArgumentList
|
||||
leftParenthesis: (
|
||||
arguments
|
||||
IntegerLiteral
|
||||
literal: 0
|
||||
rightParenthesis: )
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_getter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment int get foo {
|
||||
return augmented;
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ReturnStatement
|
||||
returnKeyword: return
|
||||
expression: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_setter() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment set foo(int _) {
|
||||
augmented = 0;
|
||||
}
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBlock;
|
||||
assertParsedNodeText(node, r'''
|
||||
Block
|
||||
leftBracket: {
|
||||
statements
|
||||
ExpressionStatement
|
||||
expression: AssignmentExpression
|
||||
leftHandSide: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: =
|
||||
rightHandSide: IntegerLiteral
|
||||
literal: 0
|
||||
semicolon: ;
|
||||
rightBracket: }
|
||||
''');
|
||||
}
|
||||
|
||||
test_topLevel_variable() {
|
||||
final parseResult = parseStringWithErrors(r'''
|
||||
library augment 'test.dart';
|
||||
|
||||
augment int foo = augmented + 1;
|
||||
''');
|
||||
parseResult.assertNoErrors();
|
||||
|
||||
final node = parseResult.findNode.singleBinaryExpression;
|
||||
assertParsedNodeText(node, r'''
|
||||
BinaryExpression
|
||||
leftOperand: AugmentedExpression
|
||||
augmentedKeyword: augmented
|
||||
operator: +
|
||||
rightOperand: IntegerLiteral
|
||||
literal: 1
|
||||
''');
|
||||
}
|
||||
}
|
|
@ -6,6 +6,7 @@ import 'package:test_reflective_loader/test_reflective_loader.dart';
|
|||
|
||||
import 'augmentation_import_directive_test.dart'
|
||||
as augmentation_import_directive;
|
||||
import 'augmented_expression_test.dart' as augmented_expression;
|
||||
import 'class_test.dart' as class_;
|
||||
import 'doc_comment_test.dart' as doc_comment;
|
||||
import 'enum_test.dart' as enum_;
|
||||
|
@ -22,6 +23,7 @@ import 'variable_declaration_statement_test.dart'
|
|||
main() {
|
||||
defineReflectiveSuite(() {
|
||||
augmentation_import_directive.main();
|
||||
augmented_expression.main();
|
||||
class_.main();
|
||||
doc_comment.main();
|
||||
enum_.main();
|
||||
|
|
|
@ -131,6 +131,26 @@ class ResolvedAstPrinter extends ThrowingAstVisitor<void> {
|
|||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAugmentedExpression(AugmentedExpression node) {
|
||||
_sink.writeln('AugmentedExpression');
|
||||
_sink.withIndent(() {
|
||||
_writeNamedChildEntities(node);
|
||||
_writeElement('element', node.element);
|
||||
_writeType('staticType', node.staticType);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAugmentedInvocation(AugmentedInvocation node) {
|
||||
_sink.writeln('AugmentedInvocation');
|
||||
_sink.withIndent(() {
|
||||
_writeNamedChildEntities(node);
|
||||
_writeElement('element', node.element);
|
||||
_writeType('staticType', node.staticType);
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
void visitAwaitExpression(AwaitExpression node) {
|
||||
_sink.writeln('AwaitExpression');
|
||||
|
|
Loading…
Reference in a new issue