| Index: tool/input_sdk/private/ddc_runtime/classes.dart
|
| diff --git a/tool/input_sdk/private/ddc_runtime/classes.dart b/tool/input_sdk/private/ddc_runtime/classes.dart
|
| index d8b06e6cd72ca795d814f50db976806ffe237678..07987cffcac0608488f692099b40b9986ac57aec 100644
|
| --- a/tool/input_sdk/private/ddc_runtime/classes.dart
|
| +++ b/tool/input_sdk/private/ddc_runtime/classes.dart
|
| @@ -256,20 +256,22 @@ setSignature(f, signature) => JS('', '''(() => {
|
|
|
| hasMethod(obj, name) => JS('', '$getMethodType($obj, $name) !== void 0');
|
|
|
| -///
|
| /// Given a class and an initializer method name, creates a constructor
|
| -/// function with the same name. For example `new SomeClass.name(args)`.
|
| +/// function with the same name.
|
| ///
|
| +/// After we define the named constructor, the class can be constructed with
|
| +/// `new SomeClass.name(args)`.
|
| defineNamedConstructor(clazz, name) => JS('', '''(() => {
|
| let proto = $clazz.prototype;
|
| let initMethod = proto[$name];
|
| - let ctor = function() { return initMethod.apply(this, arguments); };
|
| + let ctor = function(...args) { initMethod.apply(this, args); };
|
| ctor.prototype = proto;
|
| // Use defineProperty so we don't hit a property defined on Function,
|
| // like `caller` and `arguments`.
|
| $defineProperty($clazz, $name, { value: ctor, configurable: true });
|
| })()''');
|
|
|
| +
|
| final _extensionType = JS('', 'Symbol("extensionType")');
|
|
|
| getExtensionType(obj) => JS('', '#[#]', obj, _extensionType);
|
| @@ -438,3 +440,37 @@ setExtensionBaseClass(derived, base) {
|
| // Link the prototype objects
|
| JS('', '#.prototype.__proto__ = #.prototype', derived, base);
|
| }
|
| +
|
| +/// Given a special constructor function that creates a function instances,
|
| +/// and a class with a `call` method, merge them so the constructor function
|
| +/// will have the correct methods and prototype.
|
| +///
|
| +/// For example:
|
| +///
|
| +/// lib.Foo = dart.callableClass(
|
| +/// function Foo { function call(...args) { ... } ... return call; },
|
| +/// class Foo { call(x) { ... } });
|
| +/// ...
|
| +/// let f = new lib.Foo();
|
| +/// f(42);
|
| +callableClass(callableCtor, classExpr) {
|
| + JS('', '#.prototype = #.prototype', callableCtor, classExpr);
|
| + // We're not going to use the original class, so we can safely replace it to
|
| + // point at this constructor for the runtime type information.
|
| + JS('', '#.prototype.constructor = #', callableCtor, callableCtor);
|
| + JS('', '#.__proto__ = #.__proto__', callableCtor, classExpr);
|
| + return callableCtor;
|
| +}
|
| +
|
| +/// Given a class and an initializer method name and a call method, creates a
|
| +/// constructor function with the same name.
|
| +///
|
| +/// For example it can be called with `new SomeClass.name(args)`.
|
| +///
|
| +/// The constructor
|
| +defineNamedConstructorCallable(clazz, name, ctor) => JS('', '''(() => {
|
| + ctor.prototype = $clazz.prototype;
|
| + // Use defineProperty so we don't hit a property defined on Function,
|
| + // like `caller` and `arguments`.
|
| + $defineProperty($clazz, $name, { value: ctor, configurable: true });
|
| +})()''');
|
|
|