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 11 matching lines...) Expand all Loading... | |
22 /// superclass (prototype). | 22 /// superclass (prototype). |
23 /// | 23 /// |
24 mixin(base, @rest mixins) => JS( | 24 mixin(base, @rest mixins) => JS( |
25 '', | 25 '', |
26 '''(() => { | 26 '''(() => { |
27 // Create an initializer for the mixin, so when derived constructor calls | 27 // Create an initializer for the mixin, so when derived constructor calls |
28 // super, we can correctly initialize base and mixins. | 28 // super, we can correctly initialize base and mixins. |
29 | 29 |
30 // Create a class that will hold all of the mixin methods. | 30 // Create a class that will hold all of the mixin methods. |
31 class Mixin extends $base {} | 31 class Mixin extends $base {} |
32 // Save the original constructor. For ClassTypeAlias definitions, this | |
33 // is the concrete type. We embed metadata (e.g., implemented interfaces) | |
34 // on this constructor and need to access that from runtime instances. | |
35 var constructor = Mixin.prototype.constructor; | |
Jacob
2017/05/19 14:31:27
nit: let
| |
32 // Copy each mixin's methods, with later ones overwriting earlier entries. | 36 // Copy each mixin's methods, with later ones overwriting earlier entries. |
33 for (let m of $mixins) { | 37 for (let m of $mixins) { |
34 $copyProperties(Mixin.prototype, m.prototype); | 38 $copyProperties(Mixin.prototype, m.prototype); |
35 } | 39 } |
40 // Restore original Mixin constructor. | |
41 Mixin.prototype.constructor = constructor; | |
36 // Initializer methods: run mixin initializers, then the base. | 42 // Initializer methods: run mixin initializers, then the base. |
37 Mixin.prototype.new = function(...args) { | 43 Mixin.prototype.new = function(...args) { |
38 // Run mixin initializers. They cannot have arguments. | 44 // Run mixin initializers. They cannot have arguments. |
39 // Run them backwards so most-derived mixin is initialized first. | 45 // Run them backwards so most-derived mixin is initialized first. |
40 for (let i = $mixins.length - 1; i >= 0; i--) { | 46 for (let i = $mixins.length - 1; i >= 0; i--) { |
41 $mixins[i].prototype.new.call(this); | 47 $mixins[i].prototype.new.call(this); |
42 } | 48 } |
43 // Run base initializer. | 49 // Run base initializer. |
44 $base.prototype.new.apply(this, args); | 50 $base.prototype.new.apply(this, args); |
45 }; | 51 }; |
46 let namedCtors = ${safeGetOwnProperty(base, _namedConstructors)}; | 52 let namedCtors = ${safeGetOwnProperty(base, _namedConstructors)}; |
47 if ($base[$_namedConstructors] != null) { | 53 if ($base[$_namedConstructors] != null) { |
48 for (let namedCtor of $base[$_namedConstructors]) { | 54 for (let namedCtor of $base[$_namedConstructors]) { |
49 Mixin.prototype[namedCtor] = function(...args) { | 55 Mixin.prototype[namedCtor] = function(...args) { |
50 // Run mixin initializers. They cannot have arguments. | 56 // Run mixin initializers. They cannot have arguments. |
51 // Run them backwards so most-derived mixin is initialized first. | 57 // Run them backwards so most-derived mixin is initialized first. |
52 for (let i = $mixins.length - 1; i >= 0; i--) { | 58 for (let i = $mixins.length - 1; i >= 0; i--) { |
53 $mixins[i].prototype.new.call(this); | 59 $mixins[i].prototype.new.call(this); |
54 } | 60 } |
55 // Run base initializer. | 61 // Run base initializer. |
56 $base.prototype[namedCtor].apply(this, args); | 62 $base.prototype[namedCtor].apply(this, args); |
57 }; | 63 }; |
64 $defineNamedConstructor(Mixin, namedCtor); | |
58 } | 65 } |
59 } | 66 } |
60 | 67 |
61 // Set the signature of the Mixin class to be the composition | 68 // Set the signature of the Mixin class to be the composition |
62 // of the signatures of the mixins. | 69 // of the signatures of the mixins. |
63 $setSignature(Mixin, { | 70 $setSignature(Mixin, { |
64 methods: () => { | 71 methods: () => { |
65 let s = {}; | 72 let s = {}; |
66 for (let m of $mixins) { | 73 for (let m of $mixins) { |
67 if (m[$_methodSig]) $copyProperties(s, m[$_methodSig]); | 74 if (m[$_methodSig]) $copyProperties(s, m[$_methodSig]); |
(...skipping 551 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
619 /// For example it can be called with `new SomeClass.name(args)`. | 626 /// For example it can be called with `new SomeClass.name(args)`. |
620 /// | 627 /// |
621 /// The constructor | 628 /// The constructor |
622 defineNamedConstructorCallable(clazz, name, ctor) => JS( | 629 defineNamedConstructorCallable(clazz, name, ctor) => JS( |
623 '', | 630 '', |
624 '''(() => { | 631 '''(() => { |
625 ctor.prototype = $clazz.prototype; | 632 ctor.prototype = $clazz.prototype; |
626 // Use defineProperty so we don't hit a property defined on Function, | 633 // Use defineProperty so we don't hit a property defined on Function, |
627 // like `caller` and `arguments`. | 634 // like `caller` and `arguments`. |
628 $defineProperty($clazz, $name, { value: ctor, configurable: true }); | 635 $defineProperty($clazz, $name, { value: ctor, configurable: true }); |
636 | |
637 let namedCtors = ${safeGetOwnProperty(clazz, _namedConstructors)}; | |
638 if (namedCtors == null) $clazz[$_namedConstructors] = namedCtors = []; | |
639 namedCtors.push($name); | |
629 })()'''); | 640 })()'''); |
630 | 641 |
631 defineEnumValues(enumClass, names) => JS( | 642 defineEnumValues(enumClass, names) => JS( |
632 '', | 643 '', |
633 '''(() => { | 644 '''(() => { |
634 let values = []; | 645 let values = []; |
635 for (var i = 0; i < $names.length; i++) { | 646 for (var i = 0; i < $names.length; i++) { |
636 let value = $const_(new $enumClass(i)); | 647 let value = $const_(new $enumClass(i)); |
637 values.push(value); | 648 values.push(value); |
638 Object.defineProperty($enumClass, $names[i], | 649 Object.defineProperty($enumClass, $names[i], |
639 { value: value, configurable: true }); | 650 { value: value, configurable: true }); |
640 } | 651 } |
641 $enumClass.values = $constList(values, $enumClass); | 652 $enumClass.values = $constList(values, $enumClass); |
642 })()'''); | 653 })()'''); |
OLD | NEW |