Chromium Code Reviews| 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'; |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 | 157 |
| 158 /// Returns `true` if [cls] is considered to be implemented by an | 158 /// Returns `true` if [cls] is considered to be implemented by an |
| 159 /// instantiated class, either directly, through subclasses or through | 159 /// instantiated class, either directly, through subclasses or through |
| 160 /// subtypes. The latter case only contains spurious information from | 160 /// subtypes. The latter case only contains spurious information from |
| 161 /// instantiations through factory constructors and mixins. | 161 /// instantiations through factory constructors and mixins. |
| 162 bool isImplemented(ClassElement cls); | 162 bool isImplemented(ClassElement cls); |
| 163 | 163 |
| 164 /// Set of all fields that are statically known to be written to. | 164 /// Set of all fields that are statically known to be written to. |
| 165 Iterable<Element> get fieldSetters; | 165 Iterable<Element> get fieldSetters; |
| 166 | 166 |
| 167 /// Call [f] for all directly or abstractly instantiated classes. | 167 /// Call [f] for all classes with instantiated types. This includes the |
| 168 void forEachInstantiatedClass( | 168 /// directly and abstractly instantiated classes but also classes whose type |
| 169 f(ClassElement cls, EnumSet<Instantiation> instantiations)); | 169 /// arguments are used in live factory constructors. |
| 170 void forEachInstantiatedClass(f(ClassElement cls, InstantiationInfo info)); | |
| 170 | 171 |
| 171 /// `true` of `Object.runtimeType` is supported. | 172 /// `true` of `Object.runtimeType` is supported. |
| 172 bool get hasRuntimeTypeSupport; | 173 bool get hasRuntimeTypeSupport; |
| 173 | 174 |
| 174 /// `true` of use of the `dart:isolate` library is supported. | 175 /// `true` of use of the `dart:isolate` library is supported. |
| 175 bool get hasIsolateSupport; | 176 bool get hasIsolateSupport; |
| 176 | 177 |
| 177 /// `true` of `Function.apply` is supported. | 178 /// `true` of `Function.apply` is supported. |
| 178 bool get hasFunctionApplySupport; | 179 bool get hasFunctionApplySupport; |
| 179 | 180 |
| 180 /// The [OpenWorld] being created by this world builder. | 181 /// The [OpenWorld] being created by this world builder. |
| 181 // TODO(johnniwinther): Merge this with [ResolutionWorldBuilder]. | 182 // TODO(johnniwinther): Merge this with [ResolutionWorldBuilder]. |
| 182 OpenWorld get openWorld; | 183 OpenWorld get openWorld; |
| 183 } | 184 } |
| 184 | 185 |
| 186 /// The type and kind of a register instantiation. | |
|
Harry Terkelsen
2016/11/18 00:11:35
what do you mean by "register instantiation"?
Johnni Winther
2016/11/18 09:52:49
register -> registered
| |
| 187 class Instance { | |
| 188 final InterfaceType type; | |
| 189 final Instantiation kind; | |
| 190 final bool isRedirection; | |
| 191 | |
| 192 Instance(this.type, this.kind, {this.isRedirection: false}); | |
| 193 | |
| 194 int get hashCode { | |
| 195 return Hashing.objectHash( | |
| 196 type, Hashing.objectHash(kind, Hashing.objectHash(isRedirection))); | |
| 197 } | |
| 198 | |
| 199 bool operator ==(other) { | |
| 200 if (identical(this, other)) return true; | |
| 201 if (other is! Instance) return false; | |
| 202 return type == other.type && | |
| 203 kind == other.kind && | |
| 204 isRedirection == other.isRedirection; | |
| 205 } | |
| 206 | |
| 207 String toString() { | |
| 208 StringBuffer sb = new StringBuffer(); | |
| 209 sb.write(type); | |
| 210 if (kind == Instantiation.DIRECTLY_INSTANTIATED) { | |
| 211 sb.write(' directly'); | |
| 212 } else if (kind == Instantiation.ABSTRACTLY_INSTANTIATED) { | |
| 213 sb.write(' abstractly'); | |
| 214 } | |
| 215 if (isRedirection) { | |
| 216 sb.write(' redirect'); | |
| 217 } | |
| 218 return sb.toString(); | |
| 219 } | |
| 220 } | |
| 221 | |
| 222 /// Information about instantiations of a class. | |
| 223 class InstantiationInfo { | |
| 224 /// A map from constructor of the class to their instantiated types. | |
| 225 /// | |
| 226 /// For instance | |
| 227 /// | |
| 228 /// class Class<T> { | |
| 229 /// Class.a(); | |
| 230 /// Class.b(); | |
| 231 /// Class.c() = Class.b<T>; | |
| 232 /// } | |
| 233 /// | |
| 234 /// main() { | |
| 235 /// new Class.a(), | |
| 236 /// new Class<int>.a(), | |
| 237 /// new Class<String>.b() | |
| 238 /// new Class<num>.c() | |
| 239 /// } | |
| 240 /// | |
| 241 /// will generate the map | |
| 242 /// | |
| 243 /// { | |
| 244 /// Class.a: { Class directly, Class<int> directly }, | |
| 245 /// Class.b: { Class<String> directly, Class<T> directly redirect }, | |
| 246 /// Class.c: { Class<num> directly }, | |
| 247 /// } | |
|
Harry Terkelsen
2016/11/18 00:11:35
consider also giving an example of a class that is
Johnni Winther
2016/11/18 09:52:49
Done.
| |
| 248 /// | |
| 249 /// If the constructor is unknown, for instance for native or mirror usage, | |
| 250 /// `null` is used as key. | |
| 251 Map<ConstructorElement, Set<Instance>> instantiationMap; | |
| 252 | |
| 253 /// Register [type] as the instantiation [kind] using [constructor]. | |
| 254 void addInstantiation( | |
| 255 ConstructorElement constructor, InterfaceType type, Instantiation kind, | |
| 256 {bool isRedirection: false}) { | |
| 257 instantiationMap ??= new Maplet<ConstructorElement, Set<Instance>>(); | |
|
Harry Terkelsen
2016/11/18 00:11:35
are maplets still better than maps? I think there
Johnni Winther
2016/11/18 09:52:49
Changed.
| |
| 258 instantiationMap | |
| 259 .putIfAbsent(constructor, () => new Setlet<Instance>()) | |
| 260 .add(new Instance(type, kind, isRedirection: isRedirection)); | |
| 261 switch (kind) { | |
| 262 case Instantiation.DIRECTLY_INSTANTIATED: | |
| 263 isDirectlyInstantiated = true; | |
| 264 break; | |
| 265 case Instantiation.ABSTRACTLY_INSTANTIATED: | |
| 266 isAbstractlyInstantiated = true; | |
| 267 break; | |
| 268 case Instantiation.UNINSTANTIATED: | |
| 269 break; | |
| 270 default: | |
| 271 throw new StateError("Instantiation $kind is not allowed."); | |
| 272 } | |
| 273 } | |
| 274 | |
| 275 /// `true` if the class is either directly or abstractly instantiated. | |
| 276 bool get hasInstantiation => | |
| 277 isDirectlyInstantiated || isAbstractlyInstantiated; | |
| 278 | |
| 279 /// `true` if the class is directly instantiated. | |
| 280 bool isDirectlyInstantiated = false; | |
| 281 | |
| 282 /// `true` if the class is abstractly instantiated. | |
| 283 bool isAbstractlyInstantiated = false; | |
| 284 | |
| 285 String toString() { | |
| 286 StringBuffer sb = new StringBuffer(); | |
| 287 sb.write('InstantiationInfo['); | |
| 288 if (instantiationMap != null) { | |
| 289 bool needsComma = false; | |
| 290 instantiationMap | |
| 291 .forEach((ConstructorElement constructor, Set<Instance> set) { | |
| 292 if (needsComma) { | |
| 293 sb.write(', '); | |
| 294 } | |
| 295 if (constructor != null) { | |
| 296 sb.write(constructor); | |
| 297 } else { | |
| 298 sb.write('<unknown>'); | |
| 299 } | |
| 300 sb.write(': '); | |
| 301 sb.write(set); | |
| 302 needsComma = true; | |
| 303 }); | |
| 304 } | |
| 305 sb.write(']'); | |
| 306 return sb.toString(); | |
| 307 } | |
| 308 } | |
| 309 | |
| 185 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { | 310 class ResolutionWorldBuilderImpl implements ResolutionWorldBuilder { |
| 186 /// The set of all directly instantiated classes, that is, classes with a | 311 /// 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 /// | 312 /// |
| 190 /// Invariant: Elements are declaration elements. | 313 /// Invariant: Elements are declaration elements. |
| 191 // TODO(johnniwinther): [_directlyInstantiatedClasses] and | 314 final Map<ClassElement, InstantiationInfo> _instantiationInfo = |
| 192 // [_instantiatedTypes] sets should be merged. | 315 <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 | 316 |
| 202 /// Classes implemented by directly instantiated classes. | 317 /// Classes implemented by directly instantiated classes. |
| 203 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); | 318 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); |
| 204 | 319 |
| 205 /// The set of all referenced static fields. | 320 /// The set of all referenced static fields. |
| 206 /// | 321 /// |
| 207 /// Invariant: Elements are declaration elements. | 322 /// Invariant: Elements are declaration elements. |
| 208 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); | 323 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); |
| 209 | 324 |
| 210 /** | 325 /** |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 265 _openWorld = new WorldImpl(this, backend, coreClasses, cacheStrategy); | 380 _openWorld = new WorldImpl(this, backend, coreClasses, cacheStrategy); |
| 266 } | 381 } |
| 267 | 382 |
| 268 OpenWorld get openWorld => _openWorld; | 383 OpenWorld get openWorld => _openWorld; |
| 269 | 384 |
| 270 /// All directly instantiated classes, that is, classes with a generative | 385 /// All directly instantiated classes, that is, classes with a generative |
| 271 /// constructor that has been called directly and not only through a | 386 /// constructor that has been called directly and not only through a |
| 272 /// super-call. | 387 /// super-call. |
| 273 // TODO(johnniwinther): Improve semantic precision. | 388 // TODO(johnniwinther): Improve semantic precision. |
| 274 Iterable<ClassElement> get directlyInstantiatedClasses { | 389 Iterable<ClassElement> get directlyInstantiatedClasses { |
| 275 return _directlyInstantiatedClasses.keys; | 390 Set<ClassElement> classes = new Set<ClassElement>(); |
| 391 _instantiationInfo.forEach((ClassElement cls, InstantiationInfo info) { | |
| 392 if (info.hasInstantiation) { | |
| 393 classes.add(cls); | |
| 394 } | |
| 395 }); | |
| 396 return classes; | |
| 276 } | 397 } |
| 277 | 398 |
| 278 /// All directly instantiated types, that is, the types of the directly | 399 /// All directly instantiated types, that is, the types of the directly |
| 279 /// instantiated classes. | 400 /// instantiated classes. |
| 280 /// | 401 /// |
| 281 /// See [directlyInstantiatedClasses]. | 402 /// See [directlyInstantiatedClasses]. |
| 282 // TODO(johnniwinther): Improve semantic precision. | 403 // TODO(johnniwinther): Improve semantic precision. |
| 283 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; | 404 Iterable<DartType> get instantiatedTypes { |
| 405 Set<InterfaceType> types = new Set<InterfaceType>(); | |
| 406 _instantiationInfo.forEach((_, InstantiationInfo info) { | |
| 407 if (info.instantiationMap != null) { | |
| 408 for (Set<Instance> instances in info.instantiationMap.values) { | |
| 409 for (Instance instance in instances) { | |
| 410 types.add(instance.type); | |
| 411 } | |
| 412 } | |
| 413 } | |
| 414 }); | |
| 415 return types; | |
| 416 } | |
| 284 | 417 |
| 285 /// Returns `true` if [cls] is considered to be implemented by an | 418 /// Returns `true` if [cls] is considered to be implemented by an |
| 286 /// instantiated class, either directly, through subclasses or through | 419 /// instantiated class, either directly, through subclasses or through |
| 287 /// subtypes. The latter case only contains spurious information from | 420 /// subtypes. The latter case only contains spurious information from |
| 288 /// instantiations through factory constructors and mixins. | 421 /// instantiations through factory constructors and mixins. |
| 289 // TODO(johnniwinther): Improve semantic precision. | 422 // TODO(johnniwinther): Improve semantic precision. |
| 290 bool isImplemented(ClassElement cls) { | 423 bool isImplemented(ClassElement cls) { |
| 291 return _implementedClasses.contains(cls.declaration); | 424 return _implementedClasses.contains(cls.declaration); |
| 292 } | 425 } |
| 293 | 426 |
| 294 /// Register [type] as (directly) instantiated. | 427 /// Register [type] as (directly) instantiated. |
| 295 /// | 428 /// |
| 296 /// If [byMirrors] is `true`, the instantiation is through mirrors. | 429 /// If [byMirrors] is `true`, the instantiation is through mirrors. |
| 297 // TODO(johnniwinther): Fully enforce the separation between exact, through | 430 // TODO(johnniwinther): Fully enforce the separation between exact, through |
| 298 // subclass and through subtype instantiated types/classes. | 431 // subclass and through subtype instantiated types/classes. |
| 299 // TODO(johnniwinther): Support unknown type arguments for generic types. | 432 // TODO(johnniwinther): Support unknown type arguments for generic types. |
| 300 void registerTypeInstantiation(InterfaceType type, | 433 void registerTypeInstantiation(InterfaceType type, |
| 301 {bool byMirrors: false, | 434 {ConstructorElement constructor, |
| 435 bool byMirrors: false, | |
| 302 bool isNative: false, | 436 bool isNative: false, |
| 437 bool isRedirection: false, | |
| 303 void onImplemented(ClassElement cls)}) { | 438 void onImplemented(ClassElement cls)}) { |
| 304 _instantiatedTypes.add(type); | |
| 305 ClassElement cls = type.element; | 439 ClassElement cls = type.element; |
| 440 InstantiationInfo info = | |
| 441 _instantiationInfo.putIfAbsent(cls, () => new InstantiationInfo()); | |
| 442 Instantiation kind = Instantiation.UNINSTANTIATED; | |
| 306 if (!cls.isAbstract | 443 if (!cls.isAbstract |
| 307 // We can't use the closed-world assumption with native abstract | 444 // We can't use the closed-world assumption with native abstract |
| 308 // classes; a native abstract class may have non-abstract subclasses | 445 // classes; a native abstract class may have non-abstract subclasses |
| 309 // not declared to the program. Instances of these classes are | 446 // not declared to the program. Instances of these classes are |
| 310 // indistinguishable from the abstract class. | 447 // indistinguishable from the abstract class. |
| 311 || | 448 || |
| 312 isNative | 449 isNative |
| 313 // Likewise, if this registration comes from the mirror system, | 450 // Likewise, if this registration comes from the mirror system, |
| 314 // all bets are off. | 451 // all bets are off. |
| 315 // TODO(herhut): Track classes required by mirrors seperately. | 452 // TODO(herhut): Track classes required by mirrors seperately. |
| 316 || | 453 || |
| 317 byMirrors) { | 454 byMirrors) { |
| 318 EnumSet<Instantiation> instantiations = _directlyInstantiatedClasses | |
| 319 .putIfAbsent(cls, () => new EnumSet<Instantiation>()); | |
| 320 if (isNative || byMirrors) { | 455 if (isNative || byMirrors) { |
| 321 instantiations.add(Instantiation.ABSTRACTLY_INSTANTIATED); | 456 kind = Instantiation.ABSTRACTLY_INSTANTIATED; |
| 322 } else { | 457 } else { |
| 323 instantiations.add(Instantiation.DIRECTLY_INSTANTIATED); | 458 kind = Instantiation.DIRECTLY_INSTANTIATED; |
| 324 } | 459 } |
| 325 } | 460 } |
| 461 info.addInstantiation(constructor, type, kind, | |
| 462 isRedirection: isRedirection); | |
| 326 | 463 |
| 327 // TODO(johnniwinther): Replace this by separate more specific mappings that | 464 // TODO(johnniwinther): Use [_instantiationInfo] to compute this information |
| 328 // include the type arguments. | 465 // instead. |
| 329 if (_implementedClasses.add(cls)) { | 466 if (_implementedClasses.add(cls)) { |
| 330 onImplemented(cls); | 467 onImplemented(cls); |
| 331 cls.allSupertypes.forEach((InterfaceType supertype) { | 468 cls.allSupertypes.forEach((InterfaceType supertype) { |
| 332 if (_implementedClasses.add(supertype.element)) { | 469 if (_implementedClasses.add(supertype.element)) { |
| 333 onImplemented(supertype.element); | 470 onImplemented(supertype.element); |
| 334 } | 471 } |
| 335 }); | 472 }); |
| 336 } | 473 } |
| 337 } | 474 } |
| 338 | 475 |
| 339 @override | 476 @override |
| 340 void forEachInstantiatedClass( | 477 void forEachInstantiatedClass(f(ClassElement cls, InstantiationInfo info)) { |
| 341 f(ClassElement cls, EnumSet<Instantiation> instantiations)) { | 478 _instantiationInfo.forEach(f); |
| 342 _directlyInstantiatedClasses.forEach(f); | |
| 343 } | 479 } |
| 344 | 480 |
| 345 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | 481 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, |
| 346 Element member, OpenWorld world) { | 482 Element member, OpenWorld world) { |
| 347 if (selectors == null) return false; | 483 if (selectors == null) return false; |
| 348 for (Selector selector in selectors.keys) { | 484 for (Selector selector in selectors.keys) { |
| 349 if (selector.appliesUnnamed(member)) { | 485 if (selector.appliesUnnamed(member)) { |
| 350 SelectorConstraints masks = selectors[selector]; | 486 SelectorConstraints masks = selectors[selector]; |
| 351 if (masks.applies(member, selector, world)) { | 487 if (masks.applies(member, selector, world)) { |
| 352 return true; | 488 return true; |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 415 fieldSetters.add(element); | 551 fieldSetters.add(element); |
| 416 break; | 552 break; |
| 417 case StaticUseKind.SUPER_TEAR_OFF: | 553 case StaticUseKind.SUPER_TEAR_OFF: |
| 418 methodsNeedingSuperGetter.add(element); | 554 methodsNeedingSuperGetter.add(element); |
| 419 break; | 555 break; |
| 420 case StaticUseKind.GENERAL: | 556 case StaticUseKind.GENERAL: |
| 421 case StaticUseKind.STATIC_TEAR_OFF: | 557 case StaticUseKind.STATIC_TEAR_OFF: |
| 422 case StaticUseKind.FIELD_GET: | 558 case StaticUseKind.FIELD_GET: |
| 423 case StaticUseKind.CONSTRUCTOR_INVOKE: | 559 case StaticUseKind.CONSTRUCTOR_INVOKE: |
| 424 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 560 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 561 case StaticUseKind.REDIRECTION: | |
| 425 break; | 562 break; |
| 426 case StaticUseKind.CLOSURE: | 563 case StaticUseKind.CLOSURE: |
| 427 allClosures.add(element); | 564 allClosures.add(element); |
| 428 break; | 565 break; |
| 429 case StaticUseKind.DIRECT_INVOKE: | 566 case StaticUseKind.DIRECT_INVOKE: |
| 430 invariant( | 567 invariant( |
| 431 element, 'Direct static use is not supported for resolution.'); | 568 element, 'Direct static use is not supported for resolution.'); |
| 432 break; | 569 break; |
| 433 } | 570 } |
| 434 } | 571 } |
| 435 | 572 |
| 436 void forgetElement(Element element, Compiler compiler) { | 573 void forgetElement(Element element, Compiler compiler) { |
| 437 allClosures.remove(element); | 574 allClosures.remove(element); |
| 438 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); | 575 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); |
| 439 closurizedMembers.remove(element); | 576 closurizedMembers.remove(element); |
| 440 fieldSetters.remove(element); | 577 fieldSetters.remove(element); |
| 441 _directlyInstantiatedClasses.remove(element); | 578 _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 } | 579 } |
| 448 | 580 |
| 449 // TODO(ahe): Replace this method with something that is O(1), for example, | 581 // TODO(ahe): Replace this method with something that is O(1), for example, |
| 450 // by using a map. | 582 // by using a map. |
| 451 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | 583 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { |
| 452 // Return new list to guard against concurrent modifications. | 584 // Return new list to guard against concurrent modifications. |
| 453 return new List<LocalFunctionElement>.from( | 585 return new List<LocalFunctionElement>.from( |
| 454 allClosures.where((LocalFunctionElement closure) { | 586 allClosures.where((LocalFunctionElement closure) { |
| 455 return closure.executableContext == element; | 587 return closure.executableContext == element; |
| 456 })); | 588 })); |
| (...skipping 237 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 694 case StaticUseKind.SUPER_TEAR_OFF: | 826 case StaticUseKind.SUPER_TEAR_OFF: |
| 695 methodsNeedingSuperGetter.add(element); | 827 methodsNeedingSuperGetter.add(element); |
| 696 break; | 828 break; |
| 697 case StaticUseKind.SUPER_FIELD_SET: | 829 case StaticUseKind.SUPER_FIELD_SET: |
| 698 case StaticUseKind.FIELD_SET: | 830 case StaticUseKind.FIELD_SET: |
| 699 case StaticUseKind.GENERAL: | 831 case StaticUseKind.GENERAL: |
| 700 case StaticUseKind.CLOSURE: | 832 case StaticUseKind.CLOSURE: |
| 701 case StaticUseKind.FIELD_GET: | 833 case StaticUseKind.FIELD_GET: |
| 702 case StaticUseKind.CONSTRUCTOR_INVOKE: | 834 case StaticUseKind.CONSTRUCTOR_INVOKE: |
| 703 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: | 835 case StaticUseKind.CONST_CONSTRUCTOR_INVOKE: |
| 836 case StaticUseKind.REDIRECTION: | |
| 704 case StaticUseKind.DIRECT_INVOKE: | 837 case StaticUseKind.DIRECT_INVOKE: |
| 705 break; | 838 break; |
| 706 } | 839 } |
| 707 } | 840 } |
| 708 | 841 |
| 709 void forgetElement(Element element, Compiler compiler) { | 842 void forgetElement(Element element, Compiler compiler) { |
| 710 _directlyInstantiatedClasses.remove(element); | 843 _directlyInstantiatedClasses.remove(element); |
| 711 if (element is ClassElement) { | 844 if (element is ClassElement) { |
| 712 assert(invariant(element, element.thisType.isRaw, | 845 assert(invariant(element, element.thisType.isRaw, |
| 713 message: 'Generic classes not supported (${element.thisType}).')); | 846 message: 'Generic classes not supported (${element.thisType}).')); |
| 714 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); | 847 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); |
| 715 } | 848 } |
| 716 } | 849 } |
| 717 } | 850 } |
| OLD | NEW |