Chromium Code Reviews| 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. |
| (...skipping 17 matching lines...) Expand all Loading... | |
| 28 } else if (element === compiler.stringClass) { | 28 } else if (element === compiler.stringClass) { |
| 29 return canBeNull ? HType.STRING_OR_NULL : HType.STRING; | 29 return canBeNull ? HType.STRING_OR_NULL : HType.STRING; |
| 30 } else if (element === compiler.boolClass) { | 30 } else if (element === compiler.boolClass) { |
| 31 return canBeNull ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN; | 31 return canBeNull ? HType.BOOLEAN_OR_NULL : HType.BOOLEAN; |
| 32 } else if (element === compiler.listClass | 32 } else if (element === compiler.listClass |
| 33 || Elements.isListSupertype(element, compiler)) { | 33 || Elements.isListSupertype(element, compiler)) { |
| 34 return new HBoundedPotentialPrimitiveArray(type, canBeNull); | 34 return new HBoundedPotentialPrimitiveArray(type, canBeNull); |
| 35 } else if (Elements.isStringSupertype(element, compiler)) { | 35 } else if (Elements.isStringSupertype(element, compiler)) { |
| 36 return new HBoundedPotentialPrimitiveString(type, canBeNull); | 36 return new HBoundedPotentialPrimitiveString(type, canBeNull); |
| 37 } else { | 37 } else { |
| 38 return new HBoundedType(type, canBeNull); | 38 return canBeNull ? new HBoundedType.canBeNull(type) |
| 39 : new HBoundedType.nonNull(type); | |
| 39 } | 40 } |
| 40 } | 41 } |
| 41 | 42 |
| 42 static final HType CONFLICTING = const HAnalysisType("conflicting"); | 43 static final HType CONFLICTING = const HAnalysisType("conflicting"); |
| 43 static final HType UNKNOWN = const HAnalysisType("unknown"); | 44 static final HType UNKNOWN = const HAnalysisType("unknown"); |
| 44 static final HType BOOLEAN = const HBooleanType(); | 45 static final HType BOOLEAN = const HBooleanType(); |
| 45 static final HType NUMBER = const HNumberType(); | 46 static final HType NUMBER = const HNumberType(); |
| 46 static final HType INTEGER = const HIntegerType(); | 47 static final HType INTEGER = const HIntegerType(); |
| 47 static final HType DOUBLE = const HDoubleType(); | 48 static final HType DOUBLE = const HDoubleType(); |
| 48 static final HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType(); | 49 static final HType INDEXABLE_PRIMITIVE = const HIndexablePrimitiveType(); |
| (...skipping 541 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 590 if (other.isString()) return HType.CONFLICTING; | 591 if (other.isString()) return HType.CONFLICTING; |
| 591 if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY; | 592 if (other.isIndexablePrimitive()) return HType.EXTENDABLE_ARRAY; |
| 592 if (other is HBoundedPotentialPrimitiveArray) return HType.EXTENDABLE_ARRAY; | 593 if (other is HBoundedPotentialPrimitiveArray) return HType.EXTENDABLE_ARRAY; |
| 593 return HType.CONFLICTING; | 594 return HType.CONFLICTING; |
| 594 } | 595 } |
| 595 } | 596 } |
| 596 | 597 |
| 597 class HBoundedType extends HType { | 598 class HBoundedType extends HType { |
| 598 final Type type; | 599 final Type type; |
| 599 final bool _canBeNull; | 600 final bool _canBeNull; |
| 601 final bool _isExact; | |
|
ngeoffray
2012/05/29 12:16:21
I think I'd prefer having a HExactType extends HTy
karlklose
2012/05/29 13:25:16
The complicated code for the union/intersection wa
| |
| 602 | |
| 603 toString() { | |
| 604 return 'BoundedType($type, $_canBeNull, $_isExact)'; | |
| 605 } | |
| 600 | 606 |
| 601 bool canBeNull() => _canBeNull; | 607 bool canBeNull() => _canBeNull; |
| 602 | 608 |
| 603 const HBoundedType(Type this.type, [bool this._canBeNull = false]); | 609 bool isExact() => _isExact; |
| 604 String toString() => type.toString(); | 610 |
| 611 const HBoundedType(Type this.type, bool this._canBeNull, this._isExact); | |
|
ngeoffray
2012/05/29 12:16:21
Maybe use named arguments here and at the call sit
karlklose
2012/05/29 13:25:16
Done.
| |
| 612 const HBoundedType.exact(Type type) : this(type, false, true); | |
| 613 const HBoundedType.canBeNull(Type type) : this(type, true, false); | |
|
ngeoffray
2012/05/29 12:16:21
canBeNull -> withNull?
karlklose
2012/05/29 13:25:16
Done.
| |
| 614 const HBoundedType.nonNull(Type type) : this(type, false, false); | |
| 605 | 615 |
| 606 Type computeType(Compiler compiler) => type; | 616 Type computeType(Compiler compiler) => type; |
| 607 | 617 |
| 608 HType combine(HType other) { | 618 Element lookupMember(SourceString name) { |
| 619 if (!isExact()) return null; | |
| 620 ClassElement classElement = type.element; | |
| 621 return classElement.lookupMember(name); | |
| 622 } | |
| 623 | |
| 624 HType intersection(HType other) { | |
| 625 assert(!(isExact() && canBeNull())); | |
| 626 if (other.isNull()) return canBeNull() ? HType.NULL : HType.CONFLICTING; | |
| 609 if (other is HBoundedType) { | 627 if (other is HBoundedType) { |
| 610 HBoundedType temp = other; | 628 HBoundedType temp = other; |
| 611 // Return [other] in case it is an exact type. | 629 if (this.type === temp.type) { |
| 612 if (this.type === temp.type) return other; | 630 if (isExact()) { |
| 631 return this; | |
| 632 } else if (other.isExact()){ | |
| 633 return other; | |
| 634 } else if (canBeNull()) { | |
| 635 return other; | |
| 636 } else { | |
| 637 return this; | |
| 638 } | |
| 639 } else if (canBeNull() && other.canBeNull()) { | |
| 640 return HType.NULL; | |
| 641 } | |
| 613 } | 642 } |
| 614 if (other.isUnknown()) return this; | 643 if (other.isUnknown()) return this; |
| 615 return HType.CONFLICTING; | 644 return HType.CONFLICTING; |
| 616 } | 645 } |
| 617 | 646 |
| 618 // As long as we don't keep track of super/sub types for non-primitive types | 647 bool operator ==(HType other) { |
| 619 // the intersection and union is the same, except when [other] is | 648 if (other is !HBoundedType) return false; |
| 620 // null. | 649 HBoundedType bounded = other; |
| 621 HType intersection(HType other) { | 650 return (type === bounded.type && canBeNull() === bounded.canBeNull() |
| 622 if (other.isNull()) return canBeNull() ? HType.NULL : HType.CONFLICTING; | 651 && isExact() === other .isExact()); |
| 623 return combine(other); | |
| 624 } | 652 } |
| 625 | 653 |
| 626 HType union(HType other) { | 654 HType union(HType other) { |
| 627 if (other.isNull()) { | 655 if (other.isNull()) { |
| 628 if (canBeNull()) { | 656 if (canBeNull()) { |
| 629 return this; | 657 return this; |
| 630 } else { | 658 } else { |
| 631 return new HBoundedType(type, true); | 659 return new HBoundedType.canBeNull(type); |
| 632 } | 660 } |
| 633 } | 661 } |
| 634 return combine(other); | 662 if (other is HBoundedType) { |
| 635 } | 663 HBoundedType temp = other; |
| 636 } | 664 if (type !== temp.type) return HType.CONFLICTING; |
| 637 | 665 if (isExact()) return other; |
| 638 class HExactType extends HBoundedType { | 666 if (other.isExact()) return this; |
| 639 const HExactType(Type type) : super(type); | 667 return canBeNull() ? this : other; |
| 640 bool isExact() => true; | |
| 641 | |
| 642 Element lookupMember(SourceString name) { | |
| 643 ClassElement classElement = type.element; | |
| 644 return classElement.lookupMember(name); | |
| 645 } | |
| 646 | |
| 647 HType combine(HType other) { | |
| 648 if (other.isExact()) { | |
| 649 HExactType concrete = other; | |
| 650 if (this.type === concrete.type) return this; | |
| 651 } | 668 } |
| 652 if (other.isUnknown()) return this; | 669 if (other.isUnknown()) return this; |
| 653 return HType.CONFLICTING; | 670 return HType.CONFLICTING; |
| 654 } | 671 } |
| 655 | |
| 656 HType union(HType other) { | |
| 657 if (other.isNull()) return HType.CONFLICTING; | |
| 658 return combine(other); | |
| 659 } | |
| 660 } | 672 } |
| 661 | 673 |
| 662 class HBoundedPotentialPrimitiveType extends HBoundedType { | 674 class HBoundedPotentialPrimitiveType extends HBoundedType { |
| 663 const HBoundedPotentialPrimitiveType(Type type, bool canBeNull) | 675 const HBoundedPotentialPrimitiveType(Type type, bool canBeNull) |
| 664 : super(type, canBeNull); | 676 : super(type, canBeNull, false); |
| 665 bool canBePrimitive() => true; | 677 bool canBePrimitive() => true; |
| 666 } | 678 } |
| 667 | 679 |
| 668 class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType { | 680 class HBoundedPotentialPrimitiveArray extends HBoundedPotentialPrimitiveType { |
| 669 const HBoundedPotentialPrimitiveArray(Type type, bool canBeNull) | 681 const HBoundedPotentialPrimitiveArray(Type type, bool canBeNull) |
| 670 : super(type, canBeNull); | 682 : super(type, canBeNull); |
| 671 | 683 |
| 672 HType union(HType other) { | 684 HType union(HType other) { |
| 673 if (other.isString()) return HType.CONFLICTING; | 685 if (other.isString()) return HType.CONFLICTING; |
| 674 if (other.isReadableArray()) return this; | 686 if (other.isReadableArray()) return this; |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 720 HType intersection(HType other) { | 732 HType intersection(HType other) { |
| 721 if (other.isString()) return HType.STRING; | 733 if (other.isString()) return HType.STRING; |
| 722 if (other.isStringOrNull()) { | 734 if (other.isStringOrNull()) { |
| 723 return canBeNull() ? HType.STRING_OR_NULL : HType.STRING; | 735 return canBeNull() ? HType.STRING_OR_NULL : HType.STRING; |
| 724 } | 736 } |
| 725 if (other.isReadableArray()) return HType.CONFLICTING; | 737 if (other.isReadableArray()) return HType.CONFLICTING; |
| 726 if (other.isIndexablePrimitive()) return HType.STRING; | 738 if (other.isIndexablePrimitive()) return HType.STRING; |
| 727 return super.intersection(other); | 739 return super.intersection(other); |
| 728 } | 740 } |
| 729 } | 741 } |
| OLD | NEW |