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' show |
8 fillLiteralMap, InternalMap, NoInline, NoThrows, patch, JsLinkedHashMap, | 8 fillLiteralMap, InternalMap, NoInline, NoSideEffects, NoThrows, patch, |
9 LinkedHashMapCell, LinkedHashMapKeyIterable, LinkedHashMapKeyIterator; | 9 JsLinkedHashMap, LinkedHashMapCell, LinkedHashMapKeyIterable, |
| 10 LinkedHashMapKeyIterator; |
10 | 11 |
11 @patch | 12 @patch |
12 class HashMap<K, V> { | 13 class HashMap<K, V> { |
13 @patch | 14 @patch |
14 factory HashMap({ bool equals(K key1, K key2), | 15 factory HashMap({ bool equals(K key1, K key2), |
15 int hashCode(K key), | 16 int hashCode(K key), |
16 bool isValidKey(potentialKey) }) { | 17 bool isValidKey(potentialKey) }) { |
17 if (isValidKey == null) { | 18 if (isValidKey == null) { |
18 if (hashCode == null) { | 19 if (hashCode == null) { |
19 if (equals == null) { | 20 if (equals == null) { |
(...skipping 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
379 if (identical(JS('var', '#[#]', bucket, i), key)) return i; | 380 if (identical(JS('var', '#[#]', bucket, i), key)) return i; |
380 } | 381 } |
381 return -1; | 382 return -1; |
382 } | 383 } |
383 } | 384 } |
384 | 385 |
385 class _CustomHashMap<K, V> extends _HashMap<K, V> { | 386 class _CustomHashMap<K, V> extends _HashMap<K, V> { |
386 final _Equality<K> _equals; | 387 final _Equality<K> _equals; |
387 final _Hasher<K> _hashCode; | 388 final _Hasher<K> _hashCode; |
388 final _Predicate _validKey; | 389 final _Predicate _validKey; |
| 390 |
389 _CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey)) | 391 _CustomHashMap(this._equals, this._hashCode, bool validKey(potentialKey)) |
390 : _validKey = (validKey != null) ? validKey : ((v) => v is K); | 392 : _validKey = (validKey != null) ? validKey : ((v) => v is K); |
391 | 393 |
392 V operator[](Object key) { | 394 V operator[](Object key) { |
393 if (!_validKey(key)) return null; | 395 if (!_validKey(key)) return null; |
394 return super._get(key); | 396 return super._get(key); |
395 } | 397 } |
396 | 398 |
397 void operator[]=(K key, V value) { | 399 void operator[]=(K key, V value) { |
398 super._set(key, value); | 400 super._set(key, value); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
485 | 487 |
486 @patch | 488 @patch |
487 class LinkedHashMap<K, V> { | 489 class LinkedHashMap<K, V> { |
488 @patch | 490 @patch |
489 factory LinkedHashMap({ bool equals(K key1, K key2), | 491 factory LinkedHashMap({ bool equals(K key1, K key2), |
490 int hashCode(K key), | 492 int hashCode(K key), |
491 bool isValidKey(potentialKey) }) { | 493 bool isValidKey(potentialKey) }) { |
492 if (isValidKey == null) { | 494 if (isValidKey == null) { |
493 if (hashCode == null) { | 495 if (hashCode == null) { |
494 if (equals == null) { | 496 if (equals == null) { |
495 return new JsLinkedHashMap<K, V>(); | 497 return new JsLinkedHashMap<K, V>.es6(); |
496 } | 498 } |
497 hashCode = _defaultHashCode; | 499 hashCode = _defaultHashCode; |
498 } else { | 500 } else { |
499 if (identical(identityHashCode, hashCode) && | 501 if (identical(identityHashCode, hashCode) && |
500 identical(identical, equals)) { | 502 identical(identical, equals)) { |
501 return new _LinkedIdentityHashMap<K, V>(); | 503 return new _LinkedIdentityHashMap<K, V>(); |
502 } | 504 } |
503 if (equals == null) { | 505 if (equals == null) { |
504 equals = _defaultEquals; | 506 equals = _defaultEquals; |
505 } | 507 } |
506 } | 508 } |
507 } else { | 509 } else { |
508 if (hashCode == null) { | 510 if (hashCode == null) { |
509 hashCode = _defaultHashCode; | 511 hashCode = _defaultHashCode; |
510 } | 512 } |
511 if (equals == null) { | 513 if (equals == null) { |
512 equals = _defaultEquals; | 514 equals = _defaultEquals; |
513 } | 515 } |
514 } | 516 } |
515 return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey); | 517 return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey); |
516 } | 518 } |
517 | 519 |
518 @patch | 520 @patch |
519 factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>; | 521 factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>; |
520 | 522 |
521 // Private factory constructor called by generated code for map literals. | 523 // Private factory constructor called by generated code for map literals. |
522 @NoInline() | 524 @NoInline() |
523 factory LinkedHashMap._literal(List keyValuePairs) { | 525 factory LinkedHashMap._literal(List keyValuePairs) { |
524 return fillLiteralMap(keyValuePairs, new JsLinkedHashMap<K, V>()); | 526 return fillLiteralMap(keyValuePairs, new JsLinkedHashMap<K, V>.es6()); |
525 } | 527 } |
526 | 528 |
527 // Private factory constructor called by generated code for map literals. | 529 // Private factory constructor called by generated code for map literals. |
528 @NoThrows() @NoInline() | 530 @NoThrows() @NoInline() @NoSideEffects() |
529 factory LinkedHashMap._empty() { | 531 factory LinkedHashMap._empty() { |
530 return new JsLinkedHashMap<K, V>(); | 532 return new JsLinkedHashMap<K, V>.es6(); |
531 } | 533 } |
532 } | 534 } |
533 | 535 |
| 536 // TODO(floitsch): use ES6 Maps when available. |
534 class _LinkedIdentityHashMap<K, V> extends JsLinkedHashMap<K, V> { | 537 class _LinkedIdentityHashMap<K, V> extends JsLinkedHashMap<K, V> { |
535 int internalComputeHashCode(var key) { | 538 int internalComputeHashCode(var key) { |
536 // We force the hash codes to be unsigned 30-bit integers to avoid | 539 // We force the hash codes to be unsigned 30-bit integers to avoid |
537 // issues with problematic keys like '__proto__'. Another option | 540 // issues with problematic keys like '__proto__'. Another option |
538 // would be to throw an exception if the hash code isn't a number. | 541 // would be to throw an exception if the hash code isn't a number. |
539 return JS('int', '# & 0x3ffffff', identityHashCode(key)); | 542 return JS('int', '# & 0x3ffffff', identityHashCode(key)); |
540 } | 543 } |
541 | 544 |
542 int internalFindBucketIndex(var bucket, var key) { | 545 int internalFindBucketIndex(var bucket, var key) { |
543 if (bucket == null) return -1; | 546 if (bucket == null) return -1; |
544 int length = JS('int', '#.length', bucket); | 547 int length = JS('int', '#.length', bucket); |
545 for (int i = 0; i < length; i++) { | 548 for (int i = 0; i < length; i++) { |
546 LinkedHashMapCell cell = JS('var', '#[#]', bucket, i); | 549 LinkedHashMapCell cell = JS('var', '#[#]', bucket, i); |
547 if (identical(cell.hashMapCellKey, key)) return i; | 550 if (identical(cell.hashMapCellKey, key)) return i; |
548 } | 551 } |
549 return -1; | 552 return -1; |
550 } | 553 } |
551 } | 554 } |
552 | 555 |
| 556 // TODO(floitsch): use ES6 maps when available. |
553 class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> { | 557 class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> { |
554 final _Equality<K> _equals; | 558 final _Equality<K> _equals; |
555 final _Hasher<K> _hashCode; | 559 final _Hasher<K> _hashCode; |
556 final _Predicate _validKey; | 560 final _Predicate _validKey; |
| 561 |
557 _LinkedCustomHashMap(this._equals, this._hashCode, | 562 _LinkedCustomHashMap(this._equals, this._hashCode, |
558 bool validKey(potentialKey)) | 563 bool validKey(potentialKey)) |
559 : _validKey = (validKey != null) ? validKey : ((v) => v is K); | 564 : _validKey = (validKey != null) ? validKey : ((v) => v is K); |
560 | 565 |
561 V operator[](Object key) { | 566 V operator[](Object key) { |
562 if (!_validKey(key)) return null; | 567 if (!_validKey(key)) return null; |
563 return super.internalGet(key); | 568 return super.internalGet(key); |
564 } | 569 } |
565 | 570 |
566 void operator[]=(K key, V value) { | 571 void operator[]=(K key, V value) { |
(...skipping 891 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1458 } else if (_cell == null) { | 1463 } else if (_cell == null) { |
1459 _current = null; | 1464 _current = null; |
1460 return false; | 1465 return false; |
1461 } else { | 1466 } else { |
1462 _current = _cell._element; | 1467 _current = _cell._element; |
1463 _cell = _cell._next; | 1468 _cell = _cell._next; |
1464 return true; | 1469 return true; |
1465 } | 1470 } |
1466 } | 1471 } |
1467 } | 1472 } |
OLD | NEW |