Chromium Code Reviews| 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 |