OLD | NEW |
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 the operations that define and manipulate Dart | |
6 * classes. Included in this are: | |
7 * - Generics | |
8 * - Class metadata | |
9 * - Extension methods | |
10 */ | |
11 | |
12 // TODO(leafp): Consider splitting some of this out. | |
13 dart_library.library('dart/_classes', null, /* Imports */[ | 1 dart_library.library('dart/_classes', null, /* Imports */[ |
14 ], /* Lazy Imports */[ | 2 'dart/_utils' |
15 'dart/_utils', | 3 ], /* Lazy imports */[ |
16 'dart/core', | |
17 'dart/_interceptors', | |
18 'dart/_types', | 4 'dart/_types', |
19 'dart/_rtti', | 5 'dart/_rtti', |
20 ], function(exports, dart_utils, core, _interceptors, types, rtti) { | 6 'dart/core', |
| 7 'dart/_interceptors' |
| 8 ], function(exports, utils, _types, rtti, core, _interceptors) { |
21 'use strict'; | 9 'use strict'; |
22 | 10 const assert = utils.assert; |
23 const assert = dart_utils.assert_; | 11 const copyProperties = utils.copyProperties; |
24 const copyProperties = dart_utils.copyProperties; | 12 const copyTheseProperties = utils.copyTheseProperties; |
25 const copyTheseProperties = dart_utils.copyTheseProperties; | 13 const defineMemoizedGetter = utils.defineMemoizedGetter; |
26 const defineMemoizedGetter = dart_utils.defineMemoizedGetter; | 14 const safeGetOwnProperty = utils.safeGetOwnProperty; |
27 const safeGetOwnProperty = dart_utils.safeGetOwnProperty; | 15 const throwInternalError = utils.throwInternalError; |
28 const throwInternalError = dart_utils.throwInternalError; | |
29 | |
30 const defineProperty = Object.defineProperty; | 16 const defineProperty = Object.defineProperty; |
31 const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; | 17 const getOwnPropertyDescriptor = Object.getOwnPropertyDescriptor; |
32 const getOwnPropertySymbols = Object.getOwnPropertySymbols; | 18 const getOwnPropertySymbols = Object.getOwnPropertySymbols; |
33 | 19 const _mixins = Symbol("mixins"); |
34 /** The Symbol for storing type arguments on a specialized generic type. */ | 20 const implements$ = Symbol("implements"); |
35 const _mixins = Symbol('mixins'); | 21 const metadata = Symbol("metadata"); |
36 const _implements = Symbol('implements'); | |
37 exports.implements = _implements; | |
38 const _metadata = Symbol('metadata'); | |
39 exports.metadata = _metadata; | |
40 | |
41 /** | |
42 * Returns a new type that mixes members from base and all mixins. | |
43 * | |
44 * Each mixin applies in sequence, with further to the right ones overriding | |
45 * previous entries. | |
46 * | |
47 * For each mixin, we only take its own properties, not anything from its | |
48 * superclass (prototype). | |
49 */ | |
50 function mixin(base, ...mixins) { | 22 function mixin(base, ...mixins) { |
51 // Create an initializer for the mixin, so when derived constructor calls | |
52 // super, we can correctly initialize base and mixins. | |
53 | |
54 // Create a class that will hold all of the mixin methods. | |
55 class Mixin extends base { | 23 class Mixin extends base { |
56 // Initializer method: run mixin initializers, then the base. | |
57 [base.name](...args) { | 24 [base.name](...args) { |
58 // Run mixin initializers. They cannot have arguments. | |
59 // Run them backwards so most-derived mixin is initialized first. | |
60 for (let i = mixins.length - 1; i >= 0; i--) { | 25 for (let i = mixins.length - 1; i >= 0; i--) { |
61 let mixin = mixins[i]; | 26 let mixin = mixins[i]; |
62 let init = mixin.prototype[mixin.name]; | 27 let init = mixin.prototype[mixin.name]; |
63 if (init) init.call(this); | 28 if (init) init.call(this); |
64 } | 29 } |
65 // Run base initializer. | |
66 let init = base.prototype[base.name]; | 30 let init = base.prototype[base.name]; |
67 if (init) init.apply(this, args); | 31 if (init) init.apply(this, args); |
68 } | 32 } |
69 } | 33 } |
70 // Copy each mixin's methods, with later ones overwriting earlier entries. | |
71 for (let m of mixins) { | 34 for (let m of mixins) { |
72 copyProperties(Mixin.prototype, m.prototype); | 35 copyProperties(Mixin.prototype, m.prototype); |
73 } | 36 } |
74 | |
75 // Set the signature of the Mixin class to be the composition | |
76 // of the signatures of the mixins. | |
77 setSignature(Mixin, { | 37 setSignature(Mixin, { |
78 methods: () => { | 38 methods: () => { |
79 let s = {}; | 39 let s = {}; |
80 for (let m of mixins) { | 40 for (let m of mixins) { |
81 copyProperties(s, m[_methodSig]); | 41 copyProperties(s, m[_methodSig]); |
82 } | 42 } |
83 return s; | 43 return s; |
84 } | 44 } |
85 }); | 45 }); |
86 | |
87 // Save mixins for reflection | |
88 Mixin[_mixins] = mixins; | 46 Mixin[_mixins] = mixins; |
89 return Mixin; | 47 return Mixin; |
90 } | 48 } |
91 exports.mixin = mixin; | 49 function getMixins(clazz) { |
92 | |
93 function getMixins (clazz) { | |
94 return clazz[_mixins]; | 50 return clazz[_mixins]; |
95 } | 51 } |
96 exports.getMixins = getMixins; | 52 function getImplements(clazz) { |
97 | 53 return clazz[implements$]; |
98 function getImplements (clazz) { | |
99 return clazz[_implements]; | |
100 } | 54 } |
101 exports.getImplements = getImplements; | 55 const _typeArguments = Symbol("typeArguments"); |
102 | 56 const _originalDeclaration = Symbol("originalDeclaration"); |
103 /** The Symbol for storing type arguments on a specialized generic type. */ | |
104 let _typeArguments = Symbol('typeArguments'); | |
105 let _originalDeclaration = Symbol('originalDeclaration'); | |
106 | |
107 /** Memoize a generic type constructor function. */ | |
108 function generic(typeConstructor) { | 57 function generic(typeConstructor) { |
109 let length = typeConstructor.length; | 58 let length = typeConstructor.length; |
110 if (length < 1) { | 59 if (length < 1) { |
111 throwInternalError('must have at least one generic type argument'); | 60 throwInternalError('must have at least one generic type argument'); |
112 } | 61 } |
113 let resultMap = new Map(); | 62 let resultMap = new Map(); |
114 function makeGenericType(...args) { | 63 function makeGenericType(...args) { |
115 if (args.length != length && args.length != 0) { | 64 if (args.length != length && args.length != 0) { |
116 throwInternalError('requires ' + length + ' or 0 type arguments'); | 65 throwInternalError('requires ' + length + ' or 0 type arguments'); |
117 } | 66 } |
118 while (args.length < length) args.push(types.dynamic); | 67 while (args.length < length) |
119 | 68 args.push(_types.dynamic); |
120 let value = resultMap; | 69 let value = resultMap; |
121 for (let i = 0; i < length; i++) { | 70 for (let i = 0; i < length; i++) { |
122 let arg = args[i]; | 71 let arg = args[i]; |
123 if (arg == null) { | 72 if (arg == null) { |
124 throwInternalError('type arguments should not be null: ' | 73 throwInternalError('type arguments should not be null: ' + typeConstru
ctor); |
125 + typeConstructor); | |
126 } | 74 } |
127 let map = value; | 75 let map = value; |
128 value = map.get(arg); | 76 value = map.get(arg); |
129 if (value === void 0) { | 77 if (value === void 0) { |
130 if (i + 1 == length) { | 78 if (i + 1 == length) { |
131 value = typeConstructor.apply(null, args); | 79 value = typeConstructor.apply(null, args); |
132 // Save the type constructor and arguments for reflection. | |
133 if (value) { | 80 if (value) { |
134 value[_typeArguments] = args; | 81 value[_typeArguments] = args; |
135 value[_originalDeclaration] = makeGenericType; | 82 value[_originalDeclaration] = makeGenericType; |
136 } | 83 } |
137 } else { | 84 } else { |
138 value = new Map(); | 85 value = new Map(); |
139 } | 86 } |
140 map.set(arg, value); | 87 map.set(arg, value); |
141 } | 88 } |
142 } | 89 } |
143 return value; | 90 return value; |
144 } | 91 } |
145 return makeGenericType; | 92 return makeGenericType; |
146 } | 93 } |
147 exports.generic = generic; | |
148 | |
149 function getGenericClass(type) { | 94 function getGenericClass(type) { |
150 return safeGetOwnProperty(type, _originalDeclaration); | 95 return safeGetOwnProperty(type, _originalDeclaration); |
151 }; | 96 } |
152 exports.getGenericClass = getGenericClass; | |
153 | |
154 function getGenericArgs(type) { | 97 function getGenericArgs(type) { |
155 return safeGetOwnProperty(type, _typeArguments); | 98 return safeGetOwnProperty(type, _typeArguments); |
156 }; | 99 } |
157 exports.getGenericArgs = getGenericArgs; | 100 const _constructorSig = Symbol("sigCtor"); |
158 | 101 const _methodSig = Symbol("sig"); |
159 let _constructorSig = Symbol('sigCtor'); | 102 const _staticSig = Symbol("sigStatic"); |
160 let _methodSig = Symbol("sig"); | 103 function getMethodType(obj, name) { |
161 let _staticSig = Symbol("sigStatic"); | |
162 | |
163 /// Get the type of a method using the stored signature | |
164 function _getMethodType(obj, name) { | |
165 if (obj === void 0) return void 0; | 104 if (obj === void 0) return void 0; |
166 if (obj == null) return void 0; | 105 if (obj == null) return void 0; |
167 let sigObj = obj.__proto__.constructor[_methodSig]; | 106 let sigObj = obj.__proto__.constructor[_methodSig]; |
168 if (sigObj === void 0) return void 0; | 107 if (sigObj === void 0) return void 0; |
169 let parts = sigObj[name]; | 108 let parts = sigObj[name]; |
170 if (parts === void 0) return void 0; | 109 if (parts === void 0) return void 0; |
171 return types.definiteFunctionType.apply(null, parts); | 110 return _types.definiteFunctionType.apply(null, parts); |
172 } | 111 } |
173 | 112 function classGetConstructorType(cls, name) { |
174 /// Get the type of a constructor from a class using the stored signature | 113 if (!name) name = cls.name; |
175 /// If name is undefined, returns the type of the default constructor | |
176 /// Returns undefined if the constructor is not found. | |
177 function _getConstructorType(cls, name) { | |
178 if(!name) name = cls.name; | |
179 if (cls === void 0) return void 0; | 114 if (cls === void 0) return void 0; |
180 if (cls == null) return void 0; | 115 if (cls == null) return void 0; |
181 let sigCtor = cls[_constructorSig]; | 116 let sigCtor = cls[_constructorSig]; |
182 if (sigCtor === void 0) return void 0; | 117 if (sigCtor === void 0) return void 0; |
183 let parts = sigCtor[name]; | 118 let parts = sigCtor[name]; |
184 if (parts === void 0) return void 0; | 119 if (parts === void 0) return void 0; |
185 return types.definiteFunctionType.apply(null, parts); | 120 return _types.definiteFunctionType.apply(null, parts); |
186 } | 121 } |
187 exports.classGetConstructorType = _getConstructorType; | |
188 | |
189 /// Given an object and a method name, tear off the method. | |
190 /// Sets the runtime type of the torn off method appropriately, | |
191 /// and also binds the object. | |
192 /// | |
193 /// If the optional `f` argument is passed in, it will be used as the method. | |
194 /// This supports cases like `super.foo` where we need to tear off the method | |
195 /// from the superclass, not from the `obj` directly. | |
196 /// TODO(leafp): Consider caching the tearoff on the object? | |
197 function bind(obj, name, f) { | 122 function bind(obj, name, f) { |
198 if (f === void 0) f = obj[name]; | 123 if (f === void 0) f = obj[name]; |
199 f = f.bind(obj); | 124 f = f.bind(obj); |
200 // TODO(jmesserly): track the function's signature on the function, instead | 125 let sig = getMethodType(obj, name); |
201 // of having to go back to the class? | |
202 let sig = _getMethodType(obj, name); | |
203 assert(sig); | 126 assert(sig); |
204 rtti.tag(f, sig); | 127 rtti.tag(f, sig); |
205 return f; | 128 return f; |
206 } | 129 } |
207 exports.bind = bind; | |
208 | |
209 // Set up the method signature field on the constructor | |
210 function _setMethodSignature(f, sigF) { | 130 function _setMethodSignature(f, sigF) { |
211 defineMemoizedGetter(f, _methodSig, () => { | 131 defineMemoizedGetter(f, _methodSig, () => { |
212 let sigObj = sigF(); | 132 let sigObj = sigF(); |
213 sigObj.__proto__ = f.__proto__[_methodSig]; | 133 sigObj.__proto__ = f.__proto__[_methodSig]; |
214 return sigObj; | 134 return sigObj; |
215 }); | 135 }); |
216 } | 136 } |
217 | |
218 // Set up the constructor signature field on the constructor | |
219 function _setConstructorSignature(f, sigF) { | 137 function _setConstructorSignature(f, sigF) { |
220 defineMemoizedGetter(f, _constructorSig, sigF); | 138 defineMemoizedGetter(f, _constructorSig, sigF); |
221 } | 139 } |
222 | |
223 // Set up the static signature field on the constructor | |
224 function _setStaticSignature(f, sigF) { | 140 function _setStaticSignature(f, sigF) { |
225 defineMemoizedGetter(f, _staticSig, sigF); | 141 defineMemoizedGetter(f, _staticSig, sigF); |
226 } | 142 } |
227 | |
228 // Set the lazily computed runtime type field on static methods | |
229 function _setStaticTypes(f, names) { | 143 function _setStaticTypes(f, names) { |
230 for (let name of names) { | 144 for (let name of names) { |
231 rtti.tagMemoized(f[name], function() { | 145 rtti.tagMemoized(f[name], function() { |
232 let parts = f[_staticSig][name]; | 146 let parts = f[_staticSig][name]; |
233 return types.definiteFunctionType.apply(null, parts); | 147 return _types.definiteFunctionType.apply(null, parts); |
234 }) | 148 }); |
235 } | 149 } |
236 } | 150 } |
237 | |
238 /// Set up the type signature of a class (constructor object) | |
239 /// f is a constructor object | |
240 /// signature is an object containing optional properties as follows: | |
241 /// methods: A function returning an object mapping method names | |
242 /// to method types. The function is evaluated lazily and cached. | |
243 /// statics: A function returning an object mapping static method | |
244 /// names to types. The function is evalutated lazily and cached. | |
245 /// names: An array of the names of the static methods. Used to | |
246 /// permit eagerly setting the runtimeType field on the methods | |
247 /// while still lazily computing the type descriptor object. | |
248 function setSignature(f, signature) { | 151 function setSignature(f, signature) { |
249 let constructors = | 152 let constructors = 'constructors' in signature ? signature.constructors : ()
=> ({}); |
250 ('constructors' in signature) ? signature.constructors : () => ({}); | 153 let methods = 'methods' in signature ? signature.methods : () => ({}); |
251 let methods = | 154 let statics = 'statics' in signature ? signature.statics : () => ({}); |
252 ('methods' in signature) ? signature.methods : () => ({}); | 155 let names = 'names' in signature ? signature.names : []; |
253 let statics = | |
254 ('statics' in signature) ? signature.statics : () => ({}); | |
255 let names = | |
256 ('names' in signature) ? signature.names : []; | |
257 _setConstructorSignature(f, constructors); | 156 _setConstructorSignature(f, constructors); |
258 _setMethodSignature(f, methods); | 157 _setMethodSignature(f, methods); |
259 _setStaticSignature(f, statics); | 158 _setStaticSignature(f, statics); |
260 _setStaticTypes(f, names); | 159 _setStaticTypes(f, names); |
261 rtti.tagMemoized(f, () => core.Type); | 160 rtti.tagMemoized(f, () => core.Type); |
262 } | 161 } |
263 exports.setSignature = setSignature; | |
264 | |
265 function hasMethod(obj, name) { | 162 function hasMethod(obj, name) { |
266 return _getMethodType(obj, name) !== void 0; | 163 return getMethodType(obj, name) !== void 0; |
267 } | 164 } |
268 exports.hasMethod = hasMethod; | |
269 | |
270 exports.getMethodType = _getMethodType; | |
271 | |
272 /** | |
273 * This is called whenever a derived class needs to introduce a new field, | |
274 * shadowing a field or getter/setter pair on its parent. | |
275 * | |
276 * This is important because otherwise, trying to read or write the field | |
277 * would end up calling the getter or setter, and one of those might not even | |
278 * exist, resulting in a runtime error. Even if they did exist, that's the | |
279 * wrong behavior if a new field was declared. | |
280 */ | |
281 function virtualField(subclass, fieldName) { | 165 function virtualField(subclass, fieldName) { |
282 // If the field is already overridden, do nothing. | |
283 let prop = getOwnPropertyDescriptor(subclass.prototype, fieldName); | 166 let prop = getOwnPropertyDescriptor(subclass.prototype, fieldName); |
284 if (prop) return; | 167 if (prop) return; |
285 | |
286 let symbol = Symbol(subclass.name + '.' + fieldName); | 168 let symbol = Symbol(subclass.name + '.' + fieldName); |
287 defineProperty(subclass.prototype, fieldName, { | 169 defineProperty(subclass.prototype, fieldName, { |
288 get: function() { return this[symbol]; }, | 170 get: function() { |
289 set: function(x) { this[symbol] = x; } | 171 return this[symbol]; |
| 172 }, |
| 173 set: function(x) { |
| 174 this[symbol] = x; |
| 175 } |
290 }); | 176 }); |
291 } | 177 } |
292 exports.virtualField = virtualField; | |
293 | |
294 /** | |
295 * Given a class and an initializer method name, creates a constructor | |
296 * function with the same name. For example `new SomeClass.name(args)`. | |
297 */ | |
298 function defineNamedConstructor(clazz, name) { | 178 function defineNamedConstructor(clazz, name) { |
299 let proto = clazz.prototype; | 179 let proto = clazz.prototype; |
300 let initMethod = proto[name]; | 180 let initMethod = proto[name]; |
301 let ctor = function() { return initMethod.apply(this, arguments); }; | 181 let ctor = function() { |
| 182 return initMethod.apply(this, arguments); |
| 183 }; |
302 ctor.prototype = proto; | 184 ctor.prototype = proto; |
303 // Use defineProperty so we don't hit a property defined on Function, | 185 defineProperty(clazz, name, {value: ctor, configurable: true}); |
304 // like `caller` and `arguments`. | |
305 defineProperty(clazz, name, { value: ctor, configurable: true }); | |
306 } | 186 } |
307 exports.defineNamedConstructor = defineNamedConstructor; | 187 const _extensionType = Symbol("extensionType"); |
308 | 188 const dartx = {}; |
309 let _extensionType = Symbol('extensionType'); | |
310 | |
311 let dartx = {}; | |
312 exports.dartx = dartx; | |
313 | |
314 function getExtensionSymbol(name) { | 189 function getExtensionSymbol(name) { |
315 let sym = dartx[name]; | 190 let sym = dartx[name]; |
316 if (!sym) dartx[name] = sym = Symbol('dartx.' + name); | 191 if (!sym) dartx[name] = sym = Symbol('dartx.' + name); |
317 return sym; | 192 return sym; |
318 } | 193 } |
319 | |
320 function defineExtensionNames(names) { | 194 function defineExtensionNames(names) { |
321 names.forEach(getExtensionSymbol); | 195 names.forEach(getExtensionSymbol); |
322 } | 196 } |
323 exports.defineExtensionNames = defineExtensionNames; | |
324 | |
325 /** | |
326 * Copy symbols from the prototype of the source to destination. | |
327 * These are the only properties safe to copy onto an existing public | |
328 * JavaScript class. | |
329 */ | |
330 function registerExtension(jsType, dartExtType) { | 197 function registerExtension(jsType, dartExtType) { |
331 let extProto = dartExtType.prototype; | 198 let extProto = dartExtType.prototype; |
332 let jsProto = jsType.prototype; | 199 let jsProto = jsType.prototype; |
333 | |
334 // Mark the JS type's instances so we can easily check for extensions. | |
335 assert(jsProto[_extensionType] === void 0); | 200 assert(jsProto[_extensionType] === void 0); |
336 jsProto[_extensionType] = extProto; | 201 jsProto[_extensionType] = extProto; |
337 | |
338 let dartObjProto = core.Object.prototype; | 202 let dartObjProto = core.Object.prototype; |
339 while (extProto !== dartObjProto && extProto !== jsProto) { | 203 while (extProto !== dartObjProto && extProto !== jsProto) { |
340 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto)); | 204 copyTheseProperties(jsProto, extProto, getOwnPropertySymbols(extProto)); |
341 extProto = extProto.__proto__; | 205 extProto = extProto.__proto__; |
342 } | 206 } |
343 let originalSigFn = getOwnPropertyDescriptor(dartExtType, _methodSig).get; | 207 let originalSigFn = getOwnPropertyDescriptor(dartExtType, _methodSig).get; |
344 assert(originalSigFn); | 208 assert(originalSigFn); |
345 defineMemoizedGetter(jsType, _methodSig, originalSigFn); | 209 defineMemoizedGetter(jsType, _methodSig, originalSigFn); |
346 } | 210 } |
347 exports.registerExtension = registerExtension; | |
348 | |
349 /** | |
350 * Mark a concrete type as implementing extension methods. | |
351 * For example: `class MyIter implements Iterable`. | |
352 * | |
353 * This takes a list of names, which are the extension methods implemented. | |
354 * It will add a forwarder, so the extension method name redirects to the | |
355 * normal Dart method name. For example: | |
356 * | |
357 * defineExtensionMembers(MyType, ['add', 'remove']); | |
358 * | |
359 * Results in: | |
360 * | |
361 * MyType.prototype[dartx.add] = MyType.prototype.add; | |
362 * MyType.prototype[dartx.remove] = MyType.prototype.remove; | |
363 */ | |
364 // TODO(jmesserly): essentially this gives two names to the same method. | |
365 // This benefit is roughly equivalent call performance either way, but the | |
366 // cost is we need to call defineExtensionMembers any time a subclass | |
367 // overrides one of these methods. | |
368 function defineExtensionMembers(type, methodNames) { | 211 function defineExtensionMembers(type, methodNames) { |
369 let proto = type.prototype; | 212 let proto = type.prototype; |
370 for (let name of methodNames) { | 213 for (let name of methodNames) { |
371 let method = getOwnPropertyDescriptor(proto, name); | 214 let method = getOwnPropertyDescriptor(proto, name); |
372 defineProperty(proto, getExtensionSymbol(name), method); | 215 defineProperty(proto, getExtensionSymbol(name), method); |
373 } | 216 } |
374 // Ensure the signature is available too. | |
375 // TODO(jmesserly): not sure if we can do this in a cleaner way. Essentially | |
376 // we need to copy the signature (and in the future, other data like | |
377 // annotations) any time we copy a method as part of our metaprogramming. | |
378 // It might be more friendly to JS metaprogramming if we include this info | |
379 // on the function. | |
380 let originalSigFn = getOwnPropertyDescriptor(type, _methodSig).get; | 217 let originalSigFn = getOwnPropertyDescriptor(type, _methodSig).get; |
381 defineMemoizedGetter(type, _methodSig, function() { | 218 defineMemoizedGetter(type, _methodSig, function() { |
382 let sig = originalSigFn(); | 219 let sig = originalSigFn(); |
383 for (let name of methodNames) { | 220 for (let name of methodNames) { |
384 sig[getExtensionSymbol(name)] = sig[name]; | 221 sig[getExtensionSymbol(name)] = sig[name]; |
385 } | 222 } |
386 return sig; | 223 return sig; |
387 }); | 224 }); |
388 } | 225 } |
389 exports.defineExtensionMembers = defineExtensionMembers; | |
390 | |
391 function canonicalMember(obj, name) { | 226 function canonicalMember(obj, name) { |
392 if (obj != null && obj[_extensionType]) return dartx[name]; | 227 if (obj != null && obj[_extensionType]) return dartx[name]; |
393 // Check for certain names that we can't use in JS | |
394 if (name == 'constructor' || name == 'prototype') { | 228 if (name == 'constructor' || name == 'prototype') { |
395 name = '+' + name; | 229 name = '+' + name; |
396 } | 230 } |
397 return name; | 231 return name; |
398 } | 232 } |
399 exports.canonicalMember = canonicalMember; | |
400 | |
401 /** Sets the type of `obj` to be `type` */ | |
402 function setType(obj, type) { | 233 function setType(obj, type) { |
403 obj.__proto__ = type.prototype; | 234 obj.__proto__ = type.prototype; |
404 return obj; | 235 return obj; |
405 } | 236 } |
406 | |
407 /** Sets the element type of a list literal. */ | |
408 function list(obj, elementType) { | 237 function list(obj, elementType) { |
409 return setType(obj, _interceptors.JSArray$(elementType)); | 238 return setType(obj, _interceptors.JSArray$(elementType)); |
410 } | 239 } |
411 exports.list = list; | |
412 | |
413 function setBaseClass(derived, base) { | 240 function setBaseClass(derived, base) { |
414 // Link the extension to the type it's extending as a base class. | |
415 derived.prototype.__proto__ = base.prototype; | 241 derived.prototype.__proto__ = base.prototype; |
416 } | 242 } |
| 243 // Exports: |
| 244 exports.assert = assert; |
| 245 exports.copyProperties = copyProperties; |
| 246 exports.copyTheseProperties = copyTheseProperties; |
| 247 exports.defineMemoizedGetter = defineMemoizedGetter; |
| 248 exports.safeGetOwnProperty = safeGetOwnProperty; |
| 249 exports.throwInternalError = throwInternalError; |
| 250 exports.defineProperty = defineProperty; |
| 251 exports.getOwnPropertyDescriptor = getOwnPropertyDescriptor; |
| 252 exports.getOwnPropertySymbols = getOwnPropertySymbols; |
| 253 exports.implements = implements$; |
| 254 exports.metadata = metadata; |
| 255 exports.mixin = mixin; |
| 256 exports.getMixins = getMixins; |
| 257 exports.getImplements = getImplements; |
| 258 exports.generic = generic; |
| 259 exports.getGenericClass = getGenericClass; |
| 260 exports.getGenericArgs = getGenericArgs; |
| 261 exports.getMethodType = getMethodType; |
| 262 exports.classGetConstructorType = classGetConstructorType; |
| 263 exports.bind = bind; |
| 264 exports.setSignature = setSignature; |
| 265 exports.hasMethod = hasMethod; |
| 266 exports.virtualField = virtualField; |
| 267 exports.defineNamedConstructor = defineNamedConstructor; |
| 268 exports.dartx = dartx; |
| 269 exports.getExtensionSymbol = getExtensionSymbol; |
| 270 exports.defineExtensionNames = defineExtensionNames; |
| 271 exports.registerExtension = registerExtension; |
| 272 exports.defineExtensionMembers = defineExtensionMembers; |
| 273 exports.canonicalMember = canonicalMember; |
| 274 exports.setType = setType; |
| 275 exports.list = list; |
417 exports.setBaseClass = setBaseClass; | 276 exports.setBaseClass = setBaseClass; |
418 | |
419 }); | 277 }); |
OLD | NEW |