Skip to content

Commit fea5f58

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Add DartTypeVisitor and DartType.accept(DartTypeVisitor) to API.
[email protected] Bug: #40478 Change-Id: I8453011f4a39323bda86244a749509b4b347b4b6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/153361 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 42fcc18 commit fea5f58

18 files changed

+240
-181
lines changed

pkg/analyzer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
## 0.39.13-dev
22
* Added 'dart/sdk/build_sdk_summary.dart' with `buildSdkSummary`.
33
* Added `DynamicType`, `NeverType`, and `VoidType` interfaces.
4+
* Added `TypeVisitor` and `DartType.accept(TypeVisitor)`.
45

56
## 0.39.12
67
* Deprecated `canUseSummaries` in `DartSdkManager` constructor.

pkg/analyzer/lib/dart/element/type.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
/// the references to `String` and `int` are type arguments.
2222
import 'package:analyzer/dart/element/element.dart';
2323
import 'package:analyzer/dart/element/nullability_suffix.dart';
24+
import 'package:analyzer/dart/element/type_visitor.dart';
2425
import 'package:analyzer/src/dart/element/type.dart' show InterfaceTypeImpl;
2526

2627
/// The type associated with elements in the element model.
@@ -122,6 +123,9 @@ abstract class DartType {
122123
/// Return the nullability suffix of this type.
123124
NullabilitySuffix get nullabilitySuffix;
124125

126+
/// Use the given [visitor] to visit this type.
127+
R accept<R>(TypeVisitor<R> visitor);
128+
125129
/// Return the presentation of this type as it should appear when presented
126130
/// to users in contexts such as error messages.
127131
///
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
import 'package:analyzer/dart/element/type.dart';
6+
7+
/// Interface for type visitors.
8+
///
9+
/// Clients may not extend, implement, or mix-in this class.
10+
abstract class TypeVisitor<R> {
11+
const TypeVisitor();
12+
13+
R visitDynamicType(DynamicType type);
14+
15+
R visitFunctionType(FunctionType type);
16+
17+
R visitInterfaceType(InterfaceType type);
18+
19+
R visitNeverType(NeverType type);
20+
21+
R visitTypeParameterType(TypeParameterType type);
22+
23+
R visitVoidType(VoidType type);
24+
}
25+
26+
/// Invokes [visitDartType] from any other `visitXyz` method.
27+
///
28+
/// Clients may extend this class.
29+
abstract class UnifyingTypeVisitor<R> implements TypeVisitor<R> {
30+
const UnifyingTypeVisitor();
31+
32+
/// By default other `visitXyz` methods invoke this method.
33+
R visitDartType(DartType type);
34+
35+
@override
36+
R visitDynamicType(DynamicType type) => visitDartType(type);
37+
38+
@override
39+
R visitFunctionType(FunctionType type) => visitDartType(type);
40+
41+
@override
42+
R visitInterfaceType(InterfaceType type) => visitDartType(type);
43+
44+
@override
45+
R visitNeverType(NeverType type) => visitDartType(type);
46+
47+
@override
48+
R visitTypeParameterType(TypeParameterType type) => visitDartType(type);
49+
50+
@override
51+
R visitVoidType(VoidType type) => visitDartType(type);
52+
}

pkg/analyzer/lib/src/dart/constant/has_type_parameter_reference.dart

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import 'package:analyzer/src/dart/element/type_visitor.dart';
88
/// Return `true` if the [type] has a type parameter reference.
99
bool hasTypeParameterReference(DartType type) {
1010
var visitor = _ReferencesTypeParameterVisitor();
11-
DartTypeVisitor.visit(type, visitor);
11+
type.accept(visitor);
1212
return visitor.result;
1313
}
1414

@@ -23,9 +23,6 @@ class _ReferencesTypeParameterVisitor extends RecursiveTypeVisitor {
2323
/// The result of whether any type parameters were found.
2424
bool result = false;
2525

26-
@override
27-
bool defaultDartType(_) => true;
28-
2926
@override
3027
bool visitTypeParameterType(_) {
3128
result = true;

pkg/analyzer/lib/src/dart/element/nullability_eliminator.dart

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
import 'package:analyzer/dart/element/nullability_suffix.dart';
66
import 'package:analyzer/dart/element/type.dart';
77
import 'package:analyzer/src/dart/element/replacement_visitor.dart';
8-
import 'package:analyzer/src/dart/element/type.dart';
98
import 'package:analyzer/src/dart/element/type_provider.dart';
109
import 'package:analyzer/src/generated/utilities_dart.dart';
1110

@@ -15,7 +14,7 @@ class NullabilityEliminator extends ReplacementVisitor {
1514
NullabilityEliminator(this._typeProvider);
1615

1716
@override
18-
DartType visitNeverType(NeverTypeImpl type) {
17+
DartType visitNeverType(NeverType type) {
1918
return _typeProvider.nullStar;
2019
}
2120

@@ -43,6 +42,7 @@ class NullabilityEliminator extends ReplacementVisitor {
4342
return type;
4443
}
4544

46-
return NullabilityEliminator(typeProvider).visit(type) ?? type;
45+
var visitor = NullabilityEliminator(typeProvider);
46+
return type.accept<DartType>(visitor) ?? type;
4747
}
4848
}

pkg/analyzer/lib/src/dart/element/replacement_visitor.dart

Lines changed: 10 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,20 @@
55
import 'package:analyzer/dart/element/element.dart';
66
import 'package:analyzer/dart/element/nullability_suffix.dart';
77
import 'package:analyzer/dart/element/type.dart';
8+
import 'package:analyzer/dart/element/type_visitor.dart';
89
import 'package:analyzer/src/dart/element/element.dart';
910
import 'package:analyzer/src/dart/element/extensions.dart';
1011
import 'package:analyzer/src/dart/element/type.dart';
1112
import 'package:analyzer/src/dart/element/type_algebra.dart';
1213
import 'package:analyzer/src/dart/element/type_schema.dart';
1314
import 'package:analyzer/src/dart/element/type_visitor.dart';
1415
import 'package:analyzer/src/generated/utilities_dart.dart';
15-
import 'package:analyzer/src/summary2/function_type_builder.dart';
16-
import 'package:analyzer/src/summary2/named_type_builder.dart';
1716
import 'package:meta/meta.dart';
1817

1918
/// Helper visitor that clones a type if a nested type is replaced, and
2019
/// otherwise returns `null`.
21-
class ReplacementVisitor implements DartTypeVisitor<DartType> {
20+
class ReplacementVisitor
21+
implements TypeVisitor<DartType>, InferenceTypeVisitor<DartType> {
2222
const ReplacementVisitor();
2323

2424
void changeVariance() {}
@@ -103,16 +103,12 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
103103
}
104104

105105
@override
106-
DartType defaultDartType(DartType type) {
106+
DartType visitDartType(DartType type) {
107107
return null;
108108
}
109109

110-
DartType visit(DartType type) {
111-
return DartTypeVisitor.visit(type, this);
112-
}
113-
114110
@override
115-
DartType visitDynamicType(DynamicTypeImpl type) {
111+
DartType visitDynamicType(DynamicType type) {
116112
return null;
117113
}
118114

@@ -125,7 +121,7 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
125121
var typeParameter = node.typeFormals[i];
126122
var bound = typeParameter.bound;
127123
if (bound != null) {
128-
var newBound = visit(bound);
124+
var newBound = bound.accept(this);
129125
if (newBound != null) {
130126
newTypeParameters ??= node.typeFormals.toList(growable: false);
131127
newTypeParameters[i] = TypeParameterElementImpl.synthetic(
@@ -160,7 +156,7 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
160156

161157
DartType visitType(DartType type) {
162158
if (type == null) return null;
163-
var result = visit(type);
159+
var result = type.accept(this);
164160
if (substitution != null) {
165161
result = substitution.substituteType(result ?? type);
166162
}
@@ -202,18 +198,13 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
202198
);
203199
}
204200

205-
@override
206-
DartType visitFunctionTypeBuilder(FunctionTypeBuilder type) {
207-
throw UnimplementedError();
208-
}
209-
210201
@override
211202
DartType visitInterfaceType(InterfaceType type) {
212203
var newNullability = visitNullability(type);
213204

214205
List<DartType> newTypeArguments;
215206
for (var i = 0; i < type.typeArguments.length; i++) {
216-
var substitution = visit(type.typeArguments[i]);
207+
var substitution = type.typeArguments[i].accept(this);
217208
if (substitution != null) {
218209
newTypeArguments ??= type.typeArguments.toList(growable: false);
219210
newTypeArguments[i] = substitution;
@@ -228,12 +219,7 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
228219
}
229220

230221
@override
231-
DartType visitNamedTypeBuilder(NamedTypeBuilder type) {
232-
throw UnimplementedError();
233-
}
234-
235-
@override
236-
DartType visitNeverType(NeverTypeImpl type) {
222+
DartType visitNeverType(NeverType type) {
237223
var newNullability = visitNullability(type);
238224

239225
return createNeverType(
@@ -256,7 +242,7 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
256242

257243
var promotedBound = (type as TypeParameterTypeImpl).promotedBound;
258244
if (promotedBound != null) {
259-
var newPromotedBound = visit(promotedBound);
245+
var newPromotedBound = promotedBound.accept(this);
260246
return createPromotedTypeParameterType(
261247
type: type,
262248
newNullability: newNullability,

pkg/analyzer/lib/src/dart/element/type.dart

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import 'package:analyzer/dart/element/null_safety_understanding_flag.dart';
1010
import 'package:analyzer/dart/element/nullability_suffix.dart';
1111
import 'package:analyzer/dart/element/type.dart';
1212
import 'package:analyzer/dart/element/type_provider.dart';
13+
import 'package:analyzer/dart/element/type_visitor.dart';
1314
import 'package:analyzer/src/dart/analysis/session.dart';
1415
import 'package:analyzer/src/dart/element/display_string_builder.dart';
1516
import 'package:analyzer/src/dart/element/element.dart';
@@ -68,6 +69,11 @@ class DynamicTypeImpl extends TypeImpl implements DynamicType {
6869
@override
6970
bool operator ==(Object object) => identical(object, this);
7071

72+
@override
73+
R accept<R>(TypeVisitor<R> visitor) {
74+
return visitor.visitDynamicType(this);
75+
}
76+
7177
@override
7278
void appendTo(ElementDisplayStringBuilder builder) {
7379
builder.writeDynamicType();
@@ -268,6 +274,11 @@ class FunctionTypeImpl extends TypeImpl implements FunctionType {
268274
return false;
269275
}
270276

277+
@override
278+
R accept<R>(TypeVisitor<R> visitor) {
279+
return visitor.visitFunctionType(this);
280+
}
281+
271282
@override
272283
void appendTo(ElementDisplayStringBuilder builder) {
273284
builder.writeFunctionType(this);
@@ -873,6 +884,11 @@ class InterfaceTypeImpl extends TypeImpl implements InterfaceType {
873884
return false;
874885
}
875886

887+
@override
888+
R accept<R>(TypeVisitor<R> visitor) {
889+
return visitor.visitInterfaceType(this);
890+
}
891+
876892
@override
877893
void appendTo(ElementDisplayStringBuilder builder) {
878894
builder.writeInterfaceType(this);
@@ -1678,6 +1694,11 @@ class NeverTypeImpl extends TypeImpl implements NeverType {
16781694
@override
16791695
bool operator ==(Object object) => identical(object, this);
16801696

1697+
@override
1698+
R accept<R>(TypeVisitor<R> visitor) {
1699+
return visitor.visitNeverType(this);
1700+
}
1701+
16811702
@override
16821703
void appendTo(ElementDisplayStringBuilder builder) {
16831704
builder.writeNeverType(this);
@@ -1950,6 +1971,11 @@ class TypeParameterTypeImpl extends TypeImpl implements TypeParameterType {
19501971
return false;
19511972
}
19521973

1974+
@override
1975+
R accept<R>(TypeVisitor<R> visitor) {
1976+
return visitor.visitTypeParameterType(this);
1977+
}
1978+
19531979
@override
19541980
void appendTo(ElementDisplayStringBuilder builder) {
19551981
builder.writeTypeParameterType(this);
@@ -2086,6 +2112,11 @@ class VoidTypeImpl extends TypeImpl implements VoidType {
20862112
@override
20872113
bool operator ==(Object object) => identical(object, this);
20882114

2115+
@override
2116+
R accept<R>(TypeVisitor<R> visitor) {
2117+
return visitor.visitVoidType(this);
2118+
}
2119+
20892120
@override
20902121
void appendTo(ElementDisplayStringBuilder builder) {
20912122
builder.writeVoidType();

0 commit comments

Comments
 (0)