OLD | NEW |
---|---|
(Empty) | |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 /* This library defines a set of general javascript utilities for us | |
6 * by the Dart runtime. | |
7 */ | |
8 | |
9 var js_utils; | |
10 (function (js_utils) { | |
11 'use strict'; | |
12 | |
13 const defineProperty = Object.defineProperty; | |
14 js_utils.defineProperty = defineProperty; | |
15 const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | |
16 js_utils.getOwnPropertyDescriptor = getOwnPropertyDescriptor; | |
17 const getOwnPropertyNames = Object.getOwnPropertyNames; | |
18 js_utils.getOwnPropertyNames = getOwnPropertyNames; | |
19 const getOwnPropertySymbols = Object.getOwnPropertySymbols; | |
20 js_utils.getOwnPropertySymbols = getOwnPropertySymbols; | |
21 const hasOwnProperty = Object.prototype.hasOwnProperty; | |
22 js_utils.hasOwnProperty = hasOwnProperty; | |
23 const slice = [].slice; | |
24 js_utils.slice = [].slice; | |
25 | |
26 /* This error indicates a bug in the runtime or the compiler. | |
27 */ | |
28 function throwRuntimeError(message) { | |
29 throw Error(message); | |
30 } | |
31 js_utils.throwRuntimeError = throwRuntimeError; | |
32 | |
33 function assert(condition) { | |
34 if (!condition) throwRuntimeError("The compiler is broken: failed assert"); | |
35 } | |
36 js_utils.assert = assert; | |
37 | |
38 function getOwnNamesAndSymbols(obj) { | |
39 return getOwnPropertyNames(obj).concat(getOwnPropertySymbols(obj)); | |
40 } | |
41 js_utils.getOwnNamesAndSymbols = getOwnNamesAndSymbols; | |
42 | |
43 function safeGetOwnProperty(obj, name) { | |
44 let desc = getOwnPropertyDescriptor(obj, name); | |
45 if (desc) return desc.value; | |
46 } | |
47 js_utils.safeGetOwnProperty = safeGetOwnProperty; | |
48 | |
49 /** | |
50 * Defines a lazy property. | |
51 * After initial get or set, it will replace itself with a value property. | |
52 */ | |
53 // TODO(jmesserly): is this the best implementation for JS engines? | |
54 // TODO(jmesserly): reusing descriptor objects has been shown to improve | |
55 // performance in other projects (e.g. webcomponents.js ShadowDOM polyfill). | |
56 function defineLazyProperty(to, name, desc) { | |
57 let init = desc.get; | |
58 let writable = !!desc.set; | |
59 function lazySetter(value) { | |
60 defineProperty(to, name, { value: value, writable: writable }); | |
61 } | |
62 function lazyGetter() { | |
63 // Clear the init function to detect circular initialization. | |
64 let f = init; | |
65 if (f === null) throwRuntimeError('circular initialization for field ' + n ame); | |
vsm
2015/06/12 15:50:32
length
Leaf
2015/06/12 19:52:13
Done.
| |
66 init = null; | |
67 | |
68 // Compute and store the value. | |
69 let value = f(); | |
70 lazySetter(value); | |
71 return value; | |
72 } | |
73 desc.get = lazyGetter; | |
74 desc.configurable = true; | |
75 if (writable) desc.set = lazySetter; | |
76 defineProperty(to, name, desc); | |
77 } | |
78 js_utils.defineLazyProperty = defineLazyProperty; | |
79 | |
80 function defineLazy(to, from) { | |
81 for (let name of getOwnNamesAndSymbols(from)) { | |
82 defineLazyProperty(to, name, getOwnPropertyDescriptor(from, name)); | |
83 } | |
84 } | |
85 js_utils.defineLazy = defineLazy; | |
86 | |
87 function defineMemoizedGetter(obj, name, get) { | |
88 let cache = null; | |
89 function getter() { | |
90 if (cache != null) return cache; | |
91 cache = get(); | |
92 get = null; | |
93 return cache; | |
94 } | |
95 defineProperty(obj, name, {get: getter, configurable: true}); | |
96 } | |
97 js_utils.defineMemoizedGetter = defineMemoizedGetter; | |
98 | |
99 function copyTheseProperties(to, from, names) { | |
100 for (let name of names) { | |
101 defineProperty(to, name, getOwnPropertyDescriptor(from, name)); | |
102 } | |
103 return to; | |
104 } | |
105 js_utils.copyTheseProperties = copyTheseProperties; | |
106 | |
107 /** | |
108 * Copy properties from source to destination object. | |
109 * This operation is commonly called `mixin` in JS. | |
110 */ | |
111 function copyProperties(to, from) { | |
112 return copyTheseProperties(to, from, getOwnNamesAndSymbols(from)); | |
113 } | |
114 js_utils.copyProperties = copyProperties; | |
115 | |
116 })(js_utils || (js_utils = {})); | |
OLD | NEW |