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

Side by Side Diff: lib/compiler/implementation/ssa/types.dart

Issue 10389063: Implement PrimitiveOrNull types. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 7 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 | Annotate | Revision Log
« no previous file with comments | « lib/compiler/implementation/ssa/optimize.dart ('k') | tests/language/language.status » ('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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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 abstract class HType { 5 abstract class HType {
6 const HType(); 6 const HType();
7 7
8 /** 8 /**
9 * Returns a [HType] that represents all types that have [type] as a 9 * Returns an [HType] that represents [type] and all types that have
10 * supertype, or the type [type]. 10 * [type] as supertype.
11 */ 11 */
12 factory HType.fromBoundedType(Type type, 12 factory HType.fromBoundedType(Type type,
13 Compiler compiler, 13 Compiler compiler,
14 [bool canBeNull = false]) { 14 [bool canBeNull = false]) {
15 Element element = type.element; 15 Element element = type.element;
16 if (element.kind === ElementKind.TYPE_VARIABLE) { 16 if (element.kind === ElementKind.TYPE_VARIABLE) {
17 compiler.unimplemented("type variables"); 17 // TODO(ngeoffray): Replace object type with [type].
18 return new HBoundedPotentialPrimitiveType(
19 compiler.objectClass.computeType(compiler), canBeNull);
18 } 20 }
19 21
20 if (!canBeNull) { 22 if (element === compiler.intClass) {
21 if (element === compiler.intClass) { 23 return canBeNull ? HType.INTEGER_OR_NULL : HType.INTEGER;
22 return HType.INTEGER; 24 } else if (element === compiler.numClass) {
23 } else if (element === compiler.numClass) { 25 return canBeNull ? HType.NUMBER_OR_NULL : HType.NUMBER;
24 return HType.NUMBER; 26 } else if (element === compiler.doubleClass) {
25 } else if (element === compiler.doubleClass) { 27 return canBeNull ? HType.DOUBLE_OR_NULL : HType.DOUBLE;
26 return HType.DOUBLE; 28 } else if (element === compiler.stringClass) {
27 } else if (element === compiler.stringClass) { 29 return canBeNull ? HType.STRING_OR_NULL : HType.STRING;
28 return HType.STRING; 30 } else if (element === compiler.boolClass) {
29 } else if (element === compiler.boolClass) { 31 return canBeNull ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN;
30 return HType.BOOLEAN; 32 } else if (element === compiler.listClass
31 }
32 }
33 if (element === compiler.listClass
34 || Elements.isListSupertype(element, compiler)) { 33 || Elements.isListSupertype(element, compiler)) {
35 return new HBoundedPotentialPrimitiveArray(type, canBeNull); 34 return new HBoundedPotentialPrimitiveArray(type, canBeNull);
36 } else if (Elements.isStringSupertype(element, compiler)) { 35 } else if (Elements.isStringSupertype(element, compiler)) {
37 return new HBoundedPotentialPrimitiveString(type, canBeNull); 36 return new HBoundedPotentialPrimitiveString(type, canBeNull);
38 } else if (element === compiler.intClass
39 || element === compiler.boolClass
40 || element === compiler.numClass
41 || element === compiler.doubleClass
42 || element === compiler.stringClass) {
43 // TODO(ngeoffray): Create primitive nullable types.
44 return null;
45 } else { 37 } else {
46 return new HBoundedType(type, canBeNull); 38 return new HBoundedType(type, canBeNull);
47 } 39 }
48 } 40 }
49 41
50 static final HType CONFLICTING = const HAnalysisType("conflicting"); 42 static final HType CONFLICTING = const HAnalysisType("conflicting");
51 static final HType UNKNOWN = const HAnalysisType("unknown"); 43 static final HType UNKNOWN = const HAnalysisType("unknown");
52 static final HType BOOLEAN = const HBooleanType(); 44 static final HType BOOLEAN = const HBooleanType();
53 static final HType NUMBER = const HNumberType(); 45 static final HType NUMBER = const HNumberType();
54 static final HType INTEGER = const HIntegerType(); 46 static final HType INTEGER = const HIntegerType();
55 static final HType DOUBLE = const HDoubleType(); 47 static final HType DOUBLE = const HDoubleType();
56 static final HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType(); 48 static final HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType();
57 static final HType STRING = const HStringType(); 49 static final HType STRING = const HStringType();
58 static final HType READABLE_ARRAY = const HReadableArrayType(); 50 static final HType READABLE_ARRAY = const HReadableArrayType();
59 static final HType MUTABLE_ARRAY = const HMutableArrayType(); 51 static final HType MUTABLE_ARRAY = const HMutableArrayType();
60 static final HType EXTENDABLE_ARRAY = const HExtendableArrayType(); 52 static final HType EXTENDABLE_ARRAY = const HExtendableArrayType();
61 53
54 static final HType BOOLEAN_OR_NULL = const HBooleanOrNullType();
55 static final HType NUMBER_OR_NULL = const HNumberOrNullType();
56 static final HType INTEGER_OR_NULL = const HIntegerOrNullType();
57 static final HType DOUBLE_OR_NULL = const HDoubleOrNullType();
58 static final HType STRING_OR_NULL = const HStringOrNullType();
59
62 bool isConflicting() => this === CONFLICTING; 60 bool isConflicting() => this === CONFLICTING;
63 bool isUnknown() => this === UNKNOWN; 61 bool isUnknown() => this === UNKNOWN;
64 bool isBoolean() => false; 62 bool isBoolean() => false;
65 bool isNumber() => false; 63 bool isNumber() => false;
66 bool isInteger() => false; 64 bool isInteger() => false;
67 bool isDouble() => false; 65 bool isDouble() => false;
68 bool isString() => false; 66 bool isString() => false;
67 bool isBooleanOrNull() => false;
68 bool isNumberOrNull() => false;
69 bool isIntegerOrNull() => false;
70 bool isDoubleOrNull() => false;
71 bool isStringOrNull() => false;
69 bool isIndexablePrimitive() => false; 72 bool isIndexablePrimitive() => false;
70 bool isReadableArray() => false; 73 bool isReadableArray() => false;
71 bool isMutableArray() => false; 74 bool isMutableArray() => false;
72 bool isExtendableArray() => false; 75 bool isExtendableArray() => false;
73 bool isPrimitive() => false; 76 bool isPrimitive() => false;
74 bool isExact() => false; 77 bool isExact() => false;
75 78
76 bool canBePrimitive() => false; 79 bool canBePrimitive() => false;
77 bool canBeNull() => false; 80 bool canBeNull() => false;
78 81
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
132 HType union(HType other) => combine(other); 135 HType union(HType other) => combine(other);
133 HType intersection(HType other) => combine(other); 136 HType intersection(HType other) => combine(other);
134 } 137 }
135 138
136 abstract class HPrimitiveType extends HType { 139 abstract class HPrimitiveType extends HType {
137 const HPrimitiveType(); 140 const HPrimitiveType();
138 bool isPrimitive() => true; 141 bool isPrimitive() => true;
139 bool canBePrimitive() => true; 142 bool canBePrimitive() => true;
140 } 143 }
141 144
145 abstract class HPrimitiveOrNullType extends HType {
146 const HPrimitiveOrNullType();
147 bool canBePrimitive() => true;
148 bool canBeNull() => true;
149 }
150
151 class HBooleanOrNullType extends HPrimitiveOrNullType {
152 const HBooleanOrNullType();
153 String toString() => "boolean or null";
154 bool isBooleanOrNull() => true;
155
156 Type computeType(Compiler compiler) {
157 return compiler.boolClass.computeType(compiler);
158 }
159
160 HType union(HType other) {
161 if (other.isUnknown()) return HType.BOOLEAN_OR_NULL;
162 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
163 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL;
164 return HType.CONFLICTING;
165 }
166
167 HType intersection(HType other) {
168 if (other.isUnknown()) return HType.BOOLEAN_OR_NULL;
169 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
170 if (other.isBoolean()) return HType.BOOLEAN;
171 return HType.CONFLICTING;
172 }
173 }
174
142 class HBooleanType extends HPrimitiveType { 175 class HBooleanType extends HPrimitiveType {
143 const HBooleanType(); 176 const HBooleanType();
144 bool isBoolean() => true; 177 bool isBoolean() => true;
145 String toString() => "boolean"; 178 String toString() => "boolean";
146 179
147 Type computeType(Compiler compiler) { 180 Type computeType(Compiler compiler) {
148 return compiler.boolClass.computeType(compiler); 181 return compiler.boolClass.computeType(compiler);
149 } 182 }
150 183
151 HType combine(HType other) { 184 HType union(HType other) {
152 if (other.isBoolean() || other.isUnknown()) return HType.BOOLEAN; 185 if (other.isUnknown()) return HType.BOOLEAN;
186 if (other.isBoolean()) return HType.BOOLEAN;
187 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL;
153 return HType.CONFLICTING; 188 return HType.CONFLICTING;
154 } 189 }
155 190
156 // Since the boolean type is a one-element set the union and intersection are 191 HType intersection(HType other) {
157 // the same. 192 if (other.isUnknown()) return HType.BOOLEAN;
158 HType union(HType other) => combine(other); 193 if (other.isBooleanOrNull()) return HType.BOOLEAN;
159 HType intersection(HType other) => combine(other); 194 if (other.isBoolean()) return HType.BOOLEAN;
195 return HType.CONFLICTING;
196 }
197 }
198
199 class HNumberOrNullType extends HPrimitiveOrNullType {
200 const HNumberOrNullType();
201 bool isNumberOrNull() => true;
202 String toString() => "number or null";
203
204 Type computeType(Compiler compiler) {
205 return compiler.numClass.computeType(compiler);
206 }
207
208 HType union(HType other) {
209 if (other.isUnknown()) return HType.NUMBER_OR_NULL;
210 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
211 if (other.isNumber()) return HType.NUMBER_OR_NULL;
212 return HType.CONFLICTING;
213 }
214
215 HType intersection(HType other) {
216 if (other.isUnknown()) return HType.NUMBER_OR_NULL;
217 if (other.isInteger()) return HType.INTEGER;
218 if (other.isDouble()) return HType.DOUBLE;
219 if (other.isNumber()) return HType.NUMBER;
220 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
221 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
222 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
223 return HType.CONFLICTING;
224 }
160 } 225 }
161 226
162 class HNumberType extends HPrimitiveType { 227 class HNumberType extends HPrimitiveType {
163 const HNumberType(); 228 const HNumberType();
164 bool isNumber() => true; 229 bool isNumber() => true;
165 String toString() => "number"; 230 String toString() => "number";
166 231
167 Type computeType(Compiler compiler) { 232 Type computeType(Compiler compiler) {
168 return compiler.numClass.computeType(compiler); 233 return compiler.numClass.computeType(compiler);
169 } 234 }
170 235
171 HType union(HType other) { 236 HType union(HType other) {
172 if (other.isNumber() || other.isUnknown()) return HType.NUMBER; 237 if (other.isNumber()) return HType.NUMBER;
238 if (other.isUnknown()) return HType.NUMBER;
239 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
173 return HType.CONFLICTING; 240 return HType.CONFLICTING;
174 } 241 }
175 242
176 HType intersection(HType other) { 243 HType intersection(HType other) {
177 if (other.isUnknown()) return HType.NUMBER; 244 if (other.isUnknown()) return HType.NUMBER;
178 if (other.isNumber()) return other; 245 if (other.isNumber()) return other;
246 if (other.isIntegerOrNull()) return HType.INTEGER;
247 if (other.isDoubleOrNull()) return HType.DOUBLE;
248 if (other.isNumberOrNull()) return HType.NUMBER;
249 return HType.CONFLICTING;
250 }
251 }
252
253 class HIntegerOrNullType extends HNumberOrNullType {
254 const HIntegerOrNullType();
255 bool isIntegerOrNull() => true;
256 String toString() => "integer or null";
257
258 Type computeType(Compiler compiler) {
259 return compiler.intClass.computeType(compiler);
260 }
261
262 HType union(HType other) {
263 if (other.isUnknown()) return HType.INTEGER_OR_NULL;
264 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
265 if (other.isInteger()) return HType.INTEGER_OR_NULL;
266 if (other.isNumber()) return HType.NUMBER_OR_NULL;
267 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
268 return HType.CONFLICTING;
269 }
270
271 HType intersection(HType other) {
272 if (other.isUnknown()) return HType.INTEGER_OR_NULL;
273 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
274 if (other.isInteger()) return HType.INTEGER;
275 if (other.isDouble()) return HType.CONFLICTING;
276 if (other.isDoubleOrNull()) return HType.CONFLICTING;
277 if (other.isNumber()) return HType.INTEGER;
278 if (other.isNumberOrNull()) return HType.INTEGER_OR_NULL;
179 return HType.CONFLICTING; 279 return HType.CONFLICTING;
180 } 280 }
181 } 281 }
182 282
183 class HIntegerType extends HNumberType { 283 class HIntegerType extends HNumberType {
184 const HIntegerType(); 284 const HIntegerType();
185 bool isInteger() => true; 285 bool isInteger() => true;
186 String toString() => "integer"; 286 String toString() => "integer";
187 287
188 Type computeType(Compiler compiler) { 288 Type computeType(Compiler compiler) {
189 return compiler.intClass.computeType(compiler); 289 return compiler.intClass.computeType(compiler);
190 } 290 }
191 291
192 HType union(HType other) { 292 HType union(HType other) {
193 if (other.isInteger() || other.isUnknown()) return HType.INTEGER; 293 if (other.isUnknown()) return HType.INTEGER;
294 if (other.isInteger()) return HType.INTEGER;
295 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL;
194 if (other.isNumber()) return HType.NUMBER; 296 if (other.isNumber()) return HType.NUMBER;
297 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
195 return HType.CONFLICTING; 298 return HType.CONFLICTING;
196 } 299 }
197 300
198 HType intersection(HType other) { 301 HType intersection(HType other) {
199 if (other.isUnknown()) return HType.INTEGER; 302 if (other.isUnknown()) return HType.INTEGER;
303 if (other.isIntegerOrNull()) return HType.INTEGER;
304 if (other.isInteger()) return HType.INTEGER;
200 if (other.isDouble()) return HType.CONFLICTING; 305 if (other.isDouble()) return HType.CONFLICTING;
201 if (other.isNumber()) return this; 306 if (other.isDoubleOrNull()) return HType.CONFLICTING;
307 if (other.isNumber()) return HType.INTEGER;
308 if (other.isNumberOrNull()) return HType.INTEGER;
309 return HType.CONFLICTING;
310 }
311 }
312
313 class HDoubleOrNullType extends HNumberOrNullType {
314 const HDoubleOrNullType();
315 bool isDoubleOrNull() => true;
316 String toString() => "double or null";
317
318 Type computeType(Compiler compiler) {
319 return compiler.doubleClass.computeType(compiler);
320 }
321
322 HType union(HType other) {
323 if (other.isUnknown()) return HType.DOUBLE_OR_NULL;
324 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
325 if (other.isDouble()) return HType.DOUBLE_OR_NULL;
326 if (other.isNumber()) return HType.NUMBER_OR_NULL;
327 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
328 return HType.CONFLICTING;
329 }
330
331 HType intersection(HType other) {
332 if (other.isUnknown()) return HType.DOUBLE_OR_NULL;
333 if (other.isIntegerOrNull()) return HType.CONFLICTING;
334 if (other.isInteger()) return HType.CONFLICTING;
335 if (other.isDouble()) return HType.DOUBLE;
336 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
337 if (other.isNumber()) return HType.DOUBLE;
338 if (other.isNumberOrNull()) return HType.DOUBLE_OR_NULL;
202 return HType.CONFLICTING; 339 return HType.CONFLICTING;
203 } 340 }
204 } 341 }
205 342
206 class HDoubleType extends HNumberType { 343 class HDoubleType extends HNumberType {
207 const HDoubleType(); 344 const HDoubleType();
208 bool isDouble() => true; 345 bool isDouble() => true;
209 String toString() => "double"; 346 String toString() => "double";
210 347
211 Type computeType(Compiler compiler) { 348 Type computeType(Compiler compiler) {
212 return compiler.doubleClass.computeType(compiler); 349 return compiler.doubleClass.computeType(compiler);
213 } 350 }
214 351
215 HType union(HType other) { 352 HType union(HType other) {
216 if (other.isDouble() || other.isUnknown()) return HType.DOUBLE; 353 if (other.isUnknown()) return HType.DOUBLE;
354 if (other.isDouble()) return HType.DOUBLE;
355 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL;
217 if (other.isNumber()) return HType.NUMBER; 356 if (other.isNumber()) return HType.NUMBER;
357 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL;
218 return HType.CONFLICTING; 358 return HType.CONFLICTING;
219 } 359 }
220 360
221 HType intersection(HType other) { 361 HType intersection(HType other) {
222 if (other.isUnknown()) return HType.DOUBLE; 362 if (other.isUnknown()) return HType.DOUBLE;
363 if (other.isIntegerOrNull()) return HType.CONFLICTING;
223 if (other.isInteger()) return HType.CONFLICTING; 364 if (other.isInteger()) return HType.CONFLICTING;
224 if (other.isNumber()) return this; 365 if (other.isDouble()) return HType.DOUBLE;
366 if (other.isDoubleOrNull()) return HType.DOUBLE;
367 if (other.isNumber()) return HType.DOUBLE;
368 if (other.isNumberOrNull()) return HType.DOUBLE;
225 return HType.CONFLICTING; 369 return HType.CONFLICTING;
226 } 370 }
227 } 371 }
228 372
229 class HIndexablePrimitiveType extends HPrimitiveType { 373 class HIndexablePrimitiveType extends HPrimitiveType {
230 const HIndexablePrimitiveType(); 374 const HIndexablePrimitiveType();
231 bool isIndexablePrimitive() => true; 375 bool isIndexablePrimitive() => true;
232 String toString() => "indexable"; 376 String toString() => "indexable";
233 377
234 Type computeType(Compiler compiler) { 378 Type computeType(Compiler compiler) {
(...skipping 17 matching lines...) Expand all
252 396
253 HType intersection(HType other) { 397 HType intersection(HType other) {
254 if (other.isUnknown()) return HType.INDEXABLE_PRIMITIVE; 398 if (other.isUnknown()) return HType.INDEXABLE_PRIMITIVE;
255 if (other.isIndexablePrimitive()) return other; 399 if (other.isIndexablePrimitive()) return other;
256 if (other is HBoundedPotentialPrimitiveString) return HType.STRING; 400 if (other is HBoundedPotentialPrimitiveString) return HType.STRING;
257 if (other is HBoundedPotentialPrimitiveArray) return HType.READABLE_ARRAY; 401 if (other is HBoundedPotentialPrimitiveArray) return HType.READABLE_ARRAY;
258 return HType.CONFLICTING; 402 return HType.CONFLICTING;
259 } 403 }
260 } 404 }
261 405
406 class HStringOrNullType extends HPrimitiveOrNullType {
407 const HStringOrNullType();
408 bool isStringOrNull() => true;
409 String toString() => "String or null";
410
411 Type computeType(Compiler compiler) {
412 return compiler.stringClass.computeType(compiler);
413 }
414
415 HType union(HType other) {
416 if (other.isUnknown()) return HType.STRING_OR_NULL;
417 if (other.isString()) return HType.STRING_OR_NULL;
418 if (other.isStringOrNull()) return HType.STRING_OR_NULL;
419 if (other.isIndexablePrimitive()) {
420 // We don't have a type that represents the nullable indexable
421 // primitive.
422 return HType.CONFLICTING;
423 }
424 if (other is HBoundedPotentialPrimitiveString) {
425 if (other.canBeNull()) {
426 return other;
427 } else {
428 HBoundedType boundedType = other;
429 return new HBoundedPotentialPrimitiveString(boundedType.type, true);
430 }
431 }
432 return HType.CONFLICTING;
433 }
434
435 HType intersection(HType other) {
436 if (other.isUnknown()) return HType.STRING_OR_NULL;
437 if (other.isString()) return HType.STRING;
438 if (other.isStringOrNull()) return HType.STRING_OR_NULL;
439 if (other.isArray()) return HType.CONFLICTING;
440 if (other.isIndexablePrimitive()) return HType.STRING;
441 if (other is HBoundedPotentialPrimitiveString) {
442 return other.canBeNull() ? HType.STRING_OR_NULL : HType.STRING;
443 }
444 return HType.CONFLICTING;
445 }
446 }
447
262 class HStringType extends HIndexablePrimitiveType { 448 class HStringType extends HIndexablePrimitiveType {
263 const HStringType(); 449 const HStringType();
264 bool isString() => true; 450 bool isString() => true;
265 String toString() => "String"; 451 String toString() => "String";
266 452
267 Type computeType(Compiler compiler) { 453 Type computeType(Compiler compiler) {
268 return compiler.stringClass.computeType(compiler); 454 return compiler.stringClass.computeType(compiler);
269 } 455 }
270 456
271 HType union(HType other) { 457 HType union(HType other) {
272 if (other.isUnknown()) return HType.STRING; 458 if (other.isUnknown()) return HType.STRING;
273 if (other.isString()) return HType.STRING; 459 if (other.isString()) return HType.STRING;
460 if (other.isStringOrNull()) return HType.STRING_OR_NULL;
274 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; 461 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE;
275 if (other is HBoundedPotentialPrimitiveString) return other; 462 if (other is HBoundedPotentialPrimitiveString) return other;
276 return HType.CONFLICTING; 463 return HType.CONFLICTING;
277 } 464 }
278 465
279 HType intersection(HType other) { 466 HType intersection(HType other) {
280 if (other.isUnknown()) return HType.STRING; 467 if (other.isUnknown()) return HType.STRING;
281 if (other.isString()) return HType.STRING; 468 if (other.isString()) return HType.STRING;
282 if (other.isArray()) return HType.CONFLICTING; 469 if (other.isArray()) return HType.CONFLICTING;
283 if (other.isIndexablePrimitive()) return HType.STRING; 470 if (other.isIndexablePrimitive()) return HType.STRING;
471 if (other.isStringOrNull()) return HType.STRING;
284 if (other is HBoundedPotentialPrimitiveString) return HType.STRING; 472 if (other is HBoundedPotentialPrimitiveString) return HType.STRING;
285 return HType.CONFLICTING; 473 return HType.CONFLICTING;
286 } 474 }
287 } 475 }
288 476
289 class HReadableArrayType extends HIndexablePrimitiveType { 477 class HReadableArrayType extends HIndexablePrimitiveType {
290 const HReadableArrayType(); 478 const HReadableArrayType();
291 bool isReadableArray() => true; 479 bool isReadableArray() => true;
292 String toString() => "readable array"; 480 String toString() => "readable array";
293 481
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after
401 HType combine(HType other) { 589 HType combine(HType other) {
402 if (other.isExact()) { 590 if (other.isExact()) {
403 HExactType concrete = other; 591 HExactType concrete = other;
404 if (this.type === concrete.type) return this; 592 if (this.type === concrete.type) return this;
405 } 593 }
406 if (other.isUnknown()) return this; 594 if (other.isUnknown()) return this;
407 return HType.CONFLICTING; 595 return HType.CONFLICTING;
408 } 596 }
409 } 597 }
410 598
411 class HBoundedPotentialPrimitiveArray extends HBoundedType { 599 class HBoundedPotentialPrimitiveType extends HBoundedType {
600 const HBoundedPotentialPrimitiveType(Type type, bool canBeNull)
601 : super(type, canBeNull);
602 bool canBePrimitive() => true;
603 }
604
605 class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType {
412 const HBoundedPotentialPrimitiveArray(Type type, bool canBeNull) 606 const HBoundedPotentialPrimitiveArray(Type type, bool canBeNull)
413 : super(type, canBeNull); 607 : super(type, canBeNull);
414 bool canBePrimitive() => true;
415 608
416 HType union(HType other) { 609 HType union(HType other) {
417 if (other.isString()) return HType.CONFLICTING; 610 if (other.isString()) return HType.CONFLICTING;
418 if (other.isReadableArray()) return this; 611 if (other.isReadableArray()) return this;
419 // TODO(ngeoffray): implement union types. 612 // TODO(ngeoffray): implement union types.
420 if (other.isIndexablePrimitive()) return HType.CONFLICTING; 613 if (other.isIndexablePrimitive()) return HType.CONFLICTING;
421 return super.union(other); 614 return super.union(other);
422 } 615 }
423 616
424 HType intersection(HType other) { 617 HType intersection(HType other) {
425 if (other.isString()) return HType.CONFLICTING; 618 if (other.isString()) return HType.CONFLICTING;
426 if (other.isReadableArray()) return other; 619 if (other.isReadableArray()) return other;
427 if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY; 620 if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY;
428 return super.intersection(other); 621 return super.intersection(other);
429 } 622 }
430 } 623 }
431 624
432 class HBoundedPotentialPrimitiveString extends HBoundedType { 625 class HBoundedPotentialPrimitiveString extends HBoundedPotentialPrimitiveType {
433 const HBoundedPotentialPrimitiveString(Type type, bool canBeNull) 626 const HBoundedPotentialPrimitiveString(Type type, bool canBeNull)
434 : super(type, canBeNull); 627 : super(type, canBeNull);
435 bool canBePrimitive() => true;
436 628
437 HType union(HType other) { 629 HType union(HType other) {
438 if (other.isString()) return this; 630 if (other.isString()) return this;
631 if (other.isStringOrNull()) {
632 if (canBeNull()) {
633 return this;
634 } else {
635 return new HBoundedPotentialPrimitiveString(type, true);
636 }
637 }
439 // TODO(ngeoffray): implement union types. 638 // TODO(ngeoffray): implement union types.
440 if (other.isIndexablePrimitive()) return HType.CONFLICTING; 639 if (other.isIndexablePrimitive()) return HType.CONFLICTING;
441 return super.union(other); 640 return super.union(other);
442 } 641 }
443 642
444 HType intersection(HType other) { 643 HType intersection(HType other) {
445 if (other.isString()) return HType.STRING; 644 if (other.isString()) return HType.STRING;
645 if (other.isStringOrNull()) {
646 return canBeNull() ? HType.STRING_OR_NULL : HType.STRING;
647 }
446 if (other.isReadableArray()) return HType.CONFLICTING; 648 if (other.isReadableArray()) return HType.CONFLICTING;
447 if (other.isIndexablePrimitive()) return HType.STRING; 649 if (other.isIndexablePrimitive()) return HType.STRING;
448 return super.intersection(other); 650 return super.intersection(other);
449 } 651 }
450 } 652 }
OLDNEW
« no previous file with comments | « lib/compiler/implementation/ssa/optimize.dart ('k') | tests/language/language.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698