OLD | NEW |
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 an [HType] that represents [type] and all types that have | 9 * Returns an [HType] that represents [type] and all types that have |
10 * [type] as supertype. | 10 * [type] as supertype. |
11 */ | 11 */ |
12 factory HType.fromBoundedType(Type type, | 12 factory HType.fromBoundedType(DartType 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 // TODO(ngeoffray): Replace object type with [type]. | 17 // TODO(ngeoffray): Replace object type with [type]. |
18 return new HBoundedPotentialPrimitiveType( | 18 return new HBoundedPotentialPrimitiveType( |
19 compiler.objectClass.computeType(compiler), canBeNull); | 19 compiler.objectClass.computeType(compiler), canBeNull); |
20 } | 20 } |
21 | 21 |
22 if (element === compiler.intClass) { | 22 if (element === compiler.intClass) { |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
80 bool isExact() => false; | 80 bool isExact() => false; |
81 | 81 |
82 bool canBePrimitive() => false; | 82 bool canBePrimitive() => false; |
83 bool canBeNull() => false; | 83 bool canBeNull() => false; |
84 | 84 |
85 /** A type is useful it is not unknown, not conflicting, and not null. */ | 85 /** A type is useful it is not unknown, not conflicting, and not null. */ |
86 bool isUseful() => !isUnknown() && !isConflicting() && !isNull(); | 86 bool isUseful() => !isUnknown() && !isConflicting() && !isNull(); |
87 /** Alias for isReadableArray. */ | 87 /** Alias for isReadableArray. */ |
88 bool isArray() => isReadableArray(); | 88 bool isArray() => isReadableArray(); |
89 | 89 |
90 abstract Type computeType(Compiler compiler); | 90 abstract DartType computeType(Compiler compiler); |
91 | 91 |
92 /** | 92 /** |
93 * The intersection of two types is the intersection of its values. For | 93 * The intersection of two types is the intersection of its values. For |
94 * example: | 94 * example: |
95 * * INTEGER.intersect(NUMBER) => INTEGER. | 95 * * INTEGER.intersect(NUMBER) => INTEGER. |
96 * * DOUBLE.intersect(INTEGER) => CONFLICTING. | 96 * * DOUBLE.intersect(INTEGER) => CONFLICTING. |
97 * * MUTABLE_ARRAY.intersect(READABLE_ARRAY) => MUTABLE_ARRAY. | 97 * * MUTABLE_ARRAY.intersect(READABLE_ARRAY) => MUTABLE_ARRAY. |
98 * | 98 * |
99 * When there is no predefined type to represent the intersection returns | 99 * When there is no predefined type to represent the intersection returns |
100 * [CONFLICTING]. | 100 * [CONFLICTING]. |
(...skipping 17 matching lines...) Expand all Loading... |
118 */ | 118 */ |
119 abstract HType union(HType other); | 119 abstract HType union(HType other); |
120 } | 120 } |
121 | 121 |
122 /** Used to represent [HType.UNKNOWN] and [HType.CONFLICTING]. */ | 122 /** Used to represent [HType.UNKNOWN] and [HType.CONFLICTING]. */ |
123 abstract class HAnalysisType extends HType { | 123 abstract class HAnalysisType extends HType { |
124 final String name; | 124 final String name; |
125 const HAnalysisType(this.name); | 125 const HAnalysisType(this.name); |
126 String toString() => name; | 126 String toString() => name; |
127 | 127 |
128 Type computeType(Compiler compiler) => null; | 128 DartType computeType(Compiler compiler) => null; |
129 } | 129 } |
130 | 130 |
131 class HUnknownType extends HAnalysisType { | 131 class HUnknownType extends HAnalysisType { |
132 const HUnknownType() : super("unknown"); | 132 const HUnknownType() : super("unknown"); |
133 bool canBePrimitive() => true; | 133 bool canBePrimitive() => true; |
134 bool canBeNull() => true; | 134 bool canBeNull() => true; |
135 | 135 |
136 HType union(HType other) => this; | 136 HType union(HType other) => this; |
137 HType intersection(HType other) => other; | 137 HType intersection(HType other) => other; |
138 } | 138 } |
(...skipping 12 matching lines...) Expand all Loading... |
151 bool isPrimitive() => true; | 151 bool isPrimitive() => true; |
152 bool canBePrimitive() => true; | 152 bool canBePrimitive() => true; |
153 } | 153 } |
154 | 154 |
155 class HNullType extends HPrimitiveType { | 155 class HNullType extends HPrimitiveType { |
156 const HNullType(); | 156 const HNullType(); |
157 bool canBeNull() => true; | 157 bool canBeNull() => true; |
158 bool isNull() => true; | 158 bool isNull() => true; |
159 String toString() => 'null'; | 159 String toString() => 'null'; |
160 | 160 |
161 Type computeType(Compiler compiler) => null; | 161 DartType computeType(Compiler compiler) => null; |
162 | 162 |
163 HType union(HType other) { | 163 HType union(HType other) { |
164 if (other.isConflicting()) return HType.NULL; | 164 if (other.isConflicting()) return HType.NULL; |
165 if (other.isUnknown()) return HType.UNKNOWN; | 165 if (other.isUnknown()) return HType.UNKNOWN; |
166 if (other.isString()) return HType.STRING_OR_NULL; | 166 if (other.isString()) return HType.STRING_OR_NULL; |
167 if (other.isInteger()) return HType.INTEGER_OR_NULL; | 167 if (other.isInteger()) return HType.INTEGER_OR_NULL; |
168 if (other.isDouble()) return HType.DOUBLE_OR_NULL; | 168 if (other.isDouble()) return HType.DOUBLE_OR_NULL; |
169 if (other.isNumber()) return HType.NUMBER_OR_NULL; | 169 if (other.isNumber()) return HType.NUMBER_OR_NULL; |
170 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL; | 170 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL; |
171 if (!other.canBeNull()) return HType.UNKNOWN; | 171 if (!other.canBeNull()) return HType.UNKNOWN; |
(...skipping 12 matching lines...) Expand all Loading... |
184 const HPrimitiveOrNullType(); | 184 const HPrimitiveOrNullType(); |
185 bool canBePrimitive() => true; | 185 bool canBePrimitive() => true; |
186 bool canBeNull() => true; | 186 bool canBeNull() => true; |
187 } | 187 } |
188 | 188 |
189 class HBooleanOrNullType extends HPrimitiveOrNullType { | 189 class HBooleanOrNullType extends HPrimitiveOrNullType { |
190 const HBooleanOrNullType(); | 190 const HBooleanOrNullType(); |
191 String toString() => "boolean or null"; | 191 String toString() => "boolean or null"; |
192 bool isBooleanOrNull() => true; | 192 bool isBooleanOrNull() => true; |
193 | 193 |
194 Type computeType(Compiler compiler) { | 194 DartType computeType(Compiler compiler) { |
195 return compiler.boolClass.computeType(compiler); | 195 return compiler.boolClass.computeType(compiler); |
196 } | 196 } |
197 | 197 |
198 HType union(HType other) { | 198 HType union(HType other) { |
199 if (other.isConflicting()) return HType.BOOLEAN_OR_NULL; | 199 if (other.isConflicting()) return HType.BOOLEAN_OR_NULL; |
200 if (other.isUnknown()) return HType.UNKNOWN; | 200 if (other.isUnknown()) return HType.UNKNOWN; |
201 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; | 201 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; |
202 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL; | 202 if (other.isBoolean()) return HType.BOOLEAN_OR_NULL; |
203 if (other.isNull()) return HType.BOOLEAN_OR_NULL; | 203 if (other.isNull()) return HType.BOOLEAN_OR_NULL; |
204 return HType.UNKNOWN; | 204 return HType.UNKNOWN; |
205 } | 205 } |
206 | 206 |
207 HType intersection(HType other) { | 207 HType intersection(HType other) { |
208 if (other.isUnknown()) return HType.BOOLEAN_OR_NULL; | 208 if (other.isUnknown()) return HType.BOOLEAN_OR_NULL; |
209 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; | 209 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; |
210 if (other.isBoolean()) return HType.BOOLEAN; | 210 if (other.isBoolean()) return HType.BOOLEAN; |
211 if (other.canBeNull()) return HType.NULL; | 211 if (other.canBeNull()) return HType.NULL; |
212 return HType.CONFLICTING; | 212 return HType.CONFLICTING; |
213 } | 213 } |
214 } | 214 } |
215 | 215 |
216 class HBooleanType extends HPrimitiveType { | 216 class HBooleanType extends HPrimitiveType { |
217 const HBooleanType(); | 217 const HBooleanType(); |
218 bool isBoolean() => true; | 218 bool isBoolean() => true; |
219 String toString() => "boolean"; | 219 String toString() => "boolean"; |
220 | 220 |
221 Type computeType(Compiler compiler) { | 221 DartType computeType(Compiler compiler) { |
222 return compiler.boolClass.computeType(compiler); | 222 return compiler.boolClass.computeType(compiler); |
223 } | 223 } |
224 | 224 |
225 HType union(HType other) { | 225 HType union(HType other) { |
226 if (other.isConflicting()) return HType.BOOLEAN; | 226 if (other.isConflicting()) return HType.BOOLEAN; |
227 if (other.isUnknown()) return HType.UNKNOWN; | 227 if (other.isUnknown()) return HType.UNKNOWN; |
228 if (other.isBoolean()) return HType.BOOLEAN; | 228 if (other.isBoolean()) return HType.BOOLEAN; |
229 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; | 229 if (other.isBooleanOrNull()) return HType.BOOLEAN_OR_NULL; |
230 if (other.isNull()) return HType.BOOLEAN_OR_NULL; | 230 if (other.isNull()) return HType.BOOLEAN_OR_NULL; |
231 return HType.UNKNOWN; | 231 return HType.UNKNOWN; |
232 } | 232 } |
233 | 233 |
234 HType intersection(HType other) { | 234 HType intersection(HType other) { |
235 if (other.isUnknown()) return HType.BOOLEAN; | 235 if (other.isUnknown()) return HType.BOOLEAN; |
236 if (other.isBooleanOrNull()) return HType.BOOLEAN; | 236 if (other.isBooleanOrNull()) return HType.BOOLEAN; |
237 if (other.isBoolean()) return HType.BOOLEAN; | 237 if (other.isBoolean()) return HType.BOOLEAN; |
238 return HType.CONFLICTING; | 238 return HType.CONFLICTING; |
239 } | 239 } |
240 } | 240 } |
241 | 241 |
242 class HNumberOrNullType extends HPrimitiveOrNullType { | 242 class HNumberOrNullType extends HPrimitiveOrNullType { |
243 const HNumberOrNullType(); | 243 const HNumberOrNullType(); |
244 bool isNumberOrNull() => true; | 244 bool isNumberOrNull() => true; |
245 String toString() => "number or null"; | 245 String toString() => "number or null"; |
246 | 246 |
247 Type computeType(Compiler compiler) { | 247 DartType computeType(Compiler compiler) { |
248 return compiler.numClass.computeType(compiler); | 248 return compiler.numClass.computeType(compiler); |
249 } | 249 } |
250 | 250 |
251 HType union(HType other) { | 251 HType union(HType other) { |
252 if (other.isConflicting()) return HType.NUMBER_OR_NULL; | 252 if (other.isConflicting()) return HType.NUMBER_OR_NULL; |
253 if (other.isUnknown()) return HType.UNKNOWN; | 253 if (other.isUnknown()) return HType.UNKNOWN; |
254 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; | 254 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; |
255 if (other.isNumber()) return HType.NUMBER_OR_NULL; | 255 if (other.isNumber()) return HType.NUMBER_OR_NULL; |
256 if (other.isNull()) return HType.NUMBER_OR_NULL; | 256 if (other.isNull()) return HType.NUMBER_OR_NULL; |
257 return HType.UNKNOWN; | 257 return HType.UNKNOWN; |
(...skipping 10 matching lines...) Expand all Loading... |
268 if (other.canBeNull()) return HType.NULL; | 268 if (other.canBeNull()) return HType.NULL; |
269 return HType.CONFLICTING; | 269 return HType.CONFLICTING; |
270 } | 270 } |
271 } | 271 } |
272 | 272 |
273 class HNumberType extends HPrimitiveType { | 273 class HNumberType extends HPrimitiveType { |
274 const HNumberType(); | 274 const HNumberType(); |
275 bool isNumber() => true; | 275 bool isNumber() => true; |
276 String toString() => "number"; | 276 String toString() => "number"; |
277 | 277 |
278 Type computeType(Compiler compiler) { | 278 DartType computeType(Compiler compiler) { |
279 return compiler.numClass.computeType(compiler); | 279 return compiler.numClass.computeType(compiler); |
280 } | 280 } |
281 | 281 |
282 HType union(HType other) { | 282 HType union(HType other) { |
283 if (other.isConflicting()) return HType.NUMBER; | 283 if (other.isConflicting()) return HType.NUMBER; |
284 if (other.isUnknown()) return HType.UNKNOWN; | 284 if (other.isUnknown()) return HType.UNKNOWN; |
285 if (other.isNumber()) return HType.NUMBER; | 285 if (other.isNumber()) return HType.NUMBER; |
286 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; | 286 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; |
287 if (other.isNull()) return HType.NUMBER_OR_NULL; | 287 if (other.isNull()) return HType.NUMBER_OR_NULL; |
288 return HType.UNKNOWN; | 288 return HType.UNKNOWN; |
289 } | 289 } |
290 | 290 |
291 HType intersection(HType other) { | 291 HType intersection(HType other) { |
292 if (other.isUnknown()) return HType.NUMBER; | 292 if (other.isUnknown()) return HType.NUMBER; |
293 if (other.isNumber()) return other; | 293 if (other.isNumber()) return other; |
294 if (other.isIntegerOrNull()) return HType.INTEGER; | 294 if (other.isIntegerOrNull()) return HType.INTEGER; |
295 if (other.isDoubleOrNull()) return HType.DOUBLE; | 295 if (other.isDoubleOrNull()) return HType.DOUBLE; |
296 if (other.isNumberOrNull()) return HType.NUMBER; | 296 if (other.isNumberOrNull()) return HType.NUMBER; |
297 return HType.CONFLICTING; | 297 return HType.CONFLICTING; |
298 } | 298 } |
299 } | 299 } |
300 | 300 |
301 class HIntegerOrNullType extends HNumberOrNullType { | 301 class HIntegerOrNullType extends HNumberOrNullType { |
302 const HIntegerOrNullType(); | 302 const HIntegerOrNullType(); |
303 bool isIntegerOrNull() => true; | 303 bool isIntegerOrNull() => true; |
304 String toString() => "integer or null"; | 304 String toString() => "integer or null"; |
305 | 305 |
306 Type computeType(Compiler compiler) { | 306 DartType computeType(Compiler compiler) { |
307 return compiler.intClass.computeType(compiler); | 307 return compiler.intClass.computeType(compiler); |
308 } | 308 } |
309 | 309 |
310 HType union(HType other) { | 310 HType union(HType other) { |
311 if (other.isConflicting()) return HType.INTEGER_OR_NULL; | 311 if (other.isConflicting()) return HType.INTEGER_OR_NULL; |
312 if (other.isUnknown()) return HType.UNKNOWN; | 312 if (other.isUnknown()) return HType.UNKNOWN; |
313 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; | 313 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; |
314 if (other.isInteger()) return HType.INTEGER_OR_NULL; | 314 if (other.isInteger()) return HType.INTEGER_OR_NULL; |
315 if (other.isNumber()) return HType.NUMBER_OR_NULL; | 315 if (other.isNumber()) return HType.NUMBER_OR_NULL; |
316 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; | 316 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; |
(...skipping 12 matching lines...) Expand all Loading... |
329 if (other.canBeNull()) return HType.NULL; | 329 if (other.canBeNull()) return HType.NULL; |
330 return HType.CONFLICTING; | 330 return HType.CONFLICTING; |
331 } | 331 } |
332 } | 332 } |
333 | 333 |
334 class HIntegerType extends HNumberType { | 334 class HIntegerType extends HNumberType { |
335 const HIntegerType(); | 335 const HIntegerType(); |
336 bool isInteger() => true; | 336 bool isInteger() => true; |
337 String toString() => "integer"; | 337 String toString() => "integer"; |
338 | 338 |
339 Type computeType(Compiler compiler) { | 339 DartType computeType(Compiler compiler) { |
340 return compiler.intClass.computeType(compiler); | 340 return compiler.intClass.computeType(compiler); |
341 } | 341 } |
342 | 342 |
343 HType union(HType other) { | 343 HType union(HType other) { |
344 if (other.isConflicting()) return HType.INTEGER; | 344 if (other.isConflicting()) return HType.INTEGER; |
345 if (other.isUnknown()) return HType.UNKNOWN; | 345 if (other.isUnknown()) return HType.UNKNOWN; |
346 if (other.isInteger()) return HType.INTEGER; | 346 if (other.isInteger()) return HType.INTEGER; |
347 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; | 347 if (other.isIntegerOrNull()) return HType.INTEGER_OR_NULL; |
348 if (other.isNumber()) return HType.NUMBER; | 348 if (other.isNumber()) return HType.NUMBER; |
349 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; | 349 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; |
(...skipping 11 matching lines...) Expand all Loading... |
361 if (other.isNumberOrNull()) return HType.INTEGER; | 361 if (other.isNumberOrNull()) return HType.INTEGER; |
362 return HType.CONFLICTING; | 362 return HType.CONFLICTING; |
363 } | 363 } |
364 } | 364 } |
365 | 365 |
366 class HDoubleOrNullType extends HNumberOrNullType { | 366 class HDoubleOrNullType extends HNumberOrNullType { |
367 const HDoubleOrNullType(); | 367 const HDoubleOrNullType(); |
368 bool isDoubleOrNull() => true; | 368 bool isDoubleOrNull() => true; |
369 String toString() => "double or null"; | 369 String toString() => "double or null"; |
370 | 370 |
371 Type computeType(Compiler compiler) { | 371 DartType computeType(Compiler compiler) { |
372 return compiler.doubleClass.computeType(compiler); | 372 return compiler.doubleClass.computeType(compiler); |
373 } | 373 } |
374 | 374 |
375 HType union(HType other) { | 375 HType union(HType other) { |
376 if (other.isConflicting()) return HType.DOUBLE_OR_NULL; | 376 if (other.isConflicting()) return HType.DOUBLE_OR_NULL; |
377 if (other.isUnknown()) return HType.UNKNOWN; | 377 if (other.isUnknown()) return HType.UNKNOWN; |
378 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; | 378 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; |
379 if (other.isDouble()) return HType.DOUBLE_OR_NULL; | 379 if (other.isDouble()) return HType.DOUBLE_OR_NULL; |
380 if (other.isNumber()) return HType.NUMBER_OR_NULL; | 380 if (other.isNumber()) return HType.NUMBER_OR_NULL; |
381 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; | 381 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; |
(...skipping 12 matching lines...) Expand all Loading... |
394 if (other.canBeNull()) return HType.NULL; | 394 if (other.canBeNull()) return HType.NULL; |
395 return HType.CONFLICTING; | 395 return HType.CONFLICTING; |
396 } | 396 } |
397 } | 397 } |
398 | 398 |
399 class HDoubleType extends HNumberType { | 399 class HDoubleType extends HNumberType { |
400 const HDoubleType(); | 400 const HDoubleType(); |
401 bool isDouble() => true; | 401 bool isDouble() => true; |
402 String toString() => "double"; | 402 String toString() => "double"; |
403 | 403 |
404 Type computeType(Compiler compiler) { | 404 DartType computeType(Compiler compiler) { |
405 return compiler.doubleClass.computeType(compiler); | 405 return compiler.doubleClass.computeType(compiler); |
406 } | 406 } |
407 | 407 |
408 HType union(HType other) { | 408 HType union(HType other) { |
409 if (other.isConflicting()) return HType.DOUBLE; | 409 if (other.isConflicting()) return HType.DOUBLE; |
410 if (other.isUnknown()) return HType.UNKNOWN; | 410 if (other.isUnknown()) return HType.UNKNOWN; |
411 if (other.isDouble()) return HType.DOUBLE; | 411 if (other.isDouble()) return HType.DOUBLE; |
412 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; | 412 if (other.isDoubleOrNull()) return HType.DOUBLE_OR_NULL; |
413 if (other.isNumber()) return HType.NUMBER; | 413 if (other.isNumber()) return HType.NUMBER; |
414 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; | 414 if (other.isNumberOrNull()) return HType.NUMBER_OR_NULL; |
(...skipping 11 matching lines...) Expand all Loading... |
426 if (other.isNumberOrNull()) return HType.DOUBLE; | 426 if (other.isNumberOrNull()) return HType.DOUBLE; |
427 return HType.CONFLICTING; | 427 return HType.CONFLICTING; |
428 } | 428 } |
429 } | 429 } |
430 | 430 |
431 class HIndexablePrimitiveType extends HPrimitiveType { | 431 class HIndexablePrimitiveType extends HPrimitiveType { |
432 const HIndexablePrimitiveType(); | 432 const HIndexablePrimitiveType(); |
433 bool isIndexablePrimitive() => true; | 433 bool isIndexablePrimitive() => true; |
434 String toString() => "indexable"; | 434 String toString() => "indexable"; |
435 | 435 |
436 Type computeType(Compiler compiler) { | 436 DartType computeType(Compiler compiler) { |
437 // TODO(ngeoffray): Represent union types. | 437 // TODO(ngeoffray): Represent union types. |
438 return null; | 438 return null; |
439 } | 439 } |
440 | 440 |
441 HType union(HType other) { | 441 HType union(HType other) { |
442 if (other.isConflicting()) return HType.INDEXABLE_PRIMITIVE; | 442 if (other.isConflicting()) return HType.INDEXABLE_PRIMITIVE; |
443 if (other.isUnknown()) return HType.UNKNOWN; | 443 if (other.isUnknown()) return HType.UNKNOWN; |
444 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; | 444 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; |
445 if (other is HBoundedPotentialPrimitiveString) { | 445 if (other is HBoundedPotentialPrimitiveString) { |
446 // TODO(ngeoffray): Represent union types. | 446 // TODO(ngeoffray): Represent union types. |
(...skipping 13 matching lines...) Expand all Loading... |
460 if (other is HBoundedPotentialPrimitiveArray) return HType.READABLE_ARRAY; | 460 if (other is HBoundedPotentialPrimitiveArray) return HType.READABLE_ARRAY; |
461 return HType.CONFLICTING; | 461 return HType.CONFLICTING; |
462 } | 462 } |
463 } | 463 } |
464 | 464 |
465 class HStringOrNullType extends HPrimitiveOrNullType { | 465 class HStringOrNullType extends HPrimitiveOrNullType { |
466 const HStringOrNullType(); | 466 const HStringOrNullType(); |
467 bool isStringOrNull() => true; | 467 bool isStringOrNull() => true; |
468 String toString() => "String or null"; | 468 String toString() => "String or null"; |
469 | 469 |
470 Type computeType(Compiler compiler) { | 470 DartType computeType(Compiler compiler) { |
471 return compiler.stringClass.computeType(compiler); | 471 return compiler.stringClass.computeType(compiler); |
472 } | 472 } |
473 | 473 |
474 HType union(HType other) { | 474 HType union(HType other) { |
475 if (other.isConflicting()) return HType.STRING_OR_NULL; | 475 if (other.isConflicting()) return HType.STRING_OR_NULL; |
476 if (other.isUnknown()) return HType.UNKNOWN; | 476 if (other.isUnknown()) return HType.UNKNOWN; |
477 if (other.isString()) return HType.STRING_OR_NULL; | 477 if (other.isString()) return HType.STRING_OR_NULL; |
478 if (other.isStringOrNull()) return HType.STRING_OR_NULL; | 478 if (other.isStringOrNull()) return HType.STRING_OR_NULL; |
479 if (other.isIndexablePrimitive()) { | 479 if (other.isIndexablePrimitive()) { |
480 // We don't have a type that represents the nullable indexable | 480 // We don't have a type that represents the nullable indexable |
(...skipping 24 matching lines...) Expand all Loading... |
505 if (other.canBeNull()) return HType.NULL; | 505 if (other.canBeNull()) return HType.NULL; |
506 return HType.CONFLICTING; | 506 return HType.CONFLICTING; |
507 } | 507 } |
508 } | 508 } |
509 | 509 |
510 class HStringType extends HIndexablePrimitiveType { | 510 class HStringType extends HIndexablePrimitiveType { |
511 const HStringType(); | 511 const HStringType(); |
512 bool isString() => true; | 512 bool isString() => true; |
513 String toString() => "String"; | 513 String toString() => "String"; |
514 | 514 |
515 Type computeType(Compiler compiler) { | 515 DartType computeType(Compiler compiler) { |
516 return compiler.stringClass.computeType(compiler); | 516 return compiler.stringClass.computeType(compiler); |
517 } | 517 } |
518 | 518 |
519 HType union(HType other) { | 519 HType union(HType other) { |
520 if (other.isConflicting()) return HType.STRING; | 520 if (other.isConflicting()) return HType.STRING; |
521 if (other.isUnknown()) return HType.UNKNOWN; | 521 if (other.isUnknown()) return HType.UNKNOWN; |
522 if (other.isString()) return HType.STRING; | 522 if (other.isString()) return HType.STRING; |
523 if (other.isStringOrNull()) return HType.STRING_OR_NULL; | 523 if (other.isStringOrNull()) return HType.STRING_OR_NULL; |
524 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; | 524 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; |
525 if (other is HBoundedPotentialPrimitiveString) return other; | 525 if (other is HBoundedPotentialPrimitiveString) return other; |
(...skipping 10 matching lines...) Expand all Loading... |
536 if (other is HBoundedPotentialPrimitiveString) return HType.STRING; | 536 if (other is HBoundedPotentialPrimitiveString) return HType.STRING; |
537 return HType.CONFLICTING; | 537 return HType.CONFLICTING; |
538 } | 538 } |
539 } | 539 } |
540 | 540 |
541 class HReadableArrayType extends HIndexablePrimitiveType { | 541 class HReadableArrayType extends HIndexablePrimitiveType { |
542 const HReadableArrayType(); | 542 const HReadableArrayType(); |
543 bool isReadableArray() => true; | 543 bool isReadableArray() => true; |
544 String toString() => "readable array"; | 544 String toString() => "readable array"; |
545 | 545 |
546 Type computeType(Compiler compiler) { | 546 DartType computeType(Compiler compiler) { |
547 return compiler.listClass.computeType(compiler); | 547 return compiler.listClass.computeType(compiler); |
548 } | 548 } |
549 | 549 |
550 HType union(HType other) { | 550 HType union(HType other) { |
551 if (other.isConflicting()) return HType.READABLE_ARRAY; | 551 if (other.isConflicting()) return HType.READABLE_ARRAY; |
552 if (other.isUnknown()) return HType.UNKNOWN; | 552 if (other.isUnknown()) return HType.UNKNOWN; |
553 if (other.isReadableArray()) return HType.READABLE_ARRAY; | 553 if (other.isReadableArray()) return HType.READABLE_ARRAY; |
554 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; | 554 if (other.isIndexablePrimitive()) return HType.INDEXABLE_PRIMITIVE; |
555 if (other is HBoundedPotentialPrimitiveArray) return other; | 555 if (other is HBoundedPotentialPrimitiveArray) return other; |
556 return HType.UNKNOWN; | 556 return HType.UNKNOWN; |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 if (other.isUnknown()) return HType.EXTENDABLE_ARRAY; | 611 if (other.isUnknown()) return HType.EXTENDABLE_ARRAY; |
612 if (other.isExtendableArray()) return HType.EXTENDABLE_ARRAY; | 612 if (other.isExtendableArray()) return HType.EXTENDABLE_ARRAY; |
613 if (other.isString()) return HType.CONFLICTING; | 613 if (other.isString()) return HType.CONFLICTING; |
614 if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY; | 614 if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY; |
615 if (other is HBoundedPotentialPrimitiveArray) return HType.EXTENDABLE_ARRAY; | 615 if (other is HBoundedPotentialPrimitiveArray) return HType.EXTENDABLE_ARRAY; |
616 return HType.CONFLICTING; | 616 return HType.CONFLICTING; |
617 } | 617 } |
618 } | 618 } |
619 | 619 |
620 class HBoundedType extends HType { | 620 class HBoundedType extends HType { |
621 final Type type; | 621 final DartType type; |
622 final bool _canBeNull; | 622 final bool _canBeNull; |
623 final bool _isExact; | 623 final bool _isExact; |
624 | 624 |
625 toString() { | 625 toString() { |
626 return 'BoundedType($type, $_canBeNull, $_isExact)'; | 626 return 'BoundedType($type, $_canBeNull, $_isExact)'; |
627 } | 627 } |
628 | 628 |
629 bool canBeNull() => _canBeNull; | 629 bool canBeNull() => _canBeNull; |
630 | 630 |
631 bool isExact() => _isExact; | 631 bool isExact() => _isExact; |
632 | 632 |
633 const HBoundedType(Type this.type, | 633 const HBoundedType(DartType this.type, |
634 [bool canBeNull = false, isExact = false]) | 634 [bool canBeNull = false, isExact = false]) |
635 : _canBeNull = canBeNull, _isExact = isExact; | 635 : _canBeNull = canBeNull, _isExact = isExact; |
636 const HBoundedType.exact(Type type) : this(type, isExact: true); | 636 const HBoundedType.exact(DartType type) : this(type, isExact: true); |
637 const HBoundedType.withNull(Type type) : this(type, canBeNull: true); | 637 const HBoundedType.withNull(DartType type) : this(type, canBeNull: true); |
638 const HBoundedType.nonNull(Type type) : this(type); | 638 const HBoundedType.nonNull(DartType type) : this(type); |
639 | 639 |
640 Type computeType(Compiler compiler) => type; | 640 DartType computeType(Compiler compiler) => type; |
641 | 641 |
642 Element lookupMember(SourceString name) { | 642 Element lookupMember(SourceString name) { |
643 if (!isExact()) return null; | 643 if (!isExact()) return null; |
644 ClassElement classElement = type.element; | 644 ClassElement classElement = type.element; |
645 return classElement.lookupMember(name); | 645 return classElement.lookupMember(name); |
646 } | 646 } |
647 | 647 |
648 HType intersection(HType other) { | 648 HType intersection(HType other) { |
649 assert(!(isExact() && canBeNull())); | 649 assert(!(isExact() && canBeNull())); |
650 if (other.isNull()) return canBeNull() ? HType.NULL : HType.CONFLICTING; | 650 if (other.isNull()) return canBeNull() ? HType.NULL : HType.CONFLICTING; |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
688 if (isExact()) return other; | 688 if (isExact()) return other; |
689 if (other.isExact()) return this; | 689 if (other.isExact()) return this; |
690 return canBeNull() ? this : other; | 690 return canBeNull() ? this : other; |
691 } | 691 } |
692 if (other.isConflicting()) return this; | 692 if (other.isConflicting()) return this; |
693 return HType.UNKNOWN; | 693 return HType.UNKNOWN; |
694 } | 694 } |
695 } | 695 } |
696 | 696 |
697 class HBoundedPotentialPrimitiveType extends HBoundedType { | 697 class HBoundedPotentialPrimitiveType extends HBoundedType { |
698 const HBoundedPotentialPrimitiveType(Type type, bool canBeNull) | 698 const HBoundedPotentialPrimitiveType(DartType type, bool canBeNull) |
699 : super(type, canBeNull, false); | 699 : super(type, canBeNull, false); |
700 bool canBePrimitive() => true; | 700 bool canBePrimitive() => true; |
701 } | 701 } |
702 | 702 |
703 class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType { | 703 class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType { |
704 const HBoundedPotentialPrimitiveArray(Type type, bool canBeNull) | 704 const HBoundedPotentialPrimitiveArray(DartType type, bool canBeNull) |
705 : super(type, canBeNull); | 705 : super(type, canBeNull); |
706 | 706 |
707 HType union(HType other) { | 707 HType union(HType other) { |
708 if (other.isString()) return HType.UNKNOWN; | 708 if (other.isString()) return HType.UNKNOWN; |
709 if (other.isReadableArray()) return this; | 709 if (other.isReadableArray()) return this; |
710 // TODO(ngeoffray): implement union types. | 710 // TODO(ngeoffray): implement union types. |
711 if (other.isIndexablePrimitive()) return HType.UNKNOWN; | 711 if (other.isIndexablePrimitive()) return HType.UNKNOWN; |
712 if (other.isNull()) { | 712 if (other.isNull()) { |
713 if (canBeNull()) { | 713 if (canBeNull()) { |
714 return this; | 714 return this; |
715 } else { | 715 } else { |
716 return new HBoundedPotentialPrimitiveArray(type, true); | 716 return new HBoundedPotentialPrimitiveArray(type, true); |
717 } | 717 } |
718 } | 718 } |
719 return super.union(other); | 719 return super.union(other); |
720 } | 720 } |
721 | 721 |
722 HType intersection(HType other) { | 722 HType intersection(HType other) { |
723 if (other.isString()) return HType.CONFLICTING; | 723 if (other.isString()) return HType.CONFLICTING; |
724 if (other.isReadableArray()) return other; | 724 if (other.isReadableArray()) return other; |
725 if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY; | 725 if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY; |
726 return super.intersection(other); | 726 return super.intersection(other); |
727 } | 727 } |
728 } | 728 } |
729 | 729 |
730 class HBoundedPotentialPrimitiveString extends HBoundedPotentialPrimitiveType { | 730 class HBoundedPotentialPrimitiveString extends HBoundedPotentialPrimitiveType { |
731 const HBoundedPotentialPrimitiveString(Type type, bool canBeNull) | 731 const HBoundedPotentialPrimitiveString(DartType type, bool canBeNull) |
732 : super(type, canBeNull); | 732 : super(type, canBeNull); |
733 | 733 |
734 HType union(HType other) { | 734 HType union(HType other) { |
735 if (other.isString()) return this; | 735 if (other.isString()) return this; |
736 if (other.isStringOrNull()) { | 736 if (other.isStringOrNull()) { |
737 if (canBeNull()) { | 737 if (canBeNull()) { |
738 return this; | 738 return this; |
739 } else { | 739 } else { |
740 return new HBoundedPotentialPrimitiveString(type, true); | 740 return new HBoundedPotentialPrimitiveString(type, true); |
741 } | 741 } |
(...skipping 29 matching lines...) Expand all Loading... |
771 operator [](HInstruction instruction) { | 771 operator [](HInstruction instruction) { |
772 HType result = _map[instruction]; | 772 HType result = _map[instruction]; |
773 if (result == null) return instruction.guaranteedType; | 773 if (result == null) return instruction.guaranteedType; |
774 return result; | 774 return result; |
775 } | 775 } |
776 | 776 |
777 operator []=(HInstruction instruction, HType value) { | 777 operator []=(HInstruction instruction, HType value) { |
778 _map[instruction] = value; | 778 _map[instruction] = value; |
779 } | 779 } |
780 } | 780 } |
OLD | NEW |