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 |