Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 /// This library defines the representation of runtime types. | 5 /// This library defines the representation of runtime types. |
| 6 part of dart._runtime; | 6 part of dart._runtime; |
| 7 | 7 |
| 8 final metadata = JS('', 'Symbol("metadata")'); | 8 final metadata = JS('', 'Symbol("metadata")'); |
| 9 | 9 |
| 10 /// The symbol used to store the cached `Type` object associated with a class. | 10 /// The symbol used to store the cached `Type` object associated with a class. |
| (...skipping 637 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 648 if (n1 === void 0) { | 648 if (n1 === void 0) { |
| 649 return ($isCovariant) ? false : null; | 649 return ($isCovariant) ? false : null; |
| 650 } | 650 } |
| 651 if (!$_isSubtype(n2, n1, !$isCovariant)) { | 651 if (!$_isSubtype(n2, n1, !$isCovariant)) { |
| 652 return null; | 652 return null; |
| 653 } | 653 } |
| 654 } | 654 } |
| 655 | 655 |
| 656 // Check return type last, so that arity mismatched functions can be | 656 // Check return type last, so that arity mismatched functions can be |
| 657 // definitively rejected. | 657 // definitively rejected. |
| 658 | |
| 659 // We allow any type to subtype a void return type, but not vice versa | |
| 660 if (ret2 === $_void) return true; | |
| 661 // Dart allows void functions to subtype dynamic functions, but not | |
| 662 // other functions. | |
| 663 // TODO(jmesserly): this check does not match our compile time subtype | |
| 664 // implementation. Reconcile. | |
| 665 if (ret1 === $_void) { | |
| 666 return ret2 === $dynamic || ret2 === $FutureOr; | |
|
Leaf
2017/02/06 21:11:59
For now, can you keep this test? Deleting it is w
Jennifer Messerly
2017/02/06 22:50:12
okay, sure, it should be _isTop(ret2) then?
Leaf
2017/02/06 22:55:54
Yep, that would be the best fix.
| |
| 667 } | |
| 668 if (!$_isSubtype(ret1, ret2, $isCovariant)) return null; | 658 if (!$_isSubtype(ret1, ret2, $isCovariant)) return null; |
| 669 return true; | 659 return true; |
| 670 })()'''); | 660 })()'''); |
| 671 | 661 |
| 672 /// TODO(leafp): This duplicates code in operations.dart. | 662 /// TODO(leafp): This duplicates code in operations.dart. |
| 673 /// I haven't found a way to factor it out that makes the | 663 /// I haven't found a way to factor it out that makes the |
| 674 /// code generator happy though. | 664 /// code generator happy though. |
| 675 _subtypeMemo(f) => JS( | 665 _subtypeMemo(f) => JS( |
| 676 '', | 666 '', |
| 677 '''(() => { | 667 '''(() => { |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 691 }; | 681 }; |
| 692 })()'''); | 682 })()'''); |
| 693 | 683 |
| 694 /// Returns true if [t1] <: [t2]. | 684 /// Returns true if [t1] <: [t2]. |
| 695 /// Returns false if [t1] </: [t2] in both spec and strong mode | 685 /// Returns false if [t1] </: [t2] in both spec and strong mode |
| 696 /// Returns undefined if [t1] </: [t2] in strong mode, but spec | 686 /// Returns undefined if [t1] </: [t2] in strong mode, but spec |
| 697 /// mode may differ | 687 /// mode may differ |
| 698 final isSubtype = JS( | 688 final isSubtype = JS( |
| 699 '', '$_subtypeMemo((t1, t2) => (t1 === t2) || $_isSubtype(t1, t2, true))'); | 689 '', '$_subtypeMemo((t1, t2) => (t1 === t2) || $_isSubtype(t1, t2, true))'); |
| 700 | 690 |
| 701 _isBottom(type) => JS('bool', '# == #', type, bottom); | 691 _isBottom(type) => JS('bool', '# == # || # == #', type, bottom, type, Null); |
| 702 | 692 |
| 703 _isTop(type) { | 693 _isTop(type) { |
| 704 if (JS('bool', '# === #', getGenericClass(type), getGenericClass(FutureOr))) { | 694 if (JS('bool', '# === #', getGenericClass(type), getGenericClass(FutureOr))) { |
| 705 return _isTop(JS('', '#[0]', getGenericArgs(type))); | 695 return _isTop(JS('', '#[0]', getGenericArgs(type))); |
| 706 } | 696 } |
| 707 return JS('bool', '# == # || # == #', type, Object, type, dynamic); | 697 return JS('bool', '# == # || # == # || # == #', |
| 698 type, Object, type, dynamic, type, _void); | |
| 708 } | 699 } |
| 709 | 700 |
| 710 _isSubtype(t1, t2, isCovariant) => JS( | 701 _isSubtype(t1, t2, isCovariant) => JS( |
| 711 '', | 702 '', |
| 712 '''(() => { | 703 '''(() => { |
| 713 if ($t1 === $t2) return true; | 704 if ($t1 === $t2) return true; |
| 714 | 705 |
| 715 // Trivially true. | 706 // Trivially true. |
| 716 if ($_isTop($t2) || $_isBottom($t1)) { | 707 if ($_isTop($t2) || $_isBottom($t1)) { |
| 717 return true; | 708 return true; |
| (...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 870 return true; | 861 return true; |
| 871 } | 862 } |
| 872 | 863 |
| 873 let typeArgs = $getGenericArgs($type); | 864 let typeArgs = $getGenericArgs($type); |
| 874 if (!typeArgs) return true; | 865 if (!typeArgs) return true; |
| 875 for (let t of typeArgs) { | 866 for (let t of typeArgs) { |
| 876 if (t != $Object && t != $dynamic) return false; | 867 if (t != $Object && t != $dynamic) return false; |
| 877 } | 868 } |
| 878 return true; | 869 return true; |
| 879 })()'''); | 870 })()'''); |
| OLD | NEW |