Skip to content

Commit 1801969

Browse files
srawlinscommit-bot@chromium.org
authored andcommitted
Add ImplicitCallReference AST node subtype and visit methods
Bug: #47443 Change-Id: I70f9fda3256f963b805ba379d79f706010f0c2fa Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/216269 Commit-Queue: Samuel Rawlins <[email protected]> Reviewed-by: Konstantin Shcheglov <[email protected]> Reviewed-by: Brian Wilkerson <[email protected]>
1 parent aeb6767 commit 1801969

File tree

7 files changed

+170
-0
lines changed

7 files changed

+170
-0
lines changed

pkg/analyzer/lib/dart/ast/ast.dart

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -479,6 +479,8 @@ abstract class AstVisitor<R> {
479479

480480
R? visitImplementsClause(ImplementsClause node);
481481

482+
R? visitImplicitCallReference(ImplicitCallReference node);
483+
482484
R? visitImportDirective(ImportDirective node);
483485

484486
R? visitIndexExpression(IndexExpression node);
@@ -2599,6 +2601,33 @@ abstract class ImplementsClause implements AstNode {
25992601
NodeList<NamedType> get interfaces2;
26002602
}
26012603

2604+
/// An expression representing an implicit 'call' method reference.
2605+
///
2606+
/// Objects of this type are not produced directly by the parser (because the
2607+
/// parser cannot tell whether an expression refers to a callable type); they
2608+
/// are produced at resolution time.
2609+
///
2610+
/// Clients may not extend, implement or mix-in this class.
2611+
abstract class ImplicitCallReference implements MethodReferenceExpression {
2612+
/// Return the expression from which a `call` method is being referenced.
2613+
Expression get expression;
2614+
2615+
/// Return the element associated with the implicit 'call' reference based on
2616+
/// the static types.
2617+
@override
2618+
MethodElement get staticElement;
2619+
2620+
/// The type arguments being applied to the tear-off, or `null` if there are
2621+
/// no type arguments.
2622+
TypeArgumentList? get typeArguments;
2623+
2624+
/// The actual type arguments being applied to the tear-off, either explicitly
2625+
/// specified in [typeArguments], or inferred.
2626+
///
2627+
/// Returns an empty list if the 'call' method does not have type parameters.
2628+
List<DartType> get typeArgumentTypes;
2629+
}
2630+
26022631
/// An import directive.
26032632
///
26042633
/// importDirective ::=

pkg/analyzer/lib/dart/ast/ast_factory.dart

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@
55
import 'package:_fe_analyzer_shared/src/scanner/token.dart';
66
import 'package:analyzer/dart/analysis/features.dart';
77
import 'package:analyzer/dart/ast/ast.dart';
8+
import 'package:analyzer/dart/element/element.dart';
9+
import 'package:analyzer/dart/element/type.dart';
810
import 'package:analyzer/src/generated/utilities_dart.dart';
911

1012
/// A collection of factory methods which may be used to create concrete
@@ -580,6 +582,17 @@ abstract class AstFactory {
580582
ImplementsClause implementsClause(
581583
Token implementsKeyword, List<NamedType> interfaces);
582584

585+
/// Returns a newly created implicit call reference.
586+
///
587+
/// The [typeArguments] can be `null` if there are no type arguments being
588+
/// applied to the reference.
589+
ImplicitCallReference implicitCallReference({
590+
required Expression expression,
591+
required MethodElement staticElement,
592+
required TypeArgumentList? typeArguments,
593+
required List<DartType> typeArgumentTypes,
594+
});
595+
583596
/// Returns a newly created import directive. Either or both of the
584597
/// [comment] and [metadata] can be `null` if the function does not have the
585598
/// corresponding attribute. The [deferredKeyword] can be `null` if the import

pkg/analyzer/lib/dart/ast/visitor.dart

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,9 @@ class GeneralizingAstVisitor<R> implements AstVisitor<R> {
382382
@override
383383
R? visitImplementsClause(ImplementsClause node) => visitNode(node);
384384

385+
@override
386+
R? visitImplicitCallReference(ImplicitCallReference node) => visitNode(node);
387+
385388
@override
386389
R? visitImportDirective(ImportDirective node) =>
387390
visitNamespaceDirective(node);
@@ -1034,6 +1037,12 @@ class RecursiveAstVisitor<R> implements AstVisitor<R> {
10341037
return null;
10351038
}
10361039

1040+
@override
1041+
R? visitImplicitCallReference(ImplicitCallReference node) {
1042+
node.visitChildren(this);
1043+
return null;
1044+
}
1045+
10371046
@override
10381047
R? visitImportDirective(ImportDirective node) {
10391048
node.visitChildren(this);
@@ -1623,6 +1632,9 @@ class SimpleAstVisitor<R> implements AstVisitor<R> {
16231632
@override
16241633
R? visitImplementsClause(ImplementsClause node) => null;
16251634

1635+
@override
1636+
R? visitImplicitCallReference(ImplicitCallReference node) => null;
1637+
16261638
@override
16271639
R? visitImportDirective(ImportDirective node) => null;
16281640

@@ -2031,6 +2043,9 @@ class ThrowingAstVisitor<R> implements AstVisitor<R> {
20312043
@override
20322044
R? visitImplementsClause(ImplementsClause node) => _throw(node);
20332045

2046+
@override
2047+
R? visitImplicitCallReference(ImplicitCallReference node) => _throw(node);
2048+
20342049
@override
20352050
R? visitImportDirective(ImportDirective node) => _throw(node);
20362051

@@ -2768,6 +2783,14 @@ class TimedAstVisitor<T> implements AstVisitor<T> {
27682783
return result;
27692784
}
27702785

2786+
@override
2787+
T? visitImplicitCallReference(ImplicitCallReference node) {
2788+
stopwatch.start();
2789+
T? result = _baseVisitor.visitImplicitCallReference(node);
2790+
stopwatch.stop();
2791+
return result;
2792+
}
2793+
27712794
@override
27722795
T? visitImportDirective(ImportDirective node) {
27732796
stopwatch.start();
@@ -3497,6 +3520,9 @@ class UnifyingAstVisitor<R> implements AstVisitor<R> {
34973520
@override
34983521
R? visitImplementsClause(ImplementsClause node) => visitNode(node);
34993522

3523+
@override
3524+
R? visitImplicitCallReference(ImplicitCallReference node) => visitNode(node);
3525+
35003526
@override
35013527
R? visitImportDirective(ImportDirective node) => visitNode(node);
35023528

pkg/analyzer/lib/src/dart/ast/ast.dart

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5803,6 +5803,69 @@ class ImplementsClauseImpl extends AstNodeImpl implements ImplementsClause {
58035803
}
58045804
}
58055805

5806+
class ImplicitCallReferenceImpl extends ExpressionImpl
5807+
implements ImplicitCallReference {
5808+
ExpressionImpl _expression;
5809+
5810+
TypeArgumentListImpl? _typeArguments;
5811+
5812+
@override
5813+
List<DartType> typeArgumentTypes;
5814+
5815+
@override
5816+
MethodElement staticElement;
5817+
5818+
ImplicitCallReferenceImpl(
5819+
this._expression, {
5820+
required this.staticElement,
5821+
required TypeArgumentListImpl? typeArguments,
5822+
required this.typeArgumentTypes,
5823+
}) : _typeArguments = typeArguments {
5824+
_becomeParentOf(_expression);
5825+
_becomeParentOf(_typeArguments);
5826+
}
5827+
5828+
@override
5829+
Token get beginToken => expression.beginToken;
5830+
5831+
@override
5832+
Iterable<SyntacticEntity> get childEntities => ChildEntities()
5833+
..add(expression)
5834+
..add(typeArguments);
5835+
5836+
@override
5837+
Token get endToken => typeArguments?.endToken ?? expression.endToken;
5838+
5839+
@override
5840+
ExpressionImpl get expression => _expression;
5841+
5842+
set expression(ExpressionImpl value) {
5843+
_expression = _becomeParentOf(value);
5844+
}
5845+
5846+
@override
5847+
Precedence get precedence =>
5848+
typeArguments == null ? expression.precedence : Precedence.postfix;
5849+
5850+
@override
5851+
TypeArgumentListImpl? get typeArguments => _typeArguments;
5852+
5853+
set typeArguments(TypeArgumentListImpl? value) {
5854+
_typeArguments = _becomeParentOf(value);
5855+
}
5856+
5857+
@override
5858+
E? accept<E>(AstVisitor<E> visitor) {
5859+
return visitor.visitImplicitCallReference(this);
5860+
}
5861+
5862+
@override
5863+
void visitChildren(AstVisitor visitor) {
5864+
expression.accept(visitor);
5865+
typeArguments?.accept(visitor);
5866+
}
5867+
}
5868+
58065869
/// An import directive.
58075870
///
58085871
/// importDirective ::=

pkg/analyzer/lib/src/dart/ast/ast_factory.dart

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ import 'package:_fe_analyzer_shared/src/scanner/token.dart';
66
import 'package:analyzer/dart/analysis/features.dart';
77
import 'package:analyzer/dart/ast/ast.dart';
88
import 'package:analyzer/dart/ast/ast_factory.dart';
9+
import 'package:analyzer/dart/element/element.dart';
10+
import 'package:analyzer/dart/element/type.dart';
911
import 'package:analyzer/src/dart/ast/ast.dart';
1012
import 'package:analyzer/src/generated/utilities_dart.dart';
1113

@@ -785,6 +787,18 @@ class AstFactoryImpl extends AstFactory {
785787
Token implementsKeyword, List<NamedType> interfaces) =>
786788
ImplementsClauseImpl(implementsKeyword, interfaces);
787789

790+
@override
791+
ImplicitCallReferenceImpl implicitCallReference({
792+
required Expression expression,
793+
required MethodElement staticElement,
794+
required TypeArgumentList? typeArguments,
795+
required List<DartType> typeArgumentTypes,
796+
}) =>
797+
ImplicitCallReferenceImpl(expression as ExpressionImpl,
798+
staticElement: staticElement,
799+
typeArguments: typeArguments as TypeArgumentListImpl?,
800+
typeArgumentTypes: typeArgumentTypes);
801+
788802
@override
789803
ImportDirectiveImpl importDirective(
790804
Comment? comment,

pkg/analyzer/lib/src/dart/ast/to_source_visitor.dart

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -603,6 +603,12 @@ class ToSourceVisitor implements AstVisitor<void> {
603603
_visitNodeList(node.interfaces2, separator: ', ');
604604
}
605605

606+
@override
607+
void visitImplicitCallReference(ImplicitCallReference node) {
608+
_visitNode(node.expression);
609+
_visitNode(node.typeArguments);
610+
}
611+
606612
@override
607613
void visitImportDirective(ImportDirective node) {
608614
_visitNodeList(node.metadata, separator: ' ', suffix: ' ');

pkg/analyzer/lib/src/dart/ast/utilities.dart

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -722,6 +722,13 @@ class AstComparator implements AstVisitor<bool> {
722722
_isEqualNodeLists(node.interfaces2, other.interfaces2);
723723
}
724724

725+
@override
726+
bool visitImplicitCallReference(ImplicitCallReference node) {
727+
ImplicitCallReference other = _other as ImplicitCallReference;
728+
return isEqualNodes(node.expression, other.expression) &&
729+
isEqualNodes(node.typeArguments, other.typeArguments);
730+
}
731+
725732
@override
726733
bool visitImportDirective(ImportDirective node) {
727734
ImportDirective other = _other as ImportDirective;
@@ -2344,6 +2351,18 @@ class NodeReplacer implements AstVisitor<bool> {
23442351
return visitNode(node);
23452352
}
23462353

2354+
@override
2355+
bool visitImplicitCallReference(covariant ImplicitCallReferenceImpl node) {
2356+
if (identical(node.expression, _oldNode)) {
2357+
node.expression = _newNode as ExpressionImpl;
2358+
return true;
2359+
} else if (identical(node.typeArguments, _oldNode)) {
2360+
node.typeArguments = _newNode as TypeArgumentListImpl;
2361+
return true;
2362+
}
2363+
return visitNode(node);
2364+
}
2365+
23472366
@override
23482367
bool visitImportDirective(covariant ImportDirectiveImpl node) {
23492368
if (identical(node.prefix, _oldNode)) {

0 commit comments

Comments
 (0)