| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 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 | 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 part of types; | 5 part of types; |
| 6 | 6 |
| 7 /// A [ContainerTypeMask] is a [TypeMask] for a specific allocation | 7 /// A [ContainerTypeMask] is a [TypeMask] for a specific allocation |
| 8 /// site of a container (currently only List) that will get specialized | 8 /// site of a container (currently only List) that will get specialized |
| 9 /// once the [TypeGraphInferrer] phase finds an element type for it. | 9 /// once the [TypeGraphInferrer] phase finds an element type for it. |
| 10 class ContainerTypeMask extends ForwardingTypeMask { | 10 class ContainerTypeMask extends ForwardingTypeMask { |
| 11 final TypeMask forwardTo; | 11 final TypeMask forwardTo; |
| 12 | 12 |
| 13 // The [Node] where this type mask was created. | 13 // The [Node] where this type mask was created. |
| 14 final Node allocationNode; | 14 final Node allocationNode; |
| 15 | 15 |
| 16 // The [Element] where this type mask was created. | 16 // The [Element] where this type mask was created. |
| 17 final Element allocationElement; | 17 final Element allocationElement; |
| 18 | 18 |
| 19 // The element type of this container. | 19 // The element type of this container. |
| 20 final TypeMask elementType; | 20 final TypeMask elementType; |
| 21 | 21 |
| 22 // The length of the container. | 22 // The length of the container. |
| 23 final int length; | 23 final int length; |
| 24 | 24 |
| 25 ContainerTypeMask(this.forwardTo, | 25 ContainerTypeMask(this.forwardTo, this.allocationNode, this.allocationElement, |
| 26 this.allocationNode, | 26 this.elementType, this.length); |
| 27 this.allocationElement, | |
| 28 this.elementType, | |
| 29 this.length); | |
| 30 | 27 |
| 31 TypeMask nullable() { | 28 TypeMask nullable() { |
| 32 return isNullable | 29 return isNullable |
| 33 ? this | 30 ? this |
| 34 : new ContainerTypeMask(forwardTo.nullable(), | 31 : new ContainerTypeMask(forwardTo.nullable(), allocationNode, |
| 35 allocationNode, | 32 allocationElement, elementType, length); |
| 36 allocationElement, | |
| 37 elementType, | |
| 38 length); | |
| 39 } | 33 } |
| 40 | 34 |
| 41 TypeMask nonNullable() { | 35 TypeMask nonNullable() { |
| 42 return isNullable | 36 return isNullable |
| 43 ? new ContainerTypeMask(forwardTo.nonNullable(), | 37 ? new ContainerTypeMask(forwardTo.nonNullable(), allocationNode, |
| 44 allocationNode, | 38 allocationElement, elementType, length) |
| 45 allocationElement, | |
| 46 elementType, | |
| 47 length) | |
| 48 : this; | 39 : this; |
| 49 } | 40 } |
| 50 | 41 |
| 51 bool get isContainer => true; | 42 bool get isContainer => true; |
| 52 bool get isExact => true; | 43 bool get isExact => true; |
| 53 | 44 |
| 54 bool equalsDisregardNull(other) { | 45 bool equalsDisregardNull(other) { |
| 55 if (other is! ContainerTypeMask) return false; | 46 if (other is! ContainerTypeMask) return false; |
| 56 return super.equalsDisregardNull(other) && | 47 return super.equalsDisregardNull(other) && |
| 57 allocationNode == other.allocationNode && | 48 allocationNode == other.allocationNode && |
| 58 elementType == other.elementType && | 49 elementType == other.elementType && |
| 59 length == other.length; | 50 length == other.length; |
| 60 } | 51 } |
| 61 | 52 |
| 62 TypeMask intersection(TypeMask other, ClassWorld classWorld) { | 53 TypeMask intersection(TypeMask other, ClassWorld classWorld) { |
| 63 TypeMask forwardIntersection = forwardTo.intersection(other, classWorld); | 54 TypeMask forwardIntersection = forwardTo.intersection(other, classWorld); |
| 64 if (forwardIntersection.isEmptyOrNull) return forwardIntersection; | 55 if (forwardIntersection.isEmptyOrNull) return forwardIntersection; |
| 65 return forwardIntersection.isNullable | 56 return forwardIntersection.isNullable ? nullable() : nonNullable(); |
| 66 ? nullable() | |
| 67 : nonNullable(); | |
| 68 } | 57 } |
| 69 | 58 |
| 70 TypeMask union(other, ClassWorld classWorld) { | 59 TypeMask union(other, ClassWorld classWorld) { |
| 71 if (this == other) { | 60 if (this == other) { |
| 72 return this; | 61 return this; |
| 73 } else if (equalsDisregardNull(other)) { | 62 } else if (equalsDisregardNull(other)) { |
| 74 return other.isNullable ? other : this; | 63 return other.isNullable ? other : this; |
| 75 } else if (other.isEmptyOrNull) { | 64 } else if (other.isEmptyOrNull) { |
| 76 return other.isNullable ? this.nullable() : this; | 65 return other.isNullable ? this.nullable() : this; |
| 77 } else if (other.isContainer | 66 } else if (other.isContainer && |
| 78 && elementType != null | 67 elementType != null && |
| 79 && other.elementType != null) { | 68 other.elementType != null) { |
| 80 TypeMask newElementType = | 69 TypeMask newElementType = |
| 81 elementType.union(other.elementType, classWorld); | 70 elementType.union(other.elementType, classWorld); |
| 82 int newLength = (length == other.length) ? length : null; | 71 int newLength = (length == other.length) ? length : null; |
| 83 TypeMask newForwardTo = forwardTo.union(other.forwardTo, classWorld); | 72 TypeMask newForwardTo = forwardTo.union(other.forwardTo, classWorld); |
| 84 return new ContainerTypeMask( | 73 return new ContainerTypeMask( |
| 85 newForwardTo, | 74 newForwardTo, |
| 86 allocationNode == other.allocationNode ? allocationNode : null, | 75 allocationNode == other.allocationNode ? allocationNode : null, |
| 87 allocationElement == other.allocationElement ? allocationElement | 76 allocationElement == other.allocationElement |
| 88 : null, | 77 ? allocationElement |
| 89 newElementType, newLength); | 78 : null, |
| 79 newElementType, |
| 80 newLength); |
| 90 } else { | 81 } else { |
| 91 return forwardTo.union(other, classWorld); | 82 return forwardTo.union(other, classWorld); |
| 92 } | 83 } |
| 93 } | 84 } |
| 94 | 85 |
| 95 bool operator==(other) => super == other; | 86 bool operator ==(other) => super == other; |
| 96 | 87 |
| 97 int get hashCode { | 88 int get hashCode { |
| 98 return computeHashCode( | 89 return computeHashCode( |
| 99 allocationNode, isNullable, elementType, length, forwardTo); | 90 allocationNode, isNullable, elementType, length, forwardTo); |
| 100 } | 91 } |
| 101 | 92 |
| 102 String toString() { | 93 String toString() { |
| 103 return 'Container mask: $elementType length: $length type: $forwardTo'; | 94 return 'Container mask: $elementType length: $length type: $forwardTo'; |
| 104 } | 95 } |
| 105 } | 96 } |
| OLD | NEW |