| 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 var dart, _js_helper, _js_primitives, dartx; | 5 var dart, _js_helper, _js_primitives, dartx; |
| 6 (function (dart) { | 6 (function (dart) { |
| 7 'use strict'; | 7 'use strict'; |
| 8 | 8 |
| 9 // TODO(vsm): This is referenced (as init.globalState) from | 9 // TODO(vsm): This is referenced (as init.globalState) from |
| 10 // isolate_helper.dart. Where should it go? | 10 // isolate_helper.dart. Where should it go? |
| 11 // See: https://github.com/dart-lang/dev_compiler/issues/164 | 11 // See: https://github.com/dart-lang/dev_compiler/issues/164 |
| 12 dart.globalState = null; | 12 dart.globalState = null; |
| 13 | 13 |
| 14 const defineProperty = Object.defineProperty; | 14 const defineProperty = Object.defineProperty; |
| 15 const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | 15 const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; |
| 16 const getOwnPropertyNames = Object.getOwnPropertyNames; | 16 const getOwnPropertyNames = Object.getOwnPropertyNames; |
| 17 const getOwnPropertySymbols = Object.getOwnPropertySymbols; | 17 const getOwnPropertySymbols = Object.getOwnPropertySymbols; |
| 18 const hasOwnProperty = Object.prototype.hasOwnProperty; | 18 const hasOwnProperty = Object.prototype.hasOwnProperty; |
| 19 const slice = [].slice; | 19 const slice = [].slice; |
| 20 | 20 |
| 21 let _constructorSig = Symbol('sigCtor'); |
| 22 let _methodSig = Symbol("sig"); |
| 23 let _staticSig = Symbol("sigStatic"); |
| 24 |
| 21 function getOwnNamesAndSymbols(obj) { | 25 function getOwnNamesAndSymbols(obj) { |
| 22 return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj)); | 26 return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj)); |
| 23 } | 27 } |
| 24 | 28 |
| 25 function dload(obj, field) { | 29 function dload(obj, field) { |
| 26 field = _canonicalFieldName(obj, field, [], field); | 30 field = _canonicalFieldName(obj, field, [], field); |
| 27 if (_getMethodType(obj, field) !== void 0) { | 31 if (_getMethodType(obj, field) !== void 0) { |
| 28 return dart.bind(obj, field); | 32 return dart.bind(obj, field); |
| 29 } | 33 } |
| 30 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain | 34 // TODO(vsm): Implement NSM robustly. An 'in' check breaks on certain |
| (...skipping 716 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 747 dart.defineLazyClassGeneric = defineLazyProperty; | 751 dart.defineLazyClassGeneric = defineLazyProperty; |
| 748 | 752 |
| 749 function defineMemoizedGetter(obj, name, get) { | 753 function defineMemoizedGetter(obj, name, get) { |
| 750 let cache = null; | 754 let cache = null; |
| 751 function getter() { | 755 function getter() { |
| 752 if (cache != null) return cache; | 756 if (cache != null) return cache; |
| 753 cache = get(); | 757 cache = get(); |
| 754 get = null; | 758 get = null; |
| 755 return cache; | 759 return cache; |
| 756 } | 760 } |
| 757 defineProperty(obj, name, {get : getter}); | 761 defineProperty(obj, name, {get: getter, configurable: true}); |
| 758 } | 762 } |
| 759 | 763 |
| 760 function copyPropertiesHelper(to, from, names) { | 764 function copyPropertiesHelper(to, from, names) { |
| 761 for (let name of names) { | 765 for (let name of names) { |
| 762 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); | 766 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); |
| 763 } | 767 } |
| 764 return to; | 768 return to; |
| 765 } | 769 } |
| 766 | 770 |
| 767 /** | 771 /** |
| 768 * Copy properties from source to destination object. | 772 * Copy properties from source to destination object. |
| 769 * This operation is commonly called `mixin` in JS. | 773 * This operation is commonly called `mixin` in JS. |
| 770 */ | 774 */ |
| 771 function copyProperties(to, from) { | 775 function copyProperties(to, from) { |
| 772 return copyPropertiesHelper(to, from, getOwnNamesAndSymbols(from)); | 776 return copyPropertiesHelper(to, from, getOwnNamesAndSymbols(from)); |
| 773 } | 777 } |
| 774 dart.copyProperties = copyProperties; | 778 dart.copyProperties = copyProperties; |
| 775 | 779 |
| 776 function getExtensionSymbol(name) { | 780 function getExtensionSymbol(name) { |
| 777 let sym = dartx[name]; | 781 let sym = dartx[name]; |
| 778 if (!sym) dartx[name] = sym = Symbol('dartx.' + name); | 782 if (!sym) dartx[name] = sym = Symbol('dartx.' + name); |
| 779 return sym; | 783 return sym; |
| 780 } | 784 } |
| 781 | 785 |
| 786 function defineExtensionNames(names) { |
| 787 names.forEach(getExtensionSymbol); |
| 788 } |
| 789 dart.defineExtensionNames = defineExtensionNames; |
| 790 |
| 782 /** | 791 /** |
| 783 * Copy symbols from the prototype of the source to destination. | 792 * Copy symbols from the prototype of the source to destination. |
| 784 * These are the only properties safe to copy onto an existing public | 793 * These are the only properties safe to copy onto an existing public |
| 785 * JavaScript class. | 794 * JavaScript class. |
| 786 */ | 795 */ |
| 787 function registerExtension(jsType, dartExtType) { | 796 function registerExtension(jsType, dartExtType) { |
| 788 let extProto = dartExtType.prototype; | 797 let extProto = dartExtType.prototype; |
| 789 let jsProto = jsType.prototype; | 798 let jsProto = jsType.prototype; |
| 790 | 799 |
| 791 // Mark the JS type's instances so we can easily check for extensions. | 800 // Mark the JS type's instances so we can easily check for extensions. |
| 792 assert(jsProto[_extensionType] === void 0); | 801 assert(jsProto[_extensionType] === void 0); |
| 793 jsProto[_extensionType] = extProto; | 802 jsProto[_extensionType] = extProto; |
| 794 for (let name of getOwnPropertyNames(extProto)) { | 803 copyPropertiesHelper(jsProto, extProto, getOwnPropertySymbols(extProto)); |
| 795 let symbol = getExtensionSymbol(name); | |
| 796 defineProperty(jsProto, symbol, getOwnPropertyDescriptor(extProto, name)); | |
| 797 } | |
| 798 } | 804 } |
| 799 dart.registerExtension = registerExtension; | 805 dart.registerExtension = registerExtension; |
| 800 | 806 |
| 801 /** | 807 /** |
| 802 * Mark a concrete type as implementing extension methods. | 808 * Mark a concrete type as implementing extension methods. |
| 803 * For example: `class MyIter implements Iterable`. | 809 * For example: `class MyIter implements Iterable`. |
| 804 * | 810 * |
| 805 * This takes a list of names, which are the extension methods implemented. | 811 * This takes a list of names, which are the extension methods implemented. |
| 806 * It will add a forwarder, so the extension method name redirects to the | 812 * It will add a forwarder, so the extension method name redirects to the |
| 807 * normal Dart method name. For example: | 813 * normal Dart method name. For example: |
| 808 * | 814 * |
| 809 * defineExtensionMembers(MyType, ['add', 'remove']); | 815 * defineExtensionMembers(MyType, ['add', 'remove']); |
| 810 * | 816 * |
| 811 * Results in: | 817 * Results in: |
| 812 * | 818 * |
| 813 * MyType.prototype[dartx.add] = MyType.prototype.add; | 819 * MyType.prototype[dartx.add] = MyType.prototype.add; |
| 814 * MyType.prototype[dartx.remove] = MyType.prototype.remove; | 820 * MyType.prototype[dartx.remove] = MyType.prototype.remove; |
| 815 */ | 821 */ |
| 816 // TODO(jmesserly): essentially this gives two names to the same method. | 822 // TODO(jmesserly): essentially this gives two names to the same method. |
| 817 // This benefit is roughly equivalent call performance either way, but the | 823 // This benefit is roughly equivalent call performance either way, but the |
| 818 // cost is we need to call implementExtension any time a subclass overrides | 824 // cost is we need to call defineExtensionMEmbers any time a subclass override
s |
| 819 // one of these methods. | 825 // one of these methods. |
| 820 function defineExtensionMembers(type, methodNames) { | 826 function defineExtensionMembers(type, methodNames) { |
| 821 let proto = type.prototype; | 827 let proto = type.prototype; |
| 822 for (let name of methodNames) { | 828 for (let name of methodNames) { |
| 823 let method = getOwnPropertyDescriptor(proto, name); | 829 let method = getOwnPropertyDescriptor(proto, name); |
| 824 defineProperty(proto, getExtensionSymbol(name), method); | 830 defineProperty(proto, getExtensionSymbol(name), method); |
| 825 } | 831 } |
| 832 // Ensure the signature is available too. |
| 833 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially |
| 834 // we need to copy the signature (and in the future, other data like |
| 835 // annotations) any time we copy a method as part of our metaprogramming. |
| 836 // It might be more friendly to JS metaprogramming if we include this info |
| 837 // on the function. |
| 838 var originalSigFn = getOwnPropertyDescriptor(type, _methodSig).get; |
| 839 defineMemoizedGetter(type, _methodSig, function() { |
| 840 var sig = originalSigFn(); |
| 841 for (let name of methodNames) { |
| 842 sig[getExtensionSymbol(name)] = sig[name]; |
| 843 } |
| 844 return sig; |
| 845 }); |
| 826 } | 846 } |
| 827 dart.defineExtensionMembers = defineExtensionMembers; | 847 dart.defineExtensionMembers = defineExtensionMembers; |
| 828 | 848 |
| 829 function setBaseClass(derived, base) { | 849 function setBaseClass(derived, base) { |
| 830 // Link the extension to the type it's extending as a base class. | 850 // Link the extension to the type it's extending as a base class. |
| 831 derived.prototype.__proto__ = base.prototype; | 851 derived.prototype.__proto__ = base.prototype; |
| 832 } | 852 } |
| 833 dart.setBaseClass = setBaseClass; | 853 dart.setBaseClass = setBaseClass; |
| 834 | 854 |
| 835 /** | 855 /** |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 889 } | 909 } |
| 890 } | 910 } |
| 891 // Copy each mixin's methods, with later ones overwriting earlier entries. | 911 // Copy each mixin's methods, with later ones overwriting earlier entries. |
| 892 for (let m of mixins) { | 912 for (let m of mixins) { |
| 893 copyProperties(Mixin.prototype, m.prototype); | 913 copyProperties(Mixin.prototype, m.prototype); |
| 894 } | 914 } |
| 895 | 915 |
| 896 // Set the signature of the Mixin class to be the composition | 916 // Set the signature of the Mixin class to be the composition |
| 897 // of the signatures of the mixins. | 917 // of the signatures of the mixins. |
| 898 dart.setSignature(Mixin, { | 918 dart.setSignature(Mixin, { |
| 899 methods : () => { | 919 methods: () => { |
| 900 let s = {}; | 920 let s = {}; |
| 901 for (let m of mixins) { | 921 for (let m of mixins) { |
| 902 copyProperties(s, m[_methodSig]); | 922 copyProperties(s, m[_methodSig]); |
| 903 } | 923 } |
| 904 return s; | 924 return s; |
| 905 } | 925 } |
| 906 }); | 926 }); |
| 907 | 927 |
| 908 // Save mixins for reflection | 928 // Save mixins for reflection |
| 909 Mixin[dart.mixins] = mixins; | 929 Mixin[dart.mixins] = mixins; |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1013 } | 1033 } |
| 1014 map.set(arg, value); | 1034 map.set(arg, value); |
| 1015 } | 1035 } |
| 1016 } | 1036 } |
| 1017 return value; | 1037 return value; |
| 1018 } | 1038 } |
| 1019 return makeGenericType; | 1039 return makeGenericType; |
| 1020 } | 1040 } |
| 1021 dart.generic = generic; | 1041 dart.generic = generic; |
| 1022 | 1042 |
| 1023 let _constructorSig = Symbol('sigCtor'); | |
| 1024 let _methodSig = Symbol("sig"); | |
| 1025 let _staticSig = Symbol("sigStatic"); | |
| 1026 | |
| 1027 /// Get the type of a function using the store runtime type | 1043 /// Get the type of a function using the store runtime type |
| 1028 function _getFunctionType(f) { | 1044 function _getFunctionType(f) { |
| 1029 return f[_runtimeType]; | 1045 return f[_runtimeType]; |
| 1030 } | 1046 } |
| 1031 | 1047 |
| 1032 /// Get the type of a method using the stored signature | 1048 /// Get the type of a method using the stored signature |
| 1033 function _getMethodType(obj, name) { | 1049 function _getMethodType(obj, name) { |
| 1034 if (obj === void 0) return void 0; | 1050 if (obj === void 0) return void 0; |
| 1035 if (obj == null) return void 0; | 1051 if (obj == null) return void 0; |
| 1036 let sigObj = obj.__proto__.constructor[_methodSig]; | 1052 let sigObj = obj.__proto__.constructor[_methodSig]; |
| (...skipping 273 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1310 // TODO(vsm): DOM facades? | 1326 // TODO(vsm): DOM facades? |
| 1311 // See: https://github.com/dart-lang/dev_compiler/issues/173 | 1327 // See: https://github.com/dart-lang/dev_compiler/issues/173 |
| 1312 NodeList.prototype.get = function(i) { return this[i]; }; | 1328 NodeList.prototype.get = function(i) { return this[i]; }; |
| 1313 NamedNodeMap.prototype.get = function(i) { return this[i]; }; | 1329 NamedNodeMap.prototype.get = function(i) { return this[i]; }; |
| 1314 DOMTokenList.prototype.get = function(i) { return this[i]; }; | 1330 DOMTokenList.prototype.get = function(i) { return this[i]; }; |
| 1315 | 1331 |
| 1316 /** Dart extension members. */ | 1332 /** Dart extension members. */ |
| 1317 dartx = dartx || {}; | 1333 dartx = dartx || {}; |
| 1318 | 1334 |
| 1319 })(dart || (dart = {})); | 1335 })(dart || (dart = {})); |
| OLD | NEW |