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 a7e7ee25f3029aa7ece7e59f3827117d9b2c11c8..71bc64ecc52ec67664cde79417275d5dedd8e7d5 100644 |
--- a/sdk/lib/_internal/lib/collection_patch.dart |
+++ b/sdk/lib/_internal/lib/collection_patch.dart |
@@ -83,13 +83,17 @@ class _HashMap<K, V> implements HashMap<K, V> { |
var nums = _nums; |
return (nums == null) ? false : _hasTableEntry(nums, key); |
} else { |
- var rest = _rest; |
- if (rest == null) return false; |
- var bucket = _getBucket(rest, key); |
- return _findBucketIndex(bucket, key) >= 0; |
+ return _containsKey(key); |
} |
} |
+ bool _containsKey(Object key) { |
+ var rest = _rest; |
+ if (rest == null) return false; |
+ var bucket = _getBucket(rest, key); |
+ return _findBucketIndex(bucket, key) >= 0; |
+ } |
+ |
bool containsValue(Object value) { |
return _computeKeys().any((each) => this[each] == value); |
} |
@@ -108,14 +112,18 @@ class _HashMap<K, V> implements HashMap<K, V> { |
var nums = _nums; |
return (nums == null) ? null : _getTableEntry(nums, key); |
} else { |
- var rest = _rest; |
- if (rest == null) return null; |
- var bucket = _getBucket(rest, key); |
- int index = _findBucketIndex(bucket, key); |
- return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1); |
+ return _get(key); |
} |
} |
+ V _get(Object key) { |
+ var rest = _rest; |
+ if (rest == null) return null; |
+ var bucket = _getBucket(rest, key); |
+ int index = _findBucketIndex(bucket, key); |
+ return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1); |
+ } |
+ |
void operator[]=(K key, V value) { |
if (_isStringKey(key)) { |
var strings = _strings; |
@@ -126,23 +134,27 @@ class _HashMap<K, V> implements HashMap<K, V> { |
if (nums == null) _nums = nums = _newHashTable(); |
_addHashTableEntry(nums, key, value); |
} else { |
- var rest = _rest; |
- if (rest == null) _rest = rest = _newHashTable(); |
- var hash = _computeHashCode(key); |
- var bucket = JS('var', '#[#]', rest, hash); |
- if (bucket == null) { |
- _setTableEntry(rest, hash, JS('var', '[#, #]', key, value)); |
+ _set(key, value); |
+ } |
+ } |
+ |
+ void _set(K key, V value) { |
+ var rest = _rest; |
+ if (rest == null) _rest = rest = _newHashTable(); |
+ var hash = _computeHashCode(key); |
+ var bucket = JS('var', '#[#]', rest, hash); |
+ if (bucket == null) { |
+ _setTableEntry(rest, hash, JS('var', '[#, #]', key, value)); |
+ _length++; |
+ _keys = null; |
+ } else { |
+ int index = _findBucketIndex(bucket, key); |
+ if (index >= 0) { |
+ JS('void', '#[#] = #', bucket, index + 1, value); |
+ } else { |
+ JS('void', '#.push(#, #)', bucket, key, value); |
_length++; |
_keys = null; |
- } else { |
- int index = _findBucketIndex(bucket, key); |
- if (index >= 0) { |
- JS('void', '#[#] = #', bucket, index + 1, value); |
- } else { |
- JS('void', '#.push(#, #)', bucket, key, value); |
- _length++; |
- _keys = null; |
- } |
} |
} |
} |
@@ -160,21 +172,25 @@ class _HashMap<K, V> implements HashMap<K, V> { |
} else if (_isNumericKey(key)) { |
return _removeHashTableEntry(_nums, key); |
} else { |
- var rest = _rest; |
- if (rest == null) return null; |
- var bucket = _getBucket(rest, key); |
- int index = _findBucketIndex(bucket, key); |
- if (index < 0) return null; |
- // TODO(kasperl): Consider getting rid of the bucket list when |
- // the length reaches zero. |
- _length--; |
- _keys = null; |
- // Use splice to remove the two [key, value] elements at the |
- // index and return the value. |
- return JS('var', '#.splice(#, 2)[1]', bucket, index); |
+ return _remove(key); |
} |
} |
+ V _remove(Object key) { |
+ var rest = _rest; |
+ if (rest == null) return null; |
+ var bucket = _getBucket(rest, key); |
+ int index = _findBucketIndex(bucket, key); |
+ if (index < 0) return null; |
+ // TODO(kasperl): Consider getting rid of the bucket list when |
+ // the length reaches zero. |
+ _length--; |
+ _keys = null; |
+ // Use splice to remove the two [key, value] elements at the |
+ // index and return the value. |
+ return JS('var', '#.splice(#, 2)[1]', bucket, index); |
+ } |
+ |
void clear() { |
if (_length > 0) { |
_strings = _nums = _rest = _keys = null; |
@@ -370,17 +386,21 @@ class _CustomHashMap<K, V> extends _HashMap<K, V> { |
V operator[](Object key) { |
if (!_validKey(key)) return null; |
- return super[key]; |
+ return super._get(key); |
+ } |
+ |
+ void operator[]=(K key, V value) { |
+ super._set(key, value); |
} |
bool containsKey(Object key) { |
if (!_validKey(key)) return false; |
- return super.containsKey(key); |
+ return super._containsKey(key); |
} |
V remove(Object key) { |
if (!_validKey(key)) return null; |
- return super.remove(key); |
+ return super._remove(key); |
} |
int _computeHashCode(var key) { |
@@ -555,13 +575,17 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> { |
LinkedHashMapCell cell = _getTableEntry(nums, key); |
return cell != null; |
} else { |
- var rest = _rest; |
- if (rest == null) return false; |
- var bucket = _getBucket(rest, key); |
- return _findBucketIndex(bucket, key) >= 0; |
+ return _containsKey(key); |
} |
} |
+ bool _containsKey(Object key) { |
+ var rest = _rest; |
+ if (rest == null) return false; |
+ var bucket = _getBucket(rest, key); |
+ return _findBucketIndex(bucket, key) >= 0; |
+ } |
+ |
bool containsValue(Object value) { |
return keys.any((each) => this[each] == value); |
} |
@@ -584,16 +608,20 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> { |
LinkedHashMapCell cell = _getTableEntry(nums, key); |
return (cell == null) ? null : cell._value; |
} else { |
- var rest = _rest; |
- if (rest == null) return null; |
- var bucket = _getBucket(rest, key); |
- int index = _findBucketIndex(bucket, key); |
- if (index < 0) return null; |
- LinkedHashMapCell cell = JS('var', '#[#]', bucket, index); |
- return cell._value; |
+ return _get(key); |
} |
} |
+ V _get(K key) { |
+ var rest = _rest; |
+ if (rest == null) return null; |
+ var bucket = _getBucket(rest, key); |
+ int index = _findBucketIndex(bucket, key); |
+ if (index < 0) return null; |
+ LinkedHashMapCell cell = JS('var', '#[#]', bucket, index); |
+ return cell._value; |
+ } |
+ |
void operator[]=(K key, V value) { |
if (_isStringKey(key)) { |
var strings = _strings; |
@@ -604,22 +632,26 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> { |
if (nums == null) _nums = nums = _newHashTable(); |
_addHashTableEntry(nums, key, value); |
} else { |
- var rest = _rest; |
- if (rest == null) _rest = rest = _newHashTable(); |
- var hash = _computeHashCode(key); |
- var bucket = JS('var', '#[#]', rest, hash); |
- if (bucket == null) { |
- LinkedHashMapCell cell = _newLinkedCell(key, value); |
- _setTableEntry(rest, hash, JS('var', '[#]', cell)); |
+ _set(key, value); |
+ } |
+ } |
+ |
+ void _set(K key, V value) { |
+ var rest = _rest; |
+ if (rest == null) _rest = rest = _newHashTable(); |
+ var hash = _computeHashCode(key); |
+ var bucket = JS('var', '#[#]', rest, hash); |
+ if (bucket == null) { |
+ LinkedHashMapCell cell = _newLinkedCell(key, value); |
+ _setTableEntry(rest, hash, JS('var', '[#]', cell)); |
+ } else { |
+ int index = _findBucketIndex(bucket, key); |
+ if (index >= 0) { |
+ LinkedHashMapCell cell = JS('var', '#[#]', bucket, index); |
+ cell._value = value; |
} else { |
- int index = _findBucketIndex(bucket, key); |
- if (index >= 0) { |
- LinkedHashMapCell cell = JS('var', '#[#]', bucket, index); |
- cell._value = value; |
- } else { |
- LinkedHashMapCell cell = _newLinkedCell(key, value); |
- JS('void', '#.push(#)', bucket, cell); |
- } |
+ LinkedHashMapCell cell = _newLinkedCell(key, value); |
+ JS('void', '#.push(#)', bucket, cell); |
} |
} |
} |
@@ -637,21 +669,25 @@ class _LinkedHashMap<K, V> implements LinkedHashMap<K, V> { |
} else if (_isNumericKey(key)) { |
return _removeHashTableEntry(_nums, key); |
} else { |
- var rest = _rest; |
- if (rest == null) return null; |
- var bucket = _getBucket(rest, key); |
- int index = _findBucketIndex(bucket, key); |
- if (index < 0) return null; |
- // Use splice to remove the [cell] element at the index and |
- // unlink the cell before returning its value. |
- LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index); |
- _unlinkCell(cell); |
- // TODO(kasperl): Consider getting rid of the bucket list when |
- // the length reaches zero. |
- return cell._value; |
+ return _remove(key); |
} |
} |
+ V _remove(Object key) { |
+ var rest = _rest; |
+ if (rest == null) return null; |
+ var bucket = _getBucket(rest, key); |
+ int index = _findBucketIndex(bucket, key); |
+ if (index < 0) return null; |
+ // Use splice to remove the [cell] element at the index and |
+ // unlink the cell before returning its value. |
+ LinkedHashMapCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index); |
+ _unlinkCell(cell); |
+ // TODO(kasperl): Consider getting rid of the bucket list when |
+ // the length reaches zero. |
+ return cell._value; |
+ } |
+ |
void clear() { |
if (_length > 0) { |
_strings = _nums = _rest = _first = _last = null; |
@@ -823,17 +859,21 @@ class _LinkedCustomHashMap<K, V> extends _LinkedHashMap<K, V> { |
V operator[](Object key) { |
if (!_validKey(key)) return null; |
- return super[key]; |
+ return super._get(key); |
+ } |
+ |
+ void operator[]=(K key, V value) { |
+ super._set(key, value); |
} |
bool containsKey(Object key) { |
if (!_validKey(key)) return false; |
- return super.containsKey(key); |
+ return super._containsKey(key); |
} |
V remove(Object key) { |
if (!_validKey(key)) return null; |
- return super.remove(key); |
+ return super._remove(key); |
} |
int _computeHashCode(var key) { |
@@ -995,17 +1035,25 @@ class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> { |
var nums = _nums; |
return (nums == null) ? false : _hasTableEntry(nums, object); |
} else { |
- var rest = _rest; |
- if (rest == null) return false; |
- var bucket = _getBucket(rest, object); |
- return _findBucketIndex(bucket, object) >= 0; |
+ return _contains(object); |
} |
} |
+ bool _contains(Object object) { |
+ var rest = _rest; |
+ if (rest == null) return false; |
+ var bucket = _getBucket(rest, object); |
+ return _findBucketIndex(bucket, object) >= 0; |
+ } |
+ |
E lookup(Object object) { |
if (_isStringElement(object) || _isNumericElement(object)) { |
return this.contains(object) ? object : null; |
} |
+ return _lookup(object); |
+ } |
+ |
+ E _lookup(Object object) { |
var rest = _rest; |
if (rest == null) return null; |
var bucket = _getBucket(rest, object); |
@@ -1025,23 +1073,27 @@ class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> { |
if (nums == null) _nums = nums = _newHashTable(); |
return _addHashTableEntry(nums, element); |
} else { |
- var rest = _rest; |
- if (rest == null) _rest = rest = _newHashTable(); |
- var hash = _computeHashCode(element); |
- var bucket = JS('var', '#[#]', rest, hash); |
- if (bucket == null) { |
- _setTableEntry(rest, hash, JS('var', '[#]', element)); |
- } else { |
- int index = _findBucketIndex(bucket, element); |
- if (index >= 0) return false; |
- JS('void', '#.push(#)', bucket, element); |
- } |
- _length++; |
- _elements = null; |
- return true; |
+ return _add(element); |
} |
} |
+ bool _add(E element) { |
+ var rest = _rest; |
+ if (rest == null) _rest = rest = _newHashTable(); |
+ var hash = _computeHashCode(element); |
+ var bucket = JS('var', '#[#]', rest, hash); |
+ if (bucket == null) { |
+ _setTableEntry(rest, hash, JS('var', '[#]', element)); |
+ } else { |
+ int index = _findBucketIndex(bucket, element); |
+ if (index >= 0) return false; |
+ JS('void', '#.push(#)', bucket, element); |
+ } |
+ _length++; |
+ _elements = null; |
+ return true; |
+ } |
+ |
void addAll(Iterable<E> objects) { |
for (E each in objects) { |
add(each); |
@@ -1054,22 +1106,26 @@ class _HashSet<E> extends _HashSetBase<E> implements HashSet<E> { |
} else if (_isNumericElement(object)) { |
return _removeHashTableEntry(_nums, object); |
} else { |
- var rest = _rest; |
- if (rest == null) return false; |
- var bucket = _getBucket(rest, object); |
- int index = _findBucketIndex(bucket, object); |
- if (index < 0) return false; |
- // TODO(kasperl): Consider getting rid of the bucket list when |
- // the length reaches zero. |
- _length--; |
- _elements = null; |
- // TODO(kasperl): It would probably be faster to move the |
- // element to the end and reduce the length of the bucket list. |
- JS('void', '#.splice(#, 1)', bucket, index); |
- return true; |
+ return _remove(object); |
} |
} |
+ bool _remove(object) { |
+ var rest = _rest; |
+ if (rest == null) return false; |
+ var bucket = _getBucket(rest, object); |
+ int index = _findBucketIndex(bucket, object); |
+ if (index < 0) return false; |
+ // TODO(kasperl): Consider getting rid of the bucket list when |
+ // the length reaches zero. |
+ _length--; |
+ _elements = null; |
+ // TODO(kasperl): It would probably be faster to move the |
+ // element to the end and reduce the length of the bucket list. |
+ JS('void', '#.splice(#, 1)', bucket, index); |
+ return true; |
+ } |
+ |
void removeAll(Iterable<Object> objectsToRemove) { |
for (var each in objectsToRemove) { |
remove(each); |
@@ -1275,19 +1331,21 @@ class _CustomHashSet<E> extends _HashSet<E> { |
return JS('int', '# & 0x3ffffff', _hasher(element)); |
} |
+ bool add(E object) => super._add(object); |
+ |
bool contains(Object object) { |
if (!_validKey(object)) return false; |
- return super.contains(object); |
+ return super._contains(object); |
} |
E lookup(Object object) { |
if (!_validKey(object)) return null; |
- return super.lookup(object); |
+ return super._lookup(object); |
} |
bool remove(Object object) { |
if (!_validKey(object)) return false; |
- return super.remove(object); |
+ return super._remove(object); |
} |
bool containsAll(Iterable<Object> elements) { |
@@ -1428,26 +1486,34 @@ class _LinkedHashSet<E> extends _HashSetBase<E> implements LinkedHashSet<E> { |
LinkedHashSetCell cell = _getTableEntry(nums, object); |
return cell != null; |
} else { |
- var rest = _rest; |
- if (rest == null) return false; |
- var bucket = _getBucket(rest, object); |
- return _findBucketIndex(bucket, object) >= 0; |
+ return _contains(object); |
} |
} |
+ bool _contains(Object object) { |
+ var rest = _rest; |
+ if (rest == null) return false; |
+ var bucket = _getBucket(rest, object); |
+ return _findBucketIndex(bucket, object) >= 0; |
+ } |
+ |
E lookup(Object object) { |
if (_isStringElement(object) || _isNumericElement(object)) { |
return this.contains(object) ? object : null; |
} else { |
- var rest = _rest; |
- if (rest == null) return null; |
- var bucket = _getBucket(rest, object); |
- var index = _findBucketIndex(bucket, object); |
- if (index < 0) return null; |
- return bucket[index]._element; |
+ return _lookup(object); |
} |
} |
+ E _lookup(Object object) { |
+ var rest = _rest; |
+ if (rest == null) return null; |
+ var bucket = _getBucket(rest, object); |
+ var index = _findBucketIndex(bucket, object); |
+ if (index < 0) return null; |
+ return bucket[index]._element; |
+ } |
+ |
void forEach(void action(E element)) { |
LinkedHashSetCell cell = _first; |
int modifications = _modifications; |
@@ -1481,23 +1547,27 @@ class _LinkedHashSet<E> extends _HashSetBase<E> implements LinkedHashSet<E> { |
if (nums == null) _nums = nums = _newHashTable(); |
return _addHashTableEntry(nums, element); |
} else { |
- var rest = _rest; |
- if (rest == null) _rest = rest = _newHashTable(); |
- var hash = _computeHashCode(element); |
- var bucket = JS('var', '#[#]', rest, hash); |
- if (bucket == null) { |
- LinkedHashSetCell cell = _newLinkedCell(element); |
- _setTableEntry(rest, hash, JS('var', '[#]', cell)); |
- } else { |
- int index = _findBucketIndex(bucket, element); |
- if (index >= 0) return false; |
- LinkedHashSetCell cell = _newLinkedCell(element); |
- JS('void', '#.push(#)', bucket, cell); |
- } |
- return true; |
+ return _add(element); |
} |
} |
+ bool _add(E element) { |
+ var rest = _rest; |
+ if (rest == null) _rest = rest = _newHashTable(); |
+ var hash = _computeHashCode(element); |
+ var bucket = JS('var', '#[#]', rest, hash); |
+ if (bucket == null) { |
+ LinkedHashSetCell cell = _newLinkedCell(element); |
+ _setTableEntry(rest, hash, JS('var', '[#]', cell)); |
+ } else { |
+ int index = _findBucketIndex(bucket, element); |
+ if (index >= 0) return false; |
+ LinkedHashSetCell cell = _newLinkedCell(element); |
+ JS('void', '#.push(#)', bucket, cell); |
+ } |
+ return true; |
+ } |
+ |
void addAll(Iterable<E> objects) { |
for (E object in objects) { |
add(object); |
@@ -1510,19 +1580,23 @@ class _LinkedHashSet<E> extends _HashSetBase<E> implements LinkedHashSet<E> { |
} else if (_isNumericElement(object)) { |
return _removeHashTableEntry(_nums, object); |
} else { |
- var rest = _rest; |
- if (rest == null) return false; |
- var bucket = _getBucket(rest, object); |
- int index = _findBucketIndex(bucket, object); |
- if (index < 0) return false; |
- // Use splice to remove the [cell] element at the index and |
- // unlink it. |
- LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index); |
- _unlinkCell(cell); |
- return true; |
+ return _remove(object); |
} |
} |
+ bool _remove(Object object) { |
+ var rest = _rest; |
+ if (rest == null) return false; |
+ var bucket = _getBucket(rest, object); |
+ int index = _findBucketIndex(bucket, object); |
+ if (index < 0) return false; |
+ // Use splice to remove the [cell] element at the index and |
+ // unlink it. |
+ LinkedHashSetCell cell = JS('var', '#.splice(#, 1)[0]', bucket, index); |
+ _unlinkCell(cell); |
+ return true; |
+ } |
+ |
void removeAll(Iterable objectsToRemove) { |
for (var each in objectsToRemove) { |
remove(each); |
@@ -1734,19 +1808,21 @@ class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> { |
return JS('int', '# & 0x3ffffff', _hasher(element)); |
} |
+ bool add(E element) => super._add(element); |
+ |
bool contains(Object object) { |
if (!_validKey(object)) return false; |
- return super.contains(object); |
+ return super._contains(object); |
} |
E lookup(Object object) { |
if (!_validKey(object)) return null; |
- return super.lookup(object); |
+ return super._lookup(object); |
} |
bool remove(Object object) { |
if (!_validKey(object)) return false; |
- return super.remove(object); |
+ return super._remove(object); |
} |
bool containsAll(Iterable<Object> elements) { |