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(base)}")); | 92 "class $base.\n${classWorld.dump()}")); |
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 assert(invariant(base, classWorld.isInstantiated(base), | 102 if (classWorld.hasAnyStrictSubclass(base)) { |
103 message: () => "Cannot create subclass type mask for uninstantiated " | 103 return new FlatTypeMask.subclass(base); |
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); | |
110 } else { | 104 } else { |
111 return new TypeMask.exact(topmost, classWorld); | 105 return new TypeMask.exactOrEmpty(base, classWorld); |
112 } | 106 } |
113 } | 107 } |
114 | 108 |
115 factory TypeMask.subtype(ClassElement base, ClassWorld classWorld) { | 109 factory TypeMask.subtype(ClassElement base, ClassWorld classWorld) { |
116 ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base); | 110 if (classWorld.hasOnlySubclasses(base)) { |
117 if (topmost == null) { | 111 return new TypeMask.subclass(base, classWorld); |
118 return new TypeMask.empty(); | |
119 } | 112 } |
120 if (classWorld.hasOnlySubclasses(topmost)) { | 113 if (classWorld.hasAnyStrictSubtype(base)) { |
121 return new TypeMask.subclass(topmost, classWorld); | 114 return new FlatTypeMask.subtype(base); |
122 } | |
123 if (classWorld.hasAnyStrictSubtype(topmost)) { | |
124 return new FlatTypeMask.subtype(topmost); | |
125 } else { | 115 } else { |
126 return new TypeMask.exact(topmost, classWorld); | 116 return new TypeMask.exactOrEmpty(base, classWorld); |
127 } | 117 } |
128 } | 118 } |
129 | 119 |
130 const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty; | 120 const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty; |
131 | 121 |
132 factory TypeMask.nonNullExact(ClassElement base, ClassWorld classWorld) { | 122 factory TypeMask.nonNullExact(ClassElement base, ClassWorld classWorld) { |
133 assert(invariant(base, classWorld.isInstantiated(base), | 123 assert(invariant(base, classWorld.isInstantiated(base), |
134 message: () => "Cannot create exact type mask for uninstantiated " | 124 message: () => "Cannot create exact type mask for " |
135 "class $base.\n${classWorld.dump(base)}")); | 125 "uninstantiated class $base.\n${classWorld.dump(base)}")); |
136 return new FlatTypeMask.nonNullExact(base); | 126 return new FlatTypeMask.nonNullExact(base); |
137 } | 127 } |
138 | 128 |
139 factory TypeMask.nonNullExactOrEmpty(ClassElement base, | 129 factory TypeMask.nonNullExactOrEmpty(ClassElement base, |
140 ClassWorld classWorld) { | 130 ClassWorld classWorld) { |
141 if (classWorld.isInstantiated(base)) { | 131 if (classWorld.isInstantiated(base)) { |
142 return new FlatTypeMask.nonNullExact(base); | 132 return new FlatTypeMask.nonNullExact(base); |
143 } | 133 } |
144 return const TypeMask.nonNullEmpty(); | 134 return const TypeMask.nonNullEmpty(); |
145 } | 135 } |
146 | 136 |
147 factory TypeMask.nonNullSubclass(ClassElement base, ClassWorld classWorld) { | 137 factory TypeMask.nonNullSubclass(ClassElement base, ClassWorld classWorld) { |
148 assert(invariant(base, classWorld.isInstantiated(base), | 138 if (classWorld.hasAnyStrictSubclass(base)) { |
149 message: () => "Cannot create subclass type mask for uninstantiated " | 139 return new FlatTypeMask.nonNullSubclass(base); |
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); | |
156 } else { | 140 } else { |
157 return new TypeMask.nonNullExact(topmost, classWorld); | 141 return new TypeMask.nonNullExactOrEmpty(base, classWorld); |
158 } | 142 } |
159 } | 143 } |
160 | 144 |
161 factory TypeMask.nonNullSubtype(ClassElement base, ClassWorld classWorld) { | 145 factory TypeMask.nonNullSubtype(ClassElement base, ClassWorld classWorld) { |
162 ClassElement topmost = classWorld.getLubOfInstantiatedSubtypes(base); | 146 if (classWorld.hasOnlySubclasses(base)) { |
163 if (topmost == null) { | 147 return new TypeMask.nonNullSubclass(base, classWorld); |
164 return new TypeMask.nonNullEmpty(); | |
165 } | 148 } |
166 if (classWorld.hasOnlySubclasses(topmost)) { | 149 if (classWorld.hasAnyStrictSubtype(base)) { |
167 return new TypeMask.nonNullSubclass(topmost, classWorld); | 150 return new FlatTypeMask.nonNullSubtype(base); |
168 } | |
169 if (classWorld.hasAnyStrictSubtype(topmost)) { | |
170 return new FlatTypeMask.nonNullSubtype(topmost); | |
171 } else { | 151 } else { |
172 return new TypeMask.nonNullExact(topmost, classWorld); | 152 return new TypeMask.nonNullExactOrEmpty(base, classWorld); |
173 } | 153 } |
174 } | 154 } |
175 | 155 |
176 factory TypeMask.unionOf(Iterable<TypeMask> masks, ClassWorld classWorld) { | 156 factory TypeMask.unionOf(Iterable<TypeMask> masks, ClassWorld classWorld) { |
177 return UnionTypeMask.unionOf(masks, classWorld); | 157 return UnionTypeMask.unionOf(masks, classWorld); |
178 } | 158 } |
179 | 159 |
180 /** | 160 /** |
181 * If [mask] is forwarding, returns the first non-forwarding [TypeMask] in | 161 * If [mask] is forwarding, returns the first non-forwarding [TypeMask] in |
182 * [mask]'s forwarding chain. | 162 * [mask]'s forwarding chain. |
(...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
350 /** | 330 /** |
351 * Returns the [element] that is known to always be hit at runtime | 331 * Returns the [element] that is known to always be hit at runtime |
352 * on this mask. Returns null if there is none. | 332 * on this mask. Returns null if there is none. |
353 */ | 333 */ |
354 // TODO(johnniwinther): Move this method to [World]. | 334 // TODO(johnniwinther): Move this method to [World]. |
355 Element locateSingleElement( | 335 Element locateSingleElement( |
356 Selector selector, | 336 Selector selector, |
357 TypeMask mask, | 337 TypeMask mask, |
358 Compiler compiler); | 338 Compiler compiler); |
359 } | 339 } |
OLD | NEW |