Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(739)

Side by Side Diff: pkg/compiler/lib/src/types/type_mask.dart

Issue 2420073002: Decouple TypeMask from ClassElement (Closed)
Patch Set: Updated cf. comments. Created 4 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « pkg/compiler/lib/src/types/masks.dart ('k') | pkg/compiler/lib/src/types/union_type_mask.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 masks; 5 part of masks;
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 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 } 70 }
71 } 71 }
72 72
73 /** 73 /**
74 * A type mask represents a set of contained classes, but the 74 * A type mask represents a set of contained classes, but the
75 * operations on it are not guaranteed to be precise and they may 75 * operations on it are not guaranteed to be precise and they may
76 * yield conservative answers that contain too many classes. 76 * yield conservative answers that contain too many classes.
77 */ 77 */
78 abstract class TypeMask implements ReceiverConstraint, AbstractValue { 78 abstract class TypeMask implements ReceiverConstraint, AbstractValue {
79 factory TypeMask( 79 factory TypeMask(
80 ClassElement base, int kind, bool isNullable, ClosedWorld closedWorld) { 80 Entity base, int kind, bool isNullable, ClosedWorld closedWorld) {
81 return new FlatTypeMask.normalized( 81 return new FlatTypeMask.normalized(
82 base, (kind << 1) | (isNullable ? 1 : 0), closedWorld); 82 base, (kind << 1) | (isNullable ? 1 : 0), closedWorld);
83 } 83 }
84 84
85 const factory TypeMask.empty() = FlatTypeMask.empty; 85 const factory TypeMask.empty() = FlatTypeMask.empty;
86 86
87 factory TypeMask.exact(ClassElement base, ClosedWorld closedWorld) { 87 factory TypeMask.exact(Entity base, ClosedWorld closedWorld) {
88 assert(invariant(base, closedWorld.isInstantiated(base), 88 assert(invariant(base, closedWorld.isInstantiated(base),
89 message: () => "Cannot create exact type mask for uninstantiated " 89 message: () => "Cannot create exact type mask for uninstantiated "
90 "class $base.\n${closedWorld.dump(base)}")); 90 "class $base.\n${closedWorld.dump(base)}"));
91 return new FlatTypeMask.exact(base); 91 return new FlatTypeMask.exact(base);
92 } 92 }
93 93
94 factory TypeMask.exactOrEmpty(ClassElement base, ClosedWorld closedWorld) { 94 factory TypeMask.exactOrEmpty(Entity base, ClosedWorld closedWorld) {
95 if (closedWorld.isInstantiated(base)) return new FlatTypeMask.exact(base); 95 if (closedWorld.isInstantiated(base)) return new FlatTypeMask.exact(base);
96 return const TypeMask.empty(); 96 return const TypeMask.empty();
97 } 97 }
98 98
99 factory TypeMask.subclass(ClassElement base, ClosedWorld closedWorld) { 99 factory TypeMask.subclass(Entity base, ClosedWorld closedWorld) {
100 assert(invariant(base, closedWorld.isInstantiated(base), 100 assert(invariant(base, closedWorld.isInstantiated(base),
101 message: () => "Cannot create subclass type mask for uninstantiated " 101 message: () => "Cannot create subclass type mask for uninstantiated "
102 "class $base.\n${closedWorld.dump(base)}")); 102 "class $base.\n${closedWorld.dump(base)}"));
103 ClassElement topmost = closedWorld.getLubOfInstantiatedSubclasses(base); 103 Entity topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
104 if (topmost == null) { 104 if (topmost == null) {
105 return new TypeMask.empty(); 105 return new TypeMask.empty();
106 } else if (closedWorld.hasAnyStrictSubclass(topmost)) { 106 } else if (closedWorld.hasAnyStrictSubclass(topmost)) {
107 return new FlatTypeMask.subclass(topmost); 107 return new FlatTypeMask.subclass(topmost);
108 } else { 108 } else {
109 return new TypeMask.exact(topmost, closedWorld); 109 return new TypeMask.exact(topmost, closedWorld);
110 } 110 }
111 } 111 }
112 112
113 factory TypeMask.subtype(ClassElement base, ClosedWorld closedWorld) { 113 factory TypeMask.subtype(Entity base, ClosedWorld closedWorld) {
114 ClassElement topmost = closedWorld.getLubOfInstantiatedSubtypes(base); 114 Entity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
115 if (topmost == null) { 115 if (topmost == null) {
116 return new TypeMask.empty(); 116 return new TypeMask.empty();
117 } 117 }
118 if (closedWorld.hasOnlySubclasses(topmost)) { 118 if (closedWorld.hasOnlySubclasses(topmost)) {
119 return new TypeMask.subclass(topmost, closedWorld); 119 return new TypeMask.subclass(topmost, closedWorld);
120 } 120 }
121 if (closedWorld.hasAnyStrictSubtype(topmost)) { 121 if (closedWorld.hasAnyStrictSubtype(topmost)) {
122 return new FlatTypeMask.subtype(topmost); 122 return new FlatTypeMask.subtype(topmost);
123 } else { 123 } else {
124 return new TypeMask.exact(topmost, closedWorld); 124 return new TypeMask.exact(topmost, closedWorld);
125 } 125 }
126 } 126 }
127 127
128 const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty; 128 const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
129 129
130 factory TypeMask.nonNullExact(ClassElement base, ClosedWorld closedWorld) { 130 factory TypeMask.nonNullExact(Entity base, ClosedWorld closedWorld) {
131 assert(invariant(base, closedWorld.isInstantiated(base), 131 assert(invariant(base, closedWorld.isInstantiated(base),
132 message: () => "Cannot create exact type mask for uninstantiated " 132 message: () => "Cannot create exact type mask for uninstantiated "
133 "class $base.\n${closedWorld.dump(base)}")); 133 "class $base.\n${closedWorld.dump(base)}"));
134 return new FlatTypeMask.nonNullExact(base); 134 return new FlatTypeMask.nonNullExact(base);
135 } 135 }
136 136
137 factory TypeMask.nonNullExactOrEmpty( 137 factory TypeMask.nonNullExactOrEmpty(Entity base, ClosedWorld closedWorld) {
138 ClassElement base, ClosedWorld closedWorld) {
139 if (closedWorld.isInstantiated(base)) { 138 if (closedWorld.isInstantiated(base)) {
140 return new FlatTypeMask.nonNullExact(base); 139 return new FlatTypeMask.nonNullExact(base);
141 } 140 }
142 return const TypeMask.nonNullEmpty(); 141 return const TypeMask.nonNullEmpty();
143 } 142 }
144 143
145 factory TypeMask.nonNullSubclass(ClassElement base, ClosedWorld closedWorld) { 144 factory TypeMask.nonNullSubclass(Entity base, ClosedWorld closedWorld) {
146 assert(invariant(base, closedWorld.isInstantiated(base), 145 assert(invariant(base, closedWorld.isInstantiated(base),
147 message: () => "Cannot create subclass type mask for uninstantiated " 146 message: () => "Cannot create subclass type mask for uninstantiated "
148 "class $base.\n${closedWorld.dump(base)}")); 147 "class $base.\n${closedWorld.dump(base)}"));
149 ClassElement topmost = closedWorld.getLubOfInstantiatedSubclasses(base); 148 Entity topmost = closedWorld.getLubOfInstantiatedSubclasses(base);
150 if (topmost == null) { 149 if (topmost == null) {
151 return new TypeMask.nonNullEmpty(); 150 return new TypeMask.nonNullEmpty();
152 } else if (closedWorld.hasAnyStrictSubclass(topmost)) { 151 } else if (closedWorld.hasAnyStrictSubclass(topmost)) {
153 return new FlatTypeMask.nonNullSubclass(topmost); 152 return new FlatTypeMask.nonNullSubclass(topmost);
154 } else { 153 } else {
155 return new TypeMask.nonNullExact(topmost, closedWorld); 154 return new TypeMask.nonNullExact(topmost, closedWorld);
156 } 155 }
157 } 156 }
158 157
159 factory TypeMask.nonNullSubtype(ClassElement base, ClosedWorld closedWorld) { 158 factory TypeMask.nonNullSubtype(Entity base, ClosedWorld closedWorld) {
160 ClassElement topmost = closedWorld.getLubOfInstantiatedSubtypes(base); 159 Entity topmost = closedWorld.getLubOfInstantiatedSubtypes(base);
161 if (topmost == null) { 160 if (topmost == null) {
162 return new TypeMask.nonNullEmpty(); 161 return new TypeMask.nonNullEmpty();
163 } 162 }
164 if (closedWorld.hasOnlySubclasses(topmost)) { 163 if (closedWorld.hasOnlySubclasses(topmost)) {
165 return new TypeMask.nonNullSubclass(topmost, closedWorld); 164 return new TypeMask.nonNullSubclass(topmost, closedWorld);
166 } 165 }
167 if (closedWorld.hasAnyStrictSubtype(topmost)) { 166 if (closedWorld.hasAnyStrictSubtype(topmost)) {
168 return new FlatTypeMask.nonNullSubtype(topmost); 167 return new FlatTypeMask.nonNullSubtype(topmost);
169 } else { 168 } else {
170 return new TypeMask.nonNullExact(topmost, closedWorld); 169 return new TypeMask.nonNullExact(topmost, closedWorld);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
280 bool get isForwarding; 279 bool get isForwarding;
281 280
282 /// Returns `true` if this mask holds encodes an exact value within a type. 281 /// Returns `true` if this mask holds encodes an exact value within a type.
283 bool get isValue; 282 bool get isValue;
284 283
285 bool containsOnlyInt(ClosedWorld closedWorld); 284 bool containsOnlyInt(ClosedWorld closedWorld);
286 bool containsOnlyDouble(ClosedWorld closedWorld); 285 bool containsOnlyDouble(ClosedWorld closedWorld);
287 bool containsOnlyNum(ClosedWorld closedWorld); 286 bool containsOnlyNum(ClosedWorld closedWorld);
288 bool containsOnlyBool(ClosedWorld closedWorld); 287 bool containsOnlyBool(ClosedWorld closedWorld);
289 bool containsOnlyString(ClosedWorld closedWorld); 288 bool containsOnlyString(ClosedWorld closedWorld);
290 bool containsOnly(ClassElement element); 289 bool containsOnly(Entity cls);
291 290
292 /** 291 /**
293 * Compares two [TypeMask] objects for structural equality. 292 * Compares two [TypeMask] objects for structural equality.
294 * 293 *
295 * Note: This may differ from semantic equality in the set containment sense. 294 * Note: This may differ from semantic equality in the set containment sense.
296 * Use [containsMask] and [isInMask] for that, instead. 295 * Use [containsMask] and [isInMask] for that, instead.
297 */ 296 */
298 bool operator ==(other); 297 bool operator ==(other);
299 298
300 /** 299 /**
301 * If this returns `true`, [other] is guaranteed to be a supertype of this 300 * If this returns `true`, [other] is guaranteed to be a supertype of this
302 * mask, i.e., this mask is in [other]. However, the inverse does not hold. 301 * mask, i.e., this mask is in [other]. However, the inverse does not hold.
303 * Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of 302 * Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of
304 * false negatives. 303 * false negatives.
305 */ 304 */
306 bool isInMask(TypeMask other, ClosedWorld closedWorld); 305 bool isInMask(TypeMask other, ClosedWorld closedWorld);
307 306
308 /** 307 /**
309 * If this returns `true`, [other] is guaranteed to be a subtype of this mask, 308 * If this returns `true`, [other] is guaranteed to be a subtype of this mask,
310 * i.e., this mask contains [other]. However, the inverse does not hold. 309 * i.e., this mask contains [other]. However, the inverse does not hold.
311 * Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of 310 * Enable [UnionTypeMask.PERFORM_EXTRA_CONTAINS_CHECK] to be notified of
312 * false negatives. 311 * false negatives.
313 */ 312 */
314 bool containsMask(TypeMask other, ClosedWorld closedWorld); 313 bool containsMask(TypeMask other, ClosedWorld closedWorld);
315 314
316 /** 315 /**
317 * Returns whether this type mask is an instance of [cls]. 316 * Returns whether this type mask is an instance of [cls].
318 */ 317 */
319 bool satisfies(ClassElement cls, ClosedWorld closedWorld); 318 bool satisfies(Entity cls, ClosedWorld closedWorld);
320 319
321 /** 320 /**
322 * Returns whether or not this type mask contains the given type. 321 * Returns whether or not this type mask contains the given class [cls].
323 */ 322 */
324 bool contains(ClassElement type, ClosedWorld closedWorld); 323 bool contains(Entity cls, ClosedWorld closedWorld);
325 324
326 /** 325 /**
327 * Returns whether or not this type mask contains all types. 326 * Returns whether or not this type mask contains all types.
328 */ 327 */
329 bool containsAll(ClosedWorld closedWorld); 328 bool containsAll(ClosedWorld closedWorld);
330 329
331 /** 330 /// Returns the [Entity] if this type represents a single class, otherwise
332 * Returns the [ClassElement] if this type represents a single class, 331 /// returns `null`. This method is conservative.
333 * otherwise returns `null`. This method is conservative. 332 Entity singleClass(ClosedWorld closedWorld);
334 */
335 ClassElement singleClass(ClosedWorld closedWorld);
336 333
337 /** 334 /**
338 * Returns a type mask representing the union of [this] and [other]. 335 * Returns a type mask representing the union of [this] and [other].
339 */ 336 */
340 TypeMask union(TypeMask other, ClosedWorld closedWorld); 337 TypeMask union(TypeMask other, ClosedWorld closedWorld);
341 338
342 /// Returns whether the intersection of this and [other] is empty. 339 /// Returns whether the intersection of this and [other] is empty.
343 bool isDisjoint(TypeMask other, ClosedWorld closedWorld); 340 bool isDisjoint(TypeMask other, ClosedWorld closedWorld);
344 341
345 /** 342 /**
346 * Returns a type mask representing the intersection of [this] and [other]. 343 * Returns a type mask representing the intersection of [this] and [other].
347 */ 344 */
348 TypeMask intersection(TypeMask other, ClosedWorld closedWorld); 345 TypeMask intersection(TypeMask other, ClosedWorld closedWorld);
349 346
350 /** 347 /**
351 * Returns whether [element] is a potential target when being 348 * Returns whether [element] is a potential target when being
352 * invoked on this type mask. [selector] is used to ensure library 349 * invoked on this type mask. [selector] is used to ensure library
353 * privacy is taken into account. 350 * privacy is taken into account.
354 */ 351 */
355 bool canHit(Element element, Selector selector, ClosedWorld closedWorld); 352 bool canHit(Element element, Selector selector, ClosedWorld closedWorld);
356 353
357 /** 354 /**
358 * Returns the [element] that is known to always be hit at runtime 355 * Returns the [element] that is known to always be hit at runtime
359 * on this mask. Returns null if there is none. 356 * on this mask. Returns null if there is none.
360 */ 357 */
361 // TODO(johnniwinther): Move this method to [World]. 358 // TODO(johnniwinther): Move this method to [World].
362 Element locateSingleElement(Selector selector, Compiler compiler); 359 Element locateSingleElement(Selector selector, Compiler compiler);
363 } 360 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/types/masks.dart ('k') | pkg/compiler/lib/src/types/union_type_mask.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698