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; |
11 import '../dart_types.dart'; | 11 import '../dart_types.dart'; |
12 import '../elements/elements.dart'; | 12 import '../elements/elements.dart'; |
13 import '../util/util.dart'; | 13 import '../util/util.dart'; |
14 import '../world.dart' show ClassWorld, ClosedWorld, OpenWorld; | 14 import '../world.dart' show World, ClosedWorld, OpenWorld; |
15 import 'selector.dart' show Selector; | 15 import 'selector.dart' show Selector; |
16 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; | 16 import 'use.dart' show DynamicUse, DynamicUseKind, StaticUse, StaticUseKind; |
17 | 17 |
18 /// The known constraint on receiver for a dynamic call site. | 18 /// The known constraint on receiver for a dynamic call site. |
19 /// | 19 /// |
20 /// This can for instance be used to constrain this dynamic call to `foo` to | 20 /// This can for instance be used to constrain this dynamic call to `foo` to |
21 /// 'receivers of the exact instance `Bar`': | 21 /// 'receivers of the exact instance `Bar`': |
22 /// | 22 /// |
23 /// class Bar { | 23 /// class Bar { |
24 /// void foo() {} | 24 /// void foo() {} |
25 /// } | 25 /// } |
26 /// main() => new Bar().foo(); | 26 /// main() => new Bar().foo(); |
27 /// | 27 /// |
28 abstract class ReceiverConstraint { | 28 abstract class ReceiverConstraint { |
29 /// Returns whether [element] is a potential target when being | 29 /// Returns whether [element] is a potential target when being |
30 /// invoked on a receiver with this constraint. [selector] is used to ensure | 30 /// invoked on a receiver with this constraint. [selector] is used to ensure |
31 /// library privacy is taken into account. | 31 /// library privacy is taken into account. |
32 bool canHit(Element element, Selector selector, ClassWorld classWorld); | 32 bool canHit(Element element, Selector selector, World world); |
33 | 33 |
34 /// Returns whether this [TypeMask] applied to [selector] can hit a | 34 /// Returns whether this [TypeMask] applied to [selector] can hit a |
35 /// [noSuchMethod]. | 35 /// [noSuchMethod]. |
36 bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld); | 36 bool needsNoSuchMethodHandling(Selector selector, World world); |
37 } | 37 } |
38 | 38 |
39 /// The combined constraints on receivers all the dynamic call sites of the same | 39 /// The combined constraints on receivers all the dynamic call sites of the same |
40 /// selector. | 40 /// selector. |
41 /// | 41 /// |
42 /// For instance for these calls | 42 /// For instance for these calls |
43 /// | 43 /// |
44 /// class A { | 44 /// class A { |
45 /// foo(a, b) {} | 45 /// foo(a, b) {} |
46 /// } | 46 /// } |
(...skipping 17 matching lines...) Expand all Loading... |
64 /// class A { | 64 /// class A { |
65 /// foo(a, b) {} | 65 /// foo(a, b) {} |
66 /// } | 66 /// } |
67 /// class B { | 67 /// class B { |
68 /// foo(a, b) {} | 68 /// foo(a, b) {} |
69 /// } | 69 /// } |
70 /// new A().foo(a, b); | 70 /// new A().foo(a, b); |
71 /// | 71 /// |
72 /// Ideally the selector constraints for calls `foo` with two positional | 72 /// Ideally the selector constraints for calls `foo` with two positional |
73 /// arguments apply to `A.foo` but `B.foo`. | 73 /// arguments apply to `A.foo` but `B.foo`. |
74 bool applies(Element element, Selector selector, ClassWorld world); | 74 bool applies(Element element, Selector selector, World world); |
75 | 75 |
76 /// Returns `true` if at least one of the receivers matching these constraints | 76 /// Returns `true` if at least one of the receivers matching these constraints |
77 /// in the closed [world] have no implementation matching [selector]. | 77 /// in the closed [world] have no implementation matching [selector]. |
78 /// | 78 /// |
79 /// For instance for this code snippet | 79 /// For instance for this code snippet |
80 /// | 80 /// |
81 /// class A {} | 81 /// class A {} |
82 /// class B { foo() {} } | 82 /// class B { foo() {} } |
83 /// m(b) => (b ? new A() : new B()).foo(); | 83 /// m(b) => (b ? new A() : new B()).foo(); |
84 /// | 84 /// |
85 /// the potential receiver `new A()` has no implementation of `foo` and thus | 85 /// the potential receiver `new A()` has no implementation of `foo` and thus |
86 /// needs to handle the call through its `noSuchMethod` handler. | 86 /// needs to handle the call through its `noSuchMethod` handler. |
87 bool needsNoSuchMethodHandling(Selector selector, ClassWorld world); | 87 bool needsNoSuchMethodHandling(Selector selector, World world); |
88 } | 88 } |
89 | 89 |
90 /// A mutable [SelectorConstraints] used in [Universe]. | 90 /// A mutable [SelectorConstraints] used in [Universe]. |
91 abstract class UniverseSelectorConstraints extends SelectorConstraints { | 91 abstract class UniverseSelectorConstraints extends SelectorConstraints { |
92 /// Adds [constraint] to these selector constraints. Return `true` if the set | 92 /// Adds [constraint] to these selector constraints. Return `true` if the set |
93 /// of potential receivers expanded due to the new constraint. | 93 /// of potential receivers expanded due to the new constraint. |
94 bool addReceiverConstraint(ReceiverConstraint constraint); | 94 bool addReceiverConstraint(ReceiverConstraint constraint); |
95 } | 95 } |
96 | 96 |
97 /// Strategy for computing the constraints on potential receivers of dynamic | 97 /// Strategy for computing the constraints on potential receivers of dynamic |
98 /// call sites. | 98 /// call sites. |
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 /// [ClosedWorld]. The concepts here and in [ClosedWorld] 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 // TODO(johnniwinther): Move common implementation to a [UniverseBase] when | 110 // TODO(johnniwinther): Move common implementation to a [UniverseBase] when |
111 // universes and worlds have been unified. | 111 // universes and worlds have been unified. |
112 abstract class Universe { | 112 abstract class Universe { |
113 /// All directly instantiated classes, that is, classes with a generative | 113 /// All directly instantiated classes, that is, classes with a generative |
114 /// constructor that has been called directly and not only through a | 114 /// constructor that has been called directly and not only through a |
115 /// super-call. | 115 /// super-call. |
116 // TODO(johnniwinther): Improve semantic precision. | 116 // TODO(johnniwinther): Improve semantic precision. |
117 Iterable<ClassElement> get directlyInstantiatedClasses; | 117 Iterable<ClassElement> get directlyInstantiatedClasses; |
118 | 118 |
119 /// All types that are checked either through is, as or checked mode checks. | 119 /// All types that are checked either through is, as or checked mode checks. |
120 Iterable<DartType> get isChecks; | 120 Iterable<DartType> get isChecks; |
121 | 121 |
122 /// Registers that [type] is checked in this universe. The unaliased type is | 122 /// Registers that [type] is checked in this universe. The unaliased type is |
123 /// returned. | 123 /// returned. |
124 DartType registerIsCheck(DartType type, Compiler compiler); | 124 DartType registerIsCheck(DartType type, Compiler compiler); |
125 | 125 |
126 /// All directly instantiated types, that is, the types of the directly | 126 /// All directly instantiated types, that is, the types of the directly |
127 /// instantiated classes. | 127 /// instantiated classes. |
128 // TODO(johnniwinther): Improve semantic precision. | 128 // TODO(johnniwinther): Improve semantic precision. |
129 Iterable<DartType> get instantiatedTypes; | 129 Iterable<DartType> get instantiatedTypes; |
130 | 130 |
131 /// Returns `true` if [member] is invoked as a setter. | 131 /// Returns `true` if [member] is invoked as a setter. |
132 bool hasInvokedSetter(Element member, ClassWorld world); | 132 bool hasInvokedSetter(Element member, World world); |
133 } | 133 } |
134 | 134 |
135 abstract class ResolutionUniverse implements Universe { | 135 abstract class ResolutionUniverse implements Universe { |
136 /// Set of (live) local functions (closures) whose signatures reference type | 136 /// Set of (live) local functions (closures) whose signatures reference type |
137 /// variables. | 137 /// variables. |
138 /// | 138 /// |
139 /// A live function is one whose enclosing member function has been enqueued. | 139 /// A live function is one whose enclosing member function has been enqueued. |
140 Set<Element> get closuresWithFreeTypeVariables; | 140 Set<Element> get closuresWithFreeTypeVariables; |
141 | 141 |
142 /// Set of (live) `call` methods whose signatures reference type variables. | 142 /// Set of (live) `call` methods whose signatures reference type variables. |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
292 onImplemented(cls); | 292 onImplemented(cls); |
293 cls.allSupertypes.forEach((InterfaceType supertype) { | 293 cls.allSupertypes.forEach((InterfaceType supertype) { |
294 if (_implementedClasses.add(supertype.element)) { | 294 if (_implementedClasses.add(supertype.element)) { |
295 onImplemented(supertype.element); | 295 onImplemented(supertype.element); |
296 } | 296 } |
297 }); | 297 }); |
298 } | 298 } |
299 } | 299 } |
300 | 300 |
301 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | 301 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, |
302 Element member, ClassWorld world) { | 302 Element member, OpenWorld world) { |
303 if (selectors == null) return false; | 303 if (selectors == null) return false; |
304 for (Selector selector in selectors.keys) { | 304 for (Selector selector in selectors.keys) { |
305 if (selector.appliesUnnamed(member, world.backend)) { | 305 if (selector.appliesUnnamed(member)) { |
306 SelectorConstraints masks = selectors[selector]; | 306 SelectorConstraints masks = selectors[selector]; |
307 if (masks.applies(member, selector, world)) { | 307 if (masks.applies(member, selector, world)) { |
308 return true; | 308 return true; |
309 } | 309 } |
310 } | 310 } |
311 } | 311 } |
312 return false; | 312 return false; |
313 } | 313 } |
314 | 314 |
315 bool hasInvocation(Element member, OpenWorld world) { | 315 bool hasInvocation(Element member, OpenWorld world) { |
(...skipping 219 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
535 onImplemented(supertype.element); | 535 onImplemented(supertype.element); |
536 } | 536 } |
537 }); | 537 }); |
538 } | 538 } |
539 } | 539 } |
540 | 540 |
541 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, | 541 bool _hasMatchingSelector(Map<Selector, SelectorConstraints> selectors, |
542 Element member, ClosedWorld world) { | 542 Element member, ClosedWorld world) { |
543 if (selectors == null) return false; | 543 if (selectors == null) return false; |
544 for (Selector selector in selectors.keys) { | 544 for (Selector selector in selectors.keys) { |
545 if (selector.appliesUnnamed(member, world.backend)) { | 545 if (selector.appliesUnnamed(member)) { |
546 SelectorConstraints masks = selectors[selector]; | 546 SelectorConstraints masks = selectors[selector]; |
547 if (masks.applies(member, selector, world)) { | 547 if (masks.applies(member, selector, world)) { |
548 return true; | 548 return true; |
549 } | 549 } |
550 } | 550 } |
551 } | 551 } |
552 return false; | 552 return false; |
553 } | 553 } |
554 | 554 |
555 bool hasInvocation(Element member, ClosedWorld world) { | 555 bool hasInvocation(Element member, ClosedWorld world) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
656 | 656 |
657 void forgetElement(Element element, Compiler compiler) { | 657 void forgetElement(Element element, Compiler compiler) { |
658 _directlyInstantiatedClasses.remove(element); | 658 _directlyInstantiatedClasses.remove(element); |
659 if (element is ClassElement) { | 659 if (element is ClassElement) { |
660 assert(invariant(element, element.thisType.isRaw, | 660 assert(invariant(element, element.thisType.isRaw, |
661 message: 'Generic classes not supported (${element.thisType}).')); | 661 message: 'Generic classes not supported (${element.thisType}).')); |
662 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); | 662 _instantiatedTypes..remove(element.rawType)..remove(element.thisType); |
663 } | 663 } |
664 } | 664 } |
665 } | 665 } |
OLD | NEW |