| Index: runtime/lib/collection_patch.dart
|
| diff --git a/runtime/lib/collection_patch.dart b/runtime/lib/collection_patch.dart
|
| index 640b72bbe7dabd9d38ccad7f79a03e662cd70507..9f0c74fad4a7efd0bc94e22c91b32e61cbf21786 100644
|
| --- a/runtime/lib/collection_patch.dart
|
| +++ b/runtime/lib/collection_patch.dart
|
| @@ -11,12 +11,15 @@ patch class HashMap<K, V> {
|
| if (equals == null) {
|
| return new _HashMap<K, V>();
|
| }
|
| - if (identical(identical, equals)) {
|
| + hashCode = _defaultHashCode;
|
| + } else {
|
| + if (identical(identityHashCode, hashCode) &&
|
| + identical(identical, equals)) {
|
| return new _IdentityHashMap<K, V>();
|
| }
|
| - hashCode = _defaultHashCode;
|
| - } else if (equals == null) {
|
| - equals = _defaultEquals;
|
| + if (equals == null) {
|
| + equals = _defaultEquals;
|
| + }
|
| }
|
| } else {
|
| if (hashCode == null) {
|
| @@ -28,8 +31,11 @@ patch class HashMap<K, V> {
|
| }
|
| return new _CustomHashMap<K, V>(equals, hashCode, isValidKey);
|
| }
|
| +
|
| + /* patch */ factory HashMap.identity() = _IdentityHashMap<K, V>;
|
| }
|
|
|
| +
|
| const int _MODIFICATION_COUNT_MASK = 0x3fffffff;
|
|
|
| class _HashMap<K, V> implements HashMap<K, V> {
|
| @@ -320,7 +326,7 @@ class _CustomHashMap<K, V> extends _HashMap<K, V> {
|
| class _IdentityHashMap<K, V> extends _HashMap<K, V> {
|
|
|
| bool containsKey(Object key) {
|
| - int hashCode = key.hashCode;
|
| + int hashCode = identityHashCode(key);
|
| List buckets = _buckets;
|
| int index = hashCode & (buckets.length - 1);
|
| _HashMapEntry entry = buckets[index];
|
| @@ -332,7 +338,7 @@ class _IdentityHashMap<K, V> extends _HashMap<K, V> {
|
| }
|
|
|
| V operator[](Object key) {
|
| - int hashCode = key.hashCode;
|
| + int hashCode = identityHashCode(key);
|
| List buckets = _buckets;
|
| int index = hashCode & (buckets.length - 1);
|
| _HashMapEntry entry = buckets[index];
|
| @@ -346,7 +352,7 @@ class _IdentityHashMap<K, V> extends _HashMap<K, V> {
|
| }
|
|
|
| void operator []=(K key, V value) {
|
| - int hashCode = key.hashCode;
|
| + int hashCode = identityHashCode(key);
|
| List buckets = _buckets;
|
| int length = buckets.length;
|
| int index = hashCode & (length - 1);
|
| @@ -362,7 +368,7 @@ class _IdentityHashMap<K, V> extends _HashMap<K, V> {
|
| }
|
|
|
| V putIfAbsent(K key, V ifAbsent()) {
|
| - int hashCode = key.hashCode;
|
| + int hashCode = identityHashCode(key);
|
| List buckets = _buckets;
|
| int length = buckets.length;
|
| int index = hashCode & (length - 1);
|
| @@ -384,7 +390,7 @@ class _IdentityHashMap<K, V> extends _HashMap<K, V> {
|
| }
|
|
|
| V remove(Object key) {
|
| - int hashCode = key.hashCode;
|
| + int hashCode = identityHashCode(key);
|
| List buckets = _buckets;
|
| int index = hashCode & (buckets.length - 1);
|
| _HashMapEntry entry = buckets[index];
|
| @@ -509,20 +515,28 @@ patch class HashSet<E> {
|
| if (equals == null) {
|
| return new _HashSet<E>();
|
| }
|
| - if (identical(identical, equals)) {
|
| + hashCode = _defaultHashCode;
|
| + } else {
|
| + if (identical(identityHashCode, hashCode) &&
|
| + identical(identical, equals)) {
|
| return new _IdentityHashSet<E>();
|
| }
|
| - _hashCode = _defaultHashCode;
|
| - } else if (equals == null) {
|
| - _equals = _defaultEquals;
|
| + if (equals == null) {
|
| + equals = _defaultEquals;
|
| + }
|
| }
|
| - isValidKey = new _TypeTest<E>().test;
|
| } else {
|
| - if (hashCode == null) hashCode = _defaultHashCode;
|
| - if (equals == null) equals = _defaultEquals;
|
| + if (hashCode == null) {
|
| + hashCode = _defaultHashCode;
|
| + }
|
| + if (equals == null) {
|
| + equals = _defaultEquals;
|
| + }
|
| }
|
| return new _CustomHashSet<E>(equals, hashCode, isValidKey);
|
| }
|
| +
|
| + /* patch */ factory HashSet.identity() = _IdentityHashSet<E>;
|
| }
|
|
|
| class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> {
|
| @@ -688,6 +702,7 @@ class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> {
|
| }
|
|
|
| class _IdentityHashSet<E> extends _HashSet<E> {
|
| + int _hashCode(e) => identityHashCode(e);
|
| bool _equals(e1, e2) => identical(e1, e2);
|
| HashSet<E> _newSet() => new _IdentityHashSet<E>();
|
| }
|
| @@ -696,7 +711,8 @@ class _CustomHashSet<E> extends _HashSet<E> {
|
| final _Equality<E> _equality;
|
| final _Hasher<E> _hasher;
|
| final _Predicate _validKey;
|
| - _CustomHashSet(this._equality, this._hasher, this._validKey);
|
| + _CustomHashSet(this._equality, this._hasher, bool validKey(Object o))
|
| + : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
|
|
|
| bool remove(Object element) {
|
| if (!_validKey(element)) return false;
|
| @@ -877,12 +893,15 @@ patch class LinkedHashMap<K, V> {
|
| if (equals == null) {
|
| return new _LinkedHashMap<K, V>();
|
| }
|
| - if (identical(identical, equals)) {
|
| + hashCode = _defaultHashCode;
|
| + } else {
|
| + if (identical(identityHashCode, hashCode) &&
|
| + identical(identical, equals)) {
|
| return new _LinkedIdentityHashMap<K, V>();
|
| }
|
| - hashCode = _defaultHashCode;
|
| - } else if (equals == null) {
|
| - equals = _defaultEquals;
|
| + if (equals == null) {
|
| + equals = _defaultEquals;
|
| + }
|
| }
|
| } else {
|
| if (hashCode == null) {
|
| @@ -894,6 +913,8 @@ patch class LinkedHashMap<K, V> {
|
| }
|
| return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
|
| }
|
| +
|
| + /* patch */ factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>;
|
| }
|
|
|
| // Methods that are exactly the same in all three linked hash map variants.
|
| @@ -1004,20 +1025,28 @@ patch class LinkedHashSet<E> {
|
| if (equals == null) {
|
| return new _LinkedHashSet<E>();
|
| }
|
| - if (identical(identical, equals)) {
|
| + hashCode = _defaultHashCode;
|
| + } else {
|
| + if (identical(identityHashCode, hashCode) &&
|
| + identical(identical, equals)) {
|
| return new _LinkedIdentityHashSet<E>();
|
| }
|
| - _hashCode = _defaultHashCode;
|
| - } else if (equals == null) {
|
| - _equals = _defaultEquals;
|
| + if (equals == null) {
|
| + equals = _defaultEquals;
|
| + }
|
| }
|
| - isValidKey = new _TypeTest<E>().test;
|
| } else {
|
| - if (hashCode == null) hashCode = _defaultHashCode;
|
| - if (equals == null) equals = _defaultEquals;
|
| + if (hashCode == null) {
|
| + hashCode = _defaultHashCode;
|
| + }
|
| + if (equals == null) {
|
| + equals = _defaultEquals;
|
| + }
|
| }
|
| return new _LinkedCustomHashSet<E>(equals, hashCode, isValidKey);
|
| }
|
| +
|
| + /* patch */ factory LinkedHashSet.identity() = _LinkedIdentityHashSet<E>;
|
| }
|
|
|
| class _LinkedHashSetEntry extends _HashSetEntry {
|
| @@ -1129,6 +1158,7 @@ class _LinkedHashSet<E> extends _HashSet<E>
|
| }
|
|
|
| class _LinkedIdentityHashSet<E> extends _LinkedHashSet<E> {
|
| + int _hashCode(e) => identityHashCode(e);
|
| bool _equals(e1, e2) => identical(e1, e2);
|
| HashSet<E> _newSet() => new _LinkedIdentityHashSet<E>();
|
| }
|
| @@ -1138,7 +1168,7 @@ class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> {
|
| final _Hasher<E> _hasher;
|
| final _Predicate _validKey;
|
|
|
| - _LinkedCustomHashSet(this._equality, this._hasher, bool validKey(object))
|
| + _LinkedCustomHashSet(this._equality, this._hasher, bool validKey(Object o))
|
| : _validKey = (validKey != null) ? validKey : new _TypeTest<E>().test;
|
|
|
| bool _equals(e1, e2) => _equality(e1, e2);
|
|
|