| Index: pkg/serialization/lib/src/serialization_helpers.dart
|
| diff --git a/pkg/serialization/lib/src/serialization_helpers.dart b/pkg/serialization/lib/src/serialization_helpers.dart
|
| index d9ad747bfa48a4b88211dcfdb8450ec6279433dd..ec898574730d0cbba7d0ad886adf306d80a6cb88 100644
|
| --- a/pkg/serialization/lib/src/serialization_helpers.dart
|
| +++ b/pkg/serialization/lib/src/serialization_helpers.dart
|
| @@ -180,3 +180,64 @@ class _Sentinel {
|
| final _wrappedObject;
|
| const _Sentinel(this._wrappedObject);
|
| }
|
| +
|
| +/**
|
| + * This is used in the implementation of [IdentityMap]. We wrap all the keys
|
| + * in an [_IdentityMapKey] that compares using the identity of the wrapped
|
| + * objects. It also treats equal primitive values as identical
|
| + * to conserve space.
|
| + */
|
| +class _IdentityMapKey {
|
| + _IdentityMapKey(this._value);
|
| + var _value;
|
| +
|
| + /**
|
| + * Check if an object is primitive to know if we should compare it using
|
| + * equality or identity. We don't test null/true/false where it's the same.
|
| + */
|
| + _isPrimitive(x) => x is String || x is num;
|
| +
|
| + operator ==(_IdentityMapKey w) =>
|
| + _isPrimitive(_value) ? _value == w._value : identical(_value, w._value);
|
| + get hashCode => _value.hashCode;
|
| + get object => _value;
|
| +}
|
| +
|
| +/**
|
| + * This provides an identity map. We wrap all the objects in
|
| + * an [_IdentityMapKey] that compares using the identity of the
|
| + * wrapped objects. It also treats equal primitive values as identical
|
| + * to conserve space.
|
| + */
|
| +class IdentityMap<K, V> extends LinkedHashMap<K, V> {
|
| +// TODO(alanknight): Replace with a system identity-based map once
|
| +// one is available. Issue 4161.
|
| +// TODO(lrn): Replace with identity map when custom hash maps are introduced
|
| +// (which is soon).
|
| +
|
| + // Check before wrapping because some methods may call others, e.g. on
|
| + // dart2js putIfAbsent calls containsKey, so without this we wrap forever.
|
| + _wrap(Object key) =>
|
| + (key is _IdentityMapKey) ? key : new _IdentityMapKey(key);
|
| + _unwrap(_IdentityMapKey wrapper) => wrapper.object;
|
| +
|
| + Iterable<K> get keys => super.keys.map((x) => _unwrap(x));
|
| + Iterable<V> get values => super.values;
|
| +
|
| + void forEach(void f(K key, V value)) {
|
| + super.forEach((k, v) => f(_unwrap(k), v));
|
| + }
|
| +
|
| + V operator [](K key) => super[_wrap(key)];
|
| +
|
| + void operator []=(K key, V value) {
|
| + super[_wrap(key)] = value;
|
| + }
|
| +
|
| + V putIfAbsent(K key, Function ifAbsent) =>
|
| + super.putIfAbsent(_wrap(key), ifAbsent);
|
| +
|
| + bool containsKey(Object key) => super.containsKey(_wrap(key));
|
| +
|
| + V remove(Object key) => super.remove(_wrap(key));
|
| +}
|
|
|