| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
| 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. | |
| 4 | |
| 5 part of types; | |
| 6 | |
| 7 /** | |
| 8 * A [MapTypeMask] is a [TypeMask] for a specific allocation | |
| 9 * site of a map (currently only internal Map class) that will get specialized | |
| 10 * once the [TypeGraphInferrer] phase finds a key and/or value type for it. | |
| 11 */ | |
| 12 class MapTypeMask extends ForwardingTypeMask { | |
| 13 final TypeMask forwardTo; | |
| 14 | |
| 15 // The [Node] where this type mask was created. | |
| 16 final Node allocationNode; | |
| 17 | |
| 18 // The [Element] where this type mask was created. | |
| 19 final Element allocationElement; | |
| 20 | |
| 21 // The value type of this map. | |
| 22 final TypeMask valueType; | |
| 23 | |
| 24 // The key type of this map. | |
| 25 final TypeMask keyType; | |
| 26 | |
| 27 MapTypeMask(this.forwardTo, | |
| 28 this.allocationNode, | |
| 29 this.allocationElement, | |
| 30 this.keyType, | |
| 31 this.valueType); | |
| 32 | |
| 33 TypeMask nullable() { | |
| 34 return isNullable | |
| 35 ? this | |
| 36 : new MapTypeMask(forwardTo.nullable(), | |
| 37 allocationNode, | |
| 38 allocationElement, | |
| 39 keyType, | |
| 40 valueType); | |
| 41 } | |
| 42 | |
| 43 TypeMask nonNullable() { | |
| 44 return isNullable | |
| 45 ? new MapTypeMask(forwardTo.nonNullable(), | |
| 46 allocationNode, | |
| 47 allocationElement, | |
| 48 keyType, | |
| 49 valueType) | |
| 50 : this; | |
| 51 } | |
| 52 | |
| 53 bool get isContainer => false; | |
| 54 bool get isMap => true; | |
| 55 bool get isExact => true; | |
| 56 | |
| 57 bool equalsDisregardNull(other) { | |
| 58 if (other is! MapTypeMask) return false; | |
| 59 return super.equalsDisregardNull(other) && | |
| 60 allocationNode == other.allocationNode && | |
| 61 keyType == other.keyType && | |
| 62 valueType == other.valueType; | |
| 63 } | |
| 64 | |
| 65 TypeMask intersection(TypeMask other, ClassWorld classWorld) { | |
| 66 TypeMask forwardIntersection = forwardTo.intersection(other, classWorld); | |
| 67 if (forwardIntersection.isEmpty) return forwardIntersection; | |
| 68 return forwardIntersection.isNullable | |
| 69 ? nullable() | |
| 70 : nonNullable(); | |
| 71 } | |
| 72 | |
| 73 TypeMask union(other, ClassWorld classWorld) { | |
| 74 if (this == other) { | |
| 75 return this; | |
| 76 } else if (equalsDisregardNull(other)) { | |
| 77 return other.isNullable ? other : this; | |
| 78 } else if (other.isEmpty) { | |
| 79 return other.isNullable ? this.nullable() : this; | |
| 80 } else if (other.isMap && | |
| 81 keyType != null && | |
| 82 other.keyType != null && | |
| 83 valueType != null && | |
| 84 other.valueType != null) { | |
| 85 TypeMask newKeyType = | |
| 86 keyType.union(other.keyType, classWorld); | |
| 87 TypeMask newValueType = | |
| 88 valueType.union(other.valueType, classWorld); | |
| 89 TypeMask newForwardTo = forwardTo.union(other.forwardTo, classWorld); | |
| 90 return new MapTypeMask( | |
| 91 newForwardTo, null, null, newKeyType, newValueType); | |
| 92 } else if (other.isDictionary) { | |
| 93 assert(other.keyType == classWorld.compiler.typesTask.stringType); | |
| 94 TypeMask newKeyType = keyType.union(other.keyType, classWorld); | |
| 95 TypeMask newValueType = | |
| 96 other.typeMap.values.fold(keyType, (p,n) => p.union(n, classWorld)); | |
| 97 TypeMask newForwardTo = forwardTo.union(other.forwardTo, classWorld); | |
| 98 MapTypeMask newMapTypeMask = new MapTypeMask( | |
| 99 newForwardTo, | |
| 100 allocationNode == other.allocationNode ? allocationNode : null, | |
| 101 allocationElement == other.allocationElement ? allocationElement | |
| 102 : null, | |
| 103 newKeyType, newValueType); | |
| 104 return newMapTypeMask; | |
| 105 } else { | |
| 106 return forwardTo.union(other, classWorld); | |
| 107 } | |
| 108 } | |
| 109 | |
| 110 bool operator==(other) => super == other; | |
| 111 | |
| 112 int get hashCode { | |
| 113 return computeHashCode( | |
| 114 allocationNode, isNullable, keyType, valueType, forwardTo); | |
| 115 } | |
| 116 | |
| 117 String toString() { | |
| 118 return 'Map mask: [$keyType/$valueType] type: $forwardTo'; | |
| 119 } | |
| 120 } | |
| OLD | NEW |