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 | 4 |
5 /// This library defines the operations that define and manipulate Dart | 5 /// This library defines the operations that define and manipulate Dart |
6 /// classes. Included in this are: | 6 /// classes. Included in this are: |
7 /// - Generics | 7 /// - Generics |
8 /// - Class metadata | 8 /// - Class metadata |
9 /// - Extension methods | 9 /// - Extension methods |
10 /// | 10 /// |
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
249 ('names' in signature) ? signature.names : []; | 249 ('names' in signature) ? signature.names : []; |
250 $_setConstructorSignature($f, constructors); | 250 $_setConstructorSignature($f, constructors); |
251 $_setMethodSignature($f, methods); | 251 $_setMethodSignature($f, methods); |
252 $_setStaticSignature($f, statics); | 252 $_setStaticSignature($f, statics); |
253 $_setStaticTypes($f, names); | 253 $_setStaticTypes($f, names); |
254 $tagLazy($f, () => $Type); | 254 $tagLazy($f, () => $Type); |
255 })()'''); | 255 })()'''); |
256 | 256 |
257 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0'); | 257 hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0'); |
258 | 258 |
259 /// | |
260 /// Given a class and an initializer method name, creates a constructor | 259 /// Given a class and an initializer method name, creates a constructor |
261 /// function with the same name. For example `new SomeClass.name(args)`. | 260 /// function with the same name. For example `new SomeClass.name(args)`. |
262 /// | |
263 defineNamedConstructor(clazz, name) => JS('', '''(() => { | 261 defineNamedConstructor(clazz, name) => JS('', '''(() => { |
264 let proto = $clazz.prototype; | 262 let proto = $clazz.prototype; |
265 let initMethod = proto[$name]; | 263 let initMethod = proto[$name]; |
266 let ctor = function() { return initMethod.apply(this, arguments); }; | 264 let ctor = function(...args) { initMethod.apply(this, args); }; |
267 ctor.prototype = proto; | 265 ctor.prototype = proto; |
268 // Use defineProperty so we don't hit a property defined on Function, | 266 // Use defineProperty so we don't hit a property defined on Function, |
269 // like `caller` and `arguments`. | 267 // like `caller` and `arguments`. |
270 $defineProperty($clazz, $name, { value: ctor, configurable: true }); | 268 $defineProperty($clazz, $name, { value: ctor, configurable: true }); |
271 })()'''); | 269 })()'''); |
272 | 270 |
| 271 /// Given a class and an initializer method name, creates a constructor |
| 272 /// function with the same name. For example `new SomeClass.name(args)`. |
| 273 defineNamedConstructorCallable(clazz, name) => JS('', '''(() => { |
| 274 let proto = $clazz.prototype; |
| 275 let initMethod = proto[$name]; |
| 276 let ctor = function (...args) { |
| 277 let call = this.call.bind(this); |
| 278 call.__proto__ = this.__proto__; |
| 279 initMethod.apply(call, args); |
| 280 return call; |
| 281 }; |
| 282 ctor.prototype = proto; |
| 283 // Use defineProperty so we don't hit a property defined on Function, |
| 284 // like `caller` and `arguments`. |
| 285 $defineProperty($clazz, $name, { value: ctor, configurable: true }); |
| 286 })()'''); |
| 287 |
| 288 |
273 final _extensionType = JS('', 'Symbol("extensionType")'); | 289 final _extensionType = JS('', 'Symbol("extensionType")'); |
274 | 290 |
275 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType); | 291 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType); |
276 | 292 |
277 final dartx = JS('', 'dartx'); | 293 final dartx = JS('', 'dartx'); |
278 | 294 |
279 getExtensionSymbol(name) { | 295 getExtensionSymbol(name) { |
280 var sym = JS('', 'dartx[#]', name); | 296 var sym = JS('', 'dartx[#]', name); |
281 if (sym == null) { | 297 if (sym == null) { |
282 sym = JS('', 'Symbol("dartx." + #.toString())', name); | 298 sym = JS('', 'Symbol("dartx." + #.toString())', name); |
(...skipping 148 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
431 JS('', '#.__proto__ = #', derived, base); | 447 JS('', '#.__proto__ = #', derived, base); |
432 } | 448 } |
433 | 449 |
434 /// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>` | 450 /// Like [setBaseClass] but for generic extension types, e.g. `JSArray<E>` |
435 setExtensionBaseClass(derived, base) { | 451 setExtensionBaseClass(derived, base) { |
436 // Mark the generic type as an extension type. | 452 // Mark the generic type as an extension type. |
437 JS('', '#.prototype[#] = #', derived, _extensionType, derived); | 453 JS('', '#.prototype[#] = #', derived, _extensionType, derived); |
438 // Link the prototype objects | 454 // Link the prototype objects |
439 JS('', '#.prototype.__proto__ = #.prototype', derived, base); | 455 JS('', '#.prototype.__proto__ = #.prototype', derived, base); |
440 } | 456 } |
| 457 |
| 458 /// Given a special constructor function that creates a function instances, |
| 459 /// and a class with a `call` method, merge them so the constructor function |
| 460 /// will have the correct methods and prototype. |
| 461 /// |
| 462 /// For example: |
| 463 /// |
| 464 /// lib.Foo = dart.callableClass( |
| 465 /// function Foo { function call(...args) { ... } ... return call; }, |
| 466 /// class Foo { call(x) { ... } }); |
| 467 /// ... |
| 468 /// let f = new lib.Foo(); |
| 469 /// f(42); |
| 470 callableClass(callableCtor, classExpr) { |
| 471 JS('', '#.prototype = #.prototype', callableCtor, classExpr); |
| 472 // We're not going to use the original class, so we can safely replace it to |
| 473 // point at this constructor for the runtime type information. |
| 474 JS('', '#.prototype.constructor = #', callableCtor, callableCtor); |
| 475 JS('', '#.__proto__ = #.__proto__', callableCtor, classExpr); |
| 476 return callableCtor; |
| 477 } |
OLD | NEW |