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

Side by Side Diff: pkg/compiler/lib/src/universe/world_builder.dart

Issue 2506393002: Enhance precision of recorded instantiation info in ResolutionWorldBuilder (Closed)
Patch Set: Updated cf. comments. Created 4 years, 1 month 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
« no previous file with comments | « pkg/compiler/lib/src/universe/use.dart ('k') | pkg/compiler/lib/src/world.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 universe; 5 library universe;
6 6
7 import 'dart:collection'; 7 import 'dart:collection';
8 8
9 import '../cache_strategy.dart'; 9 import '../cache_strategy.dart';
10 import '../common.dart'; 10 import '../common.dart';
11 import '../common/backend_api.dart' show Backend; 11 import '../common/backend_api.dart' show Backend;
12 import '../common/resolution.dart' show Resolution; 12 import '../common/resolution.dart' show Resolution;
13 import '../compiler.dart' show Compiler; 13 import '../compiler.dart' show Compiler;
14 import '../core_types.dart' show CoreClasses; 14 import '../core_types.dart' show CoreClasses;
15 import '../dart_types.dart'; 15 import '../dart_types.dart';
16 import '../elements/elements.dart'; 16 import '../elements/elements.dart';
17 import '../types/masks.dart' show CommonMasks;
18 import '../universe/class_set.dart' show Instantiation; 17 import '../universe/class_set.dart' show Instantiation;
19 import '../util/enumset.dart';
20 import '../util/util.dart'; 18 import '../util/util.dart';
21 import '../world.dart' show World, ClosedWorld, OpenWorld, WorldImpl; 19 import '../world.dart' show World, ClosedWorld, OpenWorld, WorldImpl;
22 import 'selector.dart' show Selector; 20 import 'selector.dart' show Selector;
23 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; 21 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind;
24 22
25 /// The known constraint on receiver for a dynamic call site. 23 /// The known constraint on receiver for a dynamic call site.
26 /// 24 ///
27 /// This can for instance be used to constrain this dynamic call to `foo` to 25 /// This can for instance be used to constrain this dynamic call to `foo` to
28 /// 'receivers of the exact instance `Bar`': 26 /// 'receivers of the exact instance `Bar`':
29 /// 27 ///
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after
157 155
158 /// Returns `true` if [cls] is considered to be implemented by an 156 /// Returns `true` if [cls] is considered to be implemented by an
159 /// instantiated class, either directly, through subclasses or through 157 /// instantiated class, either directly, through subclasses or through
160 /// subtypes. The latter case only contains spurious information from 158 /// subtypes. The latter case only contains spurious information from
161 /// instantiations through factory constructors and mixins. 159 /// instantiations through factory constructors and mixins.
162 bool isImplemented(ClassElement cls); 160 bool isImplemented(ClassElement cls);
163 161
164 /// Set of all fields that are statically known to be written to. 162 /// Set of all fields that are statically known to be written to.
165 Iterable<Element> get fieldSetters; 163 Iterable<Element> get fieldSetters;
166 164
167 /// Call [f] for all directly or abstractly instantiated classes. 165 /// Call [f] for all classes with instantiated types. This includes the
168 void forEachInstantiatedClass( 166 /// directly and abstractly instantiated classes but also classes whose type
169 f(ClassElement cls, EnumSet<Instantiation> instantiations)); 167 /// arguments are used in live factory constructors.
168 void forEachInstantiatedClass(f(ClassElement cls, InstantiationInfo info));
170 169
171 /// `true` of `Object.runtimeType` is supported. 170 /// `true` of `Object.runtimeType` is supported.
172 bool get hasRuntimeTypeSupport; 171 bool get hasRuntimeTypeSupport;
173 172
174 /// `true` of use of the `dart:isolate` library is supported. 173 /// `true` of use of the `dart:isolate` library is supported.
175 bool get hasIsolateSupport; 174 bool get hasIsolateSupport;
176 175
177 /// `true` of `Function.apply` is supported. 176 /// `true` of `Function.apply` is supported.
178 bool get hasFunctionApplySupport; 177 bool get hasFunctionApplySupport;
179 178
180 /// The [OpenWorld] being created by this world builder. 179 /// The [OpenWorld] being created by this world builder.
181 // TODO(johnniwinther): Merge this with [ResolutionWorldBuilder]. 180 // TODO(johnniwinther): Merge this with [ResolutionWorldBuilder].
182 OpenWorld get openWorld; 181 OpenWorld get openWorld;
183 } 182 }
184 183
184 /// The type and kind of an instantiation registered through
185 /// `ResolutionWorldBuilder.registerTypeInstantiation`.
186 class Instance {
187 final InterfaceType type;
188 final Instantiation kind;
189 final bool isRedirection;
190
191 Instance(this.type, this.kind, {this.isRedirection: false});
192
193 int get hashCode {
194 return Hashing.objectHash(
195 type, Hashing.objectHash(kind, Hashing.objectHash(isRedirection)));
196 }
197
198 bool operator ==(other) {
199 if (identical(this, other)) return true;
200 if (other is! Instance) return false;
201 return type == other.type &&
202 kind == other.kind &&
203 isRedirection == other.isRedirection;
204 }
205
206 String toString() {
207 StringBuffer sb = new StringBuffer();
208 sb.write(type);
209 if (kind == Instantiation.DIRECTLY_INSTANTIATED) {
210 sb.write(' directly');
211 } else if (kind == Instantiation.ABSTRACTLY_INSTANTIATED) {
212 sb.write(' abstractly');
213 } else if (kind == Instantiation.UNINSTANTIATED) {
214 sb.write(' none');
215 }
216 if (isRedirection) {
217 sb.write(' redirect');
218 }
219 return sb.toString();
220 }
221 }
222
223 /// Information about instantiations of a class.
224 class InstantiationInfo {
225 /// A map from constructor of the class to their instantiated types.
226 ///
227 /// For instance
228 ///
229 /// import 'dart:html';
230 ///
231 /// abstract class AbstractClass<S> {
232 /// factory AbstractClass.a() = Class<S>.a;
233 /// factory AbstractClass.b() => new Class<S>.b();
234 /// }
235 /// class Class<T> implements AbstractClass<T> {
236 /// Class.a();
237 /// Class.b();
238 /// factory Class.c() = Class.b<T>;
239 /// }
240 ///
241 ///
242 /// main() {
243 /// new Class.a();
244 /// new Class<int>.a();
245 /// new Class<String>.b();
246 /// new Class<num>.c();
247 /// new AbstractClass<double>.a();
248 /// new AbstractClass<bool>.b();
249 /// new DivElement(); // native instantiation
250 /// }
251 ///
252 /// will generate the mappings
253 ///
254 /// AbstractClass: {
255 /// AbstractClass.a: {
256 /// AbstractClass<double> none, // from `new AbstractClass<double>.a()`
257 /// },
258 /// AbstractClass.b: {
259 /// AbstractClass<bool> none, // from `new AbstractClass<bool>.b()`
260 /// },
261 /// },
262 /// Class: {
263 /// Class.a: {
264 /// Class directly, // from `new Class.a()`
265 /// Class<int> directly, // from `new Class<int>.a()`
266 /// Class<S> directly redirect, // from `factory AbstractClass.a`
267 /// },
268 /// Class.b: {
269 /// Class<String> directly, // from `new Class<String>.b()`
270 /// Class<T> directly redirect, // from `factory Class.c`
271 /// Class<S> directly, // from `factory AbstractClass.b`
272 /// },
273 /// Class.c: {
274 /// Class<num> directly, // from `new Class<num>.c()`
275 /// },
276 /// },
277 /// DivElement: {
278 /// DivElement: {
279 /// DivElement abstractly, // from `new DivElement()`
280 /// },
281 /// }
282 ///
283 /// If the constructor is unknown, for instance for native or mirror usage,
284 /// `null` is used as key.
285 Map<ConstructorElement, Set<Instance>> instantiationMap;
286
287 /// Register [type] as the instantiation [kind] using [constructor].
288 void addInstantiation(
289 ConstructorElement constructor, InterfaceType type, Instantiation kind,
290 {bool isRedirection: false}) {
291 instantiationMap ??= <ConstructorElement, Set<Instance>>{};
292 instantiationMap
293 .putIfAbsent(constructor, () => new Set<Instance>())
294 .add(new Instance(type, kind, isRedirection: isRedirection));
295 switch (kind) {
296 case Instantiation.DIRECTLY_INSTANTIATED:
297 isDirectlyInstantiated = true;
298 break;
299 case Instantiation.ABSTRACTLY_INSTANTIATED:
300 isAbstractlyInstantiated = true;
301 break;
302 case Instantiation.UNINSTANTIATED:
303 break;
304 default:
305 throw new StateError("Instantiation $kind is not allowed.");
306 }
307 }
308
309 /// `true` if the class is either directly or abstractly instantiated.
310 bool get hasInstantiation =>
311 isDirectlyInstantiated || isAbstractlyInstantiated;
312
313 /// `true` if the class is directly instantiated.
314 bool isDirectlyInstantiated = false;
315
316 /// `true` if the class is abstractly instantiated.
317 bool isAbstractlyInstantiated = false;
318
319 String toString() {
320 StringBuffer sb = new StringBuffer();
321 sb.write('InstantiationInfo[');
322 if (instantiationMap != null) {
323 bool needsComma = false;
324 instantiationMap
325 .forEach((ConstructorElement constructor, Set<Instance> set) {
326 if (needsComma) {
327 sb.write(', ');
328 }
329 if (constructor != null) {
330 sb.write(constructor);
331 } else {
332 sb.write('<unknown>');
333 }
334 sb.write(': ');
335 sb.write(set);
336 needsComma = true;
337 });
338 }
339 sb.write(']');
340 return sb.toString();
341 }
342 }
343
185 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { 344 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder {
186 /// The set of all directly instantiated classes, that is, classes with a 345 /// Instantiation information for all classes with instantiated types.
187 /// generative constructor that has been called directly and not only through
188 /// a super-call.
189 /// 346 ///
190 /// Invariant: Elements are declaration elements. 347 /// Invariant: Elements are declaration elements.
191 // TODO(johnniwinther): [_directlyInstantiatedClasses] and 348 final Map<ClassElement, InstantiationInfo> _instantiationInfo =
192 // [_instantiatedTypes] sets should be merged. 349 <ClassElement, InstantiationInfo>{};
193 final Map<ClassElement, EnumSet<Instantiation>> _directlyInstantiatedClasses =
194 <ClassElement, EnumSet<Instantiation>>{};
195
196 /// The set of all directly instantiated types, that is, the types of the
197 /// directly instantiated classes.
198 ///
199 /// See [_directlyInstantiatedClasses].
200 final Set<DartType> _instantiatedTypes = new Set<DartType>();
201 350
202 /// Classes implemented by directly instantiated classes. 351 /// Classes implemented by directly instantiated classes.
203 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); 352 final Set<ClassElement> _implementedClasses = new Set<ClassElement>();
204 353
205 /// The set of all referenced static fields. 354 /// The set of all referenced static fields.
206 /// 355 ///
207 /// Invariant: Elements are declaration elements. 356 /// Invariant: Elements are declaration elements.
208 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); 357 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>();
209 358
210 /** 359 /**
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 _openWorld = new WorldImpl(this, backend, coreClasses, cacheStrategy); 414 _openWorld = new WorldImpl(this, backend, coreClasses, cacheStrategy);
266 } 415 }
267 416
268 OpenWorld get openWorld => _openWorld; 417 OpenWorld get openWorld => _openWorld;
269 418
270 /// All directly instantiated classes, that is, classes with a generative 419 /// All directly instantiated classes, that is, classes with a generative
271 /// constructor that has been called directly and not only through a 420 /// constructor that has been called directly and not only through a
272 /// super-call. 421 /// super-call.
273 // TODO(johnniwinther): Improve semantic precision. 422 // TODO(johnniwinther): Improve semantic precision.
274 Iterable<ClassElement> get directlyInstantiatedClasses { 423 Iterable<ClassElement> get directlyInstantiatedClasses {
275 return _directlyInstantiatedClasses.keys; 424 Set<ClassElement> classes = new Set<ClassElement>();
425 _instantiationInfo.forEach((ClassElement cls, InstantiationInfo info) {
426 if (info.hasInstantiation) {
427 classes.add(cls);
428 }
429 });
430 return classes;
276 } 431 }
277 432
278 /// All directly instantiated types, that is, the types of the directly 433 /// All directly instantiated types, that is, the types of the directly
279 /// instantiated classes. 434 /// instantiated classes.
280 /// 435 ///
281 /// See [directlyInstantiatedClasses]. 436 /// See [directlyInstantiatedClasses].
282 // TODO(johnniwinther): Improve semantic precision. 437 // TODO(johnniwinther): Improve semantic precision.
283 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; 438 Iterable<DartType> get instantiatedTypes {
439 Set<InterfaceType> types = new Set<InterfaceType>();
440 _instantiationInfo.forEach((_, InstantiationInfo info) {
441 if (info.instantiationMap != null) {
442 for (Set<Instance> instances in info.instantiationMap.values) {
443 for (Instance instance in instances) {
444 types.add(instance.type);
445 }
446 }
447 }
448 });
449 return types;
450 }
284 451
285 /// Returns `true` if [cls] is considered to be implemented by an 452 /// Returns `true` if [cls] is considered to be implemented by an
286 /// instantiated class, either directly, through subclasses or through 453 /// instantiated class, either directly, through subclasses or through
287 /// subtypes. The latter case only contains spurious information from 454 /// subtypes. The latter case only contains spurious information from
288 /// instantiations through factory constructors and mixins. 455 /// instantiations through factory constructors and mixins.
289 // TODO(johnniwinther): Improve semantic precision. 456 // TODO(johnniwinther): Improve semantic precision.
290 bool isImplemented(ClassElement cls) { 457 bool isImplemented(ClassElement cls) {
291 return _implementedClasses.contains(cls.declaration); 458 return _implementedClasses.contains(cls.declaration);
292 } 459 }
293 460
294 /// Register [type] as (directly) instantiated. 461 /// Register [type] as (directly) instantiated.
295 /// 462 ///
296 /// If [byMirrors] is `true`, the instantiation is through mirrors. 463 /// If [byMirrors] is `true`, the instantiation is through mirrors.
297 // TODO(johnniwinther): Fully enforce the separation between exact, through 464 // TODO(johnniwinther): Fully enforce the separation between exact, through
298 // subclass and through subtype instantiated types/classes. 465 // subclass and through subtype instantiated types/classes.
299 // TODO(johnniwinther): Support unknown type arguments for generic types. 466 // TODO(johnniwinther): Support unknown type arguments for generic types.
300 void registerTypeInstantiation(InterfaceType type, 467 void registerTypeInstantiation(InterfaceType type,
301 {bool byMirrors: false, 468 {ConstructorElement constructor,
469 bool byMirrors: false,
302 bool isNative: false, 470 bool isNative: false,
471 bool isRedirection: false,
303 void onImplemented(ClassElement cls)}) { 472 void onImplemented(ClassElement cls)}) {
304 _instantiatedTypes.add(type);
305 ClassElement cls = type.element; 473 ClassElement cls = type.element;
474 InstantiationInfo info =
475 _instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo());
476 Instantiation kind = Instantiation.UNINSTANTIATED;
306 if (!cls.isAbstract 477 if (!cls.isAbstract
307 // We can't use the closed-world assumption with native abstract 478 // We can't use the closed-world assumption with native abstract
308 // classes; a native abstract class may have non-abstract subclasses 479 // classes; a native abstract class may have non-abstract subclasses
309 // not declared to the program. Instances of these classes are 480 // not declared to the program. Instances of these classes are
310 // indistinguishable from the abstract class. 481 // indistinguishable from the abstract class.
311 || 482 ||
312 isNative 483 isNative
313 // Likewise, if this registration comes from the mirror system, 484 // Likewise, if this registration comes from the mirror system,
314 // all bets are off. 485 // all bets are off.
315 // TODO(herhut): Track classes required by mirrors seperately. 486 // TODO(herhut): Track classes required by mirrors seperately.
316 || 487 ||
317 byMirrors) { 488 byMirrors) {
318 EnumSet<Instantiation> instantiations = _directlyInstantiatedClasses
319 .putIfAbsent(cls, () => new EnumSet<Instantiation>());
320 if (isNative || byMirrors) { 489 if (isNative || byMirrors) {
321 instantiations.add(Instantiation.ABSTRACTLY_INSTANTIATED); 490 kind = Instantiation.ABSTRACTLY_INSTANTIATED;
322 } else { 491 } else {
323 instantiations.add(Instantiation.DIRECTLY_INSTANTIATED); 492 kind = Instantiation.DIRECTLY_INSTANTIATED;
324 } 493 }
325 } 494 }
495 info.addInstantiation(constructor, type, kind,
496 isRedirection: isRedirection);
326 497
327 // TODO(johnniwinther): Replace this by separate more specific mappings that 498 // TODO(johnniwinther): Use [_instantiationInfo] to compute this information
328 // include the type arguments. 499 // instead.
329 if (_implementedClasses.add(cls)) { 500 if (_implementedClasses.add(cls)) {
330 onImplemented(cls); 501 onImplemented(cls);
331 cls.allSupertypes.forEach((InterfaceType supertype) { 502 cls.allSupertypes.forEach((InterfaceType supertype) {
332 if (_implementedClasses.add(supertype.element)) { 503 if (_implementedClasses.add(supertype.element)) {
333 onImplemented(supertype.element); 504 onImplemented(supertype.element);
334 } 505 }
335 }); 506 });
336 } 507 }
337 } 508 }
338 509
339 @override 510 @override
340 void forEachInstantiatedClass( 511 void forEachInstantiatedClass(f(ClassElement cls, InstantiationInfo info)) {
341 f(ClassElement cls, EnumSet<Instantiation> instantiations)) { 512 _instantiationInfo.forEach(f);
342 _directlyInstantiatedClasses.forEach(f);
343 } 513 }
344 514
345 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, 515 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors,
346 Element member, OpenWorld world) { 516 Element member, OpenWorld world) {
347 if (selectors == null) return false; 517 if (selectors == null) return false;
348 for (Selector selector in selectors.keys) { 518 for (Selector selector in selectors.keys) {
349 if (selector.appliesUnnamed(member)) { 519 if (selector.appliesUnnamed(member)) {
350 SelectorConstraints masks = selectors[selector]; 520 SelectorConstraints masks = selectors[selector];
351 if (masks.applies(member, selector, world)) { 521 if (masks.applies(member, selector, world)) {
352 return true; 522 return true;
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
415 fieldSetters.add(element); 585 fieldSetters.add(element);
416 break; 586 break;
417 case StaticUseKind.SUPER_TEAR_OFF: 587 case StaticUseKind.SUPER_TEAR_OFF:
418 methodsNeedingSuperGetter.add(element); 588 methodsNeedingSuperGetter.add(element);
419 break; 589 break;
420 case StaticUseKind.GENERAL: 590 case StaticUseKind.GENERAL:
421 case StaticUseKind.STATIC_TEAR_OFF: 591 case StaticUseKind.STATIC_TEAR_OFF:
422 case StaticUseKind.FIELD_GET: 592 case StaticUseKind.FIELD_GET:
423 case StaticUseKind.CONSTRUCTOR_INVOKE: 593 case StaticUseKind.CONSTRUCTOR_INVOKE:
424 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: 594 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
595 case StaticUseKind.REDIRECTION:
425 break; 596 break;
426 case StaticUseKind.CLOSURE: 597 case StaticUseKind.CLOSURE:
427 allClosures.add(element); 598 allClosures.add(element);
428 break; 599 break;
429 case StaticUseKind.DIRECT_INVOKE: 600 case StaticUseKind.DIRECT_INVOKE:
430 invariant( 601 invariant(
431 element, 'Direct static use is not supported for resolution.'); 602 element, 'Direct static use is not supported for resolution.');
432 break; 603 break;
433 } 604 }
434 } 605 }
435 606
436 void forgetElement(Element element, Compiler compiler) { 607 void forgetElement(Element element, Compiler compiler) {
437 allClosures.remove(element); 608 allClosures.remove(element);
438 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); 609 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement);
439 closurizedMembers.remove(element); 610 closurizedMembers.remove(element);
440 fieldSetters.remove(element); 611 fieldSetters.remove(element);
441 _directlyInstantiatedClasses.remove(element); 612 _instantiationInfo.remove(element);
442 if (element is ClassElement) {
443 assert(invariant(element, element.thisType.isRaw,
444 message: 'Generic classes not supported (${element.thisType}).'));
445 _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
446 }
447 } 613 }
448 614
449 // TODO(ahe): Replace this method with something that is O(1), for example, 615 // TODO(ahe): Replace this method with something that is O(1), for example,
450 // by using a map. 616 // by using a map.
451 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { 617 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) {
452 // Return new list to guard against concurrent modifications. 618 // Return new list to guard against concurrent modifications.
453 return new List<LocalFunctionElement>.from( 619 return new List<LocalFunctionElement>.from(
454 allClosures.where((LocalFunctionElement closure) { 620 allClosures.where((LocalFunctionElement closure) {
455 return closure.executableContext == element; 621 return closure.executableContext == element;
456 })); 622 }));
(...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after
694 case StaticUseKind.SUPER_TEAR_OFF: 860 case StaticUseKind.SUPER_TEAR_OFF:
695 methodsNeedingSuperGetter.add(element); 861 methodsNeedingSuperGetter.add(element);
696 break; 862 break;
697 case StaticUseKind.SUPER_FIELD_SET: 863 case StaticUseKind.SUPER_FIELD_SET:
698 case StaticUseKind.FIELD_SET: 864 case StaticUseKind.FIELD_SET:
699 case StaticUseKind.GENERAL: 865 case StaticUseKind.GENERAL:
700 case StaticUseKind.CLOSURE: 866 case StaticUseKind.CLOSURE:
701 case StaticUseKind.FIELD_GET: 867 case StaticUseKind.FIELD_GET:
702 case StaticUseKind.CONSTRUCTOR_INVOKE: 868 case StaticUseKind.CONSTRUCTOR_INVOKE:
703 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: 869 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE:
870 case StaticUseKind.REDIRECTION:
704 case StaticUseKind.DIRECT_INVOKE: 871 case StaticUseKind.DIRECT_INVOKE:
705 break; 872 break;
706 } 873 }
707 } 874 }
708 875
709 void forgetElement(Element element, Compiler compiler) { 876 void forgetElement(Element element, Compiler compiler) {
710 _directlyInstantiatedClasses.remove(element); 877 _directlyInstantiatedClasses.remove(element);
711 if (element is ClassElement) { 878 if (element is ClassElement) {
712 assert(invariant(element, element.thisType.isRaw, 879 assert(invariant(element, element.thisType.isRaw,
713 message: 'Generic classes not supported (${element.thisType}).')); 880 message: 'Generic classes not supported (${element.thisType}).'));
714 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); 881 _instantiatedTypes..remove(element.rawType)..remove(element.thisType);
715 } 882 }
716 } 883 }
717 } 884 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/universe/use.dart ('k') | pkg/compiler/lib/src/world.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698