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

Side by Side Diff: pkg/compiler/lib/src/types/union_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/type_mask.dart ('k') | pkg/compiler/lib/src/world.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 class UnionTypeMask implements TypeMask { 7 class UnionTypeMask implements TypeMask {
8 final Iterable<FlatTypeMask> disjointMasks; 8 final Iterable<FlatTypeMask> disjointMasks;
9 9
10 static const int MAX_UNION_LENGTH = 4; 10 static const int MAX_UNION_LENGTH = 4;
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
87 } 87 }
88 } 88 }
89 89
90 static TypeMask flatten(List<FlatTypeMask> masks, ClosedWorld closedWorld) { 90 static TypeMask flatten(List<FlatTypeMask> masks, ClosedWorld closedWorld) {
91 assert(masks.length > 1); 91 assert(masks.length > 1);
92 // If either type mask is a subtype type mask, we cannot use a 92 // If either type mask is a subtype type mask, we cannot use a
93 // subclass type mask to represent their union. 93 // subclass type mask to represent their union.
94 bool useSubclass = masks.every((e) => !e.isSubtype); 94 bool useSubclass = masks.every((e) => !e.isSubtype);
95 bool isNullable = masks.any((e) => e.isNullable); 95 bool isNullable = masks.any((e) => e.isNullable);
96 96
97 List<ClassElement> masksBases = masks.map((mask) => mask.base).toList(); 97 List masksBases = masks.map((mask) => mask.base).toList();
98 Iterable<ClassElement> candidates = 98 Iterable<Entity> candidates = closedWorld.commonSupertypesOf(masksBases);
99 closedWorld.commonSupertypesOf(masksBases);
100 99
101 // Compute the best candidate and its kind. 100 // Compute the best candidate and its kind.
102 ClassElement bestElement; 101 Entity bestElement;
103 int bestKind; 102 int bestKind;
104 int bestSize; 103 int bestSize;
105 for (ClassElement candidate in candidates) { 104 for (Entity candidate in candidates) {
106 bool isInstantiatedStrictSubclass(cls) => 105 bool isInstantiatedStrictSubclass(cls) =>
107 cls != candidate && 106 cls != candidate &&
108 closedWorld.isDirectlyInstantiated(cls) && 107 closedWorld.isDirectlyInstantiated(cls) &&
109 closedWorld.isSubclassOf(cls, candidate); 108 closedWorld.isSubclassOf(cls, candidate);
110 109
111 int size; 110 int size;
112 int kind; 111 int kind;
113 if (useSubclass && masksBases.every(isInstantiatedStrictSubclass)) { 112 if (useSubclass && masksBases.every(isInstantiatedStrictSubclass)) {
114 // If both [this] and [other] are subclasses of the supertype, 113 // If both [this] and [other] are subclasses of the supertype,
115 // then we prefer to construct a subclass type mask because it 114 // then we prefer to construct a subclass type mask because it
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after
224 // The fast test is precise for exact types. 223 // The fast test is precise for exact types.
225 if (other.isExact) return false; 224 if (other.isExact) return false;
226 // We cannot contain object. 225 // We cannot contain object.
227 if (other.contains(closedWorld.coreClasses.objectClass, closedWorld)) { 226 if (other.contains(closedWorld.coreClasses.objectClass, closedWorld)) {
228 return false; 227 return false;
229 } 228 }
230 FlatTypeMask flat = TypeMask.nonForwardingMask(other); 229 FlatTypeMask flat = TypeMask.nonForwardingMask(other);
231 // Check we cover the base class. 230 // Check we cover the base class.
232 if (!contains(flat.base, closedWorld)) return false; 231 if (!contains(flat.base, closedWorld)) return false;
233 // Check for other members. 232 // Check for other members.
234 Iterable<ClassElement> members; 233 Iterable<Entity> members;
235 if (flat.isSubclass) { 234 if (flat.isSubclass) {
236 members = closedWorld.strictSubclassesOf(flat.base); 235 members = closedWorld.strictSubclassesOf(flat.base);
237 } else { 236 } else {
238 assert(flat.isSubtype); 237 assert(flat.isSubtype);
239 members = closedWorld.strictSubtypesOf(flat.base); 238 members = closedWorld.strictSubtypesOf(flat.base);
240 } 239 }
241 return members.every((ClassElement cls) => this.contains(cls, closedWorld)); 240 return members.every((Entity cls) => this.contains(cls, closedWorld));
242 } 241 }
243 242
244 bool isInMask(TypeMask other, ClosedWorld closedWorld) { 243 bool isInMask(TypeMask other, ClosedWorld closedWorld) {
245 other = TypeMask.nonForwardingMask(other); 244 other = TypeMask.nonForwardingMask(other);
246 if (isNullable && !other.isNullable) return false; 245 if (isNullable && !other.isNullable) return false;
247 if (other.isUnion) { 246 if (other.isUnion) {
248 UnionTypeMask union = other; 247 UnionTypeMask union = other;
249 bool containedInAnyOf(FlatTypeMask mask, Iterable<FlatTypeMask> masks) { 248 bool containedInAnyOf(FlatTypeMask mask, Iterable<FlatTypeMask> masks) {
250 // null is not canonicalized for the union but stored only on some 249 // null is not canonicalized for the union but stored only on some
251 // masks in [disjointMask]. It has been checked in the surrounding 250 // masks in [disjointMask]. It has been checked in the surrounding
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 } 298 }
300 299
301 bool containsOnlyBool(ClosedWorld closedWorld) { 300 bool containsOnlyBool(ClosedWorld closedWorld) {
302 return disjointMasks.every((mask) => mask.containsOnlyBool(closedWorld)); 301 return disjointMasks.every((mask) => mask.containsOnlyBool(closedWorld));
303 } 302 }
304 303
305 bool containsOnlyString(ClosedWorld closedWorld) { 304 bool containsOnlyString(ClosedWorld closedWorld) {
306 return disjointMasks.every((mask) => mask.containsOnlyString(closedWorld)); 305 return disjointMasks.every((mask) => mask.containsOnlyString(closedWorld));
307 } 306 }
308 307
309 bool containsOnly(ClassElement element) { 308 bool containsOnly(Entity element) {
310 return disjointMasks.every((mask) => mask.containsOnly(element)); 309 return disjointMasks.every((mask) => mask.containsOnly(element));
311 } 310 }
312 311
313 bool satisfies(ClassElement cls, ClosedWorld closedWorld) { 312 bool satisfies(Entity cls, ClosedWorld closedWorld) {
314 return disjointMasks.every((mask) => mask.satisfies(cls, closedWorld)); 313 return disjointMasks.every((mask) => mask.satisfies(cls, closedWorld));
315 } 314 }
316 315
317 bool contains(ClassElement type, ClosedWorld closedWorld) { 316 bool contains(Entity cls, ClosedWorld closedWorld) {
318 return disjointMasks.any((e) => e.contains(type, closedWorld)); 317 return disjointMasks.any((e) => e.contains(cls, closedWorld));
319 } 318 }
320 319
321 bool containsAll(ClosedWorld closedWorld) { 320 bool containsAll(ClosedWorld closedWorld) {
322 return disjointMasks.any((mask) => mask.containsAll(closedWorld)); 321 return disjointMasks.any((mask) => mask.containsAll(closedWorld));
323 } 322 }
324 323
325 ClassElement singleClass(ClosedWorld closedWorld) => null; 324 Entity singleClass(ClosedWorld closedWorld) => null;
326 325
327 bool needsNoSuchMethodHandling(Selector selector, ClosedWorld closedWorld) { 326 bool needsNoSuchMethodHandling(Selector selector, ClosedWorld closedWorld) {
328 return disjointMasks 327 return disjointMasks
329 .any((e) => e.needsNoSuchMethodHandling(selector, closedWorld)); 328 .any((e) => e.needsNoSuchMethodHandling(selector, closedWorld));
330 } 329 }
331 330
332 bool canHit(Element element, Selector selector, ClosedWorld closedWorld) { 331 bool canHit(Element element, Selector selector, ClosedWorld closedWorld) {
333 return disjointMasks.any((e) => e.canHit(element, selector, closedWorld)); 332 return disjointMasks.any((e) => e.canHit(element, selector, closedWorld));
334 } 333 }
335 334
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 int get hashCode { 373 int get hashCode {
375 int hashCode = isNullable ? 86 : 43; 374 int hashCode = isNullable ? 86 : 43;
376 // The order of the masks in [disjointMasks] must not affect the 375 // The order of the masks in [disjointMasks] must not affect the
377 // hashCode. 376 // hashCode.
378 for (var mask in disjointMasks) { 377 for (var mask in disjointMasks) {
379 hashCode = (hashCode ^ mask.nonNullable().hashCode) & 0x3fffffff; 378 hashCode = (hashCode ^ mask.nonNullable().hashCode) & 0x3fffffff;
380 } 379 }
381 return hashCode; 380 return hashCode;
382 } 381 }
383 } 382 }
OLDNEW
« no previous file with comments | « pkg/compiler/lib/src/types/type_mask.dart ('k') | pkg/compiler/lib/src/world.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698