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 |