Index: tool/input_sdk/private/utils.dart |
diff --git a/tool/input_sdk/private/utils.dart b/tool/input_sdk/private/utils.dart |
new file mode 100644 |
index 0000000000000000000000000000000000000000..03e8f4443f0f51029970448e1ccfa43ea6f5649f |
--- /dev/null |
+++ b/tool/input_sdk/private/utils.dart |
@@ -0,0 +1,115 @@ |
+// Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file |
+// for details. All rights reserved. Use of this source code is governed by a |
+// BSD-style license that can be found in the LICENSE file. |
+ |
+library dart._utils; |
+ |
+import 'dart:_foreign_helper' show JS; |
+ |
+/// This library defines a set of general javascript utilities for us |
+/// by the Dart runtime. |
+ |
+const defineProperty = JS('', 'Object.defineProperty'); |
+const getOwnPropertyDescriptor = JS('', 'Object.getOwnPropertyDescriptor'); |
+const getOwnPropertyNames = JS('', 'Object.getOwnPropertyNames'); |
+const getOwnPropertySymbols = JS('', 'Object.getOwnPropertySymbols'); |
+ |
+const hasOwnProperty = JS('', 'Object.prototype.hasOwnProperty'); |
+ |
+// TODO(ochafik): Add ES6 class syntax support to JS intrinsics to avoid this. |
Jennifer Messerly
2015/11/30 19:00:03
ah, yeah, good idea :)
|
+const StrongModeError = JS('', '''(function() { |
+ function StrongModeError(message) { |
+ Error.call(this); |
+ this.message = message; |
+ }; |
+ Object.setPrototypeOf(StrongModeError.prototype, Error.prototype); |
+ return StrongModeError; |
+})()'''); |
+ |
+/// This error indicates a strong mode specific failure. |
+void throwStrongModeError(message) => JS('', '''(function() { |
Jennifer Messerly
2015/11/30 19:00:03
should we explicitly pass in "message"? The curren
ochafik
2015/12/01 14:41:03
Now passing args with the `foo(x) => JS('', '((x)
|
+ throw new StrongModeError(message); |
+})()'''); |
+ |
+/// This error indicates a bug in the runtime or the compiler. |
+void throwInternalError(message) => JS('', '''(function() { |
+ throw Error(message); |
+})()'''); |
+ |
+void assert_(bool condition) => JS('', '''(function() { |
+ if (!condition) throwInternalError("The compiler is broken: failed assert"); |
+})()'''); |
+ |
+getOwnNamesAndSymbols(obj) => JS('', '''(function() { |
+ return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj)); |
+})()'''); |
+ |
+safeGetOwnProperty(obj, name) => JS('', '''(function() { |
+ let desc = getOwnPropertyDescriptor(obj, name); |
Jennifer Messerly
2015/11/30 19:00:03
I wonder if some of these could be written in Dart
ochafik
2015/12/01 14:41:03
Yes definitely, I would expect more "idiomatic" re
|
+ if (desc) return desc.value; |
+})()'''); |
+ |
+/// Defines a lazy property. |
+/// After initial get or set, it will replace itself with a value property. |
+// TODO(jmesserly): reusing descriptor objects has been shown to improve |
+// performance in other projects (e.g. webcomponents.js ShadowDOM polyfill). |
+defineLazyProperty(to, name, desc) => JS('', '''(function() { |
+ let init = desc.get; |
+ let value = null; |
+ |
+ function lazySetter(x) { |
+ init = null; |
+ value = x; |
+ } |
+ function circularInitError() { |
+ throwInternalError('circular initialization for field ' + name); |
+ } |
+ function lazyGetter() { |
+ if (init == null) return value; |
+ |
+ // Compute and store the value, guarding against reentry. |
+ let f = init; |
+ init = circularInitError; |
+ lazySetter(f()); |
+ return value; |
+ } |
+ desc.get = lazyGetter; |
+ desc.configurable = true; |
+ if (desc.set) desc.set = lazySetter; |
+ return defineProperty(to, name, desc); |
+})()'''); |
+ |
+void defineLazy(to, from) => JS('', '''(function() { |
+ for (let name of getOwnNamesAndSymbols(from)) { |
+ defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); |
+ } |
+})()'''); |
+ |
+defineMemoizedGetter(obj, name, getter) => JS('', '''(function() { |
+ return defineLazyProperty(obj, name, {get: getter}); |
+})()'''); |
+ |
+copyTheseProperties(to, from, names) => JS('', '''(function() { |
+ for (let name of names) { |
+ defineProperty(to, name, getOwnPropertyDescriptor(from, name)); |
+ } |
+ return to; |
+})()'''); |
+ |
+/// Copy properties from source to destination object. |
+/// This operation is commonly called `mixin` in JS. |
+copyProperties(to, from) => JS('', '''(function() { |
+ return copyTheseProperties(to, from, getOwnNamesAndSymbols(from)); |
+})()'''); |
+ |
+/// Exports from one Dart module to another. |
+export_(to, from, show, hide) => JS('', '''(function() { |
+ if (show == void 0) { |
+ show = getOwnNamesAndSymbols(from); |
+ } |
+ if (hide != void 0) { |
+ var hideMap = new Set(hide); |
+ show = show.filter((k) => !hideMap.has(k)); |
+ } |
+ return copyTheseProperties(to, from, show); |
+})()'''); |