@@ -7,6 +7,10 @@ library fasta.kernel_target;
7
7
import 'package:kernel/ast.dart' ;
8
8
import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
9
9
import 'package:kernel/type_algebra.dart' show Substitution;
10
+ import 'package:kernel/type_environment.dart' ;
11
+
12
+ import '../builder/library_builder.dart' ;
13
+ import '../messages.dart' ;
10
14
11
15
/// Data for clone default values for synthesized function nodes once the
12
16
/// original default values have been computed.
@@ -35,32 +39,45 @@ class SynthesizedFunctionNode {
35
39
/// named parameters.
36
40
final bool identicalSignatures;
37
41
38
- final List <int >? _positionalSuperParameters;
42
+ final List <int ? >? _positionalSuperParameters;
39
43
40
44
final List <String >? _namedSuperParameters;
41
45
42
46
bool isOutlineNode;
43
47
48
+ final LibraryBuilder _libraryBuilder;
49
+
50
+ CloneVisitorNotMembers ? _cloner;
51
+
44
52
SynthesizedFunctionNode (
45
53
this ._typeSubstitution, this ._original, this ._synthesized,
46
54
{this .identicalSignatures: true ,
47
- List <int >? positionalSuperParameters: null ,
55
+ List <int ? >? positionalSuperParameters: null ,
48
56
List <String >? namedSuperParameters: null ,
49
- this .isOutlineNode: false })
57
+ this .isOutlineNode: false ,
58
+ required LibraryBuilder libraryBuilder})
50
59
: _positionalSuperParameters = positionalSuperParameters,
51
60
_namedSuperParameters = namedSuperParameters,
61
+ _libraryBuilder = libraryBuilder,
52
62
// Check that [positionalSuperParameters] and [namedSuperParameters] are
53
63
// provided or omitted together.
54
64
assert ((positionalSuperParameters == null ) ==
55
65
(namedSuperParameters == null )),
56
66
assert (positionalSuperParameters == null ||
57
67
() {
58
68
// Check that [positionalSuperParameters] is sorted if it's
59
- // provided.
60
- for (int i = 1 ; i < positionalSuperParameters.length; i++ ) {
61
- if (positionalSuperParameters[i] <
62
- positionalSuperParameters[i - 1 ]) {
63
- return false ;
69
+ // provided. The `null` values are allowed in-between the sorted
70
+ // values.
71
+ for (int i = - 1 , j = 0 ;
72
+ j < positionalSuperParameters.length;
73
+ j++ ) {
74
+ int ? currentValue = positionalSuperParameters[j];
75
+ if (currentValue != null ) {
76
+ if (i == - 1 || positionalSuperParameters[i]! < currentValue) {
77
+ i = j;
78
+ } else {
79
+ return false ;
80
+ }
64
81
}
65
82
}
66
83
return true ;
@@ -82,23 +99,11 @@ class SynthesizedFunctionNode {
82
99
return superParameterIndex == namedSuperParameters.length;
83
100
}());
84
101
85
- void cloneDefaultValues () {
102
+ void cloneDefaultValues (TypeEnvironment typeEnvironment ) {
86
103
// TODO(ahe): It is unclear if it is legal to use type variables in
87
104
// default values, but Fasta is currently allowing it, and the VM
88
105
// accepts it. If it isn't legal, the we can speed this up by using a
89
106
// single cloner without substitution.
90
- CloneVisitorNotMembers ? cloner;
91
-
92
- void cloneInitializer (VariableDeclaration originalParameter,
93
- VariableDeclaration clonedParameter) {
94
- if (originalParameter.initializer != null ) {
95
- cloner ?? =
96
- new CloneVisitorNotMembers (typeSubstitution: _typeSubstitution);
97
- clonedParameter.initializer = cloner!
98
- .clone (originalParameter.initializer! )
99
- ..parent = clonedParameter;
100
- }
101
- }
102
107
103
108
// For mixin application constructors, the argument count is the same, but
104
109
// for redirecting tear off lowerings, the argument count of the tear off
@@ -109,14 +114,21 @@ class SynthesizedFunctionNode {
109
114
assert (_positionalSuperParameters != null ||
110
115
_synthesized.positionalParameters.length ==
111
116
_original.positionalParameters.length);
112
- List <int >? positionalSuperParameters = _positionalSuperParameters;
117
+ List <int ? >? positionalSuperParameters = _positionalSuperParameters;
113
118
for (int i = 0 ; i < _original.positionalParameters.length; i++ ) {
114
119
if (positionalSuperParameters == null ) {
115
- cloneInitializer (_original.positionalParameters[i],
120
+ _cloneInitializer (_original.positionalParameters[i],
116
121
_synthesized.positionalParameters[i]);
117
122
} else if (i < positionalSuperParameters.length) {
118
- cloneInitializer (_original.positionalParameters[i],
119
- _synthesized.positionalParameters[positionalSuperParameters[i]]);
123
+ int ? superParameterIndex = positionalSuperParameters[i];
124
+ if (superParameterIndex != null ) {
125
+ VariableDeclaration originalParameter =
126
+ _original.positionalParameters[i];
127
+ VariableDeclaration synthesizedParameter =
128
+ _synthesized.positionalParameters[superParameterIndex];
129
+ _cloneDefaultValueForSuperParameters (
130
+ originalParameter, synthesizedParameter, typeEnvironment);
131
+ }
120
132
}
121
133
}
122
134
@@ -131,7 +143,7 @@ class SynthesizedFunctionNode {
131
143
}
132
144
for (int i = 0 ; i < _synthesized.namedParameters.length; i++ ) {
133
145
if (namedSuperParameters == null ) {
134
- cloneInitializer (
146
+ _cloneInitializer (
135
147
_original.namedParameters[i], _synthesized.namedParameters[i]);
136
148
} else if (superParameterNameIndex < namedSuperParameters.length &&
137
149
namedSuperParameters[superParameterNameIndex] ==
@@ -141,9 +153,12 @@ class SynthesizedFunctionNode {
141
153
int ? originalNamedParameterIndex =
142
154
originalNamedParameterIndices[superParameterName];
143
155
if (originalNamedParameterIndex != null ) {
144
- cloneInitializer (
145
- _original.namedParameters[originalNamedParameterIndex],
146
- _synthesized.namedParameters[i]);
156
+ VariableDeclaration originalParameter =
157
+ _original.namedParameters[originalNamedParameterIndex];
158
+ VariableDeclaration synthesizedParameter =
159
+ _synthesized.namedParameters[i];
160
+ _cloneDefaultValueForSuperParameters (
161
+ originalParameter, synthesizedParameter, typeEnvironment);
147
162
} else {
148
163
// TODO(cstefantsova): Handle the erroneous case of missing names.
149
164
}
@@ -155,7 +170,7 @@ class SynthesizedFunctionNode {
155
170
VariableDeclaration synthesizedParameter =
156
171
_synthesized.positionalParameters[i];
157
172
if (i < _original.positionalParameters.length) {
158
- cloneInitializer (
173
+ _cloneInitializer (
159
174
_original.positionalParameters[i], synthesizedParameter);
160
175
} else {
161
176
// Error case: use `null` as initializer.
@@ -175,7 +190,7 @@ class SynthesizedFunctionNode {
175
190
VariableDeclaration ? originalParameter =
176
191
originalParameters[synthesizedParameter.name! ];
177
192
if (originalParameter != null ) {
178
- cloneInitializer (originalParameter, synthesizedParameter);
193
+ _cloneInitializer (originalParameter, synthesizedParameter);
179
194
} else {
180
195
// Error case: use `null` as initializer.
181
196
synthesizedParameter.initializer = new NullLiteral ()
@@ -186,6 +201,43 @@ class SynthesizedFunctionNode {
186
201
}
187
202
}
188
203
204
+ void _cloneInitializer (VariableDeclaration originalParameter,
205
+ VariableDeclaration clonedParameter) {
206
+ if (originalParameter.initializer != null ) {
207
+ CloneVisitorNotMembers cloner = _cloner ?? =
208
+ new CloneVisitorNotMembers (typeSubstitution: _typeSubstitution);
209
+ clonedParameter.initializer = cloner.clone (originalParameter.initializer! )
210
+ ..parent = clonedParameter;
211
+ }
212
+ }
213
+
214
+ void _cloneDefaultValueForSuperParameters (
215
+ VariableDeclaration originalParameter,
216
+ VariableDeclaration synthesizedParameter,
217
+ TypeEnvironment typeEnvironment) {
218
+ Member member = _synthesized.parent as Member ;
219
+ Expression ? originalParameterInitializer = originalParameter.initializer;
220
+ DartType ? originalParameterInitializerType = originalParameterInitializer
221
+ ? .getStaticType (new StaticTypeContext (member, typeEnvironment));
222
+ DartType synthesizedParameterType = synthesizedParameter.type;
223
+ if (originalParameterInitializerType != null &&
224
+ typeEnvironment.isSubtypeOf (originalParameterInitializerType,
225
+ synthesizedParameterType, SubtypeCheckMode .withNullabilities)) {
226
+ _cloneInitializer (originalParameter, synthesizedParameter);
227
+ } else {
228
+ if (synthesizedParameterType.isPotentiallyNonNullable) {
229
+ _libraryBuilder.addProblem (
230
+ templateOptionalSuperParameterWithoutInitializer.withArguments (
231
+ synthesizedParameter.type,
232
+ synthesizedParameter.name! ,
233
+ _libraryBuilder.isNonNullableByDefault),
234
+ synthesizedParameter.fileOffset,
235
+ synthesizedParameter.name? .length ?? 1 ,
236
+ _libraryBuilder.fileUri);
237
+ }
238
+ }
239
+ }
240
+
189
241
@override
190
242
String toString () {
191
243
return "SynthesizedFunctionNode(original=${_original .parent }, "
0 commit comments