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

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 219 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 // constructor. 230 // constructor.
231 // For engines where we have access to the '__proto__' we can manipulate 231 // For engines where we have access to the '__proto__' we can manipulate
232 // the object literal directly. For other engines we have to create a new 232 // the object literal directly. For other engines we have to create a new
233 // object and copy over the members. 233 // object and copy over the members.
234 return ''' 234 return '''
235 function(collectedClasses) { 235 function(collectedClasses) {
236 var hasOwnProperty = Object.prototype.hasOwnProperty; 236 var hasOwnProperty = Object.prototype.hasOwnProperty;
237 for (var cls in collectedClasses) { 237 for (var cls in collectedClasses) {
238 if (hasOwnProperty.call(collectedClasses, cls)) { 238 if (hasOwnProperty.call(collectedClasses, cls)) {
239 var desc = collectedClasses[cls]; 239 var desc = collectedClasses[cls];
240 $isolatePropertiesName[cls] = $defineClassName(cls, desc[''], desc); 240 '''/* If the class does not have any declared fields (in the ''
241 property of the description), then provide an empty list of fields. */'''
242 $isolatePropertiesName[cls] = $defineClassName(cls, desc[''] || [], desc);
241 if (desc['super'] !== "") $pendingClassesName[cls] = desc['super']; 243 if (desc['super'] !== "") $pendingClassesName[cls] = desc['super'];
242 } 244 }
243 } 245 }
244 var pendingClasses = $pendingClassesName; 246 var pendingClasses = $pendingClassesName;
245 '''/* FinishClasses can be called multiple times. This means that we need to 247 '''/* FinishClasses can be called multiple times. This means that we need to
246 clear the pendingClasses property. */''' 248 clear the pendingClasses property. */'''
247 $pendingClassesName = {}; 249 $pendingClassesName = {};
248 var finishedClasses = {}; 250 var finishedClasses = {};
249 function finishClass(cls) { 251 function finishClass(cls) {
250 '''/* Opera does not support 'getOwnPropertyNames'. Therefore we use 252 '''/* Opera does not support 'getOwnPropertyNames'. Therefore we use
(...skipping 420 matching lines...) Expand 10 before | Expand all | Expand 10 after
671 emitExtraAccessors(member, defineInstanceMember); 673 emitExtraAccessors(member, defineInstanceMember);
672 } 674 }
673 675
674 /** 676 /**
675 * Documentation wanted -- johnniwinther 677 * Documentation wanted -- johnniwinther
676 * 678 *
677 * Invariant: [classElement] must be a declaration element. 679 * Invariant: [classElement] must be a declaration element.
678 */ 680 */
679 void emitInstanceMembers(ClassElement classElement, 681 void emitInstanceMembers(ClassElement classElement,
680 CodeBuffer buffer, 682 CodeBuffer buffer,
681 bool needsLeadingComma) { 683 bool emitLeadingComma) {
682 assert(invariant(classElement, classElement.isDeclaration)); 684 assert(invariant(classElement, classElement.isDeclaration));
683 bool needsComma = needsLeadingComma;
684 void defineInstanceMember(String name, StringBuffer memberBuffer) { 685 void defineInstanceMember(String name, StringBuffer memberBuffer) {
685 if (needsComma) buffer.add(','); 686 if (emitLeadingComma) buffer.add(',');
686 needsComma = true; 687 emitLeadingComma = true;
687 buffer.add('\n'); 688 buffer.add('\n');
688 buffer.add(' $name: '); 689 buffer.add(' $name: ');
689 buffer.add(memberBuffer); 690 buffer.add(memberBuffer);
690 } 691 }
691 692
692 JavaScriptBackend backend = compiler.backend; 693 JavaScriptBackend backend = compiler.backend;
693 if (classElement == backend.objectInterceptorClass) { 694 if (classElement == backend.objectInterceptorClass) {
694 emitInterceptorMethods(defineInstanceMember); 695 emitInterceptorMethods(defineInstanceMember);
695 // The ObjectInterceptor does not have any instance methods. 696 // The ObjectInterceptor does not have any instance methods.
696 return; 697 return;
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
846 String setterName = 847 String setterName =
847 namer.publicSetterName(new SourceString(accessorName)); 848 namer.publicSetterName(new SourceString(accessorName));
848 buffer.add("$setterName: function(v) { " 849 buffer.add("$setterName: function(v) { "
849 "this.$fieldName = $helperName(v$additionalArgument); }"); 850 "this.$fieldName = $helperName(v$additionalArgument); }");
850 } 851 }
851 852
852 void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) { 853 void emitClassConstructor(ClassElement classElement, CodeBuffer buffer) {
853 /* Do nothing. */ 854 /* Do nothing. */
854 } 855 }
855 856
856 void emitClassFields(ClassElement classElement, CodeBuffer buffer) { 857 void emitClassFields(ClassElement classElement,
857 buffer.add('"": ['); 858 CodeBuffer buffer,
859 bool emitEndingComma) {
858 bool isFirstField = true; 860 bool isFirstField = true;
859 visitClassFields(classElement, (Element member, 861 visitClassFields(classElement, (Element member,
860 String name, 862 String name,
861 String accessorName, 863 String accessorName,
862 bool needsGetter, 864 bool needsGetter,
863 bool needsSetter, 865 bool needsSetter,
864 bool needsCheckedSetter) { 866 bool needsCheckedSetter) {
865 if (isFirstField) { 867 if (isFirstField) {
868 buffer.add('"": [');
866 isFirstField = false; 869 isFirstField = false;
867 } else { 870 } else {
868 buffer.add(", "); 871 buffer.add(", ");
869 } 872 }
870 buffer.add('"$accessorName'); 873 buffer.add('"$accessorName');
871 int flag = 0; 874 int flag = 0;
872 if (name != accessorName) { 875 if (name != accessorName) {
873 buffer.add(':$name'); 876 buffer.add(':$name');
874 assert(needsGetter || needsSetter); 877 assert(needsGetter || needsSetter);
875 flag = RENAMING_FLAG; 878 flag = RENAMING_FLAG;
876 } 879 }
877 if (needsGetter && needsSetter) { 880 if (needsGetter && needsSetter) {
878 buffer.addCharCode(GETTER_SETTER_CODE + flag); 881 buffer.addCharCode(GETTER_SETTER_CODE + flag);
879 } else if (needsGetter) { 882 } else if (needsGetter) {
880 buffer.addCharCode(GETTER_CODE + flag); 883 buffer.addCharCode(GETTER_CODE + flag);
881 } else if (needsSetter) { 884 } else if (needsSetter) {
882 buffer.addCharCode(SETTER_CODE + flag); 885 buffer.addCharCode(SETTER_CODE + flag);
883 } 886 }
884 buffer.add('"'); 887 buffer.add('"');
885 }); 888 });
886 buffer.add(']'); 889 if (!isFirstField) {
890 // There was at least one field.
891 buffer.add(']');
892 if (emitEndingComma) {
893 buffer.add(', ');
894 }
895 }
887 } 896 }
888 897
889 /** Each getter/setter must be prefixed with a ",\n ". */ 898 /** Each getter/setter must be prefixed with a ",\n ". */
890 void emitClassGettersSetters(ClassElement classElement, CodeBuffer buffer, 899 void emitClassGettersSetters(ClassElement classElement,
891 {bool omitLeadingComma: false}) { 900 CodeBuffer buffer,
901 bool emitLeadingComma) {
892 visitClassFields(classElement, (Element member, 902 visitClassFields(classElement, (Element member,
893 String name, 903 String name,
894 String accessorName, 904 String accessorName,
895 bool needsGetter, 905 bool needsGetter,
896 bool needsSetter, 906 bool needsSetter,
897 bool needsCheckedSetter) { 907 bool needsCheckedSetter) {
898 if (needsCheckedSetter) { 908 if (needsCheckedSetter) {
899 assert(!needsSetter); 909 assert(!needsSetter);
900 if (!omitLeadingComma) { 910 if (emitLeadingComma) {
901 buffer.add(",\n "); 911 buffer.add(",\n ");
902 } else { 912 } else {
903 omitLeadingComma = false; 913 emitLeadingComma = true;
904 } 914 }
905 generateCheckedSetter(member, name, accessorName, buffer); 915 generateCheckedSetter(member, name, accessorName, buffer);
906 } 916 }
907 }); 917 });
908 } 918 }
909 919
910 /** 920 /**
911 * Documentation wanted -- johnniwinther 921 * Documentation wanted -- johnniwinther
912 * 922 *
913 * Invariant: [classElement] must be a declaration element. 923 * Invariant: [classElement] must be a declaration element.
(...skipping 13 matching lines...) Expand all
927 needsDefineClass = true; 937 needsDefineClass = true;
928 String className = namer.getName(classElement); 938 String className = namer.getName(classElement);
929 ClassElement superclass = classElement.superclass; 939 ClassElement superclass = classElement.superclass;
930 String superName = ""; 940 String superName = "";
931 if (superclass != null) { 941 if (superclass != null) {
932 superName = namer.getName(superclass); 942 superName = namer.getName(superclass);
933 } 943 }
934 944
935 buffer.add('$classesCollector.$className = {'); 945 buffer.add('$classesCollector.$className = {');
936 emitClassConstructor(classElement, buffer); 946 emitClassConstructor(classElement, buffer);
937 emitClassFields(classElement, buffer); 947 emitClassFields(classElement, buffer, true);
938 // TODO(floitsch): the emitInstanceMember should simply always emit a ',\n'. 948 // TODO(floitsch): the emitInstanceMember should simply always emit a ',\n'.
939 // That does currently not work because the native classes have a different 949 // That does currently not work because the native classes have a different
940 // syntax. 950 // syntax.
941 buffer.add(',\n "super": "$superName"'); 951 buffer.add('\n "super": "$superName"');
942 emitClassGettersSetters(classElement, buffer); 952 emitClassGettersSetters(classElement, buffer, true);
943 emitInstanceMembers(classElement, buffer, true); 953 emitInstanceMembers(classElement, buffer, true);
944 buffer.add('\n};\n\n'); 954 buffer.add('\n};\n\n');
945 } 955 }
946 956
947 void emitInterceptorMethods( 957 void emitInterceptorMethods(
948 void defineInstanceMember(String name, StringBuffer memberBuffer)) { 958 void defineInstanceMember(String name, StringBuffer memberBuffer)) {
949 JavaScriptBackend backend = compiler.backend; 959 JavaScriptBackend backend = compiler.backend;
950 // Emit forwarders for the ObjectInterceptor class. We need to 960 // Emit forwarders for the ObjectInterceptor class. We need to
951 // emit all possible sends on intercepted methods. 961 // emit all possible sends on intercepted methods.
952 for (Selector selector in backend.usedInterceptors) { 962 for (Selector selector in backend.usedInterceptors) {
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
1746 const String HOOKS_API_USAGE = """ 1756 const String HOOKS_API_USAGE = """
1747 // Generated by dart2js, the Dart to JavaScript compiler. 1757 // Generated by dart2js, the Dart to JavaScript compiler.
1748 // The code supports the following hooks: 1758 // The code supports the following hooks:
1749 // dartPrint(message) - if this function is defined it is called 1759 // dartPrint(message) - if this function is defined it is called
1750 // instead of the Dart [print] method. 1760 // instead of the Dart [print] method.
1751 // dartMainRunner(main) - if this function is defined, the Dart [main] 1761 // dartMainRunner(main) - if this function is defined, the Dart [main]
1752 // method will not be invoked directly. 1762 // method will not be invoked directly.
1753 // Instead, a closure that will invoke [main] is 1763 // Instead, a closure that will invoke [main] is
1754 // passed to [dartMainRunner]. 1764 // passed to [dartMainRunner].
1755 """; 1765 """;
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