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, NoThrows, patch, |
9 JsLinkedHashMap, Es6LinkedHashMap, | |
9 LinkedHashMapCell, LinkedHashMapKeyIterable, LinkedHashMapKeyIterator; | 10 LinkedHashMapCell, LinkedHashMapKeyIterable, 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) { |
(...skipping 360 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 if (JsLinkedHashMap.supportsEs6Maps) { |
498 return new Es6LinkedHashMap<K, V>(); | |
499 } else { | |
500 return new JsLinkedHashMap<K, V>(); | |
501 } | |
496 } | 502 } |
497 hashCode = _defaultHashCode; | 503 hashCode = _defaultHashCode; |
498 } else { | 504 } else { |
499 if (identical(identityHashCode, hashCode) && | 505 if (identical(identityHashCode, hashCode) && |
500 identical(identical, equals)) { | 506 identical(identical, equals)) { |
501 return new _LinkedIdentityHashMap<K, V>(); | 507 return new _LinkedIdentityHashMap<K, V>(); |
502 } | 508 } |
503 if (equals == null) { | 509 if (equals == null) { |
504 equals = _defaultEquals; | 510 equals = _defaultEquals; |
505 } | 511 } |
506 } | 512 } |
507 } else { | 513 } else { |
508 if (hashCode == null) { | 514 if (hashCode == null) { |
509 hashCode = _defaultHashCode; | 515 hashCode = _defaultHashCode; |
510 } | 516 } |
511 if (equals == null) { | 517 if (equals == null) { |
512 equals = _defaultEquals; | 518 equals = _defaultEquals; |
513 } | 519 } |
514 } | 520 } |
515 return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey); | 521 return new _LinkedCustomHashMap<K, V>(equals, hashCode, isValidKey); |
516 } | 522 } |
517 | 523 |
518 @patch | 524 @patch |
519 factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>; | 525 factory LinkedHashMap.identity() = _LinkedIdentityHashMap<K, V>; |
520 | 526 |
521 // Private factory constructor called by generated code for map literals. | 527 // Private factory constructor called by generated code for map literals. |
522 @NoInline() | 528 @NoInline() |
523 factory LinkedHashMap._literal(List keyValuePairs) { | 529 factory LinkedHashMap._literal(List keyValuePairs) { |
524 return fillLiteralMap(keyValuePairs, new JsLinkedHashMap<K, V>()); | 530 Map map = JsLinkedHashMap.supportsEs6Maps |
Vyacheslav Egorov (Google)
2015/03/26 00:03:57
Can this just call some force-inline static method
Harry Terkelsen
2015/03/26 00:40:06
Won't that require generic methods?
floitsch
2015/03/26 00:53:24
:)
I wondered the same, and had already started. T
| |
531 ? new Es6LinkedHashMap<K, V>() | |
532 : new JsLinkedHashMap<K, V>(); | |
533 return fillLiteralMap(keyValuePairs, map); | |
525 } | 534 } |
526 | 535 |
527 // Private factory constructor called by generated code for map literals. | 536 // Private factory constructor called by generated code for map literals. |
528 @NoThrows() @NoInline() | 537 @NoThrows() @NoInline() |
529 factory LinkedHashMap._empty() { | 538 factory LinkedHashMap._empty() { |
530 return new JsLinkedHashMap<K, V>(); | 539 return JsLinkedHashMap.supportsEs6Maps |
540 ? new Es6LinkedHashMap<K, V>() | |
541 : new JsLinkedHashMap<K, V>(); | |
531 } | 542 } |
532 } | 543 } |
533 | 544 |
545 // TODO(floitsch): use ES6 Maps when available. | |
534 class _LinkedIdentityHashMap<K, V> extends JsLinkedHashMap<K, V> { | 546 class _LinkedIdentityHashMap<K, V> extends JsLinkedHashMap<K, V> { |
547 | |
Harry Terkelsen
2015/03/26 00:40:07
unnecessary blank line
floitsch
2015/03/26 00:53:24
Done.
| |
535 int internalComputeHashCode(var key) { | 548 int internalComputeHashCode(var key) { |
536 // We force the hash codes to be unsigned 30-bit integers to avoid | 549 // We force the hash codes to be unsigned 30-bit integers to avoid |
537 // issues with problematic keys like '__proto__'. Another option | 550 // issues with problematic keys like '__proto__'. Another option |
538 // would be to throw an exception if the hash code isn't a number. | 551 // would be to throw an exception if the hash code isn't a number. |
539 return JS('int', '# & 0x3ffffff', identityHashCode(key)); | 552 return JS('int', '# & 0x3ffffff', identityHashCode(key)); |
540 } | 553 } |
541 | 554 |
542 int internalFindBucketIndex(var bucket, var key) { | 555 int internalFindBucketIndex(var bucket, var key) { |
543 if (bucket == null) return -1; | 556 if (bucket == null) return -1; |
544 int length = JS('int', '#.length', bucket); | 557 int length = JS('int', '#.length', bucket); |
545 for (int i = 0; i < length; i++) { | 558 for (int i = 0; i < length; i++) { |
546 LinkedHashMapCell cell = JS('var', '#[#]', bucket, i); | 559 LinkedHashMapCell cell = JS('var', '#[#]', bucket, i); |
547 if (identical(cell.hashMapCellKey, key)) return i; | 560 if (identical(cell.hashMapCellKey, key)) return i; |
548 } | 561 } |
549 return -1; | 562 return -1; |
550 } | 563 } |
551 } | 564 } |
552 | 565 |
566 // TODO(floitsch): use ES6 maps when available. | |
553 class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> { | 567 class _LinkedCustomHashMap<K, V> extends JsLinkedHashMap<K, V> { |
554 final _Equality<K> _equals; | 568 final _Equality<K> _equals; |
555 final _Hasher<K> _hashCode; | 569 final _Hasher<K> _hashCode; |
556 final _Predicate _validKey; | 570 final _Predicate _validKey; |
571 | |
557 _LinkedCustomHashMap(this._equals, this._hashCode, | 572 _LinkedCustomHashMap(this._equals, this._hashCode, |
558 bool validKey(potentialKey)) | 573 bool validKey(potentialKey)) |
559 : _validKey = (validKey != null) ? validKey : ((v) => v is K); | 574 : _validKey = (validKey != null) ? validKey : ((v) => v is K); |
560 | 575 |
576 | |
Harry Terkelsen
2015/03/26 00:40:06
unnecessary blank line
floitsch
2015/03/26 00:53:24
Done.
| |
561 V operator[](Object key) { | 577 V operator[](Object key) { |
562 if (!_validKey(key)) return null; | 578 if (!_validKey(key)) return null; |
563 return super.internalGet(key); | 579 return super.internalGet(key); |
564 } | 580 } |
565 | 581 |
566 void operator[]=(K key, V value) { | 582 void operator[]=(K key, V value) { |
567 super.internalSet(key, value); | 583 super.internalSet(key, value); |
568 } | 584 } |
569 | 585 |
570 bool containsKey(Object key) { | 586 bool containsKey(Object key) { |
(...skipping 887 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1458 } else if (_cell == null) { | 1474 } else if (_cell == null) { |
1459 _current = null; | 1475 _current = null; |
1460 return false; | 1476 return false; |
1461 } else { | 1477 } else { |
1462 _current = _cell._element; | 1478 _current = _cell._element; |
1463 _cell = _cell._next; | 1479 _cell = _cell._next; |
1464 return true; | 1480 return true; |
1465 } | 1481 } |
1466 } | 1482 } |
1467 } | 1483 } |
OLD | NEW |