OLD | NEW |
---|---|
1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 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. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 library fasta.kernel_library_builder; | 5 library fasta.kernel_library_builder; |
6 | 6 |
7 import 'package:kernel/ast.dart'; | 7 import 'package:kernel/ast.dart'; |
8 | 8 |
9 import 'package:kernel/clone.dart' show CloneVisitor; | 9 import 'package:kernel/clone.dart' show CloneVisitor; |
10 | 10 |
11 import '../errors.dart' show internalError; | 11 import '../errors.dart' show internalError; |
12 | 12 |
13 import '../loader.dart' show Loader; | 13 import '../loader.dart' show Loader; |
14 | 14 |
15 import '../modifier.dart' show abstractMask, staticMask; | 15 import '../modifier.dart' |
16 show abstractMask, namedMixinApplicationMask, staticMask; | |
16 | 17 |
17 import '../source/source_library_builder.dart' | 18 import '../source/source_library_builder.dart' |
18 show DeclarationBuilder, SourceLibraryBuilder; | 19 show DeclarationBuilder, SourceLibraryBuilder; |
19 | 20 |
20 import '../source/source_class_builder.dart' show SourceClassBuilder; | 21 import '../source/source_class_builder.dart' show SourceClassBuilder; |
21 | 22 |
22 import '../util/relativize.dart' show relativizeUri; | 23 import '../util/relativize.dart' show relativizeUri; |
23 | 24 |
24 import 'kernel_builder.dart' | 25 import 'kernel_builder.dart' |
25 show | 26 show |
26 AccessErrorBuilder, | 27 AccessErrorBuilder, |
27 Builder, | 28 Builder, |
28 BuiltinTypeBuilder, | 29 BuiltinTypeBuilder, |
29 ClassBuilder, | 30 ClassBuilder, |
30 ConstructorReferenceBuilder, | 31 ConstructorReferenceBuilder, |
31 FormalParameterBuilder, | 32 FormalParameterBuilder, |
32 FunctionTypeAliasBuilder, | 33 FunctionTypeAliasBuilder, |
33 InvalidTypeBuilder, | 34 InvalidTypeBuilder, |
34 KernelConstructorBuilder, | 35 KernelConstructorBuilder, |
35 KernelEnumBuilder, | 36 KernelEnumBuilder, |
36 KernelFieldBuilder, | 37 KernelFieldBuilder, |
37 KernelFormalParameterBuilder, | 38 KernelFormalParameterBuilder, |
38 KernelFunctionTypeAliasBuilder, | 39 KernelFunctionTypeAliasBuilder, |
39 KernelFunctionTypeBuilder, | 40 KernelFunctionTypeBuilder, |
40 KernelInvalidTypeBuilder, | 41 KernelInvalidTypeBuilder, |
41 KernelMixinApplicationBuilder, | 42 KernelMixinApplicationBuilder, |
42 KernelNamedMixinApplicationBuilder, | |
43 KernelNamedTypeBuilder, | 43 KernelNamedTypeBuilder, |
44 KernelProcedureBuilder, | 44 KernelProcedureBuilder, |
45 KernelTypeBuilder, | 45 KernelTypeBuilder, |
46 KernelTypeVariableBuilder, | 46 KernelTypeVariableBuilder, |
47 LibraryBuilder, | 47 LibraryBuilder, |
48 MemberBuilder, | 48 MemberBuilder, |
49 MetadataBuilder, | 49 MetadataBuilder, |
50 NamedMixinApplicationBuilder, | 50 NamedTypeBuilder, |
51 PrefixBuilder, | 51 PrefixBuilder, |
52 ProcedureBuilder, | 52 ProcedureBuilder, |
53 Scope, | 53 Scope, |
54 TypeBuilder, | 54 TypeBuilder, |
55 TypeVariableBuilder, | 55 TypeVariableBuilder, |
56 compareProcedures; | 56 compareProcedures; |
57 | 57 |
58 class KernelLibraryBuilder | 58 class KernelLibraryBuilder |
59 extends SourceLibraryBuilder<KernelTypeBuilder, Library> { | 59 extends SourceLibraryBuilder<KernelTypeBuilder, Library> { |
60 final Library library; | 60 final Library library; |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 | 96 |
97 void addClass( | 97 void addClass( |
98 List<MetadataBuilder> metadata, | 98 List<MetadataBuilder> metadata, |
99 int modifiers, | 99 int modifiers, |
100 String className, | 100 String className, |
101 List<TypeVariableBuilder> typeVariables, | 101 List<TypeVariableBuilder> typeVariables, |
102 KernelTypeBuilder supertype, | 102 KernelTypeBuilder supertype, |
103 List<KernelTypeBuilder> interfaces, | 103 List<KernelTypeBuilder> interfaces, |
104 int charOffset) { | 104 int charOffset) { |
105 // Nested declaration began in `OutlineBuilder.beginClassDeclaration`. | 105 // Nested declaration began in `OutlineBuilder.beginClassDeclaration`. |
106 var declaration = endNestedDeclaration(); | 106 var declaration = endNestedDeclaration()..resolveTypes(typeVariables, this); |
107 assert(declaration.parent == libraryDeclaration); | 107 assert(declaration.parent == libraryDeclaration); |
108 Map<String, MemberBuilder> members = declaration.members; | 108 Map<String, MemberBuilder> members = declaration.members; |
109 Map<String, MemberBuilder> constructors = declaration.constructors; | 109 Map<String, MemberBuilder> constructors = declaration.constructors; |
110 Map<String, MemberBuilder> setters = declaration.setters; | 110 Map<String, MemberBuilder> setters = declaration.setters; |
111 | 111 |
112 Scope classScope = new Scope( | 112 Scope classScope = new Scope( |
113 members, setters, scope.withTypeVariables(typeVariables), | 113 members, setters, scope.withTypeVariables(typeVariables), |
114 isModifiable: false); | 114 isModifiable: false); |
115 | 115 |
116 // When looking up a constructor, we don't consider type variables or the | 116 // When looking up a constructor, we don't consider type variables or the |
117 // library scope. | 117 // library scope. |
118 Scope constructorScope = | 118 Scope constructorScope = |
119 new Scope(constructors, null, null, isModifiable: false); | 119 new Scope(constructors, null, null, isModifiable: false); |
120 ClassBuilder cls = new SourceClassBuilder( | 120 ClassBuilder cls = new SourceClassBuilder( |
121 metadata, | 121 metadata, |
122 modifiers, | 122 modifiers, |
123 className, | 123 className, |
124 typeVariables, | 124 typeVariables, |
125 applyMixins(supertype), | 125 applyMixins(supertype, |
126 subclassName: className, typeVariables: typeVariables), | |
126 interfaces, | 127 interfaces, |
127 classScope, | 128 classScope, |
128 constructorScope, | 129 constructorScope, |
129 this, | 130 this, |
130 new List<ConstructorReferenceBuilder>.from(constructorReferences), | 131 new List<ConstructorReferenceBuilder>.from(constructorReferences), |
131 charOffset); | 132 charOffset); |
132 constructorReferences.clear(); | 133 constructorReferences.clear(); |
133 Map<String, TypeVariableBuilder> typeVariablesByName = | 134 Map<String, TypeVariableBuilder> typeVariablesByName = |
134 checkTypeVariables(typeVariables, cls); | 135 checkTypeVariables(typeVariables, cls); |
135 void setParent(String name, MemberBuilder member) { | 136 void setParent(String name, MemberBuilder member) { |
137 while (member != null) { | |
138 member.parent = cls; | |
139 member = member.next; | |
140 } | |
141 } | |
142 | |
143 void setParentAndCheckConflicts(String name, MemberBuilder member) { | |
136 if (typeVariablesByName != null) { | 144 if (typeVariablesByName != null) { |
137 TypeVariableBuilder tv = typeVariablesByName[name]; | 145 TypeVariableBuilder tv = typeVariablesByName[name]; |
138 if (tv != null) { | 146 if (tv != null) { |
139 cls.addCompileTimeError( | 147 cls.addCompileTimeError( |
140 member.charOffset, "Conflict with type variable '$name'."); | 148 member.charOffset, "Conflict with type variable '$name'."); |
141 cls.addCompileTimeError(tv.charOffset, "This is the type variable."); | 149 cls.addCompileTimeError(tv.charOffset, "This is the type variable."); |
142 } | 150 } |
143 } | 151 } |
144 while (member != null) { | 152 setParent(name, member); |
145 member.parent = cls; | |
146 member = member.next; | |
147 } | |
148 } | 153 } |
149 | 154 |
150 members.forEach(setParent); | 155 members.forEach(setParentAndCheckConflicts); |
151 constructors.forEach(setParent); | 156 constructors.forEach(setParentAndCheckConflicts); |
157 // Formally, a setter has the name `id=`, so it can never conflict with a | |
158 // type variable. | |
152 setters.forEach(setParent); | 159 setters.forEach(setParent); |
153 declaration.resolveTypes(typeVariables, this); | |
154 addBuilder(className, cls, charOffset); | 160 addBuilder(className, cls, charOffset); |
155 } | 161 } |
156 | 162 |
157 Map<String, TypeVariableBuilder> checkTypeVariables( | 163 Map<String, TypeVariableBuilder> checkTypeVariables( |
158 List<TypeVariableBuilder> typeVariables, Builder owner) { | 164 List<TypeVariableBuilder> typeVariables, Builder owner) { |
159 if (typeVariables?.isEmpty ?? true) return null; | 165 if (typeVariables?.isEmpty ?? true) return null; |
160 Map<String, TypeVariableBuilder> typeVariablesByName = | 166 Map<String, TypeVariableBuilder> typeVariablesByName = |
161 <String, TypeVariableBuilder>{}; | 167 <String, TypeVariableBuilder>{}; |
162 for (TypeVariableBuilder tv in typeVariables) { | 168 for (TypeVariableBuilder tv in typeVariables) { |
163 TypeVariableBuilder existing = typeVariablesByName[tv.name]; | 169 TypeVariableBuilder existing = typeVariablesByName[tv.name]; |
164 if (existing != null) { | 170 if (existing != null) { |
165 addCompileTimeError(tv.charOffset, | 171 addCompileTimeError(tv.charOffset, |
166 "A type variable can't have the same name as another."); | 172 "A type variable can't have the same name as another."); |
167 addCompileTimeError( | 173 addCompileTimeError( |
168 existing.charOffset, "The other type variable named '${tv.name}'."); | 174 existing.charOffset, "The other type variable named '${tv.name}'."); |
169 } else { | 175 } else { |
170 typeVariablesByName[tv.name] = tv; | 176 typeVariablesByName[tv.name] = tv; |
171 if (tv.name == owner.name) { | 177 if (owner is ClassBuilder) { |
Johnni Winther
2017/05/08 10:05:34
Why is the only for classes? Aren't `typedef F<F>(
ahe
2017/05/08 11:13:15
Not according to our tests, and it also seems like
| |
172 addCompileTimeError( | 178 if (tv.name == owner.name) { |
173 tv.charOffset, | 179 addCompileTimeError( |
174 "A type variable can't have the same name as its enclosing " | 180 tv.charOffset, |
175 "declaration."); | 181 "A type variable can't have the same name as its enclosing " |
182 "declaration."); | |
183 } | |
176 } | 184 } |
177 } | 185 } |
178 } | 186 } |
179 return typeVariablesByName; | 187 return typeVariablesByName; |
180 } | 188 } |
181 | 189 |
182 KernelNamedTypeBuilder removeTypeVariables(KernelNamedTypeBuilder type) { | |
183 return type.arguments == null | |
184 ? type | |
185 : addNamedType(type.name, null, type.charOffset); | |
186 } | |
187 | |
188 KernelTypeBuilder applyMixin( | 190 KernelTypeBuilder applyMixin( |
189 KernelTypeBuilder supertype, KernelTypeBuilder mixin, String name) { | 191 KernelTypeBuilder supertype, KernelTypeBuilder mixin, String signature, |
190 supertype = removeTypeVariables(supertype); | 192 {List<MetadataBuilder> metadata, |
191 mixin = removeTypeVariables(mixin); | 193 String name, |
194 List<TypeVariableBuilder> typeVariables, | |
195 int modifiers: abstractMask, | |
196 List<KernelTypeBuilder> interfaces, | |
197 int charOffset: -1}) { | |
192 var constructors = <String, MemberBuilder>{}; | 198 var constructors = <String, MemberBuilder>{}; |
193 if (name != null) { | 199 bool isNamed = name != null; |
194 constructors[""] = new KernelConstructorBuilder( | 200 SourceClassBuilder builder; |
195 null, 0, null, "", null, null, this, mixin.charOffset, -1, -1, null); | 201 if (isNamed) { |
196 } | 202 modifiers |= namedMixinApplicationMask; |
197 if (name == null) { | 203 } else { |
198 name = "${supertype.name}&${mixin.name}"; | 204 name = supertype.name; |
199 } | 205 int index = name.indexOf("^"); |
200 var builder = mixinApplicationClasses.putIfAbsent(name, () { | 206 if (index != -1) { |
201 var builder = new SourceClassBuilder( | 207 name = name.substring(0, index); |
202 null, // metadata | 208 } |
203 0, // modifiers | 209 name = "$name&${mixin.name}$signature"; |
210 builder = mixinApplicationClasses[name]; | |
211 } | |
212 if (builder == null) { | |
213 builder = new SourceClassBuilder( | |
214 metadata, | |
215 modifiers, | |
204 name, | 216 name, |
205 null, // typeVariables | 217 typeVariables, |
206 supertype, | 218 supertype, |
207 null, // interfaces | 219 interfaces, |
208 new Scope(<String, MemberBuilder>{}, <String, MemberBuilder>{}, | 220 new Scope(<String, MemberBuilder>{}, <String, MemberBuilder>{}, |
209 scope.withTypeVariables(null /* typeVariables */), | 221 scope.withTypeVariables(typeVariables), |
210 isModifiable: false), | 222 isModifiable: false), |
211 new Scope(constructors, null, null, isModifiable: false), | 223 new Scope(constructors, null, null, isModifiable: false), |
212 this, | 224 this, |
213 <ConstructorReferenceBuilder>[], | 225 <ConstructorReferenceBuilder>[], |
214 -1, // charOffset | 226 charOffset, |
215 null, | 227 null, |
216 mixin); | 228 mixin); |
217 addBuilder(name, builder, -1 /* charOffset */); | 229 addBuilder(name, builder, charOffset); |
218 return builder; | 230 if (!isNamed) { |
219 }); | 231 mixinApplicationClasses[name] = builder; |
220 return new KernelNamedTypeBuilder(name, null, -1 /* charOffset */, fileUri) | 232 } |
221 ..bind(builder); | 233 } |
234 return addNamedType(name, <KernelTypeBuilder>[], charOffset) | |
235 ..bind(isNamed ? builder : null); | |
222 } | 236 } |
223 | 237 |
224 KernelTypeBuilder applyMixins(KernelTypeBuilder type, [String name]) { | 238 KernelTypeBuilder applyMixins(KernelTypeBuilder type, |
239 {List<MetadataBuilder> metadata, | |
240 String name, | |
241 String subclassName, | |
242 List<TypeVariableBuilder> typeVariables, | |
243 int modifiers: abstractMask, | |
244 List<KernelTypeBuilder> interfaces, | |
245 int charOffset: -1}) { | |
225 if (type is KernelMixinApplicationBuilder) { | 246 if (type is KernelMixinApplicationBuilder) { |
247 subclassName ??= name; | |
248 List<List<String>> signatureParts = <List<String>>[]; | |
249 Map<String, String> unresolved = <String, String>{}; | |
250 Map<String, String> unresolvedReversed = <String, String>{}; | |
251 int unresolvedCount = 0; | |
252 Map<String, TypeBuilder> freeTypes = <String, TypeBuilder>{}; | |
253 | |
254 if (name == null || type.mixins.length != 1) { | |
255 TypeBuilder last = type.mixins.last; | |
256 | |
257 /// Compute a signature of the type arguments used by the supertype and | |
258 /// mixins. These types are free variables. At this point we can't | |
259 /// trust that the number of type arguments match the type parameters, | |
260 /// so we also need to be able to detect missing type arguments. To do | |
261 /// so, we separate each list of type arguments by `^` and type | |
262 /// arguments by `&`. For example, the mixin `C<S> with M<T, U>` would | |
263 /// look like this: | |
264 /// | |
265 /// ^#U0^#U1&#U2 | |
266 /// | |
267 /// Where `#U0`, `#U1`, and `#U2` are the free variables arising from | |
268 /// `S`, `T`, and `U` respectively. | |
269 /// | |
270 /// As we can resolve any type parameters used at this point, those are | |
271 /// named `#T0` and so forth. This reduces the number of free variables | |
272 /// which is crucial for memory usage and the Dart VM's bootstrap | |
273 /// sequence. | |
274 /// | |
275 /// For example, consider this use of mixin applications: | |
276 /// | |
277 /// class _InternalLinkedHashMap<K, V> extends _HashVMBase | |
278 /// with | |
279 /// MapMixin<K, V>, | |
280 /// _LinkedHashMapMixin<K, V>, | |
281 /// _HashBase, | |
282 /// _OperatorEqualsAndHashCode {} | |
283 /// | |
284 /// In this case, only two variables are free, and we produce this | |
285 /// signature: `^^#T0&#T1^#T0&#T1^^`. Assume another class uses the | |
286 /// sames mixins but with missing type arguments for `MapMixin`, its | |
287 /// signature would be: `^^^#T0&#T1^^`. | |
288 /// | |
289 /// Note that we do not need to compute a signature for a named mixin | |
290 /// application with only one mixin as we don't have to invent a name | |
291 /// for any classes in this situation. | |
292 void analyzeArguments(TypeBuilder type) { | |
293 if (name != null && type == last) { | |
294 // The last mixin of a named mixin application doesn't contribute | |
295 // to free variables. | |
296 return; | |
297 } | |
298 if (type is NamedTypeBuilder) { | |
299 List<String> part = <String>[]; | |
300 for (int i = 0; i < (type.arguments?.length ?? 0); i++) { | |
301 var argument = type.arguments[i]; | |
302 String name; | |
303 if (argument is NamedTypeBuilder) { | |
304 if (argument.builder != null) { | |
305 int index = typeVariables?.indexOf(argument.builder) ?? -1; | |
306 if (index != -1) { | |
307 name = "#T${index}"; | |
308 } | |
309 } else if (argument.arguments == null) { | |
310 name = unresolved[argument.name] ??= "#U${unresolvedCount++}"; | |
311 } | |
312 } | |
313 name ??= "#U${unresolvedCount++}"; | |
314 unresolvedReversed[name] = argument.name; | |
315 freeTypes[name] = argument; | |
316 part.add(name); | |
317 type.arguments[i] = | |
318 new KernelNamedTypeBuilder(name, null, -1, fileUri); | |
319 } | |
320 signatureParts.add(part); | |
321 } | |
322 } | |
323 | |
324 analyzeArguments(type.supertype); | |
325 type.mixins.forEach(analyzeArguments); | |
326 } | |
226 KernelTypeBuilder supertype = type.supertype; | 327 KernelTypeBuilder supertype = type.supertype; |
328 List<List<String>> currentSignatureParts = <List<String>>[]; | |
329 int currentSignatureCount = 0; | |
330 String computeSignature() { | |
331 if (freeTypes.isEmpty) return ""; | |
332 currentSignatureParts.add(signatureParts[currentSignatureCount++]); | |
333 if (currentSignatureParts.any((l) => l.isNotEmpty)) { | |
334 return "^${currentSignatureParts.map((l) => l.join('&')).join('^')}"; | |
335 } else { | |
336 return ""; | |
337 } | |
338 } | |
339 | |
340 Map<String, TypeVariableBuilder> computeTypeVariables() { | |
341 Map<String, TypeVariableBuilder> variables = | |
342 <String, TypeVariableBuilder>{}; | |
343 for (List<String> strings in currentSignatureParts) { | |
344 for (String name in strings) { | |
345 variables[name] ??= addTypeVariable(name, null, -1); | |
346 } | |
347 } | |
348 return variables; | |
349 } | |
350 | |
351 checkArguments(t) { | |
352 for (var argument in t.arguments ?? const []) { | |
353 if (argument.builder == null && argument.name.startsWith("#")) { | |
354 throw "No builder on ${argument.name}"; | |
355 } | |
356 } | |
357 } | |
358 | |
359 computeSignature(); // This combines the supertype with the first mixin. | |
227 for (int i = 0; i < type.mixins.length - 1; i++) { | 360 for (int i = 0; i < type.mixins.length - 1; i++) { |
228 supertype = applyMixin(supertype, type.mixins[i], null); | 361 Set<String> supertypeArguments = new Set<String>(); |
229 } | 362 for (var part in currentSignatureParts) { |
230 return applyMixin(supertype, type.mixins.last, name); | 363 supertypeArguments.addAll(part); |
364 } | |
365 String signature = computeSignature(); | |
366 var variables = computeTypeVariables(); | |
367 if (supertypeArguments.isNotEmpty) { | |
368 supertype = addNamedType( | |
369 supertype.name, | |
370 supertypeArguments.map((n) { | |
371 var t = addNamedType(n, null, -1)..bind(variables[n]); | |
Johnni Winther
2017/05/08 10:05:34
var t = ...
return t;
->
return ...
ahe
2017/05/08 11:13:15
Done.
| |
372 return t; | |
373 }).toList(), | |
374 -1); | |
375 } | |
376 KernelNamedTypeBuilder mixin = type.mixins[i]; | |
377 for (var type in mixin.arguments ?? const []) { | |
378 type.bind(variables[type.name]); | |
379 } | |
380 checkArguments(supertype); | |
381 checkArguments(mixin); | |
382 supertype = applyMixin(supertype, mixin, signature, | |
383 typeVariables: | |
384 new List<TypeVariableBuilder>.from(variables.values)); | |
385 } | |
386 KernelNamedTypeBuilder mixin = type.mixins.last; | |
387 | |
388 Set<String> supertypeArguments = new Set<String>(); | |
389 for (var part in currentSignatureParts) { | |
390 supertypeArguments.addAll(part); | |
391 } | |
392 String signature = name == null ? computeSignature() : ""; | |
393 var variables; | |
394 if (name == null) { | |
395 variables = computeTypeVariables(); | |
396 typeVariables = new List<TypeVariableBuilder>.from(variables.values); | |
397 if (supertypeArguments.isNotEmpty) { | |
398 supertype = addNamedType( | |
399 supertype.name, | |
400 supertypeArguments.map((n) { | |
401 var t = addNamedType(n, null, -1)..bind(variables[n]); | |
402 return t; | |
Johnni Winther
2017/05/08 10:05:34
Ditto
ahe
2017/05/08 11:13:15
Done.
| |
403 }).toList(), | |
404 -1); | |
405 } | |
406 } else { | |
407 if (supertypeArguments.isNotEmpty) { | |
408 supertype = addNamedType(supertype.name, | |
409 supertypeArguments.map((n) => freeTypes[n]).toList(), -1); | |
410 } | |
411 } | |
412 | |
413 if (name == null) { | |
414 for (var type in mixin.arguments ?? const []) { | |
415 type.bind(variables[type.name]); | |
416 } | |
417 } | |
418 checkArguments(supertype); | |
419 checkArguments(mixin); | |
420 | |
421 KernelNamedTypeBuilder t = applyMixin(supertype, mixin, signature, | |
422 metadata: metadata, | |
423 name: name, | |
424 typeVariables: typeVariables, | |
425 modifiers: modifiers, | |
426 interfaces: interfaces, | |
427 charOffset: charOffset); | |
428 if (name == null) { | |
429 var builder = t.builder; | |
430 t = addNamedType( | |
431 t.name, freeTypes.keys.map((k) => freeTypes[k]).toList(), -1); | |
432 if (builder != null) { | |
433 t.bind(builder); | |
434 } | |
435 } | |
436 return t; | |
231 } else { | 437 } else { |
232 return type; | 438 return type; |
233 } | 439 } |
234 } | 440 } |
235 | 441 |
236 void addNamedMixinApplication( | 442 void addNamedMixinApplication( |
237 List<MetadataBuilder> metadata, | 443 List<MetadataBuilder> metadata, |
238 String name, | 444 String name, |
239 List<TypeVariableBuilder> typeVariables, | 445 List<TypeVariableBuilder> typeVariables, |
240 int modifiers, | 446 int modifiers, |
241 KernelTypeBuilder mixinApplication, | 447 KernelTypeBuilder mixinApplication, |
242 List<KernelTypeBuilder> interfaces, | 448 List<KernelTypeBuilder> interfaces, |
243 int charOffset) { | 449 int charOffset) { |
244 // Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`. | 450 // Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`. |
245 var decl = endNestedDeclaration(); | 451 endNestedDeclaration().resolveTypes(typeVariables, this); |
246 KernelTypeBuilder supertype = applyMixins(mixinApplication, name); | 452 KernelNamedTypeBuilder supertype = applyMixins(mixinApplication, |
453 metadata: metadata, | |
454 name: name, | |
455 typeVariables: typeVariables, | |
456 modifiers: modifiers, | |
457 interfaces: interfaces, | |
458 charOffset: charOffset); | |
247 checkTypeVariables(typeVariables, supertype.builder); | 459 checkTypeVariables(typeVariables, supertype.builder); |
248 decl.resolveTypes(typeVariables, this); | |
249 } | 460 } |
250 | 461 |
251 void addField(List<MetadataBuilder> metadata, int modifiers, | 462 void addField(List<MetadataBuilder> metadata, int modifiers, |
252 KernelTypeBuilder type, String name, int charOffset, | 463 KernelTypeBuilder type, String name, int charOffset, |
253 {bool hasInitializer}) { | 464 {bool hasInitializer}) { |
254 addBuilder( | 465 addBuilder( |
255 name, | 466 name, |
256 new KernelFieldBuilder( | 467 new KernelFieldBuilder( |
257 metadata, type, name, modifiers, this, charOffset, | 468 metadata, type, name, modifiers, this, charOffset, |
258 hasInitializer: hasInitializer), | 469 hasInitializer: hasInitializer), |
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
627 int count = boundlessTypeVariables.length; | 838 int count = boundlessTypeVariables.length; |
628 for (KernelTypeVariableBuilder builder in boundlessTypeVariables) { | 839 for (KernelTypeVariableBuilder builder in boundlessTypeVariables) { |
629 builder.finish(this, object); | 840 builder.finish(this, object); |
630 } | 841 } |
631 boundlessTypeVariables.clear(); | 842 boundlessTypeVariables.clear(); |
632 return count; | 843 return count; |
633 } | 844 } |
634 | 845 |
635 @override | 846 @override |
636 void includePart(covariant KernelLibraryBuilder part) { | 847 void includePart(covariant KernelLibraryBuilder part) { |
848 part.mixinApplicationClasses | |
849 .forEach((String name, SourceClassBuilder builder) { | |
850 SourceClassBuilder existing = | |
851 mixinApplicationClasses.putIfAbsent(name, () => builder); | |
852 if (existing != builder) { | |
853 part.scope.local.remove(name); | |
854 } | |
855 }); | |
637 super.includePart(part); | 856 super.includePart(part); |
638 nativeMethods.addAll(part.nativeMethods); | 857 nativeMethods.addAll(part.nativeMethods); |
639 boundlessTypeVariables.addAll(part.boundlessTypeVariables); | 858 boundlessTypeVariables.addAll(part.boundlessTypeVariables); |
640 assert(mixinApplicationClasses.isEmpty); | |
641 } | 859 } |
642 } | 860 } |
OLD | NEW |