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

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