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 |