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 '../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 |