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 '../common.dart'; | 9 import '../common.dart'; |
10 import '../compiler.dart' show Compiler; | 10 import '../compiler.dart' show Compiler; |
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
100 /// Create a [UniverseSelectorConstraints] to represent the global receiver | 100 /// Create a [UniverseSelectorConstraints] to represent the global receiver |
101 /// constraints for dynamic call sites with [selector]. | 101 /// constraints for dynamic call sites with [selector]. |
102 UniverseSelectorConstraints createSelectorConstraints(Selector selector); | 102 UniverseSelectorConstraints createSelectorConstraints(Selector selector); |
103 } | 103 } |
104 | 104 |
105 /// The [Universe] is an auxiliary class used in the process of computing the | 105 /// The [Universe] is an auxiliary class used in the process of computing the |
106 /// [ClassWorld]. The concepts here and in [ClassWorld] are very similar -- in | 106 /// [ClassWorld]. The concepts here and in [ClassWorld] are very similar -- in |
107 /// the same way that the "universe expands" you can think of this as a mutable | 107 /// the same way that the "universe expands" you can think of this as a mutable |
108 /// world that is expanding as we visit and discover parts of the program. | 108 /// world that is expanding as we visit and discover parts of the program. |
109 /// TODO(sigmund): rename to "growing/expanding/mutable world"? | 109 /// TODO(sigmund): rename to "growing/expanding/mutable world"? |
110 class Universe { | 110 abstract class Universe { |
111 /// All directly instantiated classes, that is, classes with a generative | |
112 /// constructor that has been called directly and not only through a | |
113 /// super-call. | |
114 // TODO(johnniwinther): Improve semantic precision. | |
115 Iterable<ClassElement> get directlyInstantiatedClasses; | |
116 | |
117 /// All types that are checked either through is, as or checked mode checks. | |
118 Iterable<DartType> get isChecks; | |
119 | |
120 /// Registers that [type] is checked in this universe. The unaliased type is | |
121 /// returned. | |
122 DartType registerIsCheck(DartType type, Compiler compiler); | |
123 | |
124 /// All directly instantiated types, that is, the types of the directly | |
125 /// instantiated classes. | |
126 // TODO(johnniwinther): Improve semantic precision. | |
127 Iterable<DartType> get instantiatedTypes; | |
128 | |
129 /// Returns `true` if [member] is invoked as a setter. | |
130 bool hasInvokedSetter(Element member, World world); | |
131 } | |
132 | |
133 abstract class ResolutionUniverse implements Universe { | |
134 /// Set of (live) local functions (closures) whose signatures reference type | |
135 /// variables. | |
136 /// | |
137 /// A live function is one whose enclosing member function has been enqueued. | |
138 Set<Element> get closuresWithFreeTypeVariables; | |
Harry Terkelsen
2016/09/19 18:07:10
how come some of these collections are sets and so
Johnni Winther
2016/09/21 09:13:04
This is added to from the outside. Will be changed
| |
139 | |
140 /// Set of (live) `call` methods whose signatures reference type variables. | |
141 /// | |
142 /// A live `call` method is one whose enclosing class has been instantiated. | |
143 Iterable<Element> get callMethodsWithFreeTypeVariables; | |
144 | |
145 /// Set of all closures in the program. Used by the mirror tracking system | |
146 /// to find all live closure instances. | |
147 Iterable<LocalFunctionElement> get allClosures; | |
148 | |
149 /// Set of methods in instantiated classes that are potentially closurized. | |
150 Iterable<Element> get closurizedMembers; | |
151 | |
152 /// Returns `true` if [cls] is considered to be implemented by an | |
153 /// instantiated class, either directly, through subclasses or through | |
154 /// subtypes. The latter case only contains spurious information from | |
155 /// instantiations through factory constructors and mixins. | |
156 // TODO(johnniwinther): Improve semantic precision. | |
Siggi Cherem (dart-lang)
2016/09/06 17:57:43
remove TODO (it's already in the impl class below)
Johnni Winther
2016/09/21 09:13:04
Done.
| |
157 bool isImplemented(ClassElement cls); | |
158 | |
159 /// Set of all fields that are statically known to be written to. | |
160 Iterable<Element> get fieldSetters; | |
161 } | |
162 | |
163 class ResolutionUniverseImpl implements ResolutionUniverse { | |
111 /// The set of all directly instantiated classes, that is, classes with a | 164 /// The set of all directly instantiated classes, that is, classes with a |
112 /// generative constructor that has been called directly and not only through | 165 /// generative constructor that has been called directly and not only through |
113 /// a super-call. | 166 /// a super-call. |
114 /// | 167 /// |
115 /// Invariant: Elements are declaration elements. | 168 /// Invariant: Elements are declaration elements. |
116 // TODO(johnniwinther): [_directlyInstantiatedClasses] and | 169 // TODO(johnniwinther): [_directlyInstantiatedClasses] and |
117 // [_instantiatedTypes] sets should be merged. | 170 // [_instantiatedTypes] sets should be merged. |
118 final Set<ClassElement> _directlyInstantiatedClasses = | 171 final Set<ClassElement> _directlyInstantiatedClasses = |
119 new Set<ClassElement>(); | 172 new Set<ClassElement>(); |
120 | 173 |
121 /// The set of all directly instantiated types, that is, the types of the | 174 /// The set of all directly instantiated types, that is, the types of the |
122 /// directly instantiated classes. | 175 /// directly instantiated classes. |
123 /// | 176 /// |
124 /// See [_directlyInstantiatedClasses]. | 177 /// See [_directlyInstantiatedClasses]. |
125 final Set<DartType> _instantiatedTypes = new Set<DartType>(); | 178 final Set<DartType> _instantiatedTypes = new Set<DartType>(); |
126 | 179 |
127 /// Classes implemented by directly instantiated classes. | 180 /// Classes implemented by directly instantiated classes. |
128 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); | 181 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); |
129 | 182 |
130 /// The set of all referenced static fields. | 183 /// The set of all referenced static fields. |
131 /// | 184 /// |
132 /// Invariant: Elements are declaration elements. | 185 /// Invariant: Elements are declaration elements. |
133 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); | 186 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); |
134 | 187 |
135 /** | 188 /** |
136 * Documentation wanted -- johnniwinther | 189 * Documentation wanted -- johnniwinther |
137 * | 190 * |
138 * Invariant: Elements are declaration elements. | 191 * Invariant: Elements are declaration elements. |
139 */ | 192 */ |
140 final Set<FunctionElement> staticFunctionsNeedingGetter = | |
141 new Set<FunctionElement>(); | |
142 final Set<FunctionElement> methodsNeedingSuperGetter = | 193 final Set<FunctionElement> methodsNeedingSuperGetter = |
143 new Set<FunctionElement>(); | 194 new Set<FunctionElement>(); |
144 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = | 195 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = |
145 <String, Map<Selector, SelectorConstraints>>{}; | 196 <String, Map<Selector, SelectorConstraints>>{}; |
146 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = | 197 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = |
147 <String, Map<Selector, SelectorConstraints>>{}; | 198 <String, Map<Selector, SelectorConstraints>>{}; |
148 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = | 199 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = |
149 <String, Map<Selector, SelectorConstraints>>{}; | 200 <String, Map<Selector, SelectorConstraints>>{}; |
150 | 201 |
151 /** | 202 /// Fields set. |
152 * Fields accessed. Currently only the codegen knows this | |
153 * information. The resolver is too conservative when seeing a | |
154 * getter and only registers an invoked getter. | |
155 */ | |
156 final Set<Element> fieldGetters = new Set<Element>(); | |
157 | |
158 /** | |
159 * Fields set. See comment in [fieldGetters]. | |
160 */ | |
161 final Set<Element> fieldSetters = new Set<Element>(); | 203 final Set<Element> fieldSetters = new Set<Element>(); |
162 final Set<DartType> isChecks = new Set<DartType>(); | 204 final Set<DartType> isChecks = new Set<DartType>(); |
163 | 205 |
164 /** | 206 /** |
165 * Set of (live) [:call:] methods whose signatures reference type variables. | 207 * Set of (live) [:call:] methods whose signatures reference type variables. |
166 * | 208 * |
167 * A live [:call:] method is one whose enclosing class has been instantiated. | 209 * A live [:call:] method is one whose enclosing class has been instantiated. |
168 */ | 210 */ |
169 final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>(); | 211 final Set<Element> callMethodsWithFreeTypeVariables = new Set<Element>(); |
170 | 212 |
(...skipping 12 matching lines...) Expand all Loading... | |
183 final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>(); | 225 final Set<LocalFunctionElement> allClosures = new Set<LocalFunctionElement>(); |
184 | 226 |
185 /** | 227 /** |
186 * Set of methods in instantiated classes that are potentially | 228 * Set of methods in instantiated classes that are potentially |
187 * closurized. | 229 * closurized. |
188 */ | 230 */ |
189 final Set<Element> closurizedMembers = new Set<Element>(); | 231 final Set<Element> closurizedMembers = new Set<Element>(); |
190 | 232 |
191 final SelectorConstraintsStrategy selectorConstraintsStrategy; | 233 final SelectorConstraintsStrategy selectorConstraintsStrategy; |
192 | 234 |
193 Universe(this.selectorConstraintsStrategy); | 235 ResolutionUniverseImpl(this.selectorConstraintsStrategy); |
194 | 236 |
195 /// All directly instantiated classes, that is, classes with a generative | 237 /// All directly instantiated classes, that is, classes with a generative |
196 /// constructor that has been called directly and not only through a | 238 /// constructor that has been called directly and not only through a |
197 /// super-call. | 239 /// super-call. |
198 // TODO(johnniwinther): Improve semantic precision. | 240 // TODO(johnniwinther): Improve semantic precision. |
199 Iterable<ClassElement> get directlyInstantiatedClasses { | 241 Iterable<ClassElement> get directlyInstantiatedClasses { |
200 return _directlyInstantiatedClasses; | 242 return _directlyInstantiatedClasses; |
201 } | 243 } |
202 | 244 |
203 /// All directly instantiated types, that is, the types of the directly | 245 /// All directly instantiated types, that is, the types of the directly |
(...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
300 ReceiverConstraint mask = dynamicUse.mask; | 342 ReceiverConstraint mask = dynamicUse.mask; |
301 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( | 343 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( |
302 name, () => new Maplet<Selector, SelectorConstraints>()); | 344 name, () => new Maplet<Selector, SelectorConstraints>()); |
303 UniverseSelectorConstraints constraints = | 345 UniverseSelectorConstraints constraints = |
304 selectors.putIfAbsent(selector, () { | 346 selectors.putIfAbsent(selector, () { |
305 return selectorConstraintsStrategy.createSelectorConstraints(selector); | 347 return selectorConstraintsStrategy.createSelectorConstraints(selector); |
306 }); | 348 }); |
307 return constraints.addReceiverConstraint(mask); | 349 return constraints.addReceiverConstraint(mask); |
308 } | 350 } |
309 | 351 |
352 DartType registerIsCheck(DartType type, Compiler compiler) { | |
353 type.computeUnaliased(compiler.resolution); | |
354 type = type.unaliased; | |
355 // Even in checked mode, type annotations for return type and argument | |
356 // types do not imply type checks, so there should never be a check | |
357 // against the type variable of a typedef. | |
358 isChecks.add(type); | |
359 return type; | |
360 } | |
361 | |
362 void registerStaticUse(StaticUse staticUse) { | |
363 Element element = staticUse.element; | |
364 if (Elements.isStaticOrTopLevel(element) && element.isField) { | |
365 allReferencedStaticFields.add(element); | |
366 } | |
367 switch (staticUse.kind) { | |
368 case StaticUseKind.SUPER_FIELD_SET: | |
369 case StaticUseKind.FIELD_SET: | |
370 fieldSetters.add(element); | |
371 break; | |
372 case StaticUseKind.SUPER_TEAR_OFF: | |
373 methodsNeedingSuperGetter.add(element); | |
374 break; | |
375 case StaticUseKind.GENERAL: | |
376 case StaticUseKind.STATIC_TEAR_OFF: | |
377 case StaticUseKind.FIELD_GET: | |
378 break; | |
379 case StaticUseKind.CLOSURE: | |
380 allClosures.add(element); | |
381 break; | |
382 } | |
383 } | |
384 | |
385 void forgetElement(Element element, Compiler compiler) { | |
386 allClosures.remove(element); | |
387 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); | |
388 closurizedMembers.remove(element); | |
389 fieldSetters.remove(element); | |
390 _directlyInstantiatedClasses.remove(element); | |
391 if (element is ClassElement) { | |
392 assert(invariant(element, element.thisType.isRaw, | |
393 message: 'Generic classes not supported (${element.thisType}).')); | |
394 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); | |
395 } | |
396 } | |
397 | |
398 // TODO(ahe): Replace this method with something that is O(1), for example, | |
399 // by using a map. | |
400 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | |
401 // Return new list to guard against concurrent modifications. | |
402 return new List<LocalFunctionElement>.from( | |
403 allClosures.where((LocalFunctionElement closure) { | |
404 return closure.executableContext == element; | |
405 })); | |
406 } | |
407 } | |
408 | |
409 abstract class CodegenUniverse implements Universe { | |
Harry Terkelsen
2016/09/19 18:07:10
add dartdoc for this class
Johnni Winther
2016/09/21 09:13:04
Done.
| |
410 void forEachInvokedName( | |
411 f(String name, Map<Selector, SelectorConstraints> selectors)); | |
412 | |
413 void forEachInvokedGetter( | |
414 f(String name, Map<Selector, SelectorConstraints> selectors)); | |
415 | |
416 void forEachInvokedSetter( | |
417 f(String name, Map<Selector, SelectorConstraints> selectors)); | |
418 | |
419 bool hasInvokedGetter(Element member, World world); | |
420 | |
421 Map<Selector, SelectorConstraints> invocationsByName(String name); | |
422 | |
423 Map<Selector, SelectorConstraints> getterInvocationsByName(String name); | |
424 | |
425 Map<Selector, SelectorConstraints> setterInvocationsByName(String name); | |
426 | |
427 Iterable<FunctionElement> get staticFunctionsNeedingGetter; | |
428 Iterable<FunctionElement> get methodsNeedingSuperGetter; | |
429 | |
430 /// The set of all referenced static fields. | |
431 /// | |
432 /// Invariant: Elements are declaration elements. | |
433 Iterable<FieldElement> get allReferencedStaticFields; | |
434 } | |
435 | |
436 class CodegenUniverseImpl implements CodegenUniverse { | |
437 /// The set of all directly instantiated classes, that is, classes with a | |
438 /// generative constructor that has been called directly and not only through | |
439 /// a super-call. | |
440 /// | |
441 /// Invariant: Elements are declaration elements. | |
442 // TODO(johnniwinther): [_directlyInstantiatedClasses] and | |
443 // [_instantiatedTypes] sets should be merged. | |
444 final Set<ClassElement> _directlyInstantiatedClasses = | |
445 new Set<ClassElement>(); | |
446 | |
447 /// The set of all directly instantiated types, that is, the types of the | |
448 /// directly instantiated classes. | |
449 /// | |
450 /// See [_directlyInstantiatedClasses]. | |
451 final Set<DartType> _instantiatedTypes = new Set<DartType>(); | |
452 | |
453 /// Classes implemented by directly instantiated classes. | |
454 final Set<ClassElement> _implementedClasses = new Set<ClassElement>(); | |
455 | |
456 /// The set of all referenced static fields. | |
457 /// | |
458 /// Invariant: Elements are declaration elements. | |
459 final Set<FieldElement> allReferencedStaticFields = new Set<FieldElement>(); | |
460 | |
461 /** | |
462 * Documentation wanted -- johnniwinther | |
463 * | |
464 * Invariant: Elements are declaration elements. | |
465 */ | |
466 final Set<FunctionElement> staticFunctionsNeedingGetter = | |
467 new Set<FunctionElement>(); | |
468 final Set<FunctionElement> methodsNeedingSuperGetter = | |
469 new Set<FunctionElement>(); | |
470 final Map<String, Map<Selector, SelectorConstraints>> _invokedNames = | |
471 <String, Map<Selector, SelectorConstraints>>{}; | |
472 final Map<String, Map<Selector, SelectorConstraints>> _invokedGetters = | |
473 <String, Map<Selector, SelectorConstraints>>{}; | |
474 final Map<String, Map<Selector, SelectorConstraints>> _invokedSetters = | |
475 <String, Map<Selector, SelectorConstraints>>{}; | |
476 | |
477 final Set<DartType> isChecks = new Set<DartType>(); | |
478 | |
479 final SelectorConstraintsStrategy selectorConstraintsStrategy; | |
480 | |
481 CodegenUniverseImpl(this.selectorConstraintsStrategy); | |
482 | |
483 /// All directly instantiated classes, that is, classes with a generative | |
484 /// constructor that has been called directly and not only through a | |
485 /// super-call. | |
486 // TODO(johnniwinther): Improve semantic precision. | |
487 Iterable<ClassElement> get directlyInstantiatedClasses { | |
488 return _directlyInstantiatedClasses; | |
489 } | |
490 | |
491 /// All directly instantiated types, that is, the types of the directly | |
492 /// instantiated classes. | |
493 /// | |
494 /// See [directlyInstantiatedClasses]. | |
495 // TODO(johnniwinther): Improve semantic precision. | |
496 Iterable<DartType> get instantiatedTypes => _instantiatedTypes; | |
497 | |
498 /// Register [type] as (directly) instantiated. | |
499 /// | |
500 /// If [byMirrors] is `true`, the instantiation is through mirrors. | |
501 // TODO(johnniwinther): Fully enforce the separation between exact, through | |
502 // subclass and through subtype instantiated types/classes. | |
503 // TODO(johnniwinther): Support unknown type arguments for generic types. | |
504 void registerTypeInstantiation(InterfaceType type, | |
Siggi Cherem (dart-lang)
2016/09/06 17:57:43
should some of this shared code be in a shared sup
Harry Terkelsen
2016/09/19 18:07:10
I would suggest 'UniverseBase'
Johnni Winther
2016/09/21 09:13:04
I'll wait with that until the unification of world
| |
505 {bool byMirrors: false, | |
506 bool isNative: false, | |
507 void onImplemented(ClassElement cls)}) { | |
508 _instantiatedTypes.add(type); | |
509 ClassElement cls = type.element; | |
510 if (!cls.isAbstract | |
511 // We can't use the closed-world assumption with native abstract | |
512 // classes; a native abstract class may have non-abstract subclasses | |
513 // not declared to the program. Instances of these classes are | |
514 // indistinguishable from the abstract class. | |
515 || | |
516 isNative | |
517 // Likewise, if this registration comes from the mirror system, | |
518 // all bets are off. | |
519 // TODO(herhut): Track classes required by mirrors seperately. | |
520 || | |
521 byMirrors) { | |
522 _directlyInstantiatedClasses.add(cls); | |
523 } | |
524 | |
525 // TODO(johnniwinther): Replace this by separate more specific mappings that | |
526 // include the type arguments. | |
527 if (_implementedClasses.add(cls)) { | |
528 onImplemented(cls); | |
529 cls.allSupertypes.forEach((InterfaceType supertype) { | |
530 if (_implementedClasses.add(supertype.element)) { | |
531 onImplemented(supertype.element); | |
532 } | |
533 }); | |
534 } | |
535 } | |
536 | |
537 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | |
538 Element member, World world) { | |
539 if (selectors == null) return false; | |
540 for (Selector selector in selectors.keys) { | |
541 if (selector.appliesUnnamed(member, world)) { | |
542 SelectorConstraints masks = selectors[selector]; | |
543 if (masks.applies(member, selector, world)) { | |
544 return true; | |
545 } | |
546 } | |
547 } | |
548 return false; | |
549 } | |
550 | |
551 bool hasInvocation(Element member, World world) { | |
552 return _hasMatchingSelector(_invokedNames[member.name], member, world); | |
553 } | |
554 | |
555 bool hasInvokedGetter(Element member, World world) { | |
556 return _hasMatchingSelector(_invokedGetters[member.name], member, world) || | |
557 member.isFunction && methodsNeedingSuperGetter.contains(member); | |
558 } | |
559 | |
560 bool hasInvokedSetter(Element member, World world) { | |
561 return _hasMatchingSelector(_invokedSetters[member.name], member, world); | |
562 } | |
563 | |
564 bool registerDynamicUse(DynamicUse dynamicUse) { | |
565 switch (dynamicUse.kind) { | |
566 case DynamicUseKind.INVOKE: | |
567 return _registerNewSelector(dynamicUse, _invokedNames); | |
568 case DynamicUseKind.GET: | |
569 return _registerNewSelector(dynamicUse, _invokedGetters); | |
570 case DynamicUseKind.SET: | |
571 return _registerNewSelector(dynamicUse, _invokedSetters); | |
572 } | |
573 } | |
574 | |
575 bool _registerNewSelector(DynamicUse dynamicUse, | |
576 Map<String, Map<Selector, SelectorConstraints>> selectorMap) { | |
577 Selector selector = dynamicUse.selector; | |
578 String name = selector.name; | |
579 ReceiverConstraint mask = dynamicUse.mask; | |
580 Map<Selector, SelectorConstraints> selectors = selectorMap.putIfAbsent( | |
581 name, () => new Maplet<Selector, SelectorConstraints>()); | |
582 UniverseSelectorConstraints constraints = | |
583 selectors.putIfAbsent(selector, () { | |
584 return selectorConstraintsStrategy.createSelectorConstraints(selector); | |
585 }); | |
586 return constraints.addReceiverConstraint(mask); | |
587 } | |
588 | |
310 Map<Selector, SelectorConstraints> _asUnmodifiable( | 589 Map<Selector, SelectorConstraints> _asUnmodifiable( |
311 Map<Selector, SelectorConstraints> map) { | 590 Map<Selector, SelectorConstraints> map) { |
312 if (map == null) return null; | 591 if (map == null) return null; |
313 return new UnmodifiableMapView(map); | 592 return new UnmodifiableMapView(map); |
314 } | 593 } |
315 | 594 |
316 Map<Selector, SelectorConstraints> invocationsByName(String name) { | 595 Map<Selector, SelectorConstraints> invocationsByName(String name) { |
317 return _asUnmodifiable(_invokedNames[name]); | 596 return _asUnmodifiable(_invokedNames[name]); |
318 } | 597 } |
319 | 598 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
352 | 631 |
353 void registerStaticUse(StaticUse staticUse) { | 632 void registerStaticUse(StaticUse staticUse) { |
354 Element element = staticUse.element; | 633 Element element = staticUse.element; |
355 if (Elements.isStaticOrTopLevel(element) && element.isField) { | 634 if (Elements.isStaticOrTopLevel(element) && element.isField) { |
356 allReferencedStaticFields.add(element); | 635 allReferencedStaticFields.add(element); |
357 } | 636 } |
358 switch (staticUse.kind) { | 637 switch (staticUse.kind) { |
359 case StaticUseKind.STATIC_TEAR_OFF: | 638 case StaticUseKind.STATIC_TEAR_OFF: |
360 staticFunctionsNeedingGetter.add(element); | 639 staticFunctionsNeedingGetter.add(element); |
361 break; | 640 break; |
362 case StaticUseKind.FIELD_GET: | |
363 fieldGetters.add(element); | |
364 break; | |
365 case StaticUseKind.SUPER_FIELD_SET: | |
366 case StaticUseKind.FIELD_SET: | |
367 fieldSetters.add(element); | |
368 break; | |
369 case StaticUseKind.SUPER_TEAR_OFF: | 641 case StaticUseKind.SUPER_TEAR_OFF: |
370 methodsNeedingSuperGetter.add(element); | 642 methodsNeedingSuperGetter.add(element); |
371 break; | 643 break; |
644 case StaticUseKind.SUPER_FIELD_SET: | |
645 case StaticUseKind.FIELD_SET: | |
372 case StaticUseKind.GENERAL: | 646 case StaticUseKind.GENERAL: |
373 break; | |
374 case StaticUseKind.CLOSURE: | 647 case StaticUseKind.CLOSURE: |
375 allClosures.add(element); | 648 case StaticUseKind.FIELD_GET: |
376 break; | 649 break; |
377 } | 650 } |
378 } | 651 } |
379 | 652 |
380 void forgetElement(Element element, Compiler compiler) { | 653 void forgetElement(Element element, Compiler compiler) { |
381 allClosures.remove(element); | |
382 slowDirectlyNestedClosures(element).forEach(compiler.forgetElement); | |
383 closurizedMembers.remove(element); | |
384 fieldSetters.remove(element); | |
385 fieldGetters.remove(element); | |
386 _directlyInstantiatedClasses.remove(element); | 654 _directlyInstantiatedClasses.remove(element); |
387 if (element is ClassElement) { | 655 if (element is ClassElement) { |
388 assert(invariant(element, element.thisType.isRaw, | 656 assert(invariant(element, element.thisType.isRaw, |
389 message: 'Generic classes not supported (${element.thisType}).')); | 657 message: 'Generic classes not supported (${element.thisType}).')); |
390 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); | 658 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); |
391 } | 659 } |
392 } | 660 } |
393 | |
394 // TODO(ahe): Replace this method with something that is O(1), for example, | |
395 // by using a map. | |
396 List<LocalFunctionElement> slowDirectlyNestedClosures(Element element) { | |
397 // Return new list to guard against concurrent modifications. | |
398 return new List<LocalFunctionElement>.from( | |
399 allClosures.where((LocalFunctionElement closure) { | |
400 return closure.executableContext == element; | |
401 })); | |
402 } | |
403 } | 661 } |
OLD | NEW |