Chromium Code Reviews| 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); |
| +})()'''); |