Chromium Code Reviews| 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 |