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