| 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 factory HType.fromBoundedType(Type type, Compiler compiler) { | 8 /** |
| 9 * Returns a [HType] that represents all types that have [type] as a |
| 10 * supertype, or the type [type]. |
| 11 */ |
| 12 factory HType.fromBoundedType(Type type, |
| 13 Compiler compiler, |
| 14 [bool canBeNull = false]) { |
| 9 Element element = type.element; | 15 Element element = type.element; |
| 10 if (element.kind === ElementKind.TYPE_VARIABLE) { | 16 if (element.kind === ElementKind.TYPE_VARIABLE) { |
| 11 compiler.unimplemented("type variables"); | 17 compiler.unimplemented("type variables"); |
| 12 } | 18 } |
| 13 | 19 |
| 14 if (element === compiler.intClass) { | 20 if (!canBeNull) { |
| 15 return HType.INTEGER; | 21 if (element === compiler.intClass) { |
| 16 } else if (element === compiler.numClass) { | 22 return HType.INTEGER; |
| 17 return HType.NUMBER; | 23 } else if (element === compiler.numClass) { |
| 18 } else if (element === compiler.doubleClass) { | 24 return HType.NUMBER; |
| 19 return HType.DOUBLE; | 25 } else if (element === compiler.doubleClass) { |
| 20 } else if (element === compiler.stringClass) { | 26 return HType.DOUBLE; |
| 21 return HType.STRING; | 27 } else if (element === compiler.stringClass) { |
| 22 } else if (element === compiler.listClass | 28 return HType.STRING; |
| 23 || Elements.isStringSupertype(element, compiler) | 29 } else if (element === compiler.boolClass) { |
| 24 || Elements.isListSupertype(element, compiler)) { | 30 return HType.BOOLEAN; |
| 25 return new HBoundedPotentialPrimitiveType(type); | 31 } |
| 32 } |
| 33 if (element === compiler.listClass |
| 34 || Elements.isListSupertype(element, compiler)) { |
| 35 return new HBoundedPotentialPrimitiveArray(type, canBeNull); |
| 36 } else if (Elements.isStringSupertype(element, compiler)) { |
| 37 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; |
| 26 } else { | 45 } else { |
| 27 return new HBoundedType(type); | 46 return new HBoundedType(type, canBeNull); |
| 28 } | 47 } |
| 29 } | 48 } |
| 30 | 49 |
| 31 static final HType CONFLICTING = const HAnalysisType("conflicting"); | 50 static final HType CONFLICTING = const HAnalysisType("conflicting"); |
| 32 static final HType UNKNOWN = const HAnalysisType("unknown"); | 51 static final HType UNKNOWN = const HAnalysisType("unknown"); |
| 33 static final HType BOOLEAN = const HBooleanType(); | 52 static final HType BOOLEAN = const HBooleanType(); |
| 34 static final HType NUMBER = const HNumberType(); | 53 static final HType NUMBER = const HNumberType(); |
| 35 static final HType INTEGER = const HIntegerType(); | 54 static final HType INTEGER = const HIntegerType(); |
| 36 static final HType DOUBLE = const HDoubleType(); | 55 static final HType DOUBLE = const HDoubleType(); |
| 37 static final HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType(); | 56 static final HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType(); |
| (...skipping 283 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 321 HType intersection(HType other) { | 340 HType intersection(HType other) { |
| 322 if (this === other || other.isUnknown()) return HType.EXTENDABLE_ARRAY; | 341 if (this === other || other.isUnknown()) return HType.EXTENDABLE_ARRAY; |
| 323 if (other.isString()) return HType.CONFLICTING; | 342 if (other.isString()) return HType.CONFLICTING; |
| 324 if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY; | 343 if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY; |
| 325 return HType.CONFLICTING; | 344 return HType.CONFLICTING; |
| 326 } | 345 } |
| 327 } | 346 } |
| 328 | 347 |
| 329 class HBoundedType extends HType { | 348 class HBoundedType extends HType { |
| 330 final Type type; | 349 final Type type; |
| 350 final bool _canBeNull; |
| 331 | 351 |
| 332 const HBoundedType(Type this.type); | 352 bool canBeNull() => _canBeNull; |
| 353 |
| 354 const HBoundedType(Type this.type, [bool this._canBeNull = false]); |
| 333 String toString() => type.toString(); | 355 String toString() => type.toString(); |
| 334 | 356 |
| 335 Type computeType(Compiler compiler) => type; | 357 Type computeType(Compiler compiler) => type; |
| 336 | 358 |
| 337 HType combine(HType other) { | 359 HType combine(HType other) { |
| 338 if (other is HBoundedType) { | 360 if (other is HBoundedType) { |
| 339 HBoundedType temp = other; | 361 HBoundedType temp = other; |
| 340 // Return [other] in case it is an exact type. | 362 // Return [other] in case it is an exact type. |
| 341 if (this.type === temp.type) return other; | 363 if (this.type === temp.type) return other; |
| 342 } | 364 } |
| (...skipping 19 matching lines...) Expand all Loading... |
| 362 HType combine(HType other) { | 384 HType combine(HType other) { |
| 363 if (other.isExact()) { | 385 if (other.isExact()) { |
| 364 HExactType concrete = other; | 386 HExactType concrete = other; |
| 365 if (this.type === concrete.type) return this; | 387 if (this.type === concrete.type) return this; |
| 366 } | 388 } |
| 367 if (other.isUnknown()) return this; | 389 if (other.isUnknown()) return this; |
| 368 return HType.CONFLICTING; | 390 return HType.CONFLICTING; |
| 369 } | 391 } |
| 370 } | 392 } |
| 371 | 393 |
| 372 class HBoundedPotentialPrimitiveType extends HBoundedType { | 394 class HBoundedPotentialPrimitiveArray extends HBoundedType { |
| 373 const HBoundedPotentialPrimitiveType(Type type) : super(type); | 395 const HBoundedPotentialPrimitiveArray(Type type, bool canBeNull) |
| 396 : super(type, canBeNull); |
| 374 bool canBePrimitive() => true; | 397 bool canBePrimitive() => true; |
| 398 |
| 399 HType combine(HType other) { |
| 400 if (other.isReadableArray()) return other; |
| 401 if (other.isIndexablePrimitive()) return HType.READABLE_ARRAY; |
| 402 return super.combine(other); |
| 403 } |
| 375 } | 404 } |
| 405 |
| 406 class HBoundedPotentialPrimitiveString extends HBoundedType { |
| 407 const HBoundedPotentialPrimitiveString(Type type, bool canBeNull) |
| 408 : super(type, canBeNull); |
| 409 bool canBePrimitive() => true; |
| 410 |
| 411 HType combine(HType other) { |
| 412 if (other.isString()) return other; |
| 413 if (other.isIndexablePrimitive) return HType.STRING; |
| 414 return super.combine(other); |
| 415 } |
| 416 } |
| OLD | NEW |