Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(447)

Side by Side Diff: sdk/lib/_internal/compiler/implementation/js_backend/emitter.dart

Issue 11415114: Do not generate empty native classes. Fixes issue 6872. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
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
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 """;
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/_internal/compiler/implementation/js_backend/emitter_no_eval.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698