Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(581)

Side by Side Diff: pkg/front_end/lib/src/fasta/kernel/kernel_library_builder.dart

Issue 2862223002: Rewrite mixin application handling in Fasta. (Closed)
Patch Set: Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698