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 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 12 matching lines...) Expand all Loading... |
23 static void unionOfHelper(Iterable<TypeMask> masks, | 23 static void unionOfHelper(Iterable<TypeMask> masks, |
24 List<FlatTypeMask> disjoint, | 24 List<FlatTypeMask> disjoint, |
25 Compiler compiler) { | 25 Compiler compiler) { |
26 for (TypeMask mask in masks) { | 26 for (TypeMask mask in masks) { |
27 if (mask.isUnion) { | 27 if (mask.isUnion) { |
28 UnionTypeMask union = mask; | 28 UnionTypeMask union = mask; |
29 unionOfHelper(union.disjointMasks, disjoint, compiler); | 29 unionOfHelper(union.disjointMasks, disjoint, compiler); |
30 } else if (mask.isEmpty && !mask.isNullable) { | 30 } else if (mask.isEmpty && !mask.isNullable) { |
31 continue; | 31 continue; |
32 } else { | 32 } else { |
33 assert(mask.base == null || mask.base.element != compiler.dynamicClass); | 33 FlatTypeMask flatMask = mask; |
34 assert(mask is FlatTypeMask); | 34 assert(flatMask.base == null |
| 35 || flatMask.base.element != compiler.dynamicClass); |
35 int inListIndex = -1; | 36 int inListIndex = -1; |
36 bool covered = false; | 37 bool covered = false; |
37 | 38 |
38 // Iterate over [disjoint] to find out if one of the mask | 39 // Iterate over [disjoint] to find out if one of the mask |
39 // already covers [mask]. | 40 // already covers [mask]. |
40 for (int i = 0; i < disjoint.length; i++) { | 41 for (int i = 0; i < disjoint.length; i++) { |
41 FlatTypeMask current = disjoint[i]; | 42 FlatTypeMask current = disjoint[i]; |
42 if (current == null) continue; | 43 if (current == null) continue; |
43 TypeMask newMask = mask.union(current, compiler); | 44 TypeMask newMask = mask.union(current, compiler); |
44 // If we have found a disjoint union, continue iterating. | 45 // If we have found a disjoint union, continue iterating. |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
77 // If either type mask is a subtype type mask, we cannot use a | 78 // If either type mask is a subtype type mask, we cannot use a |
78 // subclass type mask to represent their union. | 79 // subclass type mask to represent their union. |
79 bool useSubclass = masks.every((e) => !e.isSubtype); | 80 bool useSubclass = masks.every((e) => !e.isSubtype); |
80 bool isNullable = masks.any((e) => e.isNullable); | 81 bool isNullable = masks.any((e) => e.isNullable); |
81 | 82 |
82 // Compute the common supertypes of the two types. | 83 // Compute the common supertypes of the two types. |
83 ClassElement firstElement = masks[0].base.element; | 84 ClassElement firstElement = masks[0].base.element; |
84 ClassElement secondElement = masks[1].base.element; | 85 ClassElement secondElement = masks[1].base.element; |
85 Iterable<ClassElement> candidates = | 86 Iterable<ClassElement> candidates = |
86 compiler.world.commonSupertypesOf(firstElement, secondElement); | 87 compiler.world.commonSupertypesOf(firstElement, secondElement); |
| 88 bool unseenType = false; |
87 for (int i = 2; i < masks.length; i++) { | 89 for (int i = 2; i < masks.length; i++) { |
88 ClassElement element = masks[i].base.element; | 90 ClassElement element = masks[i].base.element; |
89 Set<ClassElement> supertypes = compiler.world.supertypesOf(element); | 91 Set<ClassElement> supertypes = compiler.world.supertypesOf(element); |
90 if (supertypes == null) { | 92 if (supertypes == null) { |
91 candidates.clear(); | 93 unseenType = true; |
92 break; | 94 break; |
93 } | 95 } |
94 candidates = candidates.where((e) => supertypes.contains(e)); | 96 candidates = candidates.where((e) => supertypes.contains(e)); |
95 } | 97 } |
96 | 98 |
97 if (candidates.isEmpty) { | 99 if (candidates.isEmpty || unseenType) { |
98 // TODO(kasperl): Get rid of this check. It can only happen when | 100 // TODO(kasperl): Get rid of this check. It can only happen when |
99 // at least one of the two base types is 'unseen'. | 101 // at least one of the two base types is 'unseen'. |
100 return new TypeMask(compiler.objectClass.rawType, | 102 return new TypeMask(compiler.objectClass.rawType, |
101 FlatTypeMask.SUBCLASS, | 103 FlatTypeMask.SUBCLASS, |
102 isNullable); | 104 isNullable); |
103 } | 105 } |
104 // Compute the best candidate and its kind. | 106 // Compute the best candidate and its kind. |
105 ClassElement bestElement; | 107 ClassElement bestElement; |
106 int bestKind; | 108 int bestKind; |
107 int bestSize; | 109 int bestSize; |
(...skipping 140 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 | 250 |
249 String toString() => 'Union of $disjointMasks'; | 251 String toString() => 'Union of $disjointMasks'; |
250 | 252 |
251 bool operator==(other) { | 253 bool operator==(other) { |
252 if (identical(this, other)) return true; | 254 if (identical(this, other)) return true; |
253 return other is UnionTypeMask | 255 return other is UnionTypeMask |
254 && other.disjointMasks.length == disjointMasks.length | 256 && other.disjointMasks.length == disjointMasks.length |
255 && other.disjointMasks.every((e) => disjointMasks.contains(e)); | 257 && other.disjointMasks.every((e) => disjointMasks.contains(e)); |
256 } | 258 } |
257 } | 259 } |
OLD | NEW |