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

Side by Side Diff: lib/src/js/printer.dart

Issue 949383003: use js_ast instead of strings to generate JS (Closed) Base URL: git@github.com:dart-lang/dart-dev-compiler.git@master
Patch Set: add redirecting ctor test Created 5 years, 10 months 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
« no previous file with comments | « lib/src/js/nodes.dart ('k') | lib/src/js/template.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_ast; 5 part of js_ast;
6 6
7 7
8 class JavaScriptPrintingOptions { 8 class JavaScriptPrintingOptions {
9 final bool shouldCompressOutput; 9 final bool shouldCompressOutput;
10 final bool minifyLocalVariables; 10 final bool minifyLocalVariables;
11 final bool preferSemicolonToNewlineInMinifiedOutput; 11 final bool preferSemicolonToNewlineInMinifiedOutput;
12 final bool avoidKeywordsInIdentifiers;
12 13
13 JavaScriptPrintingOptions( 14 JavaScriptPrintingOptions(
14 {this.shouldCompressOutput: false, 15 {this.shouldCompressOutput: false,
15 this.minifyLocalVariables: false, 16 this.minifyLocalVariables: false,
16 this.preferSemicolonToNewlineInMinifiedOutput: false}); 17 this.preferSemicolonToNewlineInMinifiedOutput: false,
18 this.avoidKeywordsInIdentifiers: false});
17 } 19 }
18 20
19 21
20 /// An environment in which JavaScript printing is done. Provides emitting of 22 /// An environment in which JavaScript printing is done. Provides emitting of
21 /// text and pre- and post-visit callbacks. 23 /// text and pre- and post-visit callbacks.
22 abstract class JavaScriptPrintingContext { 24 abstract class JavaScriptPrintingContext {
23 /// Signals an error. This should happen only for serious internal errors. 25 /// Signals an error. This should happen only for serious internal errors.
24 void error(String message) { throw message; } 26 void error(String message) { throw message; }
25 27
26 /// Adds [string] to the output. 28 /// Adds [string] to the output.
(...skipping 310 matching lines...) Expand 10 before | Expand all | Expand 10 after
337 visitNestedExpression(loop.leftHandSide, EXPRESSION, 339 visitNestedExpression(loop.leftHandSide, EXPRESSION,
338 newInForInit: true, newAtStatementBegin: false); 340 newInForInit: true, newAtStatementBegin: false);
339 out(" in"); 341 out(" in");
340 pendingSpace = true; 342 pendingSpace = true;
341 visitNestedExpression(loop.object, EXPRESSION, 343 visitNestedExpression(loop.object, EXPRESSION,
342 newInForInit: false, newAtStatementBegin: false); 344 newInForInit: false, newAtStatementBegin: false);
343 out(")"); 345 out(")");
344 blockBody(loop.body, needsSeparation: false, needsNewline: true); 346 blockBody(loop.body, needsSeparation: false, needsNewline: true);
345 } 347 }
346 348
349 visitForOf(ForOf loop) {
350 outIndent("for");
351 spaceOut();
352 out("(");
353 visitNestedExpression(loop.leftHandSide, EXPRESSION,
354 newInForInit: true, newAtStatementBegin: false);
355 out(" of");
356 pendingSpace = true;
357 visitNestedExpression(loop.iterable, EXPRESSION,
358 newInForInit: false, newAtStatementBegin: false);
359 out(")");
360 blockBody(loop.body, needsSeparation: false, needsNewline: true);
361 }
362
347 visitWhile(While loop) { 363 visitWhile(While loop) {
348 outIndent("while"); 364 outIndent("while");
349 spaceOut(); 365 spaceOut();
350 out("("); 366 out("(");
351 visitNestedExpression(loop.condition, EXPRESSION, 367 visitNestedExpression(loop.condition, EXPRESSION,
352 newInForInit: false, newAtStatementBegin: false); 368 newInForInit: false, newAtStatementBegin: false);
353 out(")"); 369 out(")");
354 blockBody(loop.body, needsSeparation: false, needsNewline: true); 370 blockBody(loop.body, needsSeparation: false, needsNewline: true);
355 } 371 }
356 372
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
533 {bool newInForInit, bool newAtStatementBegin}) { 549 {bool newInForInit, bool newAtStatementBegin}) {
534 bool needsParentheses = 550 bool needsParentheses =
535 // a - (b + c). 551 // a - (b + c).
536 (requiredPrecedence != EXPRESSION && 552 (requiredPrecedence != EXPRESSION &&
537 node.precedenceLevel < requiredPrecedence) || 553 node.precedenceLevel < requiredPrecedence) ||
538 // for (a = (x in o); ... ; ... ) { ... } 554 // for (a = (x in o); ... ; ... ) { ... }
539 (newInForInit && node is Binary && node.op == "in") || 555 (newInForInit && node is Binary && node.op == "in") ||
540 // (function() { ... })(). 556 // (function() { ... })().
541 // ({a: 2, b: 3}.toString()). 557 // ({a: 2, b: 3}.toString()).
542 (newAtStatementBegin && (node is NamedFunction || 558 (newAtStatementBegin && (node is NamedFunction ||
543 node is Fun || 559 node is FunctionExpression ||
544 node is ObjectInitializer)); 560 node is ObjectInitializer));
545 if (needsParentheses) { 561 if (needsParentheses) {
546 inForInit = false; 562 inForInit = false;
547 atStatementBegin = false; 563 atStatementBegin = false;
548 out("("); 564 out("(");
549 visit(node); 565 visit(node);
550 out(")"); 566 out(")");
551 } else { 567 } else {
552 inForInit = newInForInit; 568 inForInit = newInForInit;
553 atStatementBegin = newAtStatementBegin; 569 atStatementBegin = newAtStatementBegin;
554 visit(node); 570 visit(node);
555 } 571 }
556 } 572 }
557 573
558 visitVariableDeclarationList(VariableDeclarationList list) { 574 visitVariableDeclarationList(VariableDeclarationList list) {
559 out("var "); 575 out(list.keyword);
576 out(" ");
560 visitCommaSeparated(list.declarations, ASSIGNMENT, 577 visitCommaSeparated(list.declarations, ASSIGNMENT,
561 newInForInit: inForInit, newAtStatementBegin: false); 578 newInForInit: inForInit, newAtStatementBegin: false);
562 } 579 }
563 580
564 visitAssignment(Assignment assignment) { 581 visitAssignment(Assignment assignment) {
565 visitNestedExpression(assignment.leftHandSide, LEFT_HAND_SIDE, 582 visitNestedExpression(assignment.leftHandSide, LEFT_HAND_SIDE,
566 newInForInit: inForInit, 583 newInForInit: inForInit,
567 newAtStatementBegin: atStatementBegin); 584 newAtStatementBegin: atStatementBegin);
568 if (assignment.value != null) { 585 if (assignment.value != null) {
569 spaceOut(); 586 spaceOut();
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
756 } 773 }
757 774
758 visitVariableUse(VariableUse ref) { 775 visitVariableUse(VariableUse ref) {
759 out(localNamer.getName(ref.name)); 776 out(localNamer.getName(ref.name));
760 } 777 }
761 778
762 visitThis(This node) { 779 visitThis(This node) {
763 out("this"); 780 out("this");
764 } 781 }
765 782
783 visitSuper(Super node) {
784 out("super");
785 }
786
766 visitVariableDeclaration(VariableDeclaration decl) { 787 visitVariableDeclaration(VariableDeclaration decl) {
767 out(localNamer.getName(decl.name)); 788 out(localNamer.getName(decl.name));
768 } 789 }
769 790
770 visitParameter(Parameter param) { 791 visitParameter(Parameter param) {
771 out(localNamer.getName(param.name)); 792 out(localNamer.getName(param.name));
772 } 793 }
773 794
774 bool isDigit(int charCode) { 795 bool isDigit(int charCode) {
775 return charCodes.$0 <= charCode && charCode <= charCodes.$9; 796 return charCodes.$0 <= charCode && charCode <= charCodes.$9;
776 } 797 }
777 798
778 bool isValidJavaScriptId(String field) { 799 bool isValidJavaScriptId(String field) {
779 if (field.length < 3) return false; 800 if (field.length < 3) return false;
780 // Ignore the leading and trailing string-delimiter. 801 // Ignore the leading and trailing string-delimiter.
781 for (int i = 1; i < field.length - 1; i++) { 802 for (int i = 1; i < field.length - 1; i++) {
782 // TODO(floitsch): allow more characters. 803 // TODO(floitsch): allow more characters.
783 int charCode = field.codeUnitAt(i); 804 int charCode = field.codeUnitAt(i);
784 if (!(charCodes.$a <= charCode && charCode <= charCodes.$z || 805 if (!(charCodes.$a <= charCode && charCode <= charCodes.$z ||
785 charCodes.$A <= charCode && charCode <= charCodes.$Z || 806 charCodes.$A <= charCode && charCode <= charCodes.$Z ||
786 charCode == charCodes.$$ || 807 charCode == charCodes.$$ ||
787 charCode == charCodes.$_ || 808 charCode == charCodes.$_ ||
788 i != 1 && isDigit(charCode))) { 809 i != 1 && isDigit(charCode))) {
789 return false; 810 return false;
790 } 811 }
791 } 812 }
792 // TODO(floitsch): normally we should also check that the field is not a 813
793 // reserved word. We don't generate fields with reserved word names except 814 if (options.avoidKeywordsInIdentifiers) {
794 // for 'super'. 815 return !_isJsKeyword(field.substring(1, field.length - 1));
795 if (field == '"super"') return false; 816 } else {
796 return true; 817 // TODO(floitsch): normally we should also check that the field is not a
818 // reserved word. We don't generate fields with reserved word names excep t
819 // for 'super'.
820 return field != '"super"';
821 }
822 }
823
824 static bool _isJsKeyword(String keyword) {
825 switch (keyword) {
826 case "break":
827 case "case":
828 case "catch":
829 case "class":
830 case "const":
831 case "continue":
832 case "debugger":
833 case "default":
834 case "delete":
835 case "do":
836 case "else":
837 case "export":
838 case "extends":
839 case "finally":
840 case "for":
841 case "function":
842 case "if":
843 case "import":
844 case "in":
845 case "instanceof":
846 case "let":
847 case "new":
848 case "return":
849 case "static":
850 case "super":
851 case "switch":
852 case "this":
853 case "throw":
854 case "try":
855 case "typeof":
856 case "var":
857 case "void":
858 case "while":
859 case "with":
860 case "yield":
861 return true;
862 }
863 return false;
797 } 864 }
798 865
799 visitAccess(PropertyAccess access) { 866 visitAccess(PropertyAccess access) {
800 visitNestedExpression(access.receiver, CALL, 867 visitNestedExpression(access.receiver, CALL,
801 newInForInit: inForInit, 868 newInForInit: inForInit,
802 newAtStatementBegin: atStatementBegin); 869 newAtStatementBegin: atStatementBegin);
803 Node selector = access.selector; 870 Node selector = access.selector;
804 if (selector is LiteralString) { 871 if (selector is LiteralString) {
805 LiteralString selectorString = selector; 872 LiteralString selectorString = selector;
806 String fieldWithQuotes = selectorString.value; 873 String fieldWithQuotes = selectorString.value;
(...skipping 15 matching lines...) Expand all
822 vars.visitNamedFunction(namedFunction); 889 vars.visitNamedFunction(namedFunction);
823 functionOut(namedFunction.function, namedFunction.name, vars); 890 functionOut(namedFunction.function, namedFunction.name, vars);
824 } 891 }
825 892
826 visitFun(Fun fun) { 893 visitFun(Fun fun) {
827 VarCollector vars = new VarCollector(); 894 VarCollector vars = new VarCollector();
828 vars.visitFun(fun); 895 vars.visitFun(fun);
829 functionOut(fun, null, vars); 896 functionOut(fun, null, vars);
830 } 897 }
831 898
899 visitArrowFun(ArrowFun fun) {
900 VarCollector vars = new VarCollector();
901 vars.visitArrowFun(fun);
902 localNamer.enterScope(vars);
903 out("(");
904 if (fun.params != null) {
905 visitCommaSeparated(fun.params, PRIMARY,
906 newInForInit: false, newAtStatementBegin: false);
907 }
908 out(")");
909 spaceOut();
910 out("=>");
911 if (fun.body is Expression) {
912 spaceOut();
913 fun.body.accept(this);
914 } else {
915 blockBody(fun.body, needsSeparation: false, needsNewline: false);
916 }
917 localNamer.leaveScope();
918 }
919
832 visitLiteralBool(LiteralBool node) { 920 visitLiteralBool(LiteralBool node) {
833 out(node.value ? "true" : "false"); 921 out(node.value ? "true" : "false");
834 } 922 }
835 923
836 visitLiteralString(LiteralString node) { 924 visitLiteralString(LiteralString node) {
837 out(node.value); 925 out(node.value);
838 } 926 }
839 927
840 visitLiteralNumber(LiteralNumber node) { 928 visitLiteralNumber(LiteralNumber node) {
841 int charCode = node.value.codeUnitAt(0); 929 int charCode = node.value.codeUnitAt(0);
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
876 throw "Unreachable"; 964 throw "Unreachable";
877 } 965 }
878 966
879 visitObjectInitializer(ObjectInitializer node) { 967 visitObjectInitializer(ObjectInitializer node) {
880 // Print all the properties on one line until we see a function-valued 968 // Print all the properties on one line until we see a function-valued
881 // property. Ideally, we would use a proper pretty-printer to make the 969 // property. Ideally, we would use a proper pretty-printer to make the
882 // decision based on layout. 970 // decision based on layout.
883 List<Property> properties = node.properties; 971 List<Property> properties = node.properties;
884 out("{"); 972 out("{");
885 indentMore(); 973 indentMore();
974
975 var isOneLiner = !properties.any((p) => p.value is FunctionExpression);
886 for (int i = 0; i < properties.length; i++) { 976 for (int i = 0; i < properties.length; i++) {
887 Expression value = properties[i].value;
888 if (i != 0) { 977 if (i != 0) {
889 out(","); 978 out(",");
890 if (node.isOneLiner) spaceOut(); 979 if (isOneLiner) spaceOut();
891 } 980 }
892 if (!node.isOneLiner) { 981 if (!isOneLiner) {
893 forceLine(); 982 forceLine();
894 indent(); 983 indent();
895 } 984 }
896 visit(properties[i]); 985 visit(properties[i]);
897 } 986 }
898 indentLess(); 987 indentLess();
899 if (!node.isOneLiner && !properties.isEmpty) { 988 if (!isOneLiner) {
900 lineOut(); 989 lineOut();
901 indent(); 990 indent();
902 } 991 }
903 out("}"); 992 out("}");
904 } 993 }
905 994
906 visitProperty(Property node) { 995 visitProperty(Property node) {
907 if (node.name is LiteralString) { 996 propertyNameOut(node.name);
908 LiteralString nameString = node.name;
909 String name = nameString.value;
910 if (isValidJavaScriptId(name)) {
911 out(name.substring(1, name.length - 1));
912 } else {
913 out(name);
914 }
915 } else {
916 assert(node.name is LiteralNumber);
917 LiteralNumber nameNumber = node.name;
918 out(nameNumber.value);
919 }
920 out(":"); 997 out(":");
921 spaceOut(); 998 spaceOut();
922 visitNestedExpression(node.value, ASSIGNMENT, 999 visitNestedExpression(node.value, ASSIGNMENT,
923 newInForInit: false, newAtStatementBegin: false); 1000 newInForInit: false, newAtStatementBegin: false);
924 } 1001 }
925 1002
926 visitRegExpLiteral(RegExpLiteral node) { 1003 visitRegExpLiteral(RegExpLiteral node) {
927 out(node.pattern); 1004 out(node.pattern);
928 } 1005 }
929 1006
1007 visitTemplateString(TemplateString node) {
1008 out('`');
1009 for (var element in node.elements) {
1010 if (element is String) {
1011 out(element);
1012 } else {
1013 out(r'${');
1014 visit(element);
1015 out('}');
1016 }
1017 }
1018 out('`');
1019 }
1020
1021 visitTaggedTemplate(TaggedTemplate node) {
1022 visit(node.tag);
1023 visit(node.template);
1024 }
1025
1026 visitClassDeclaration(ClassDeclaration node) {
1027 indent();
1028 visit(node.classExpr);
1029 lineOut();
1030 }
1031
1032 visitClassExpression(ClassExpression node) {
1033 out('class ');
1034 visit(node.name);
1035 if (node.heritage != null) {
1036 out(' extends ');
1037 visit(node.heritage);
1038 spaceOut();
1039 }
1040 out('{');
1041 lineOut();
1042 indentMore();
1043 for (var method in node.methods) {
1044 indent();
1045 visit(method);
1046 lineOut();
1047 }
1048 indentLess();
1049 indent();
1050 out('}');
1051 }
1052
1053 visitMethod(Method node) {
1054 if (node.isStatic) {
1055 out('static ');
1056 }
1057 if (node.isGetter) {
1058 out('get ');
1059 } else if (node.isSetter) {
1060 out('set ');
1061 }
1062 var vars = new VarCollector();
1063 vars.visitMethod(node);
1064
1065 propertyNameOut(node.name, inMethod: true);
1066
1067 localNamer.enterScope(vars);
1068 out("(");
1069 var fun = node.function;
1070 if (fun.params != null) {
1071 visitCommaSeparated(fun.params, PRIMARY,
1072 newInForInit: false, newAtStatementBegin: false);
1073 }
1074 out(")");
1075 // TODO(jmesserly): async modifiers
1076 if (fun.body.statements.isEmpty) {
1077 spaceOut();
1078 out("{}");
1079 } else {
1080 blockBody(fun.body, needsSeparation: false, needsNewline: false);
1081 }
1082 localNamer.leaveScope();
1083 }
1084
1085 visitPropertyName(PropertyName node) => propertyNameOut(node);
1086
1087 void propertyNameOut(Expression node, {bool inMethod: false}) {
1088 inForInit = false;
1089 atStatementBegin = false;
1090
1091 if (node is LiteralNumber) {
1092 LiteralNumber nameNumber = node;
1093 out(nameNumber.value);
1094 } else {
1095 String quotedName;
1096 if (node is PropertyName) {
1097 quotedName = "'${node.name}'";
1098 } else if (node is LiteralString) {
1099 quotedName = node.value;
1100 }
1101 if (quotedName != null) {
1102 if (isValidJavaScriptId(quotedName)) {
1103 out(quotedName.substring(1, quotedName.length - 1));
1104 } else {
1105 if (inMethod) out("[");
1106 out(quotedName);
1107 if (inMethod) out("]");
1108 }
1109 } else {
1110 // ComputedPropertyName
1111 out("[");
1112 visit(node);
1113 out("]");
1114 }
1115 }
1116 }
1117
930 visitLiteralExpression(LiteralExpression node) { 1118 visitLiteralExpression(LiteralExpression node) {
931 String template = node.template; 1119 String template = node.template;
932 List<Expression> inputs = node.inputs; 1120 List<Expression> inputs = node.inputs;
933 1121
934 List<String> parts = template.split('#'); 1122 List<String> parts = template.split('#');
935 int inputsLength = inputs == null ? 0 : inputs.length; 1123 int inputsLength = inputs == null ? 0 : inputs.length;
936 if (parts.length != inputsLength + 1) { 1124 if (parts.length != inputsLength + 1) {
937 context.error('Wrong number of arguments for JS: $template'); 1125 context.error('Wrong number of arguments for JS: $template');
938 } 1126 }
939 // Code that uses JS must take care of operator precedences, and 1127 // Code that uses JS must take care of operator precedences, and
(...skipping 18 matching lines...) Expand all
958 1146
959 visitInterpolatedLiteral(InterpolatedLiteral node) => 1147 visitInterpolatedLiteral(InterpolatedLiteral node) =>
960 visitInterpolatedNode(node); 1148 visitInterpolatedNode(node);
961 1149
962 visitInterpolatedParameter(InterpolatedParameter node) => 1150 visitInterpolatedParameter(InterpolatedParameter node) =>
963 visitInterpolatedNode(node); 1151 visitInterpolatedNode(node);
964 1152
965 visitInterpolatedSelector(InterpolatedSelector node) => 1153 visitInterpolatedSelector(InterpolatedSelector node) =>
966 visitInterpolatedNode(node); 1154 visitInterpolatedNode(node);
967 1155
1156 visitInterpolatedPropertyName(InterpolatedPropertyName node) =>
1157 visitInterpolatedNode(node);
1158
1159 visitInterpolatedMethod(InterpolatedMethod node) =>
1160 visitInterpolatedNode(node);
1161
1162 visitInterpolatedVariableDeclaration(InterpolatedVariableDeclaration node) =>
1163 visitInterpolatedNode(node);
1164
968 visitInterpolatedStatement(InterpolatedStatement node) { 1165 visitInterpolatedStatement(InterpolatedStatement node) {
969 outLn('#${node.nameOrPosition}'); 1166 outLn('#${node.nameOrPosition}');
970 } 1167 }
971 1168
972 void visitComment(Comment node) { 1169 void visitComment(Comment node) {
973 if (shouldCompressOutput) return; 1170 if (shouldCompressOutput) return;
974 String comment = node.comment.trim(); 1171 String comment = node.comment.trim();
975 if (comment.isEmpty) return; 1172 if (comment.isEmpty) return;
976 for (var line in comment.split('\n')) { 1173 for (var line in comment.split('\n')) {
977 if (comment.startsWith('//')) { 1174 if (comment.startsWith('//')) {
978 outIndentLn(line.trim()); 1175 outIndentLn(line.trim());
979 } else { 1176 } else {
980 outIndentLn('// ${line.trim()}'); 1177 outIndentLn('// ${line.trim()}');
981 } 1178 }
982 } 1179 }
983 } 1180 }
984 1181
1182 void visitCommentExpression(CommentExpression node) {
1183 if (shouldCompressOutput) return;
1184 String comment = node.comment.trim();
1185 if (comment.isEmpty) return;
1186 if (comment.startsWith('/*')) {
1187 out(comment);
1188 } else {
1189 out('/* $comment */');
1190 }
1191 visit(node.expression);
1192 }
1193
985 void visitAwait(Await node) { 1194 void visitAwait(Await node) {
986 out("await "); 1195 out("await ");
987 visit(node.expression); 1196 visit(node.expression);
988 } 1197 }
989 } 1198 }
990 1199
991 1200
992 class OrderedSet<T> { 1201 class OrderedSet<T> {
993 final Set<T> set; 1202 final Set<T> set;
994 final List<T> list; 1203 final List<T> list;
(...skipping 19 matching lines...) Expand all
1014 final OrderedSet<String> vars; 1223 final OrderedSet<String> vars;
1015 final OrderedSet<String> params; 1224 final OrderedSet<String> params;
1016 1225
1017 VarCollector() : nested = false, 1226 VarCollector() : nested = false,
1018 vars = new OrderedSet<String>(), 1227 vars = new OrderedSet<String>(),
1019 params = new OrderedSet<String>(); 1228 params = new OrderedSet<String>();
1020 1229
1021 void forEachVar(void fn(String v)) => vars.forEach(fn); 1230 void forEachVar(void fn(String v)) => vars.forEach(fn);
1022 void forEachParam(void fn(String p)) => params.forEach(fn); 1231 void forEachParam(void fn(String p)) => params.forEach(fn);
1023 1232
1024 void collectVarsInFunction(Fun fun) { 1233 void collectVarsInFunction(FunctionExpression fun) {
1025 if (!nested) { 1234 if (!nested) {
1026 nested = true; 1235 nested = true;
1027 if (fun.params != null) { 1236 if (fun.params != null) {
1028 for (int i = 0; i < fun.params.length; i++) { 1237 for (int i = 0; i < fun.params.length; i++) {
1029 params.add(fun.params[i].name); 1238 params.add(fun.params[i].name);
1030 } 1239 }
1031 } 1240 }
1032 visitBlock(fun.body); 1241 fun.body.accept(this);
1033 nested = false; 1242 nested = false;
1034 } 1243 }
1035 } 1244 }
1036 1245
1037 void visitFunctionDeclaration(FunctionDeclaration declaration) { 1246 void visitFunctionDeclaration(FunctionDeclaration declaration) {
1038 // Note that we don't bother collecting the name of the function. 1247 // Note that we don't bother collecting the name of the function.
1039 collectVarsInFunction(declaration.function); 1248 collectVarsInFunction(declaration.function);
1040 } 1249 }
1041 1250
1042 void visitNamedFunction(NamedFunction namedFunction) { 1251 void visitNamedFunction(NamedFunction namedFunction) {
1043 // Note that we don't bother collecting the name of the function. 1252 // Note that we don't bother collecting the name of the function.
1044 collectVarsInFunction(namedFunction.function); 1253 collectVarsInFunction(namedFunction.function);
1045 } 1254 }
1046 1255
1256 void visitMethod(Method declaration) {
1257 // Note that we don't bother collecting the name of the function.
1258 collectVarsInFunction(declaration.function);
1259 }
1260
1047 void visitFun(Fun fun) { 1261 void visitFun(Fun fun) {
1048 collectVarsInFunction(fun); 1262 collectVarsInFunction(fun);
1049 } 1263 }
1050 1264
1265 void visitArrowFun(ArrowFun fun) {
1266 collectVarsInFunction(fun);
1267 }
1268
1051 void visitThis(This node) {} 1269 void visitThis(This node) {}
1052 1270
1053 void visitVariableDeclaration(VariableDeclaration decl) { 1271 void visitVariableDeclaration(VariableDeclaration decl) {
1054 if (decl.allowRename) vars.add(decl.name); 1272 if (decl.allowRename) vars.add(decl.name);
1055 } 1273 }
1056 } 1274 }
1057 1275
1058 1276
1059 /** 1277 /**
1060 * Returns true, if the given node must be wrapped into braces when used 1278 * Returns true, if the given node must be wrapped into braces when used
(...skipping 13 matching lines...) Expand all
1074 1292
1075 bool visitBlock(Block node) => false; 1293 bool visitBlock(Block node) => false;
1076 bool visitExpressionStatement(ExpressionStatement node) => false; 1294 bool visitExpressionStatement(ExpressionStatement node) => false;
1077 bool visitEmptyStatement(EmptyStatement node) => false; 1295 bool visitEmptyStatement(EmptyStatement node) => false;
1078 bool visitIf(If node) { 1296 bool visitIf(If node) {
1079 if (!node.hasElse) return true; 1297 if (!node.hasElse) return true;
1080 return node.otherwise.accept(this); 1298 return node.otherwise.accept(this);
1081 } 1299 }
1082 bool visitFor(For node) => node.body.accept(this); 1300 bool visitFor(For node) => node.body.accept(this);
1083 bool visitForIn(ForIn node) => node.body.accept(this); 1301 bool visitForIn(ForIn node) => node.body.accept(this);
1302 bool visitForOf(ForOf node) => node.body.accept(this);
1084 bool visitWhile(While node) => node.body.accept(this); 1303 bool visitWhile(While node) => node.body.accept(this);
1085 bool visitDo(Do node) => false; 1304 bool visitDo(Do node) => false;
1086 bool visitContinue(Continue node) => false; 1305 bool visitContinue(Continue node) => false;
1087 bool visitBreak(Break node) => false; 1306 bool visitBreak(Break node) => false;
1088 bool visitReturn(Return node) => false; 1307 bool visitReturn(Return node) => false;
1089 bool visitThrow(Throw node) => false; 1308 bool visitThrow(Throw node) => false;
1090 bool visitTry(Try node) { 1309 bool visitTry(Try node) {
1091 if (node.finallyPart != null) { 1310 if (node.finallyPart != null) {
1092 return node.finallyPart.accept(this); 1311 return node.finallyPart.accept(this);
1093 } else { 1312 } else {
1094 return node.catchPart.accept(this); 1313 return node.catchPart.accept(this);
1095 } 1314 }
1096 } 1315 }
1097 bool visitCatch(Catch node) => node.body.accept(this); 1316 bool visitCatch(Catch node) => node.body.accept(this);
1098 bool visitSwitch(Switch node) => false; 1317 bool visitSwitch(Switch node) => false;
1099 bool visitCase(Case node) => false; 1318 bool visitCase(Case node) => false;
1100 bool visitDefault(Default node) => false; 1319 bool visitDefault(Default node) => false;
1101 bool visitFunctionDeclaration(FunctionDeclaration node) => false; 1320 bool visitFunctionDeclaration(FunctionDeclaration node) => false;
1102 bool visitLabeledStatement(LabeledStatement node) 1321 bool visitLabeledStatement(LabeledStatement node)
1103 => node.body.accept(this); 1322 => node.body.accept(this);
1104 bool visitLiteralStatement(LiteralStatement node) => true; 1323 bool visitLiteralStatement(LiteralStatement node) => true;
1324 bool visitClassDeclaration(ClassDeclaration) => false;
1105 1325
1106 bool visitExpression(Expression node) => false; 1326 bool visitExpression(Expression node) => false;
1107 } 1327 }
1108 1328
1109 1329
1110 abstract class LocalNamer { 1330 abstract class LocalNamer {
1111 String getName(String oldName); 1331 String getName(String oldName);
1112 String declareVariable(String oldName); 1332 String declareVariable(String oldName);
1113 String declareParameter(String oldName); 1333 String declareParameter(String oldName);
1114 void enterScope(VarCollector vars); 1334 void enterScope(VarCollector vars);
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
1238 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS)); 1458 codes.add(nthLetter((n ~/ nameSpaceSize) % LETTERS));
1239 } 1459 }
1240 codes.add(charCodes.$0 + digit); 1460 codes.add(charCodes.$0 + digit);
1241 newName = new String.fromCharCodes(codes); 1461 newName = new String.fromCharCodes(codes);
1242 } 1462 }
1243 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName)); 1463 assert(new RegExp(r'[a-zA-Z][a-zA-Z0-9]*').hasMatch(newName));
1244 maps.last[oldName] = newName; 1464 maps.last[oldName] = newName;
1245 return newName; 1465 return newName;
1246 } 1466 }
1247 } 1467 }
OLDNEW
« no previous file with comments | « lib/src/js/nodes.dart ('k') | lib/src/js/template.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698