| Index: sdk/lib/_internal/lib/collection_patch.dart
|
| diff --git a/sdk/lib/_internal/lib/collection_patch.dart b/sdk/lib/_internal/lib/collection_patch.dart
|
| index e275fee4097d74e7a866e7893372a68b1cc872ee..c5fa69cf9dfd4caa245c585b23dc604aa7bb86be 100644
|
| --- a/sdk/lib/_internal/lib/collection_patch.dart
|
| +++ b/sdk/lib/_internal/lib/collection_patch.dart
|
| @@ -6,34 +6,23 @@
|
| import 'dart:_foreign_helper' show JS;
|
|
|
| patch class HashMap<K, V> {
|
| - patch factory HashMap({ bool equals(K key1, K key2),
|
| - int hashCode(K key),
|
| - bool isValidKey(potentialKey) }) {
|
| - if (isValidKey == null) {
|
| - if (hashCode == null) {
|
| - if (equals == null) {
|
| - return new _HashMap<K, V>();
|
| - }
|
| - if (identical(identical, equals)) {
|
| - return new _IdentityHashMap<K, V>();
|
| - }
|
| - hashCode = _defaultHashCode;
|
| - } else if (equals == null) {
|
| - equals = _defaultEquals;
|
| - }
|
| - } else {
|
| - if (hashCode == null) {
|
| - hashCode = _defaultHashCode;
|
| - }
|
| + patch factory HashMap({ bool equals(K key1, K key2), int hashCode(K key) }) {
|
| + if (hashCode == null) {
|
| if (equals == null) {
|
| - equals = _defaultEquals;
|
| + return new _HashMapImpl<K, V>();
|
| + }
|
| + if (identical(identical, equals)) {
|
| + return new _IdentityHashMap<K, V>();
|
| }
|
| + hashCode = _defaultHashCode;
|
| + } else if (equals == null) {
|
| + equals = _defaultEquals;
|
| }
|
| - return new _CustomHashMap<K, V>(equals, hashCode, isValidKey);
|
| + return new _CustomHashMap<K, V>(equals, hashCode);
|
| }
|
| }
|
|
|
| -class _HashMap<K, V> implements HashMap<K, V> {
|
| +class _HashMapImpl<K, V> implements HashMap<K, V> {
|
| int _length = 0;
|
|
|
| // The hash map contents are divided into three parts: one part for
|
| @@ -54,7 +43,7 @@ class _HashMap<K, V> implements HashMap<K, V> {
|
| // guard against concurrent modifications.
|
| List _keys;
|
|
|
| - _Hash();
|
| + _HashMapImpl();
|
|
|
| int get length => _length;
|
| bool get isEmpty => _length == 0;
|
| @@ -245,7 +234,7 @@ class _HashMap<K, V> implements HashMap<K, V> {
|
| _setTableEntry(table, key, value);
|
| }
|
|
|
| - V _removeHashTableEntry(var table, Object key) {
|
| + V _removeHashTableEntry(var table, K key) {
|
| if (table != null && _hasTableEntry(table, key)) {
|
| V value = _getTableEntry(table, key);
|
| _deleteTableEntry(table, key);
|
| @@ -336,7 +325,7 @@ class _HashMap<K, V> implements HashMap<K, V> {
|
| }
|
| }
|
|
|
| -class _IdentityHashMap<K, V> extends _HashMap<K, V> {
|
| +class _IdentityHashMap<K, V> extends _HashMapImpl<K, V> {
|
| int _findBucketIndex(var bucket, var key) {
|
| if (bucket == null) return -1;
|
| int length = JS('int', '#.length', bucket);
|
| @@ -347,27 +336,10 @@ class _IdentityHashMap<K, V> extends _HashMap<K, V> {
|
| }
|
| }
|
|
|
| -class _CustomHashMap<K, V> extends _HashMap<K, V> {
|
| +class _CustomHashMap<K, V> extends _HashMapImpl<K, V> {
|
| final _Equality<K> _equals;
|
| final _Hasher<K> _hashCode;
|
| - final _Predicate _validKey;
|
| - _CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey))
|
| - : _validKey = (validKey != null) ? validKey : ((v) => v is K);
|
| -
|
| - V operator[](Object key) {
|
| - if (!_validKey(key)) return null;
|
| - return super[key];
|
| - }
|
| -
|
| - bool containsKey(Object key) {
|
| - if (!_validKey(key)) return false;
|
| - return super.containsKey(key);
|
| - }
|
| -
|
| - V remove(Object key) {
|
| - if (!_validKey(key)) return null;
|
| - return super.remove(key);
|
| - }
|
| + _CustomHashMap(this._equals, this._hashCode);
|
|
|
| int _computeHashCode(var key) {
|
| // We force the hash codes to be unsigned 30-bit integers to avoid
|
| @@ -444,34 +416,6 @@ class HashMapKeyIterator<E> implements Iterator<E> {
|
| }
|
|
|
| patch class LinkedHashMap<K, V> {
|
| - patch factory LinkedHashMap({ bool equals(K key1, K key2),
|
| - int hashCode(K key),
|
| - bool isValidKey(potentialKey) }) {
|
| - if (isValidKey == null) {
|
| - if (hashCode == null) {
|
| - if (equals == null) {
|
| - return new _LinkedHashMap<K, V>();
|
| - }
|
| - if (identical(identical, equals)) {
|
| - return new _LinkedIdentityHashMap<K, V>();
|
| - }
|
| - hashCode = _defaultHashCode;
|
| - } else if (equals == null) {
|
| - equals = _defaultEquals;
|
| - }
|
| - } else {
|
| - if (hashCode == null) {
|
| - hashCode = _defaultHashCode;
|
| - }
|
| - if (equals == null) {
|
| - equals = _defaultEquals;
|
| - }
|
| - }
|
| - return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey);
|
| - }
|
| -}
|
| -
|
| -class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| int _length = 0;
|
|
|
| // The hash map contents are divided into three parts: one part for
|
| @@ -496,22 +440,22 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| // iterated over.
|
| int _modifications = 0;
|
|
|
| - _LinkedHash();
|
| + patch LinkedHashMap();
|
|
|
| - int get length => _length;
|
| - bool get isEmpty => _length == 0;
|
| - bool get isNotEmpty => !isEmpty;
|
| + patch int get length => _length;
|
| + patch bool get isEmpty => _length == 0;
|
| + patch bool get isNotEmpty => !isEmpty;
|
|
|
|
|
| - Iterable<K> get keys {
|
| + patch Iterable<K> get keys {
|
| return new LinkedHashMapKeyIterable<K>(this);
|
| }
|
|
|
| - Iterable<V> get values {
|
| + patch Iterable<V> get values {
|
| return keys.map((each) => this[each]);
|
| }
|
|
|
| - bool containsKey(Object key) {
|
| + patch bool containsKey(Object key) {
|
| if (_isStringKey(key)) {
|
| var strings = _strings;
|
| if (strings == null) return false;
|
| @@ -530,17 +474,17 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| }
|
| }
|
|
|
| - bool containsValue(Object value) {
|
| + patch bool containsValue(Object value) {
|
| return keys.any((each) => this[each] == value);
|
| }
|
|
|
| - void addAll(Map<K, V> other) {
|
| + patch void addAll(Map<K, V> other) {
|
| other.forEach((K key, V value) {
|
| this[key] = value;
|
| });
|
| }
|
|
|
| - V operator[](Object key) {
|
| + patch V operator[](Object key) {
|
| if (_isStringKey(key)) {
|
| var strings = _strings;
|
| if (strings == null) return null;
|
| @@ -562,7 +506,7 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| }
|
| }
|
|
|
| - void operator[]=(K key, V value) {
|
| + patch void operator[]=(K key, V value) {
|
| if (_isStringKey(key)) {
|
| var strings = _strings;
|
| if (strings == null) _strings = strings = _newHashTable();
|
| @@ -592,14 +536,14 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| }
|
| }
|
|
|
| - V putIfAbsent(K key, V ifAbsent()) {
|
| + patch V putIfAbsent(K key, V ifAbsent()) {
|
| if (containsKey(key)) return this[key];
|
| V value = ifAbsent();
|
| this[key] = value;
|
| return value;
|
| }
|
|
|
| - V remove(Object key) {
|
| + patch V remove(Object key) {
|
| if (_isStringKey(key)) {
|
| return _removeHashTableEntry(_strings, key);
|
| } else if (_isNumericKey(key)) {
|
| @@ -620,7 +564,7 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| }
|
| }
|
|
|
| - void clear() {
|
| + patch void clear() {
|
| if (_length > 0) {
|
| _strings = _nums = _rest = _first = _last = null;
|
| _length = 0;
|
| @@ -628,7 +572,7 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| }
|
| }
|
|
|
| - void forEach(void action(K key, V value)) {
|
| + patch void forEach(void action(K key, V value)) {
|
| LinkedHashMapCell cell = _first;
|
| int modifications = _modifications;
|
| while (cell != null) {
|
| @@ -649,7 +593,7 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| }
|
| }
|
|
|
| - V _removeHashTableEntry(var table, Object key) {
|
| + V _removeHashTableEntry(var table, K key) {
|
| if (table == null) return null;
|
| LinkedHashMapCell cell = _getTableEntry(table, key);
|
| if (cell == null) return null;
|
| @@ -711,7 +655,7 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| return key is num && JS('bool', '(# & 0x3ffffff) === #', key, key);
|
| }
|
|
|
| - int _computeHashCode(var key) {
|
| + static int _computeHashCode(var key) {
|
| // We force the hash codes to be unsigned 30-bit integers to avoid
|
| // issues with problematic keys like '__proto__'. Another option
|
| // would be to throw an exception if the hash code isn't a number.
|
| @@ -731,12 +675,12 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| JS('void', 'delete #[#]', table, key);
|
| }
|
|
|
| - List _getBucket(var table, var key) {
|
| + static List _getBucket(var table, var key) {
|
| var hash = _computeHashCode(key);
|
| return JS('var', '#[#]', table, hash);
|
| }
|
|
|
| - int _findBucketIndex(var bucket, var key) {
|
| + static int _findBucketIndex(var bucket, var key) {
|
| if (bucket == null) return -1;
|
| int length = JS('int', '#.length', bucket);
|
| for (int i = 0; i < length; i++) {
|
| @@ -758,61 +702,6 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> {
|
| _deleteTableEntry(table, temporaryKey);
|
| return table;
|
| }
|
| -
|
| - String toString() => Maps.mapToString(this);
|
| -}
|
| -
|
| -class _LinkedIdentityHashMap<K, V> extends _LinkedHashMap<K, V> {
|
| - int _findBucketIndex(var bucket, var key) {
|
| - if (bucket == null) return -1;
|
| - int length = JS('int', '#.length', bucket);
|
| - for (int i = 0; i < length; i++) {
|
| - LinkedHashMapCell cell = JS('var', '#[#]', bucket, i);
|
| - if (identical(cell._key, key)) return i;
|
| - }
|
| - return -1;
|
| - }
|
| -}
|
| -
|
| -class _LinkedCustomHashMap<K, V> extends _LinkedHashMap<K, V> {
|
| - final _Equality<K> _equals;
|
| - final _Hasher<K> _hashCode;
|
| - final _Predicate _validKey;
|
| - _LinkedCustomHashMap(this._equals, this._hashCode,
|
| - bool validKey(potentialKey))
|
| - : _validKey = (validKey != null) ? validKey : ((v) => v is K);
|
| -
|
| - V operator[](Object key) {
|
| - if (!_validKey(key)) return null;
|
| - return super[key];
|
| - }
|
| -
|
| - bool containsKey(Object key) {
|
| - if (!_validKey(key)) return false;
|
| - return super.containsKey(key);
|
| - }
|
| -
|
| - V remove(Object key) {
|
| - if (!_validKey(key)) return null;
|
| - return super.remove(key);
|
| - }
|
| -
|
| - int _computeHashCode(var key) {
|
| - // We force the hash codes to be unsigned 30-bit integers to avoid
|
| - // issues with problematic keys like '__proto__'. Another option
|
| - // would be to throw an exception if the hash code isn't a number.
|
| - return JS('int', '# & 0x3ffffff', _hashCode(key));
|
| - }
|
| -
|
| - int _findBucketIndex(var bucket, var key) {
|
| - if (bucket == null) return -1;
|
| - int length = JS('int', '#.length', bucket);
|
| - for (int i = 0; i < length; i++) {
|
| - LinkedHashMapCell cell = JS('var', '#[#]', bucket, i);
|
| - if (_equals(cell._key, key)) return i;
|
| - }
|
| - return -1;
|
| - }
|
| }
|
|
|
| class LinkedHashMapCell {
|
|
|