OLD | NEW |
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 part of types; | 5 part of types; |
6 | 6 |
7 /// An implementation of a [UniverseSelectorConstraints] that is consists if an
only | 7 /// An implementation of a [UniverseSelectorConstraints] that is consists if an
only |
8 /// increasing set of [TypeMask]s, that is, once a mask is added it cannot be | 8 /// increasing set of [TypeMask]s, that is, once a mask is added it cannot be |
9 /// removed. | 9 /// removed. |
10 class IncreasingTypeMaskSet extends UniverseSelectorConstraints { | 10 class IncreasingTypeMaskSet extends UniverseSelectorConstraints { |
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
82 ClassWorld classWorld) { | 82 ClassWorld classWorld) { |
83 return new FlatTypeMask.normalized( | 83 return new FlatTypeMask.normalized( |
84 base, (kind << 1) | (isNullable ? 1 : 0), classWorld); | 84 base, (kind << 1) | (isNullable ? 1 : 0), classWorld); |
85 } | 85 } |
86 | 86 |
87 const factory TypeMask.empty() = FlatTypeMask.empty; | 87 const factory TypeMask.empty() = FlatTypeMask.empty; |
88 | 88 |
89 factory TypeMask.exact(ClassElement base, ClassWorld classWorld) { | 89 factory TypeMask.exact(ClassElement base, ClassWorld classWorld) { |
90 assert(invariant(base, classWorld.isInstantiated(base), | 90 assert(invariant(base, classWorld.isInstantiated(base), |
91 message: () => "Cannot create exact type mask for uninstantiated " | 91 message: () => "Cannot create exact type mask for uninstantiated " |
92 "class $base.\n${classWorld.dump()}")); | 92 "class $base.\n${classWorld.dump(base)}")); |
93 return new FlatTypeMask.exact(base); | 93 return new FlatTypeMask.exact(base); |
94 } | 94 } |
95 | 95 |
96 factory TypeMask.exactOrEmpty(ClassElement base, ClassWorld classWorld) { | 96 factory TypeMask.exactOrEmpty(ClassElement base, ClassWorld classWorld) { |
97 if (classWorld.isInstantiated(base)) return new FlatTypeMask.exact(base); | 97 if (classWorld.isInstantiated(base)) return new FlatTypeMask.exact(base); |
98 return const TypeMask.empty(); | 98 return const TypeMask.empty(); |
99 } | 99 } |
100 | 100 |
101 factory TypeMask.subclass(ClassElement base, ClassWorld classWorld) { | 101 factory TypeMask.subclass(ClassElement base, ClassWorld classWorld) { |
102 if (classWorld.hasAnyStrictSubclass(base)) { | 102 assert(invariant(base, classWorld.isInstantiated(base), |
103 return new FlatTypeMask.subclass(base); | 103 message: () => "Cannot create subclass type mask for uninstantiated " |
| 104 "class $base.\n${classWorld.dump(base)}")); |
| 105 ClassElement topmost = classWorld.getLubOfInstantiatedSubclasses(base); |
| 106 if (topmost == null) { |
| 107 return new TypeMask.empty(); |
| 108 } else if (classWorld.hasAnyStrictSubclass(topmost)) { |
| 109 return new FlatTypeMask.subclass(topmost); |
104 } else { | 110 } else { |
105 return new TypeMask.exactOrEmpty(base, classWorld); | 111 return new TypeMask.exact(topmost, classWorld); |
106 } | 112 } |
107 } | 113 } |
108 | 114 |
109 factory TypeMask.subtype(ClassElement base, ClassWorld classWorld) { | 115 factory TypeMask.subtype(ClassElement base, ClassWorld classWorld) { |
110 if (classWorld.hasOnlySubclasses(base)) { | 116 ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base); |
111 return new TypeMask.subclass(base, classWorld); | 117 if (topmost == null) { |
| 118 return new TypeMask.empty(); |
112 } | 119 } |
113 if (classWorld.hasAnyStrictSubtype(base)) { | 120 if (classWorld.hasOnlySubclasses(topmost)) { |
114 return new FlatTypeMask.subtype(base); | 121 return new TypeMask.subclass(topmost, classWorld); |
| 122 } |
| 123 if (classWorld.hasAnyStrictSubtype(topmost)) { |
| 124 return new FlatTypeMask.subtype(topmost); |
115 } else { | 125 } else { |
116 return new TypeMask.exactOrEmpty(base, classWorld); | 126 return new TypeMask.exact(topmost, classWorld); |
117 } | 127 } |
118 } | 128 } |
119 | 129 |
120 const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty; | 130 const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty; |
121 | 131 |
122 factory TypeMask.nonNullExact(ClassElement base, ClassWorld classWorld) { | 132 factory TypeMask.nonNullExact(ClassElement base, ClassWorld classWorld) { |
123 assert(invariant(base, classWorld.isInstantiated(base), | 133 assert(invariant(base, classWorld.isInstantiated(base), |
124 message: () => "Cannot create exact type mask for " | 134 message: () => "Cannot create exact type mask for uninstantiated " |
125 "uninstantiated class $base.\n${classWorld.dump(base)}")); | 135 "class $base.\n${classWorld.dump(base)}")); |
126 return new FlatTypeMask.nonNullExact(base); | 136 return new FlatTypeMask.nonNullExact(base); |
127 } | 137 } |
128 | 138 |
129 factory TypeMask.nonNullExactOrEmpty(ClassElement base, | 139 factory TypeMask.nonNullExactOrEmpty(ClassElement base, |
130 ClassWorld classWorld) { | 140 ClassWorld classWorld) { |
131 if (classWorld.isInstantiated(base)) { | 141 if (classWorld.isInstantiated(base)) { |
132 return new FlatTypeMask.nonNullExact(base); | 142 return new FlatTypeMask.nonNullExact(base); |
133 } | 143 } |
134 return const TypeMask.nonNullEmpty(); | 144 return const TypeMask.nonNullEmpty(); |
135 } | 145 } |
136 | 146 |
137 factory TypeMask.nonNullSubclass(ClassElement base, ClassWorld classWorld) { | 147 factory TypeMask.nonNullSubclass(ClassElement base, ClassWorld classWorld) { |
138 if (classWorld.hasAnyStrictSubclass(base)) { | 148 assert(invariant(base, classWorld.isInstantiated(base), |
139 return new FlatTypeMask.nonNullSubclass(base); | 149 message: () => "Cannot create subclass type mask for uninstantiated " |
| 150 "class $base.\n${classWorld.dump(base)}")); |
| 151 ClassElement topmost = classWorld.getLubOfInstantiatedSubclasses(base); |
| 152 if (topmost == null) { |
| 153 return new TypeMask.nonNullEmpty(); |
| 154 } else if (classWorld.hasAnyStrictSubclass(topmost)) { |
| 155 return new FlatTypeMask.nonNullSubclass(topmost); |
140 } else { | 156 } else { |
141 return new TypeMask.nonNullExactOrEmpty(base, classWorld); | 157 return new TypeMask.nonNullExact(topmost, classWorld); |
142 } | 158 } |
143 } | 159 } |
144 | 160 |
145 factory TypeMask.nonNullSubtype(ClassElement base, ClassWorld classWorld) { | 161 factory TypeMask.nonNullSubtype(ClassElement base, ClassWorld classWorld) { |
146 if (classWorld.hasOnlySubclasses(base)) { | 162 ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base); |
147 return new TypeMask.nonNullSubclass(base, classWorld); | 163 if (topmost == null) { |
| 164 return new TypeMask.nonNullEmpty(); |
148 } | 165 } |
149 if (classWorld.hasAnyStrictSubtype(base)) { | 166 if (classWorld.hasOnlySubclasses(topmost)) { |
150 return new FlatTypeMask.nonNullSubtype(base); | 167 return new TypeMask.nonNullSubclass(topmost, classWorld); |
| 168 } |
| 169 if (classWorld.hasAnyStrictSubtype(topmost)) { |
| 170 return new FlatTypeMask.nonNullSubtype(topmost); |
151 } else { | 171 } else { |
152 return new TypeMask.nonNullExactOrEmpty(base, classWorld); | 172 return new TypeMask.nonNullExact(topmost, classWorld); |
153 } | 173 } |
154 } | 174 } |
155 | 175 |
156 factory TypeMask.unionOf(Iterable<TypeMask> masks, ClassWorld classWorld) { | 176 factory TypeMask.unionOf(Iterable<TypeMask> masks, ClassWorld classWorld) { |
157 return UnionTypeMask.unionOf(masks, classWorld); | 177 return UnionTypeMask.unionOf(masks, classWorld); |
158 } | 178 } |
159 | 179 |
160 /** | 180 /** |
161 * If [mask] is forwarding, returns the first non-forwarding [TypeMask] in | 181 * If [mask] is forwarding, returns the first non-forwarding [TypeMask] in |
162 * [mask]'s forwarding chain. | 182 * [mask]'s forwarding chain. |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
330 /** | 350 /** |
331 * Returns the [element] that is known to always be hit at runtime | 351 * Returns the [element] that is known to always be hit at runtime |
332 * on this mask. Returns null if there is none. | 352 * on this mask. Returns null if there is none. |
333 */ | 353 */ |
334 // TODO(johnniwinther): Move this method to [World]. | 354 // TODO(johnniwinther): Move this method to [World]. |
335 Element locateSingleElement( | 355 Element locateSingleElement( |
336 Selector selector, | 356 Selector selector, |
337 TypeMask mask, | 357 TypeMask mask, |
338 Compiler compiler); | 358 Compiler compiler); |
339 } | 359 } |
OLD | NEW |