| 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 part of dart._runtime; | 4 part of dart._runtime; |
| 5 | 5 |
| 6 /// This library defines a set of general javascript utilities for us | 6 /// This library defines a set of general javascript utilities for us |
| 7 /// by the Dart runtime. | 7 /// by the Dart runtime. |
| 8 // TODO(ochafik): Rewrite some of these in Dart when possible. | 8 // TODO(ochafik): Rewrite some of these in Dart when possible. |
| 9 | 9 |
| 10 defineProperty(obj, name, desc) => | 10 defineProperty(obj, name, desc) => |
| 11 JS('', 'Object.defineProperty(#, #, #)', obj, name, desc); | 11 JS('', 'Object.defineProperty(#, #, #)', obj, name, desc); |
| 12 | 12 |
| 13 defineValue(obj, name, value) { | 13 defineValue(obj, name, value) { |
| 14 defineProperty(obj, name, | 14 defineProperty(obj, name, |
| 15 JS('', '{ value: #, configurable: true, writable: true }', value)); | 15 JS('', '{ value: #, configurable: true, writable: true }', value)); |
| 16 return value; | 16 return value; |
| 17 } | 17 } |
| 18 | 18 |
| 19 void defineGetter(obj, name, getter) { |
| 20 defineProperty(obj, name, JS('', '{get: #}', getter)); |
| 21 } |
| 22 |
| 23 void defineMemoizedGetter(obj, name, compute) { |
| 24 defineProperty( |
| 25 obj, |
| 26 name, |
| 27 JS('', '{get: () => #, configurable: true}', |
| 28 defineValue(obj, name, JS('', '#()', compute)))); |
| 29 } |
| 30 |
| 19 getOwnPropertyDescriptor(obj, name) => | 31 getOwnPropertyDescriptor(obj, name) => |
| 20 JS('', 'Object.getOwnPropertyDescriptor(#, #)', obj, name); | 32 JS('', 'Object.getOwnPropertyDescriptor(#, #)', obj, name); |
| 21 | 33 |
| 22 Iterable getOwnPropertyNames(obj) => | 34 Iterable getOwnPropertyNames(obj) => |
| 23 JS('', 'Object.getOwnPropertyNames(#)', obj); | 35 JS('', 'Object.getOwnPropertyNames(#)', obj); |
| 24 | 36 |
| 25 Iterable getOwnPropertySymbols(obj) => | 37 Iterable getOwnPropertySymbols(obj) => |
| 26 JS('', 'Object.getOwnPropertySymbols(#)', obj); | 38 JS('', 'Object.getOwnPropertySymbols(#)', obj); |
| 27 | 39 |
| 28 final hasOwnProperty = JS('', 'Object.prototype.hasOwnProperty'); | 40 final hasOwnProperty = JS('', 'Object.prototype.hasOwnProperty'); |
| 29 | 41 |
| 30 /// This error indicates a strong mode specific failure, other than a type | 42 /// This error indicates a strong mode specific failure, other than a type |
| 31 /// assertion failure (TypeError) or CastError. | 43 /// assertion failure (TypeError) or CastError. |
| 32 void throwStrongModeError(String message) { | 44 void throwStrongModeError(String message) { |
| 33 if (JS('bool', 'dart.__trapRuntimeErrors')) JS('', 'debugger'); | 45 if (JS('bool', 'dart.__trapRuntimeErrors')) JS('', 'debugger'); |
| 34 throw new StrongModeErrorImplementation(message); | 46 throw new StrongModeErrorImplementation(message); |
| 35 } | 47 } |
| 36 | 48 |
| 37 /// This error indicates a bug in the runtime or the compiler. | 49 /// This error indicates a bug in the runtime or the compiler. |
| 38 void throwInternalError(String message) { | 50 void throwInternalError(String message) { |
| 39 if (JS('bool', 'dart.__trapRuntimeErrors')) JS('', 'debugger'); | 51 if (JS('bool', 'dart.__trapRuntimeErrors')) JS('', 'debugger'); |
| 40 JS('', 'throw Error(#)', message); | 52 JS('', 'throw Error(#)', message); |
| 41 } | 53 } |
| 42 | 54 |
| 43 getOwnNamesAndSymbols(obj) { | 55 Iterable getOwnNamesAndSymbols(obj) { |
| 44 var names = getOwnPropertyNames(obj); | 56 var names = getOwnPropertyNames(obj); |
| 45 var symbols = getOwnPropertySymbols(obj); | 57 var symbols = getOwnPropertySymbols(obj); |
| 46 return JS('', '#.concat(#)', names, symbols); | 58 return JS('', '#.concat(#)', names, symbols); |
| 47 } | 59 } |
| 48 | 60 |
| 49 safeGetOwnProperty(obj, name) { | 61 safeGetOwnProperty(obj, name) { |
| 50 var desc = getOwnPropertyDescriptor(obj, name); | 62 var desc = getOwnPropertyDescriptor(obj, name); |
| 51 if (desc != null) return JS('', '#.value', desc); | 63 if (desc != null) return JS('', '#.value', desc); |
| 52 } | 64 } |
| 53 | 65 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 76 init = circularInitError; | 88 init = circularInitError; |
| 77 lazySetter(f()); | 89 lazySetter(f()); |
| 78 return value; | 90 return value; |
| 79 } | 91 } |
| 80 $desc.get = lazyGetter; | 92 $desc.get = lazyGetter; |
| 81 $desc.configurable = true; | 93 $desc.configurable = true; |
| 82 if ($desc.set) $desc.set = lazySetter; | 94 if ($desc.set) $desc.set = lazySetter; |
| 83 return $defineProperty($to, $name, $desc); | 95 return $defineProperty($to, $name, $desc); |
| 84 })()'''); | 96 })()'''); |
| 85 | 97 |
| 86 void defineLazy(to, from) => JS( | 98 copyTheseProperties(to, from, names) { |
| 87 '', | 99 for (var i = 0; i < JS('int', '#.length', names); ++i) { |
| 88 '''(() => { | 100 copyProperty(to, from, JS('', '#[#]', names, i)); |
| 89 for (let name of $getOwnNamesAndSymbols($from)) { | |
| 90 $defineLazyProperty($to, name, $getOwnPropertyDescriptor($from, name)); | |
| 91 } | 101 } |
| 92 })()'''); | 102 return to; |
| 93 | |
| 94 defineMemoizedGetter(obj, name, getter) { | |
| 95 return defineLazyProperty(obj, name, JS('', '{get: #}', getter)); | |
| 96 } | 103 } |
| 97 | 104 |
| 98 copyTheseProperties(to, from, names) => JS( | |
| 99 '', | |
| 100 '''(() => { | |
| 101 for (let i = 0; i < $names.length; ++i) { | |
| 102 $copyProperty($to, $from, $names[i]); | |
| 103 } | |
| 104 return $to; | |
| 105 })()'''); | |
| 106 | |
| 107 copyProperty(to, from, name) { | 105 copyProperty(to, from, name) { |
| 108 var desc = getOwnPropertyDescriptor(from, name); | 106 var desc = getOwnPropertyDescriptor(from, name); |
| 109 if (JS('bool', '# == Symbol.iterator', name)) { | 107 if (JS('bool', '# == Symbol.iterator', name)) { |
| 110 // On native types, Symbol.iterator may already be present. | 108 // On native types, Symbol.iterator may already be present. |
| 111 // TODO(jmesserly): investigate if we still need this. | 109 // TODO(jmesserly): investigate if we still need this. |
| 112 // If so, we need to find a better solution. | 110 // If so, we need to find a better solution. |
| 113 // See https://github.com/dart-lang/sdk/issues/28324 | 111 // See https://github.com/dart-lang/sdk/issues/28324 |
| 114 var existing = getOwnPropertyDescriptor(to, name); | 112 var existing = getOwnPropertyDescriptor(to, name); |
| 115 if (existing != null) { | 113 if (existing != null) { |
| 116 if (JS('bool', '#.writable', existing)) { | 114 if (JS('bool', '#.writable', existing)) { |
| 117 JS('', '#[#] = #.value', to, name, desc); | 115 JS('', '#[#] = #.value', to, name, desc); |
| 118 } | 116 } |
| 119 return; | 117 return; |
| 120 } | 118 } |
| 121 } | 119 } |
| 122 defineProperty(to, name, desc); | 120 defineProperty(to, name, desc); |
| 123 } | 121 } |
| 124 | 122 |
| 125 @JSExportName('export') | 123 @JSExportName('export') |
| 126 exportProperty(to, from, name) => copyProperty(to, from, name); | 124 exportProperty(to, from, name) => copyProperty(to, from, name); |
| 127 | 125 |
| 128 /// Copy properties from source to destination object. | 126 /// Copy properties from source to destination object. |
| 129 /// This operation is commonly called `mixin` in JS. | 127 /// This operation is commonly called `mixin` in JS. |
| 130 copyProperties(to, from) { | 128 copyProperties(to, from) { |
| 131 return copyTheseProperties(to, from, getOwnNamesAndSymbols(from)); | 129 return copyTheseProperties(to, from, getOwnNamesAndSymbols(from)); |
| 132 } | 130 } |
| OLD | NEW |