| OLD | NEW |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 } |
| OLD | NEW |