33// BSD-style license that can be found in the LICENSE.md file.
44
55import 'package:kernel/ast.dart' hide MapEntry;
6+ import 'package:kernel/type_algebra.dart' ;
67
78/// Helper visitor that clones a type if a nested type is replaced, and
89/// otherwise returns `null` .
@@ -13,33 +14,92 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
1314
1415 @override
1516 DartType visitFunctionType (FunctionType node) {
16- DartType newReturnType = node.returnType.accept (this );
17+ List <TypeParameter > newTypeParameters;
18+ for (int i = 0 ; i < node.typeParameters.length; i++ ) {
19+ TypeParameter typeParameter = node.typeParameters[i];
20+ DartType newBound = typeParameter.bound.accept (this );
21+ DartType newDefaultType = typeParameter.defaultType.accept (this );
22+ if (newBound != null || newDefaultType != null ) {
23+ newTypeParameters ?? = node.typeParameters.toList (growable: false );
24+ newTypeParameters[i] = new TypeParameter (
25+ typeParameter.name,
26+ newBound ?? typeParameter.bound,
27+ newDefaultType ?? typeParameter.defaultType);
28+ }
29+ }
30+
31+ Substitution substitution;
32+ if (newTypeParameters != null ) {
33+ List <TypeParameterType > typeParameterTypes =
34+ new List <TypeParameterType >(newTypeParameters.length);
35+ for (int i = 0 ; i < newTypeParameters.length; i++ ) {
36+ typeParameterTypes[i] = new TypeParameterType .forAlphaRenaming (
37+ node.typeParameters[i], newTypeParameters[i]);
38+ }
39+ substitution =
40+ Substitution .fromPairs (node.typeParameters, typeParameterTypes);
41+ for (int i = 0 ; i < newTypeParameters.length; i++ ) {
42+ newTypeParameters[i].bound =
43+ substitution.substituteType (newTypeParameters[i].bound);
44+ }
45+ }
46+
47+ DartType visitType (DartType type) {
48+ if (type == null ) return null ;
49+ DartType result = type.accept (this );
50+ if (substitution != null ) {
51+ result = substitution.substituteType (result ?? type);
52+ }
53+ return result;
54+ }
55+
56+ DartType newReturnType = visitType (node.returnType);
1757 changeVariance ();
1858 List <DartType > newPositionalParameters = null ;
1959 for (int i = 0 ; i < node.positionalParameters.length; i++ ) {
20- DartType substitution = node.positionalParameters[i]. accept ( this );
21- if (substitution != null ) {
60+ DartType newType = visitType ( node.positionalParameters[i]);
61+ if (newType != null ) {
2262 newPositionalParameters ?? =
2363 node.positionalParameters.toList (growable: false );
24- newPositionalParameters[i] = substitution ;
64+ newPositionalParameters[i] = newType ;
2565 }
2666 }
2767 List <NamedType > newNamedParameters = null ;
2868 for (int i = 0 ; i < node.namedParameters.length; i++ ) {
29- DartType substitution = node.namedParameters[i].type.accept (this );
30- if (substitution != null ) {
69+ DartType newType = visitType (node.namedParameters[i].type);
70+ NamedType newNamedType =
71+ createNamedType (node.namedParameters[i], newType);
72+ if (newNamedType != null ) {
3173 newNamedParameters ?? = node.namedParameters.toList (growable: false );
32- newNamedParameters[i] = new NamedType (
33- node.namedParameters[i].name, substitution,
34- isRequired: node.namedParameters[i].isRequired);
74+ newNamedParameters[i] = newNamedType;
3575 }
3676 }
3777 changeVariance ();
38- DartType typedefType = node.typedefType? .accept (this );
78+ DartType newTypedefType = visitType (node.typedefType);
79+
80+ return createFunctionType (node, newTypeParameters, newReturnType,
81+ newPositionalParameters, newNamedParameters, newTypedefType);
82+ }
83+
84+ NamedType createNamedType (NamedType node, DartType newType) {
85+ if (newType == null ) {
86+ return null ;
87+ } else {
88+ return new NamedType (node.name, newType, isRequired: node.isRequired);
89+ }
90+ }
91+
92+ DartType createFunctionType (
93+ FunctionType node,
94+ List <TypeParameter > newTypeParameters,
95+ DartType newReturnType,
96+ List <DartType > newPositionalParameters,
97+ List <NamedType > newNamedParameters,
98+ TypedefType newTypedefType) {
3999 if (newReturnType == null &&
40100 newPositionalParameters == null &&
41101 newNamedParameters == null &&
42- typedefType == null ) {
102+ newTypedefType == null ) {
43103 // No types had to be substituted.
44104 return null ;
45105 } else {
@@ -48,9 +108,9 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
48108 newReturnType ?? node.returnType,
49109 node.nullability,
50110 namedParameters: newNamedParameters ?? node.namedParameters,
51- typeParameters: node.typeParameters,
111+ typeParameters: newTypeParameters ?? node.typeParameters,
52112 requiredParameterCount: node.requiredParameterCount,
53- typedefType: typedefType);
113+ typedefType: newTypedefType ?? node. typedefType);
54114 }
55115 }
56116
@@ -64,6 +124,11 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
64124 newTypeArguments[i] = substitution;
65125 }
66126 }
127+ return createInterfaceType (node, newTypeArguments);
128+ }
129+
130+ DartType createInterfaceType (
131+ InterfaceType node, List <DartType > newTypeArguments) {
67132 if (newTypeArguments == null ) {
68133 // No type arguments needed to be substituted.
69134 return null ;
@@ -92,10 +157,20 @@ class ReplacementVisitor implements DartTypeVisitor<DartType> {
92157 DartType visitTypeParameterType (TypeParameterType node) {
93158 if (node.promotedBound != null ) {
94159 DartType newPromotedBound = node.promotedBound.accept (this );
95- if (newPromotedBound != null ) {
96- return new TypeParameterType (node.parameter,
97- node.typeParameterTypeNullability, newPromotedBound);
98- }
160+ return createPromotedTypeParameterType (node, newPromotedBound);
161+ }
162+ return createTypeParameterType (node);
163+ }
164+
165+ DartType createTypeParameterType (TypeParameterType node) {
166+ return null ;
167+ }
168+
169+ DartType createPromotedTypeParameterType (
170+ TypeParameterType node, DartType newPromotedBound) {
171+ if (newPromotedBound != null ) {
172+ return new TypeParameterType (
173+ node.parameter, node.typeParameterTypeNullability, newPromotedBound);
99174 }
100175 return null ;
101176 }
0 commit comments