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 [DictionaryTypeMask] is a [TypeMask] for a specific allocation | |
9 * site of a map (currently only internal Map class) that is used as | |
10 * a dictionary, i.e. a mapping from a set of statically known strings | |
11 * to values. These typemasks only come into existence after the | |
12 * [TypeGraphInferrer] has successfully identified such a usage. Otherwise, | |
13 * the more general [MapTypeMask] is used. | |
14 */ | |
15 class DictionaryTypeMask extends MapTypeMask { | |
16 // The underlying key/value map of this dictionary. | |
17 final Map<String, TypeMask> typeMap; | |
18 | |
19 DictionaryTypeMask(forwardTo, | |
20 allocationNode, | |
21 allocationElement, | |
22 keyType, valueType, | |
23 this.typeMap) : | |
24 super(forwardTo, allocationNode, allocationElement, keyType, valueType); | |
25 | |
26 TypeMask nullable() { | |
27 return isNullable | |
28 ? this | |
29 : new DictionaryTypeMask(forwardTo.nullable(), | |
30 allocationNode, | |
31 allocationElement, | |
32 keyType, valueType, | |
33 typeMap); | |
34 } | |
35 | |
36 TypeMask nonNullable() { | |
37 return isNullable | |
38 ? new DictionaryTypeMask(forwardTo.nonNullable(), | |
39 allocationNode, | |
40 allocationElement, | |
41 keyType, valueType, | |
42 typeMap) | |
43 : this; | |
44 } | |
45 | |
46 bool get isDictionary => true; | |
47 bool get isExact => true; | |
48 | |
49 bool equalsDisregardNull(other) { | |
50 if (other is! DictionaryTypeMask) return false; | |
51 return allocationNode == other.allocationNode && | |
52 keyType == other.keyType && | |
53 valueType == other.valueType && | |
54 typeMap.keys.every((k) => other.typeMap.containsKey(k)) && | |
55 other.typeMap.keys.every((k) => typeMap.containsKey(k) && | |
56 typeMap[k] == other.typeMap[k]); | |
57 | |
58 } | |
59 | |
60 TypeMask intersection(TypeMask other, ClassWorld classWorld) { | |
61 TypeMask forwardIntersection = forwardTo.intersection(other, classWorld); | |
62 if (forwardIntersection.isEmpty) return forwardIntersection; | |
63 return forwardIntersection.isNullable | |
64 ? nullable() | |
65 : nonNullable(); | |
66 } | |
67 | |
68 TypeMask union(other, ClassWorld classWorld) { | |
69 if (this == other) { | |
70 return this; | |
71 } else if (equalsDisregardNull(other)) { | |
72 return other.isNullable ? other : this; | |
73 } else if (other.isEmpty) { | |
74 return other.isNullable ? this.nullable() : this; | |
75 } else if (other.isDictionary) { | |
76 TypeMask newForwardTo = forwardTo.union(other.forwardTo, classWorld); | |
77 TypeMask newKeyType = keyType.union(other.keyType, classWorld); | |
78 TypeMask newValueType = valueType.union(other.valueType, classWorld); | |
79 Map<String, TypeMask> mappings = <String, TypeMask>{}; | |
80 typeMap.forEach((k,v) { | |
81 if (!other.typeMap.containsKey(k)) { | |
82 mappings[k] = v.nullable(); | |
83 } | |
84 }); | |
85 other.typeMap.forEach((k,v) { | |
86 if (typeMap.containsKey(k)) { | |
87 mappings[k] = v.union(typeMap[k], classWorld); | |
88 } else { | |
89 mappings[k] = v.nullable(); | |
90 } | |
91 }); | |
92 return new DictionaryTypeMask(newForwardTo, null, null, | |
93 newKeyType, newValueType, mappings); | |
94 } else if (other.isMap && | |
95 (other.keyType != null) && | |
96 (other.valueType != null)) { | |
97 TypeMask newForwardTo = forwardTo.union(other.forwardTo, classWorld); | |
98 TypeMask newKeyType = keyType.union(other.keyType, classWorld); | |
99 TypeMask newValueType = valueType.union(other.valueType, classWorld); | |
100 return new MapTypeMask(newForwardTo, null, null, | |
101 newKeyType, newValueType); | |
102 } else { | |
103 return forwardTo.union(other, classWorld); | |
104 } | |
105 } | |
106 | |
107 bool operator==(other) => super == other; | |
108 | |
109 int get hashCode { | |
110 return computeHashCode( | |
111 allocationNode, isNullable, typeMap, forwardTo); | |
112 } | |
113 | |
114 String toString() { | |
115 return | |
116 'Dictionary mask: [$keyType/$valueType with $typeMap] type: $forwardTo'; | |
117 } | |
118 } | |
OLD | NEW |