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 /** | 5 /** |
6 * This contains extra functions and classes useful for implementing | 6 * This contains extra functions and classes useful for implementing |
7 * serialiation. Some or all of these will be removed once the functionality is | 7 * serialiation. Some or all of these will be removed once the functionality is |
8 * available in the core library. | 8 * available in the core library. |
9 */ | 9 */ |
10 library serialization_helpers; | 10 library serialization_helpers; |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
173 } | 173 } |
174 | 174 |
175 /** | 175 /** |
176 * This acts as a stand-in for some value that cannot be hashed. We can't | 176 * This acts as a stand-in for some value that cannot be hashed. We can't |
177 * just use const Object() because the compiler will fold them together. | 177 * just use const Object() because the compiler will fold them together. |
178 */ | 178 */ |
179 class _Sentinel { | 179 class _Sentinel { |
180 final _wrappedObject; | 180 final _wrappedObject; |
181 const _Sentinel(this._wrappedObject); | 181 const _Sentinel(this._wrappedObject); |
182 } | 182 } |
| 183 |
| 184 /** |
| 185 * This is used in the implementation of [IdentityMap]. We wrap all the keys |
| 186 * in an [_IdentityMapKey] that compares using the identity of the wrapped |
| 187 * objects. It also treats equal primitive values as identical |
| 188 * to conserve space. |
| 189 */ |
| 190 class _IdentityMapKey { |
| 191 _IdentityMapKey(this._value); |
| 192 var _value; |
| 193 |
| 194 /** |
| 195 * Check if an object is primitive to know if we should compare it using |
| 196 * equality or identity. We don't test null/true/false where it's the same. |
| 197 */ |
| 198 _isPrimitive(x) => x is String || x is num; |
| 199 |
| 200 operator ==(_IdentityMapKey w) => |
| 201 _isPrimitive(_value) ? _value == w._value : identical(_value, w._value); |
| 202 get hashCode => _value.hashCode; |
| 203 get object => _value; |
| 204 } |
| 205 |
| 206 /** |
| 207 * This provides an identity map. We wrap all the objects in |
| 208 * an [_IdentityMapKey] that compares using the identity of the |
| 209 * wrapped objects. It also treats equal primitive values as identical |
| 210 * to conserve space. |
| 211 */ |
| 212 class IdentityMap<K, V> extends LinkedHashMap<K, V> { |
| 213 // TODO(alanknight): Replace with a system identity-based map once |
| 214 // one is available. Issue 4161. |
| 215 // TODO(lrn): Replace with identity map when custom hash maps are introduced |
| 216 // (which is soon). |
| 217 |
| 218 // Check before wrapping because some methods may call others, e.g. on |
| 219 // dart2js putIfAbsent calls containsKey, so without this we wrap forever. |
| 220 _wrap(Object key) => |
| 221 (key is _IdentityMapKey) ? key : new _IdentityMapKey(key); |
| 222 _unwrap(_IdentityMapKey wrapper) => wrapper.object; |
| 223 |
| 224 Iterable<K> get keys => super.keys.map((x) => _unwrap(x)); |
| 225 Iterable<V> get values => super.values; |
| 226 |
| 227 void forEach(void f(K key, V value)) { |
| 228 super.forEach((k, v) => f(_unwrap(k), v)); |
| 229 } |
| 230 |
| 231 V operator [](K key) => super[_wrap(key)]; |
| 232 |
| 233 void operator []=(K key, V value) { |
| 234 super[_wrap(key)] = value; |
| 235 } |
| 236 |
| 237 V putIfAbsent(K key, Function ifAbsent) => |
| 238 super.putIfAbsent(_wrap(key), ifAbsent); |
| 239 |
| 240 bool containsKey(Object key) => super.containsKey(_wrap(key)); |
| 241 |
| 242 V remove(Object key) => super.remove(_wrap(key)); |
| 243 } |
OLD | NEW |