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 var dart, _js_helper; | 5 var dart, _js_helper; |
| 6 (function (dart) { | 6 (function (dart) { |
| 7 'use strict'; | 7 'use strict'; |
| 8 | 8 |
| 9 let defineProperty = Object.defineProperty; | 9 let defineProperty = Object.defineProperty; |
| 10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | 10 let getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 89 | 89 |
| 90 function dsend(obj, method/*, ...args*/) { | 90 function dsend(obj, method/*, ...args*/) { |
| 91 let args = Array.prototype.slice.call(arguments, 2); | 91 let args = Array.prototype.slice.call(arguments, 2); |
| 92 return checkAndCall(obj[method], obj, args, method); | 92 return checkAndCall(obj[method], obj, args, method); |
| 93 } | 93 } |
| 94 dart.dsend = dsend; | 94 dart.dsend = dsend; |
| 95 | 95 |
| 96 function dindex(obj, index) { | 96 function dindex(obj, index) { |
| 97 // TODO(jmesserly): remove this special case once Array extensions are | 97 // TODO(jmesserly): remove this special case once Array extensions are |
| 98 // hooked up. | 98 // hooked up. |
| 99 if (obj instanceof Array && getRuntimeType(index) == core.int) { | 99 if (obj instanceof Array && runtimeType(index) == core.int) { |
| 100 return obj[index]; | 100 return obj[index]; |
| 101 } | 101 } |
| 102 return checkAndCall(obj.get, obj, [index], '[]'); | 102 return checkAndCall(obj.get, obj, [index], '[]'); |
| 103 } | 103 } |
| 104 dart.dindex = dindex; | 104 dart.dindex = dindex; |
| 105 | 105 |
| 106 function dsetindex(obj, index, value) { | 106 function dsetindex(obj, index, value) { |
| 107 return checkAndCall(obj.set, obj, [index, value], '[]='); | 107 return checkAndCall(obj.set, obj, [index, value], '[]='); |
| 108 } | 108 } |
| 109 dart.dsetindex = dsetindex; | 109 dart.dsetindex = dsetindex; |
| 110 | 110 |
| 111 /** | 111 /** |
| 112 * Returns bound `method`. | 112 * Returns bound `method`. |
| 113 * This helper function avoids needing a temp for `obj`. | 113 * This helper function avoids needing a temp for `obj`. |
| 114 */ | 114 */ |
| 115 function bind(obj, method) { | 115 function bind(obj, method) { |
| 116 // This is a static bind (dynamic would use `dload`) so no need to check | 116 // This is a static bind (dynamic would use `dload`) so no need to check |
| 117 // if `method` is really there on `obj`.` | 117 // if `method` is really there on `obj`.` |
| 118 return obj[method].bind(obj); | 118 return obj[method].bind(obj); |
| 119 } | 119 } |
| 120 dart.bind = bind; | 120 dart.bind = bind; |
| 121 | 121 |
| 122 function cast(obj, type) { | 122 function cast(obj, type) { |
| 123 // TODO(vsm): handle non-nullable types | 123 // TODO(vsm): handle non-nullable types |
| 124 if (obj == null) return obj; | 124 if (obj == null) return obj; |
| 125 let actual = getRuntimeType(obj); | 125 let actual = runtimeType(obj); |
| 126 if (isSubtype(actual, type)) return obj; | 126 if (isSubtype(actual, type)) return obj; |
| 127 throw new _js_helper.CastErrorImplementation(actual, type); | 127 throw new _js_helper.CastErrorImplementation(actual, type); |
| 128 } | 128 } |
| 129 dart.as = cast; | 129 dart.as = cast; |
| 130 | 130 |
| 131 | 131 |
| 132 // TODO(vsm): How should we encode the runtime type? | 132 // TODO(vsm): How should we encode the runtime type? |
| 133 let runtimeType = Symbol('runtimeType'); | 133 let _runtimeType = Symbol('_runtimeType'); |
| 134 | 134 |
| 135 /** | 135 /** |
| 136 * Returns the runtime type of obj. This is the same as `obj.runtimeType` | 136 * Returns the runtime type of obj. This is the same as `obj.runtimeType` |
| 137 * but will not call an overridden getter. | 137 * but will not call an overridden getter. |
| 138 * | 138 * |
| 139 * Currently this will return null for non-Dart objects. | 139 * Currently this will return null for non-Dart objects. |
| 140 */ | 140 */ |
| 141 function getRuntimeType(obj) { | 141 function runtimeType(obj) { |
|
Jennifer Messerly
2015/04/23 19:01:42
The intent of this method was "get the _real_ runt
vsm
2015/04/23 20:35:55
I've split this back out for now.
The other optio
| |
| 142 switch (typeof obj) { | 142 switch (typeof obj) { |
| 143 case "undefined": | 143 case "undefined": |
| 144 return core.Null; | 144 return core.Null; |
| 145 case "number": | 145 case "number": |
| 146 return Math.floor(obj) == obj ? core.int : core.double; | 146 return Math.floor(obj) == obj ? core.int : core.double; |
| 147 case "boolean": | 147 case "boolean": |
| 148 return core.bool; | 148 return core.bool; |
| 149 case "string": | 149 case "string": |
| 150 return core.String; | 150 return core.String; |
| 151 case "symbol": | 151 case "symbol": |
| 152 return Symbol; | 152 return Symbol; |
| 153 } | 153 } |
| 154 // Undefined is handled above. For historical reasons, | 154 // Undefined is handled above. For historical reasons, |
| 155 // typeof null == "object" in JS. | 155 // typeof null == "object" in JS. |
| 156 if (obj === null) return core.Null; | 156 if (obj === null) return core.Null; |
| 157 // TODO(vsm): Should we treat Dart and JS objects differently here? | 157 // TODO(vsm): Should we treat Dart and JS objects differently here? |
| 158 // E.g., we can check if obj instanceof core.Object to differentiate. | 158 // E.g., we can check if obj instanceof core.Object to differentiate. |
| 159 var result = obj[runtimeType]; | 159 var result = obj[_runtimeType]; |
| 160 if (result) return result; | 160 if (result) return result; |
| 161 result = obj.constructor; | 161 result = obj.constructor; |
| 162 if (result == Function) { | 162 if (result == Function) { |
| 163 return getFunctionType(obj); | 163 return getFunctionType(obj); |
| 164 } | 164 } |
| 165 return result; | 165 return result; |
| 166 } | 166 } |
| 167 dart.getRuntimeType = getRuntimeType; | 167 dart.runtimeType = runtimeType; |
| 168 | 168 |
| 169 function instanceOf(obj, type) { | 169 function instanceOf(obj, type) { |
| 170 return isSubtype(getRuntimeType(obj), type); | 170 return isSubtype(runtimeType(obj), type); |
| 171 } | 171 } |
| 172 dart.is = instanceOf; | 172 dart.is = instanceOf; |
| 173 | 173 |
| 174 /** | 174 /** |
| 175 * Computes the canonical type. | 175 * Computes the canonical type. |
| 176 * This maps JS types onto their corresponding Dart Type. | 176 * This maps JS types onto their corresponding Dart Type. |
| 177 */ | 177 */ |
| 178 // TODO(jmesserly): lots more needs to be done here. | 178 // TODO(jmesserly): lots more needs to be done here. |
| 179 function canonicalType(t) { | 179 function canonicalType(t) { |
| 180 if (t === Object) return core.Object; | 180 if (t === Object) return core.Object; |
| (...skipping 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 825 let constants = new Map(); | 825 let constants = new Map(); |
| 826 | 826 |
| 827 /** | 827 /** |
| 828 * Canonicalize a constant object. | 828 * Canonicalize a constant object. |
| 829 * | 829 * |
| 830 * Preconditions: | 830 * Preconditions: |
| 831 * - `obj` is an objects or array, not a primitive. | 831 * - `obj` is an objects or array, not a primitive. |
| 832 * - nested values of the object are themselves already canonicalized. | 832 * - nested values of the object are themselves already canonicalized. |
| 833 */ | 833 */ |
| 834 function constant(obj) { | 834 function constant(obj) { |
| 835 let objectKey = [getRuntimeType(obj)]; | 835 let objectKey = [runtimeType(obj)]; |
| 836 // There's no guarantee in JS that names/symbols are returned in the same | 836 // There's no guarantee in JS that names/symbols are returned in the same |
| 837 // order. We could probably get the same order if we're judicious about | 837 // order. We could probably get the same order if we're judicious about |
| 838 // initializing them, but easier to not depend on that. | 838 // initializing them, but easier to not depend on that. |
| 839 for (let name of getOwnNamesAndSymbols(obj)) { | 839 for (let name of getOwnNamesAndSymbols(obj)) { |
| 840 // TODO(jmesserly): we can make this faster if needed. | 840 // TODO(jmesserly): we can make this faster if needed. |
| 841 objectKey.push(name); | 841 objectKey.push(name); |
| 842 objectKey.push(obj[name]); | 842 objectKey.push(obj[name]); |
| 843 } | 843 } |
| 844 return multiKeyPutIfAbsent(constants, objectKey, () => obj); | 844 return multiKeyPutIfAbsent(constants, objectKey, () => obj); |
| 845 } | 845 } |
| 846 dart.const = constant; | 846 dart.const = constant; |
| 847 | 847 |
| 848 /** Sets the runtime type of `obj` to be `type` */ | 848 /** Sets the runtime type of `obj` to be `type` */ |
| 849 function setType(obj, type) { | 849 function setType(obj, type) { |
| 850 obj[runtimeType] = type; | 850 obj[_runtimeType] = type; |
| 851 } | 851 } |
| 852 dart.setType = setType; | 852 dart.setType = setType; |
| 853 | 853 |
| 854 function hashCode(obj) { | |
| 855 if (obj == null) { | |
| 856 return 0; | |
| 857 } | |
| 858 // TODO(vsm): What should we do for primitives and non-Dart objects? | |
| 859 switch (typeof obj) { | |
| 860 case "undefined": | |
| 861 return core.Null; | |
|
Jennifer Messerly
2015/04/23 19:01:41
copy+paste error? this code can't be reached. `obj
vsm
2015/04/23 20:35:55
Done.
| |
| 862 case "number": | |
| 863 return obj & 0x1FFFFFFF; | |
| 864 case "boolean": | |
| 865 return obj & 0x1FFFFFFF; | |
| 866 case "string": | |
| 867 // TODO(vsm): Call the JSString hashCode? | |
|
Jennifer Messerly
2015/04/23 19:01:42
+1
vsm
2015/04/23 20:35:55
Will look at primitives next.
| |
| 868 return obj.length; | |
| 869 } | |
| 870 return obj.hashCode; | |
| 871 } | |
| 872 dart.hashCode = hashCode; | |
| 873 | |
| 874 function toString(obj) { | |
|
Jennifer Messerly
2015/04/23 19:02:54
oh, just noticed noSuchMethod helper is missing?
vsm
2015/04/23 20:35:55
Added.
| |
| 875 if (obj == null) { | |
| 876 return "null"; | |
| 877 } | |
| 878 return obj.toString(); | |
|
Jennifer Messerly
2015/04/23 19:02:54
we'll have to make sure to never call dart.toStrin
vsm
2015/04/23 20:35:55
Good point! I added a check to the codegen that s
| |
| 879 } | |
| 880 dart.toString = toString; | |
| 881 | |
| 854 // TODO(jmesserly): right now this is a sentinel. It should be a type object | 882 // TODO(jmesserly): right now this is a sentinel. It should be a type object |
| 855 // of some sort, assuming we keep around `dynamic` at runtime. | 883 // of some sort, assuming we keep around `dynamic` at runtime. |
| 856 dart.dynamic = { toString() { return 'dynamic'; } }; | 884 dart.dynamic = { toString() { return 'dynamic'; } }; |
| 857 dart.void = { toString() { return 'void'; } }; | 885 dart.void = { toString() { return 'void'; } }; |
| 858 dart.bottom = { toString() { return 'bottom'; } }; | 886 dart.bottom = { toString() { return 'bottom'; } }; |
| 859 | 887 |
| 860 dart.global = window || global; | 888 dart.global = window || global; |
| 861 dart.JsSymbol = Symbol; | 889 dart.JsSymbol = Symbol; |
| 862 | 890 |
| 863 // TODO(jmesserly): hack to bootstrap the SDK | 891 // TODO(jmesserly): hack to bootstrap the SDK |
| 864 _js_helper = _js_helper || {}; | 892 _js_helper = _js_helper || {}; |
| 865 _js_helper.checkNum = notNull; | 893 _js_helper.checkNum = notNull; |
| 866 | 894 |
| 867 })(dart || (dart = {})); | 895 })(dart || (dart = {})); |
| OLD | NEW |