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 15 matching lines...) Expand all Loading... |
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 // Copy each mixin's methods, with later ones overwriting earlier entries. | 32 // Copy each mixin's methods, with later ones overwriting earlier entries. |
33 for (let m of $mixins) { | 33 for (let m of $mixins) { |
34 $copyProperties(Mixin.prototype, m.prototype); | 34 $copyProperties(Mixin.prototype, m.prototype); |
35 } | 35 } |
36 // Initializer method: run mixin initializers, then the base. | 36 // Initializer methods: run mixin initializers, then the base. |
37 Mixin.prototype.new = function(...args) { | 37 Mixin.prototype.new = function(...args) { |
38 // Run mixin initializers. They cannot have arguments. | 38 // Run mixin initializers. They cannot have arguments. |
39 // Run them backwards so most-derived mixin is initialized first. | 39 // Run them backwards so most-derived mixin is initialized first. |
40 for (let i = $mixins.length - 1; i >= 0; i--) { | 40 for (let i = $mixins.length - 1; i >= 0; i--) { |
41 $mixins[i].prototype.new.call(this); | 41 $mixins[i].prototype.new.call(this); |
42 } | 42 } |
43 // Run base initializer. | 43 // Run base initializer. |
44 $base.prototype.new.apply(this, args); | 44 $base.prototype.new.apply(this, args); |
45 }; | 45 }; |
| 46 let namedCtors = ${safeGetOwnProperty(base, _namedConstructors)}; |
| 47 if ($base[$_namedConstructors] != null) { |
| 48 for (let namedCtor of $base[$_namedConstructors]) { |
| 49 Mixin.prototype[namedCtor] = function(...args) { |
| 50 // Run mixin initializers. They cannot have arguments. |
| 51 // Run them backwards so most-derived mixin is initialized first. |
| 52 for (let i = $mixins.length - 1; i >= 0; i--) { |
| 53 $mixins[i].prototype.new.call(this); |
| 54 } |
| 55 // Run base initializer. |
| 56 $base.prototype[namedCtor].apply(this, args); |
| 57 }; |
| 58 } |
| 59 } |
46 | 60 |
47 // Set the signature of the Mixin class to be the composition | 61 // Set the signature of the Mixin class to be the composition |
48 // of the signatures of the mixins. | 62 // of the signatures of the mixins. |
49 $setSignature(Mixin, { | 63 $setSignature(Mixin, { |
50 methods: () => { | 64 methods: () => { |
51 let s = {}; | 65 let s = {}; |
52 for (let m of $mixins) { | 66 for (let m of $mixins) { |
53 if (m[$_methodSig]) $copyProperties(s, m[$_methodSig]); | 67 if (m[$_methodSig]) $copyProperties(s, m[$_methodSig]); |
54 } | 68 } |
55 return s; | 69 return s; |
(...skipping 361 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
417 /// function with the same name. | 431 /// function with the same name. |
418 /// | 432 /// |
419 /// After we define the named constructor, the class can be constructed with | 433 /// After we define the named constructor, the class can be constructed with |
420 /// `new SomeClass.name(args)`. | 434 /// `new SomeClass.name(args)`. |
421 defineNamedConstructor(clazz, name) => JS( | 435 defineNamedConstructor(clazz, name) => JS( |
422 '', | 436 '', |
423 '''(() => { | 437 '''(() => { |
424 let proto = $clazz.prototype; | 438 let proto = $clazz.prototype; |
425 let initMethod = proto[$name]; | 439 let initMethod = proto[$name]; |
426 let ctor = function(...args) { initMethod.apply(this, args); }; | 440 let ctor = function(...args) { initMethod.apply(this, args); }; |
427 ctor[$isNamedConstructor] = true; | |
428 ctor.prototype = proto; | 441 ctor.prototype = proto; |
429 // Use defineProperty so we don't hit a property defined on Function, | 442 // Use defineProperty so we don't hit a property defined on Function, |
430 // like `caller` and `arguments`. | 443 // like `caller` and `arguments`. |
431 $defineProperty($clazz, $name, { value: ctor, configurable: true }); | 444 $defineProperty($clazz, $name, { value: ctor, configurable: true }); |
| 445 |
| 446 let namedCtors = ${safeGetOwnProperty(clazz, _namedConstructors)}; |
| 447 if (namedCtors == null) $clazz[$_namedConstructors] = namedCtors = []; |
| 448 namedCtors.push($name); |
432 })()'''); | 449 })()'''); |
433 | 450 |
| 451 final _namedConstructors = JS('', 'Symbol("_namedConstructors")'); |
| 452 |
434 final _extensionType = JS('', 'Symbol("extensionType")'); | 453 final _extensionType = JS('', 'Symbol("extensionType")'); |
435 | 454 |
436 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType); | 455 getExtensionType(obj) => JS('', '#[#]', obj, _extensionType); |
437 | 456 |
438 final dartx = JS('', 'dartx'); | 457 final dartx = JS('', 'dartx'); |
439 | 458 |
440 getExtensionSymbol(name) { | 459 getExtensionSymbol(name) { |
441 var sym = JS('', 'dartx[#]', name); | 460 var sym = JS('', 'dartx[#]', name); |
442 if (sym == null) { | 461 if (sym == null) { |
443 sym = JS('', 'Symbol("dartx." + #.toString())', name); | 462 sym = JS('', 'Symbol("dartx." + #.toString())', name); |
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
651 '''(() => { | 670 '''(() => { |
652 let values = []; | 671 let values = []; |
653 for (var i = 0; i < $names.length; i++) { | 672 for (var i = 0; i < $names.length; i++) { |
654 let value = $const_(new $enumClass(i)); | 673 let value = $const_(new $enumClass(i)); |
655 values.push(value); | 674 values.push(value); |
656 Object.defineProperty($enumClass, $names[i], | 675 Object.defineProperty($enumClass, $names[i], |
657 { value: value, configurable: true }); | 676 { value: value, configurable: true }); |
658 } | 677 } |
659 $enumClass.values = $constList(values, $enumClass); | 678 $enumClass.values = $constList(values, $enumClass); |
660 })()'''); | 679 })()'''); |
OLD | NEW |