OLD | NEW |
---|---|
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, 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 js_backend; | 5 part of js_backend; |
6 | 6 |
7 /** | 7 /** |
8 * A function element that represents a closure call. The signature is copied | 8 * A function element that represents a closure call. The signature is copied |
9 * from the given element. | 9 * from the given element. |
10 */ | 10 */ |
(...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
229 // constructor. | 229 // constructor. |
230 // For engines where we have access to the '__proto__' we can manipulate | 230 // For engines where we have access to the '__proto__' we can manipulate |
231 // the object literal directly. For other engines we have to create a new | 231 // the object literal directly. For other engines we have to create a new |
232 // object and copy over the members. | 232 // object and copy over the members. |
233 return ''' | 233 return ''' |
234 function(collectedClasses) { | 234 function(collectedClasses) { |
235 var hasOwnProperty = Object.prototype.hasOwnProperty; | 235 var hasOwnProperty = Object.prototype.hasOwnProperty; |
236 for (var cls in collectedClasses) { | 236 for (var cls in collectedClasses) { |
237 if (hasOwnProperty.call(collectedClasses, cls)) { | 237 if (hasOwnProperty.call(collectedClasses, cls)) { |
238 var desc = collectedClasses[cls]; | 238 var desc = collectedClasses[cls]; |
239 $isolatePropertiesName[cls] = $defineClassName(cls, desc[''], desc); | 239 $isolatePropertiesName[cls] = $defineClassName(cls, desc[''] || [], desc); |
ahe
2012/11/22 12:22:05
I suggest that you use string juxtaposition to get
ngeoffray
2012/11/22 13:15:18
Done.
| |
240 if (desc['super'] !== "") $pendingClassesName[cls] = desc['super']; | 240 if (desc['super'] !== "") $pendingClassesName[cls] = desc['super']; |
241 } | 241 } |
242 } | 242 } |
243 var pendingClasses = $pendingClassesName; | 243 var pendingClasses = $pendingClassesName; |
244 '''/* FinishClasses can be called multiple times. This means that we need to | 244 '''/* FinishClasses can be called multiple times. This means that we need to |
245 clear the pendingClasses property. */''' | 245 clear the pendingClasses property. */''' |
246 $pendingClassesName = {}; | 246 $pendingClassesName = {}; |
247 var finishedClasses = {}; | 247 var finishedClasses = {}; |
248 function finishClass(cls) { | 248 function finishClass(cls) { |
249 '''/* Opera does not support 'getOwnPropertyNames'. Therefore we use | 249 '''/* Opera does not support 'getOwnPropertyNames'. Therefore we use |
(...skipping 414 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
664 emitExtraAccessors(member, defineInstanceMember); | 664 emitExtraAccessors(member, defineInstanceMember); |
665 } | 665 } |
666 | 666 |
667 /** | 667 /** |
668 * Documentation wanted -- johnniwinther | 668 * Documentation wanted -- johnniwinther |
669 * | 669 * |
670 * Invariant: [classElement] must be a declaration element. | 670 * Invariant: [classElement] must be a declaration element. |
671 */ | 671 */ |
672 void emitInstanceMembers(ClassElement classElement, | 672 void emitInstanceMembers(ClassElement classElement, |
673 CodeBuffer buffer, | 673 CodeBuffer buffer, |
674 bool needsLeadingComma) { | 674 {bool emitLeadingComma: true}) { |
ahe
2012/11/22 12:22:05
Why is this a named argument now?
ngeoffray
2012/11/22 13:15:18
It was to make it consistent with the other method
| |
675 assert(invariant(classElement, classElement.isDeclaration)); | 675 assert(invariant(classElement, classElement.isDeclaration)); |
676 bool needsComma = needsLeadingComma; | |
677 void defineInstanceMember(String name, StringBuffer memberBuffer) { | 676 void defineInstanceMember(String name, StringBuffer memberBuffer) { |
678 if (needsComma) buffer.add(','); | 677 if (emitLeadingComma) buffer.add(','); |
679 needsComma = true; | 678 emitLeadingComma = true; |
680 buffer.add('\n'); | 679 buffer.add('\n'); |
681 buffer.add(' $name: '); | 680 buffer.add(' $name: '); |
682 buffer.add(memberBuffer); | 681 buffer.add(memberBuffer); |
683 } | 682 } |
684 | 683 |
685 JavaScriptBackend backend = compiler.backend; | 684 JavaScriptBackend backend = compiler.backend; |
686 if (classElement == backend.objectInterceptorClass) { | 685 if (classElement == backend.objectInterceptorClass) { |
687 emitInterceptorMethods(defineInstanceMember); | 686 emitInterceptorMethods(defineInstanceMember); |
688 // The ObjectInterceptor does not have any instance methods. | 687 // The ObjectInterceptor does not have any instance methods. |
689 return; | 688 return; |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
839 String setterName = | 838 String setterName = |
840 namer.publicSetterName(new SourceString(accessorName)); | 839 namer.publicSetterName(new SourceString(accessorName)); |
841 buffer.add("$setterName: function(v) { " | 840 buffer.add("$setterName: function(v) { " |
842 "this.$fieldName = $helperName(v$additionalArgument); }"); | 841 "this.$fieldName = $helperName(v$additionalArgument); }"); |
843 } | 842 } |
844 | 843 |
845 void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) { | 844 void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) { |
846 /* Do nothing. */ | 845 /* Do nothing. */ |
847 } | 846 } |
848 | 847 |
849 void emitClassFields(ClassElement classElement, CodeBuffer buffer) { | 848 void emitClassFields(ClassElement classElement, |
850 buffer.add('"": ['); | 849 CodeBuffer buffer, |
850 {bool emitEndingComma: true}) { | |
ahe
2012/11/22 12:22:05
I think it would be better to update all the calle
ngeoffray
2012/11/22 13:15:18
Done.
| |
851 bool isFirstField = true; | 851 bool isFirstField = true; |
852 visitClassFields(classElement, (Element member, | 852 visitClassFields(classElement, (Element member, |
853 String name, | 853 String name, |
854 String accessorName, | 854 String accessorName, |
855 bool needsGetter, | 855 bool needsGetter, |
856 bool needsSetter, | 856 bool needsSetter, |
857 bool needsCheckedSetter) { | 857 bool needsCheckedSetter) { |
858 if (isFirstField) { | 858 if (isFirstField) { |
859 buffer.add('"": ['); | |
859 isFirstField = false; | 860 isFirstField = false; |
860 } else { | 861 } else { |
861 buffer.add(", "); | 862 buffer.add(", "); |
862 } | 863 } |
863 buffer.add('"$accessorName'); | 864 buffer.add('"$accessorName'); |
864 int flag = 0; | 865 int flag = 0; |
865 if (name != accessorName) { | 866 if (name != accessorName) { |
866 buffer.add(':$name'); | 867 buffer.add(':$name'); |
867 assert(needsGetter || needsSetter); | 868 assert(needsGetter || needsSetter); |
868 flag = RENAMING_FLAG; | 869 flag = RENAMING_FLAG; |
869 } | 870 } |
870 if (needsGetter && needsSetter) { | 871 if (needsGetter && needsSetter) { |
871 buffer.addCharCode(GETTER_SETTER_CODE + flag); | 872 buffer.addCharCode(GETTER_SETTER_CODE + flag); |
872 } else if (needsGetter) { | 873 } else if (needsGetter) { |
873 buffer.addCharCode(GETTER_CODE + flag); | 874 buffer.addCharCode(GETTER_CODE + flag); |
874 } else if (needsSetter) { | 875 } else if (needsSetter) { |
875 buffer.addCharCode(SETTER_CODE + flag); | 876 buffer.addCharCode(SETTER_CODE + flag); |
876 } | 877 } |
877 buffer.add('"'); | 878 buffer.add('"'); |
878 }); | 879 }); |
879 buffer.add(']'); | 880 if (!isFirstField) { |
881 // There was at least one field. | |
882 buffer.add(']'); | |
883 if (emitEndingComma) { | |
884 buffer.add(', '); | |
885 } | |
886 } | |
880 } | 887 } |
881 | 888 |
882 /** Each getter/setter must be prefixed with a ",\n ". */ | 889 /** Each getter/setter must be prefixed with a ",\n ". */ |
883 void emitClassGettersSetters(ClassElement classElement, CodeBuffer buffer, | 890 void emitClassGettersSetters(ClassElement classElement, CodeBuffer buffer, |
884 {bool omitLeadingComma: false}) { | 891 {bool emitLeadingComma: true}) { |
885 visitClassFields(classElement, (Element member, | 892 visitClassFields(classElement, (Element member, |
886 String name, | 893 String name, |
887 String accessorName, | 894 String accessorName, |
888 bool needsGetter, | 895 bool needsGetter, |
889 bool needsSetter, | 896 bool needsSetter, |
890 bool needsCheckedSetter) { | 897 bool needsCheckedSetter) { |
891 if (needsCheckedSetter) { | 898 if (needsCheckedSetter) { |
892 assert(!needsSetter); | 899 assert(!needsSetter); |
893 if (!omitLeadingComma) { | 900 if (emitLeadingComma) { |
894 buffer.add(",\n "); | 901 buffer.add(",\n "); |
895 } else { | 902 } else { |
896 omitLeadingComma = false; | 903 emitLeadingComma = true; |
897 } | 904 } |
898 generateCheckedSetter(member, name, accessorName, buffer); | 905 generateCheckedSetter(member, name, accessorName, buffer); |
899 } | 906 } |
900 }); | 907 }); |
901 } | 908 } |
902 | 909 |
903 /** | 910 /** |
904 * Documentation wanted -- johnniwinther | 911 * Documentation wanted -- johnniwinther |
905 * | 912 * |
906 * Invariant: [classElement] must be a declaration element. | 913 * Invariant: [classElement] must be a declaration element. |
(...skipping 17 matching lines...) Expand all Loading... | |
924 if (superclass != null) { | 931 if (superclass != null) { |
925 superName = namer.getName(superclass); | 932 superName = namer.getName(superclass); |
926 } | 933 } |
927 | 934 |
928 buffer.add('$classesCollector.$className = {'); | 935 buffer.add('$classesCollector.$className = {'); |
929 emitClassConstructor(classElement, buffer); | 936 emitClassConstructor(classElement, buffer); |
930 emitClassFields(classElement, buffer); | 937 emitClassFields(classElement, buffer); |
931 // TODO(floitsch): the emitInstanceMember should simply always emit a ',\n'. | 938 // TODO(floitsch): the emitInstanceMember should simply always emit a ',\n'. |
932 // That does currently not work because the native classes have a different | 939 // That does currently not work because the native classes have a different |
933 // syntax. | 940 // syntax. |
934 buffer.add(',\n "super": "$superName"'); | 941 buffer.add('\n "super": "$superName"'); |
935 emitClassGettersSetters(classElement, buffer); | 942 emitClassGettersSetters(classElement, buffer); |
936 emitInstanceMembers(classElement, buffer, true); | 943 emitInstanceMembers(classElement, buffer); |
937 buffer.add('\n};\n\n'); | 944 buffer.add('\n};\n\n'); |
938 } | 945 } |
939 | 946 |
940 void emitInterceptorMethods( | 947 void emitInterceptorMethods( |
941 void defineInstanceMember(String name, StringBuffer memberBuffer)) { | 948 void defineInstanceMember(String name, StringBuffer memberBuffer)) { |
942 JavaScriptBackend backend = compiler.backend; | 949 JavaScriptBackend backend = compiler.backend; |
943 // Emit forwarders for the ObjectInterceptor class. We need to | 950 // Emit forwarders for the ObjectInterceptor class. We need to |
944 // emit all possible sends on intercepted methods. | 951 // emit all possible sends on intercepted methods. |
945 for (Selector selector in backend.usedInterceptors) { | 952 for (Selector selector in backend.usedInterceptors) { |
946 String name; | 953 String name; |
(...skipping 787 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1734 const String HOOKS_API_USAGE = """ | 1741 const String HOOKS_API_USAGE = """ |
1735 // Generated by dart2js, the Dart to JavaScript compiler. | 1742 // Generated by dart2js, the Dart to JavaScript compiler. |
1736 // The code supports the following hooks: | 1743 // The code supports the following hooks: |
1737 // dartPrint(message) - if this function is defined it is called | 1744 // dartPrint(message) - if this function is defined it is called |
1738 // instead of the Dart [print] method. | 1745 // instead of the Dart [print] method. |
1739 // dartMainRunner(main) - if this function is defined, the Dart [main] | 1746 // dartMainRunner(main) - if this function is defined, the Dart [main] |
1740 // method will not be invoked directly. | 1747 // method will not be invoked directly. |
1741 // Instead, a closure that will invoke [main] is | 1748 // Instead, a closure that will invoke [main] is |
1742 // passed to [dartMainRunner]. | 1749 // passed to [dartMainRunner]. |
1743 """; | 1750 """; |
OLD | NEW |