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