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 part of dart2js.js_emitter.startup_emitter.model_emitter; | 5 part of dart2js.js_emitter.startup_emitter.model_emitter; |
| 6 | 6 |
| 7 /// The name of the property that stores the tear-off getter on a static | 7 /// The name of the property that stores the tear-off getter on a static |
| 8 /// function. | 8 /// function. |
| 9 /// | 9 /// |
| 10 /// This property is only used when isolates are used. | 10 /// This property is only used when isolates are used. |
| (...skipping 595 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 606 List<js.Property> properties = <js.Property>[]; | 606 List<js.Property> properties = <js.Property>[]; |
| 607 | 607 |
| 608 if (cls.superclass == null) { | 608 if (cls.superclass == null) { |
| 609 properties.add(new js.Property(js.string("constructor"), | 609 properties.add(new js.Property(js.string("constructor"), |
| 610 classReference(cls))); | 610 classReference(cls))); |
| 611 properties.add(new js.Property(namer.operatorIs(cls.element), | 611 properties.add(new js.Property(namer.operatorIs(cls.element), |
| 612 js.number(1))); | 612 js.number(1))); |
| 613 } | 613 } |
| 614 | 614 |
| 615 allMethods.forEach((Method method) { | 615 allMethods.forEach((Method method) { |
| 616 emitInstanceMethod(method).forEach((js.Name name, js.Expression code) { | 616 emitInstanceMethod(method) |
| 617 .forEach((js.Expression name, js.Expression code) { | |
| 617 properties.add(new js.Property(name, code)); | 618 properties.add(new js.Property(name, code)); |
| 618 }); | 619 }); |
| 619 }); | 620 }); |
| 620 | 621 |
| 621 return new js.ObjectInitializer(properties); | 622 return new js.ObjectInitializer(properties); |
| 622 } | 623 } |
| 623 | 624 |
| 624 /// Generates a getter for the given [field]. | 625 /// Generates a getter for the given [field]. |
| 625 Method generateGetter(Field field) { | 626 Method generateGetter(Field field) { |
| 626 assert(field.needsGetter); | 627 assert(field.needsGetter); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 672 | 673 |
| 673 return [getters, setters].expand((x) => x); | 674 return [getters, setters].expand((x) => x); |
| 674 } | 675 } |
| 675 | 676 |
| 676 /// Emits the given instance [method]. | 677 /// Emits the given instance [method]. |
| 677 /// | 678 /// |
| 678 /// The given method may be a stub-method (for example for is-checks). | 679 /// The given method may be a stub-method (for example for is-checks). |
| 679 /// | 680 /// |
| 680 /// If it is a Dart-method, all necessary stub-methods are emitted, too. In | 681 /// If it is a Dart-method, all necessary stub-methods are emitted, too. In |
| 681 /// that case the returned map contains more than just one entry. | 682 /// that case the returned map contains more than just one entry. |
| 682 Map<js.Name, js.Expression> emitInstanceMethod(Method method) { | 683 /// |
| 683 Map<js.Name, js.Expression> jsMethods = <js.Name, js.Expression>{}; | 684 /// If the method is a call-method, also returns the necessary properties |
|
Siggi Cherem (dart-lang)
2015/07/23 19:43:42
nit: call-method => closure-call-method
floitsch
2015/07/29 18:26:46
Done.
| |
| 685 /// in case the closure can be applied. | |
| 686 Map<js.Expression, js.Expression> emitInstanceMethod(Method method) { | |
| 687 Map<js.Expression, js.Expression> properties = | |
|
Siggi Cherem (dart-lang)
2015/07/23 19:43:42
nit: var?
(I prefer not to repeat the type when w
floitsch
2015/07/29 18:26:46
We always used the full type, but done.
| |
| 688 <js.Expression, js.Expression>{}; | |
| 684 | 689 |
| 685 jsMethods[method.name] = method.code; | 690 properties[method.name] = method.code; |
| 686 if (method is InstanceMethod) { | 691 if (method is InstanceMethod) { |
| 687 for (ParameterStubMethod stubMethod in method.parameterStubs) { | 692 for (ParameterStubMethod stubMethod in method.parameterStubs) { |
| 688 jsMethods[stubMethod.name] = stubMethod.code; | 693 properties[stubMethod.name] = stubMethod.code; |
| 694 } | |
| 695 | |
| 696 if (method.isClosureCallMethod && method.canBeApplied) { | |
| 697 properties[js.string(namer.callCatchAllName)] = | |
| 698 js.quoteName(method.name); | |
| 699 properties[js.string(namer.requiredParameterField)] = | |
| 700 js.number(method.requiredParameterCount); | |
| 701 properties[js.string(namer.defaultValuesField)] = | |
| 702 js.js('function() { return #; }', | |
| 703 _encodeOptionalParameterDefaultValues(method)); | |
| 689 } | 704 } |
| 690 } | 705 } |
| 691 | 706 |
| 692 return jsMethods; | 707 return properties; |
| 693 } | 708 } |
| 694 | 709 |
| 695 /// Emits the inheritance block of the fragment. | 710 /// Emits the inheritance block of the fragment. |
| 696 /// | 711 /// |
| 697 /// In this section prototype chains are updated and mixin functions are | 712 /// In this section prototype chains are updated and mixin functions are |
| 698 /// copied. | 713 /// copied. |
| 699 js.Statement emitInheritance(Fragment fragment) { | 714 js.Statement emitInheritance(Fragment fragment) { |
| 700 List<js.Expression> inheritCalls = <js.Expression>[]; | 715 List<js.Expression> inheritCalls = <js.Expression>[]; |
| 701 List<js.Expression> mixinCalls = <js.Expression>[]; | 716 List<js.Expression> mixinCalls = <js.Expression>[]; |
| 702 | 717 |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 752 // TODO(herhut): Replace [js.LiteralNull] with [js.ArrayHole]. | 767 // TODO(herhut): Replace [js.LiteralNull] with [js.ArrayHole]. |
| 753 if (method.optionalParameterDefaultValues is List) { | 768 if (method.optionalParameterDefaultValues is List) { |
| 754 List<ConstantValue> defaultValues = method.optionalParameterDefaultValues; | 769 List<ConstantValue> defaultValues = method.optionalParameterDefaultValues; |
| 755 Iterable<js.Expression> elements = | 770 Iterable<js.Expression> elements = |
| 756 defaultValues.map(generateConstantReference); | 771 defaultValues.map(generateConstantReference); |
| 757 return new js.ArrayInitializer(elements.toList()); | 772 return new js.ArrayInitializer(elements.toList()); |
| 758 } else { | 773 } else { |
| 759 Map<String, ConstantValue> defaultValues = | 774 Map<String, ConstantValue> defaultValues = |
| 760 method.optionalParameterDefaultValues; | 775 method.optionalParameterDefaultValues; |
| 761 List<js.Property> properties = <js.Property>[]; | 776 List<js.Property> properties = <js.Property>[]; |
| 762 defaultValues.forEach((String name, ConstantValue value) { | 777 List<String> names = defaultValues.keys.toList(growable: false); |
| 778 // Sort the names the same way we sort them for the named-argument calling | |
| 779 // convention. | |
| 780 names.sort(); | |
| 781 | |
| 782 for (String name in names) { | |
| 783 ConstantValue value = defaultValues[name]; | |
| 763 properties.add(new js.Property(js.string(name), | 784 properties.add(new js.Property(js.string(name), |
| 764 generateConstantReference(value))); | 785 generateConstantReference(value))); |
| 765 }); | 786 } |
| 766 return new js.ObjectInitializer(properties); | 787 return new js.ObjectInitializer(properties); |
| 767 } | 788 } |
| 768 } | 789 } |
| 769 | 790 |
| 770 /// Emits the statement that installs a tear off for a method. | 791 /// Emits the statement that installs a tear off for a method. |
| 771 /// | 792 /// |
| 772 /// Tear-offs might be passed to `Function.apply` which means that all | 793 /// Tear-offs might be passed to `Function.apply` which means that all |
| 773 /// calling-conventions (with or without optional positional/named arguments) | 794 /// calling-conventions (with or without optional positional/named arguments) |
| 774 /// are possible. As such, the tear-off needs enough information to fill in | 795 /// are possible. As such, the tear-off needs enough information to fill in |
| 775 /// missing parameters. | 796 /// missing parameters. |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 809 isIntercepted = backend.isInterceptedMethod(method.element); | 830 isIntercepted = backend.isInterceptedMethod(method.element); |
| 810 } | 831 } |
| 811 int requiredParameterCount = 0; | 832 int requiredParameterCount = 0; |
| 812 js.Expression optionalParameterDefaultValues = new js.LiteralNull(); | 833 js.Expression optionalParameterDefaultValues = new js.LiteralNull(); |
| 813 if (method.canBeApplied) { | 834 if (method.canBeApplied) { |
| 814 requiredParameterCount = method.requiredParameterCount; | 835 requiredParameterCount = method.requiredParameterCount; |
| 815 optionalParameterDefaultValues = | 836 optionalParameterDefaultValues = |
| 816 _encodeOptionalParameterDefaultValues(method); | 837 _encodeOptionalParameterDefaultValues(method); |
| 817 } | 838 } |
| 818 | 839 |
| 819 // TODO(floitsch): this can be more efficient. | 840 // TODO(floitsch): this can be more efficient. |
| 820 return js.js.statement(''' | 841 return js.js.statement(''' |
| 821 installTearOff(#container, #getterName, #isStatic, #isIntercepted, | 842 installTearOff(#container, #getterName, #isStatic, #isIntercepted, |
| 822 #requiredParameterCount, #optionalParameterDefaultValues, | 843 #requiredParameterCount, #optionalParameterDefaultValues, |
| 823 #callNames, #funsOrNames, #funType)''', | 844 #callNames, #funsOrNames, #funType)''', |
| 824 { | 845 { |
| 825 "container": container, | 846 "container": container, |
| 826 "getterName": js.quoteName(method.tearOffName), | 847 "getterName": js.quoteName(method.tearOffName), |
| 827 "isStatic": new js.LiteralBool(method.isStatic), | 848 "isStatic": new js.LiteralBool(method.isStatic), |
| 828 "isIntercepted": new js.LiteralBool(isIntercepted), | 849 "isIntercepted": new js.LiteralBool(isIntercepted), |
| 829 "requiredParameterCount": js.number(requiredParameterCount), | 850 "requiredParameterCount": js.number(requiredParameterCount), |
| (...skipping 383 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1213 } | 1234 } |
| 1214 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", | 1235 statements.add(js.js.statement("setOrUpdateInterceptorsByTag(#);", |
| 1215 js.objectLiteral(interceptorsByTag))); | 1236 js.objectLiteral(interceptorsByTag))); |
| 1216 statements.add(js.js.statement("setOrUpdateLeafTags(#);", | 1237 statements.add(js.js.statement("setOrUpdateLeafTags(#);", |
| 1217 js.objectLiteral(leafTags))); | 1238 js.objectLiteral(leafTags))); |
| 1218 statements.add(subclassAssignment); | 1239 statements.add(subclassAssignment); |
| 1219 | 1240 |
| 1220 return new js.Block(statements); | 1241 return new js.Block(statements); |
| 1221 } | 1242 } |
| 1222 } | 1243 } |
| OLD | NEW |