| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, 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 // Patch file for dart:collection classes. | 5 // Patch file for dart:collection classes. |
| 6 import 'dart:_foreign_helper' show JS; | 6 import 'dart:_foreign_helper' show JS; |
| 7 import 'dart:_js_helper' show | 7 import 'dart:_js_helper' |
| 8 fillLiteralMap, InternalMap, NoInline, NoSideEffects, NoThrows, patch, | 8 show |
| 9 JsLinkedHashMap, LinkedHashMapCell, LinkedHashMapKeyIterable, | 9 fillLiteralMap, |
| 10 LinkedHashMapKeyIterator; | 10 InternalMap, |
| 11 NoInline, |
| 12 NoSideEffects, |
| 13 NoThrows, |
| 14 patch, |
| 15 JsLinkedHashMap, |
| 16 LinkedHashMapCell, |
| 17 LinkedHashMapKeyIterable, |
| 18 LinkedHashMapKeyIterator; |
| 11 | 19 |
| 12 const _USE_ES6_MAPS = true; | 20 const _USE_ES6_MAPS = true; |
| 13 | 21 |
| 14 @patch | 22 @patch |
| 15 class HashMap<K, V> { | 23 class HashMap<K, V> { |
| 16 @patch | 24 @patch |
| 17 factory HashMap({ bool equals(K key1, K key2), | 25 factory HashMap( |
| 18 int hashCode(K key), | 26 {bool equals(K key1, K key2), |
| 19 bool isValidKey(Object potentialKey) }) { | 27 int hashCode(K key), |
| 28 bool isValidKey(Object potentialKey)}) { |
| 20 if (isValidKey == null) { | 29 if (isValidKey == null) { |
| 21 if (hashCode == null) { | 30 if (hashCode == null) { |
| 22 if (equals == null) { | 31 if (equals == null) { |
| 23 return new _HashMap<K, V>(); | 32 return new _HashMap<K, V>(); |
| 24 } | 33 } |
| 25 hashCode = _defaultHashCode; | 34 hashCode = _defaultHashCode; |
| 26 } else { | 35 } else { |
| 27 if (identical(identityHashCode, hashCode) && | 36 if (identical(identityHashCode, hashCode) && |
| 28 identical(identical, equals)) { | 37 identical(identical, equals)) { |
| 29 return new _IdentityHashMap<K, V>(); | 38 return new _IdentityHashMap<K, V>(); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 63 var _rest; | 72 var _rest; |
| 64 | 73 |
| 65 // When iterating over the hash map, it is very convenient to have a | 74 // When iterating over the hash map, it is very convenient to have a |
| 66 // list of all the keys. We cache that on the instance and clear the | 75 // list of all the keys. We cache that on the instance and clear the |
| 67 // the cache whenever the key set changes. This is also used to | 76 // the cache whenever the key set changes. This is also used to |
| 68 // guard against concurrent modifications. | 77 // guard against concurrent modifications. |
| 69 List/*<K>*/ _keys; | 78 List/*<K>*/ _keys; |
| 70 | 79 |
| 71 _HashMap(); | 80 _HashMap(); |
| 72 | 81 |
| 73 | |
| 74 int get length => _length; | 82 int get length => _length; |
| 75 bool get isEmpty => _length == 0; | 83 bool get isEmpty => _length == 0; |
| 76 bool get isNotEmpty => !isEmpty; | 84 bool get isNotEmpty => !isEmpty; |
| 77 | 85 |
| 78 Iterable<K> get keys { | 86 Iterable<K> get keys { |
| 79 return new _HashMapKeyIterable<K>(this); | 87 return new _HashMapKeyIterable<K>(this); |
| 80 } | 88 } |
| 81 | 89 |
| 82 Iterable<V> get values { | 90 Iterable<V> get values { |
| 83 return new MappedIterable<K, V>(keys, (each) => this[each]); | 91 return new MappedIterable<K, V>(keys, (each) => this[each]); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 105 bool containsValue(Object value) { | 113 bool containsValue(Object value) { |
| 106 return _computeKeys().any((each) => this[each] == value); | 114 return _computeKeys().any((each) => this[each] == value); |
| 107 } | 115 } |
| 108 | 116 |
| 109 void addAll(Map<K, V> other) { | 117 void addAll(Map<K, V> other) { |
| 110 other.forEach((K key, V value) { | 118 other.forEach((K key, V value) { |
| 111 this[key] = value; | 119 this[key] = value; |
| 112 }); | 120 }); |
| 113 } | 121 } |
| 114 | 122 |
| 115 V operator[](Object key) { | 123 V operator [](Object key) { |
| 116 if (_isStringKey(key)) { | 124 if (_isStringKey(key)) { |
| 117 var strings = _strings; | 125 var strings = _strings; |
| 118 return (strings == null) ? null : _getTableEntry(strings, key); | 126 return (strings == null) ? null : _getTableEntry(strings, key); |
| 119 } else if (_isNumericKey(key)) { | 127 } else if (_isNumericKey(key)) { |
| 120 var nums = _nums; | 128 var nums = _nums; |
| 121 return (nums == null) ? null : _getTableEntry(nums, key); | 129 return (nums == null) ? null : _getTableEntry(nums, key); |
| 122 } else { | 130 } else { |
| 123 return _get(key); | 131 return _get(key); |
| 124 } | 132 } |
| 125 } | 133 } |
| 126 | 134 |
| 127 V _get(Object key) { | 135 V _get(Object key) { |
| 128 var rest = _rest; | 136 var rest = _rest; |
| 129 if (rest == null) return null; | 137 if (rest == null) return null; |
| 130 var bucket = _getBucket(rest, key); | 138 var bucket = _getBucket(rest, key); |
| 131 int index = _findBucketIndex(bucket, key); | 139 int index = _findBucketIndex(bucket, key); |
| 132 return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1); | 140 return (index < 0) ? null : JS('var', '#[#]', bucket, index + 1); |
| 133 } | 141 } |
| 134 | 142 |
| 135 void operator[]=(K key, V value) { | 143 void operator []=(K key, V value) { |
| 136 if (_isStringKey(key)) { | 144 if (_isStringKey(key)) { |
| 137 var strings = _strings; | 145 var strings = _strings; |
| 138 if (strings == null) _strings = strings = _newHashTable(); | 146 if (strings == null) _strings = strings = _newHashTable(); |
| 139 _addHashTableEntry(strings, key, value); | 147 _addHashTableEntry(strings, key, value); |
| 140 } else if (_isNumericKey(key)) { | 148 } else if (_isNumericKey(key)) { |
| 141 var nums = _nums; | 149 var nums = _nums; |
| 142 if (nums == null) _nums = nums = _newHashTable(); | 150 if (nums == null) _nums = nums = _newHashTable(); |
| 143 _addHashTableEntry(nums, key, value); | 151 _addHashTableEntry(nums, key, value); |
| 144 } else { | 152 } else { |
| 145 _set(key, value); | 153 _set(key, value); |
| (...skipping 236 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 382 if (identical(JS('var', '#[#]', bucket, i), key)) return i; | 390 if (identical(JS('var', '#[#]', bucket, i), key)) return i; |
| 383 } | 391 } |
| 384 return -1; | 392 return -1; |
| 385 } | 393 } |
| 386 } | 394 } |
| 387 | 395 |
| 388 class _CustomHashMap<K, V> extends _HashMap<K, V> { | 396 class _CustomHashMap<K, V> extends _HashMap<K, V> { |
| 389 final _Equality<K> _equals; | 397 final _Equality<K> _equals; |
| 390 final _Hasher<K> _hashCode; | 398 final _Hasher<K> _hashCode; |
| 391 final _Predicate<Object> _validKey; | 399 final _Predicate<Object> _validKey; |
| 392 _CustomHashMap(this._equals, this._hashCode, | 400 _CustomHashMap( |
| 393 bool validKey(Object potentialKey)) | 401 this._equals, this._hashCode, bool validKey(Object potentialKey)) |
| 394 : _validKey = (validKey != null) ? validKey : ((v) => v is K); | 402 : _validKey = (validKey != null) ? validKey : ((v) => v is K); |
| 395 | 403 |
| 396 V operator[](Object key) { | 404 V operator [](Object key) { |
| 397 if (!_validKey(key)) return null; | 405 if (!_validKey(key)) return null; |
| 398 return super._get(key); | 406 return super._get(key); |
| 399 } | 407 } |
| 400 | 408 |
| 401 void operator[]=(K key, V value) { | 409 void operator []=(K key, V value) { |
| 402 super._set(key, value); | 410 super._set(key, value); |
| 403 } | 411 } |
| 404 | 412 |
| 405 bool containsKey(Object key) { | 413 bool containsKey(Object key) { |
| 406 if (!_validKey(key)) return false; | 414 if (!_validKey(key)) return false; |
| 407 return super._containsKey(key); | 415 return super._containsKey(key); |
| 408 } | 416 } |
| 409 | 417 |
| 410 V remove(Object key) { | 418 V remove(Object key) { |
| 411 if (!_validKey(key)) return null; | 419 if (!_validKey(key)) return null; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 482 // get unnecessary bailout code. | 490 // get unnecessary bailout code. |
| 483 _offset = JS('int', '#', offset + 1); | 491 _offset = JS('int', '#', offset + 1); |
| 484 return true; | 492 return true; |
| 485 } | 493 } |
| 486 } | 494 } |
| 487 } | 495 } |
| 488 | 496 |
| 489 @patch | 497 @patch |
| 490 class LinkedHashMap<K, V> { | 498 class LinkedHashMap<K, V> { |
| 491 @patch | 499 @patch |
| 492 factory LinkedHashMap({ bool equals(K key1, K key2), | 500 factory LinkedHashMap( |
| 493 int hashCode(K key), | 501 {bool equals(K key1, K key2), |
| 494 bool isValidKey(Object potentialKey) }) { | 502 int hashCode(K key), |
| 503 bool isValidKey(Object potentialKey)}) { |
| 495 if (isValidKey == null) { | 504 if (isValidKey == null) { |
| 496 if (hashCode == null) { | 505 if (hashCode == null) { |
| 497 if (equals == null) { | 506 if (equals == null) { |
| 498 return new JsLinkedHashMap<K, V>.es6(); | 507 return new JsLinkedHashMap<K, V>.es6(); |
| 499 } | 508 } |
| 500 hashCode = _defaultHashCode; | 509 hashCode = _defaultHashCode; |
| 501 } else { | 510 } else { |
| 502 if (identical(identityHashCode, hashCode) && | 511 if (identical(identityHashCode, hashCode) && |
| 503 identical(identical, equals)) { | 512 identical(identical, equals)) { |
| 504 return new _LinkedIdentityHashMap<K, V>.es6(); | 513 return new _LinkedIdentityHashMap<K, V>.es6(); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 546 if (bucket == null) return -1; | 555 if (bucket == null) return -1; |
| 547 int length = JS('int', '#.length', bucket); | 556 int length = JS('int', '#.length', bucket); |
| 548 for (int i = 0; i < length; i++) { | 557 for (int i = 0; i < length; i++) { |
| 549 LinkedHashMapCell/*<K, V>*/ cell = JS('var', '#[#]', bucket, i); | 558 LinkedHashMapCell/*<K, V>*/ cell = JS('var', '#[#]', bucket, i); |
| 550 if (identical(cell.hashMapCellKey, key)) return i; | 559 if (identical(cell.hashMapCellKey, key)) return i; |
| 551 } | 560 } |
| 552 return -1; | 561 return -1; |
| 553 } | 562 } |
| 554 } | 563 } |
| 555 | 564 |
| 556 class _Es6LinkedIdentityHashMap<K, V> | 565 class _Es6LinkedIdentityHashMap<K, V> extends _LinkedIdentityHashMap<K, V> |
| 557 extends _LinkedIdentityHashMap<K, V> implements InternalMap<K, V> { | 566 implements InternalMap<K, V> { |
| 558 final _map; | 567 final _map; |
| 559 int _modifications = 0; | 568 int _modifications = 0; |
| 560 | 569 |
| 561 _Es6LinkedIdentityHashMap() : _map = JS('var', 'new Map()'); | 570 _Es6LinkedIdentityHashMap() : _map = JS('var', 'new Map()'); |
| 562 | 571 |
| 563 int get length => JS('int', '#.size', _map); | 572 int get length => JS('int', '#.size', _map); |
| 564 bool get isEmpty => length == 0; | 573 bool get isEmpty => length == 0; |
| 565 bool get isNotEmpty => !isEmpty; | 574 bool get isNotEmpty => !isEmpty; |
| 566 | 575 |
| 567 Iterable<K> get keys => new _Es6MapIterable<K>(this, true); | 576 Iterable<K> get keys => new _Es6MapIterable<K>(this, true); |
| 568 | 577 |
| 569 Iterable<V> get values => | 578 Iterable<V> get values => new _Es6MapIterable<V>(this, false); |
| 570 new _Es6MapIterable<V>(this, false); | |
| 571 | 579 |
| 572 bool containsKey(Object key) { | 580 bool containsKey(Object key) { |
| 573 return JS('bool', '#.has(#)', _map, key); | 581 return JS('bool', '#.has(#)', _map, key); |
| 574 } | 582 } |
| 575 | 583 |
| 576 bool containsValue(Object value) { | 584 bool containsValue(Object value) { |
| 577 return values.any((each) => each == value); | 585 return values.any((each) => each == value); |
| 578 } | 586 } |
| 579 | 587 |
| 580 void addAll(Map<K, V> other) { | 588 void addAll(Map<K, V> other) { |
| 581 other.forEach((K key, V value) { | 589 other.forEach((K key, V value) { |
| 582 this[key] = value; | 590 this[key] = value; |
| 583 }); | 591 }); |
| 584 } | 592 } |
| 585 | 593 |
| 586 V operator[](Object key) { | 594 V operator [](Object key) { |
| 587 return JS('var', '#.get(#)', _map, key); | 595 return JS('var', '#.get(#)', _map, key); |
| 588 } | 596 } |
| 589 | 597 |
| 590 void operator[]=(K key, V value) { | 598 void operator []=(K key, V value) { |
| 591 JS('var', '#.set(#, #)', _map, key, value); | 599 JS('var', '#.set(#, #)', _map, key, value); |
| 592 _modified(); | 600 _modified(); |
| 593 } | 601 } |
| 594 | 602 |
| 595 V putIfAbsent(K key, V ifAbsent()) { | 603 V putIfAbsent(K key, V ifAbsent()) { |
| 596 if (containsKey(key)) return this[key]; | 604 if (containsKey(key)) return this[key]; |
| 597 V value = ifAbsent(); | 605 V value = ifAbsent(); |
| 598 this[key] = value; | 606 this[key] = value; |
| 599 return value; | 607 return value; |
| 600 } | 608 } |
| (...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 710 return true; | 718 return true; |
| 711 } | 719 } |
| 712 } | 720 } |
| 713 } | 721 } |
| 714 | 722 |
| 715 // TODO(floitsch): use ES6 maps when available. | 723 // TODO(floitsch): use ES6 maps when available. |
| 716 class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> { | 724 class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> { |
| 717 final _Equality<K> _equals; | 725 final _Equality<K> _equals; |
| 718 final _Hasher<K> _hashCode; | 726 final _Hasher<K> _hashCode; |
| 719 final _Predicate<Object> _validKey; | 727 final _Predicate<Object> _validKey; |
| 720 _LinkedCustomHashMap(this._equals, this._hashCode, | 728 _LinkedCustomHashMap( |
| 721 bool validKey(Object potentialKey)) | 729 this._equals, this._hashCode, bool validKey(Object potentialKey)) |
| 722 : _validKey = (validKey != null) ? validKey : ((v) => v is K); | 730 : _validKey = (validKey != null) ? validKey : ((v) => v is K); |
| 723 | 731 |
| 724 V operator[](Object key) { | 732 V operator [](Object key) { |
| 725 if (!_validKey(key)) return null; | 733 if (!_validKey(key)) return null; |
| 726 return super.internalGet(key); | 734 return super.internalGet(key); |
| 727 } | 735 } |
| 728 | 736 |
| 729 void operator[]=(K key, V value) { | 737 void operator []=(K key, V value) { |
| 730 super.internalSet(key, value); | 738 super.internalSet(key, value); |
| 731 } | 739 } |
| 732 | 740 |
| 733 bool containsKey(Object key) { | 741 bool containsKey(Object key) { |
| 734 if (!_validKey(key)) return false; | 742 if (!_validKey(key)) return false; |
| 735 return super.internalContainsKey(key); | 743 return super.internalContainsKey(key); |
| 736 } | 744 } |
| 737 | 745 |
| 738 V remove(Object key) { | 746 V remove(Object key) { |
| 739 if (!_validKey(key)) return null; | 747 if (!_validKey(key)) return null; |
| (...skipping 14 matching lines...) Expand all Loading... |
| 754 LinkedHashMapCell/*<K, V>*/ cell = JS('var', '#[#]', bucket, i); | 762 LinkedHashMapCell/*<K, V>*/ cell = JS('var', '#[#]', bucket, i); |
| 755 if (_equals(cell.hashMapCellKey, key)) return i; | 763 if (_equals(cell.hashMapCellKey, key)) return i; |
| 756 } | 764 } |
| 757 return -1; | 765 return -1; |
| 758 } | 766 } |
| 759 } | 767 } |
| 760 | 768 |
| 761 @patch | 769 @patch |
| 762 class HashSet<E> { | 770 class HashSet<E> { |
| 763 @patch | 771 @patch |
| 764 factory HashSet({ bool equals(E e1, E e2), | 772 factory HashSet( |
| 765 int hashCode(E e), | 773 {bool equals(E e1, E e2), |
| 766 bool isValidKey(Object potentialKey) }) { | 774 int hashCode(E e), |
| 775 bool isValidKey(Object potentialKey)}) { |
| 767 if (isValidKey == null) { | 776 if (isValidKey == null) { |
| 768 if (hashCode == null) { | 777 if (hashCode == null) { |
| 769 if (equals == null) { | 778 if (equals == null) { |
| 770 return new _HashSet<E>(); | 779 return new _HashSet<E>(); |
| 771 } | 780 } |
| 772 hashCode = _defaultHashCode; | 781 hashCode = _defaultHashCode; |
| 773 } else { | 782 } else { |
| 774 if (identical(identityHashCode, hashCode) && | 783 if (identical(identityHashCode, hashCode) && |
| 775 identical(identical, equals)) { | 784 identical(identical, equals)) { |
| 776 return new _IdentityHashSet<E>(); | 785 return new _IdentityHashSet<E>(); |
| (...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 if (identical(JS('var', '#[#]', bucket, i), element)) return i; | 1095 if (identical(JS('var', '#[#]', bucket, i), element)) return i; |
| 1087 } | 1096 } |
| 1088 return -1; | 1097 return -1; |
| 1089 } | 1098 } |
| 1090 } | 1099 } |
| 1091 | 1100 |
| 1092 class _CustomHashSet<E> extends _HashSet<E> { | 1101 class _CustomHashSet<E> extends _HashSet<E> { |
| 1093 _Equality<E> _equality; | 1102 _Equality<E> _equality; |
| 1094 _Hasher<E> _hasher; | 1103 _Hasher<E> _hasher; |
| 1095 _Predicate<Object> _validKey; | 1104 _Predicate<Object> _validKey; |
| 1096 _CustomHashSet(this._equality, this._hasher, | 1105 _CustomHashSet( |
| 1097 bool validKey(Object potentialKey)) | 1106 this._equality, this._hasher, bool validKey(Object potentialKey)) |
| 1098 : _validKey = (validKey != null) ? validKey : ((x) => x is E); | 1107 : _validKey = (validKey != null) ? validKey : ((x) => x is E); |
| 1099 | 1108 |
| 1100 Set<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey); | 1109 Set<E> _newSet() => new _CustomHashSet<E>(_equality, _hasher, _validKey); |
| 1101 | 1110 |
| 1102 int _findBucketIndex(var bucket, var element) { | 1111 int _findBucketIndex(var bucket, var element) { |
| 1103 if (bucket == null) return -1; | 1112 if (bucket == null) return -1; |
| 1104 int length = JS('int', '#.length', bucket); | 1113 int length = JS('int', '#.length', bucket); |
| 1105 for (int i = 0; i < length; i++) { | 1114 for (int i = 0; i < length; i++) { |
| 1106 if (_equality(JS('var', '#[#]', bucket, i), element)) return i; | 1115 if (_equality(JS('var', '#[#]', bucket, i), element)) return i; |
| 1107 } | 1116 } |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1160 // get unnecessary bailout code. | 1169 // get unnecessary bailout code. |
| 1161 _offset = JS('int', '#', offset + 1); | 1170 _offset = JS('int', '#', offset + 1); |
| 1162 return true; | 1171 return true; |
| 1163 } | 1172 } |
| 1164 } | 1173 } |
| 1165 } | 1174 } |
| 1166 | 1175 |
| 1167 @patch | 1176 @patch |
| 1168 class LinkedHashSet<E> { | 1177 class LinkedHashSet<E> { |
| 1169 @patch | 1178 @patch |
| 1170 factory LinkedHashSet({ bool equals(E e1, E e2), | 1179 factory LinkedHashSet( |
| 1171 int hashCode(E e), | 1180 {bool equals(E e1, E e2), |
| 1172 bool isValidKey(Object potentialKey) }) { | 1181 int hashCode(E e), |
| 1182 bool isValidKey(Object potentialKey)}) { |
| 1173 if (isValidKey == null) { | 1183 if (isValidKey == null) { |
| 1174 if (hashCode == null) { | 1184 if (hashCode == null) { |
| 1175 if (equals == null) { | 1185 if (equals == null) { |
| 1176 return new _LinkedHashSet<E>(); | 1186 return new _LinkedHashSet<E>(); |
| 1177 } | 1187 } |
| 1178 hashCode = _defaultHashCode; | 1188 hashCode = _defaultHashCode; |
| 1179 } else { | 1189 } else { |
| 1180 if (identical(identityHashCode, hashCode) && | 1190 if (identical(identityHashCode, hashCode) && |
| 1181 identical(identical, equals)) { | 1191 identical(identical, equals)) { |
| 1182 return new _LinkedIdentityHashSet<E>(); | 1192 return new _LinkedIdentityHashSet<E>(); |
| (...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1348 } | 1358 } |
| 1349 | 1359 |
| 1350 bool _remove(Object object) { | 1360 bool _remove(Object object) { |
| 1351 var rest = _rest; | 1361 var rest = _rest; |
| 1352 if (rest == null) return false; | 1362 if (rest == null) return false; |
| 1353 var bucket = _getBucket(rest, object); | 1363 var bucket = _getBucket(rest, object); |
| 1354 int index = _findBucketIndex(bucket, object); | 1364 int index = _findBucketIndex(bucket, object); |
| 1355 if (index < 0) return false; | 1365 if (index < 0) return false; |
| 1356 // Use splice to remove the [cell] element at the index and | 1366 // Use splice to remove the [cell] element at the index and |
| 1357 // unlink it. | 1367 // unlink it. |
| 1358 _LinkedHashSetCell/*<E>*/ cell = JS('var', '#.splice(#, 1)[0]', bucket, inde
x); | 1368 _LinkedHashSetCell/*<E>*/ cell = |
| 1369 JS('var', '#.splice(#, 1)[0]', bucket, index); |
| 1359 _unlinkCell(cell); | 1370 _unlinkCell(cell); |
| 1360 return true; | 1371 return true; |
| 1361 } | 1372 } |
| 1362 | 1373 |
| 1363 void removeWhere(bool test(E element)) { | 1374 void removeWhere(bool test(E element)) { |
| 1364 _filterWhere(test, true); | 1375 _filterWhere(test, true); |
| 1365 } | 1376 } |
| 1366 | 1377 |
| 1367 void retainWhere(bool test(E element)) { | 1378 void retainWhere(bool test(E element)) { |
| 1368 _filterWhere(test, false); | 1379 _filterWhere(test, false); |
| (...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1529 if (identical(cell._element, element)) return i; | 1540 if (identical(cell._element, element)) return i; |
| 1530 } | 1541 } |
| 1531 return -1; | 1542 return -1; |
| 1532 } | 1543 } |
| 1533 } | 1544 } |
| 1534 | 1545 |
| 1535 class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> { | 1546 class _LinkedCustomHashSet<E> extends _LinkedHashSet<E> { |
| 1536 _Equality<E> _equality; | 1547 _Equality<E> _equality; |
| 1537 _Hasher<E> _hasher; | 1548 _Hasher<E> _hasher; |
| 1538 _Predicate<Object> _validKey; | 1549 _Predicate<Object> _validKey; |
| 1539 _LinkedCustomHashSet(this._equality, this._hasher, | 1550 _LinkedCustomHashSet( |
| 1540 bool validKey(Object potentialKey)) | 1551 this._equality, this._hasher, bool validKey(Object potentialKey)) |
| 1541 : _validKey = (validKey != null) ? validKey : ((x) => x is E); | 1552 : _validKey = (validKey != null) ? validKey : ((x) => x is E); |
| 1542 | 1553 |
| 1543 Set<E> _newSet() => | 1554 Set<E> _newSet() => |
| 1544 new _LinkedCustomHashSet<E>(_equality, _hasher, _validKey); | 1555 new _LinkedCustomHashSet<E>(_equality, _hasher, _validKey); |
| 1545 | 1556 |
| 1546 int _findBucketIndex(var bucket, var element) { | 1557 int _findBucketIndex(var bucket, var element) { |
| 1547 if (bucket == null) return -1; | 1558 if (bucket == null) return -1; |
| 1548 int length = JS('int', '#.length', bucket); | 1559 int length = JS('int', '#.length', bucket); |
| 1549 for (int i = 0; i < length; i++) { | 1560 for (int i = 0; i < length; i++) { |
| 1550 _LinkedHashSetCell/*<E>*/ cell = JS('var', '#[#]', bucket, i); | 1561 _LinkedHashSetCell/*<E>*/ cell = JS('var', '#[#]', bucket, i); |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1622 } else if (_cell == null) { | 1633 } else if (_cell == null) { |
| 1623 _current = null; | 1634 _current = null; |
| 1624 return false; | 1635 return false; |
| 1625 } else { | 1636 } else { |
| 1626 _current = _cell._element; | 1637 _current = _cell._element; |
| 1627 _cell = _cell._next; | 1638 _cell = _cell._next; |
| 1628 return true; | 1639 return true; |
| 1629 } | 1640 } |
| 1630 } | 1641 } |
| 1631 } | 1642 } |
| OLD | NEW |