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

Side by Side Diff: sdk/lib/_internal/compiler/implementation/types/type_mask.dart

Issue 694353007: Move dart2js from sdk/lib/_internal/compiler to pkg/compiler (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 1 month 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 | Annotate | Revision Log
OLDNEW
(Empty)
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
3 // BSD-style license that can be found in the LICENSE file.
4
5 part of types;
6
7 /**
8 * A type mask represents a set of contained classes, but the
9 * operations on it are not guaranteed to be precise and they may
10 * yield conservative answers that contain too many classes.
11 */
12 abstract class TypeMask {
13 factory TypeMask(ClassElement base,
14 int kind,
15 bool isNullable,
16 ClassWorld classWorld) {
17 return new FlatTypeMask.normalized(
18 base, (kind << 1) | (isNullable ? 1 : 0), classWorld);
19 }
20
21 const factory TypeMask.empty() = FlatTypeMask.empty;
22
23 factory TypeMask.exact(ClassElement base, ClassWorld classWorld) {
24 assert(invariant(base, classWorld.isInstantiated(base),
25 message: "Cannot create extact type mask for uninstantiated class"));
26 return new FlatTypeMask.exact(base);
27 }
28
29 factory TypeMask.exactOrEmpty(ClassElement base, ClassWorld classWorld) {
30 if (classWorld.isInstantiated(base)) return new FlatTypeMask.exact(base);
31 return const TypeMask.empty();
32 }
33
34 factory TypeMask.subclass(ClassElement base, ClassWorld classWorld) {
35 if (classWorld.hasAnySubclass(base)) {
36 return new FlatTypeMask.subclass(base);
37 } else {
38 return new TypeMask.exactOrEmpty(base, classWorld);
39 }
40 }
41
42 factory TypeMask.subtype(ClassElement base, ClassWorld classWorld) {
43 if (classWorld.hasOnlySubclasses(base)) {
44 return new TypeMask.subclass(base, classWorld);
45 }
46 if (classWorld.hasAnySubtype(base)) {
47 return new FlatTypeMask.subtype(base);
48 } else {
49 return new TypeMask.exactOrEmpty(base, classWorld);
50 }
51 }
52
53 const factory TypeMask.nonNullEmpty() = FlatTypeMask.nonNullEmpty;
54
55 factory TypeMask.nonNullExact(ClassElement base, ClassWorld classWorld) {
56 assert(invariant(base, classWorld.isInstantiated(base),
57 message: "Cannot create extact type mask for uninstantiated class"));
58 return new FlatTypeMask.nonNullExact(base);
59 }
60
61 factory TypeMask.nonNullExactOrEmpty(ClassElement base,
62 ClassWorld classWorld) {
63 if (classWorld.isInstantiated(base)) {
64 return new FlatTypeMask.nonNullExact(base);
65 }
66 return const TypeMask.nonNullEmpty();
67 }
68
69 factory TypeMask.nonNullSubclass(ClassElement base, ClassWorld classWorld) {
70 if (classWorld.hasAnySubclass(base)) {
71 return new FlatTypeMask.nonNullSubclass(base);
72 } else {
73 return new TypeMask.nonNullExactOrEmpty(base, classWorld);
74 }
75 }
76
77 factory TypeMask.nonNullSubtype(ClassElement base, ClassWorld classWorld) {
78 if (classWorld.hasOnlySubclasses(base)) {
79 return new TypeMask.nonNullSubclass(base, classWorld);
80 }
81 if (classWorld.hasAnySubtype(base)) {
82 return new FlatTypeMask.nonNullSubtype(base);
83 } else {
84 return new TypeMask.nonNullExactOrEmpty(base, classWorld);
85 }
86 }
87
88 factory TypeMask.unionOf(Iterable<TypeMask> masks, ClassWorld classWorld) {
89 return UnionTypeMask.unionOf(masks, classWorld);
90 }
91
92 /**
93 * If [mask] is forwarding, returns the first non-forwarding [TypeMask] in
94 * [mask]'s forwarding chain.
95 */
96 static TypeMask nonForwardingMask(mask) {
97 while (mask.isForwarding) {
98 mask = mask.forwardTo;
99 }
100 return mask;
101 }
102
103 /**
104 * Asserts that this mask uses the smallest possible representation for
105 * its types. Currently, we normalize subtype and subclass to exact if no
106 * subtypes or subclasses are present and subtype to subclass if only
107 * subclasses exist. We also normalize exact to empty if the corresponding
108 * baseclass was never instantiated.
109 */
110 static bool assertIsNormalized(TypeMask mask, ClassWorld classWorld) {
111 String reason = getNotNormalizedReason(mask, classWorld);
112 return invariant(NO_LOCATION_SPANNABLE, reason == null,
113 message: () => '$mask is not normalized: $reason');
114 }
115
116 static String getNotNormalizedReason(TypeMask mask, ClassWorld classWorld) {
117 mask = nonForwardingMask(mask);
118 if (mask is FlatTypeMask) {
119 if (mask.isEmpty) return null;
120 if (mask.isExact) {
121 if (!classWorld.isInstantiated(mask.base)) {
122 return 'Exact ${mask.base} is not instantiated.';
123 }
124 return null;
125 }
126 if (mask.isSubclass) {
127 if (!classWorld.hasAnySubclass(mask.base)) {
128 return 'Subclass ${mask.base} does not have any subclasses.';
129 }
130 return null;
131 }
132 assert(mask.isSubtype);
133 if (!classWorld.hasAnySubtype(mask.base)) {
134 return 'Subtype ${mask.base} does not have any subclasses.';
135 }
136 if (classWorld.hasOnlySubclasses(mask.base)) {
137 return 'Subtype ${mask.base} only has subclasses.';
138 }
139 return null;
140 } else if (mask is UnionTypeMask) {
141 for (TypeMask submask in mask.disjointMasks) {
142 String submaskReason = getNotNormalizedReason(submask, classWorld);
143 if (submaskReason != null) {
144 return 'Submask $submask in $mask: $submaskReason.';
145 }
146 }
147 return null;
148 }
149 return 'Unknown type mask $mask.';
150 }
151
152 /**
153 * Returns a nullable variant of [this] type mask.
154 */
155 TypeMask nullable();
156
157 /**
158 * Returns a non-nullable variant of [this] type mask.
159 */
160 TypeMask nonNullable();
161
162 bool get isEmpty;
163 bool get isNullable;
164 bool get isExact;
165
166 /// Returns true if this mask is a union type.
167 bool get isUnion;
168
169 /// Returns `true` if this mask is a [ContainerTypeMask].
170 bool get isContainer;
171
172 /// Returns `true` if this mask is a [MapTypeMask].
173 bool get isMap;
174
175 /// Returns `true` if this mask is a [MapTypeMask] in dictionary mode, i.e.,
176 /// all keys are known string values and we have specific type information for
177 /// corresponding values.
178 bool get isDictionary;
179
180 /// Returns `true` if this mask is wrapping another mask for the purpose of
181 /// tracing.
182 bool get isForwarding;
183
184 /// Returns `true` if this mask holds encodes an exact value within a type.
185 bool get isValue;
186
187 bool containsOnlyInt(ClassWorld classWorld);
188 bool containsOnlyDouble(ClassWorld classWorld);
189 bool containsOnlyNum(ClassWorld classWorld);
190 bool containsOnlyBool(ClassWorld classWorld);
191 bool containsOnlyString(ClassWorld classWorld);
192 bool containsOnly(ClassElement element);
193
194 /**
195 * Compares two [TypeMask] objects for structural equality.
196 *
197 * Note: This may differ from semantic equality in the set containment sense.
198 * Use [containsMask] and [isInMask] for that, instead.
199 */
200 bool operator==(other);
201
202 /**
203 * Returns `true` if [other] is a supertype of this mask, i.e., if
204 * this mask is in [other].
205 */
206 bool isInMask(TypeMask other, ClassWorld classWorld);
207
208 /**
209 * Returns `true` if [other] is a subtype of this mask, i.e., if
210 * this mask contains [other].
211 */
212 bool containsMask(TypeMask other, ClassWorld classWorld);
213
214 /**
215 * Returns whether this type mask is an instance of [cls].
216 */
217 bool satisfies(ClassElement cls, ClassWorld classWorld);
218
219 /**
220 * Returns whether or not this type mask contains the given type.
221 */
222 bool contains(ClassElement type, ClassWorld classWorld);
223
224 /**
225 * Returns whether or not this type mask contains all types.
226 */
227 bool containsAll(ClassWorld classWorld);
228
229 /**
230 * Returns the [ClassElement] if this type represents a single class,
231 * otherwise returns `null`. This method is conservative.
232 */
233 ClassElement singleClass(ClassWorld classWorld);
234
235 /**
236 * Returns a type mask representing the union of [this] and [other].
237 */
238 TypeMask union(TypeMask other, ClassWorld classWorld);
239
240 /**
241 * Returns a type mask representing the intersection of [this] and [other].
242 */
243 TypeMask intersection(TypeMask other, ClassWorld classWorld);
244
245 /**
246 * Returns whether this [TypeMask] applied to [selector] can hit a
247 * [noSuchMethod].
248 */
249 bool needsNoSuchMethodHandling(Selector selector, ClassWorld classWorld);
250
251 /**
252 * Returns whether [element] is a potential target when being
253 * invoked on this type mask. [selector] is used to ensure library
254 * privacy is taken into account.
255 */
256 bool canHit(Element element, Selector selector, ClassWorld classWorld);
257
258 /**
259 * Returns the [element] that is known to always be hit at runtime
260 * on this mask. Returns null if there is none.
261 */
262 // TODO(johnniwinther): Move this method to [World].
263 Element locateSingleElement(Selector selector, Compiler compiler);
264 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698