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

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

Issue 1676463002: Type annotations instead of closure comments. (Closed) Base URL: git@github.com:dart-lang/dev_compiler.git@master
Patch Set: Created 4 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
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 printTypes;
Jennifer Messerly 2016/02/09 01:21:33 this sounds like a method name. Maybe "shouldPrint
ochafik 2016/02/10 18:12:45 Thanks, went for shouldEmitTypes
12 final bool allowSingleLineIfStatements; 13 final bool allowSingleLineIfStatements;
13 14
14 /// True to allow keywords in properties, such as `obj.var` or `obj.function` 15 /// True to allow keywords in properties, such as `obj.var` or `obj.function`
15 /// Modern JS engines support this. 16 /// Modern JS engines support this.
16 final bool allowKeywordsInProperties; 17 final bool allowKeywordsInProperties;
17 18
18 JavaScriptPrintingOptions( 19 JavaScriptPrintingOptions(
19 {this.shouldCompressOutput: false, 20 {this.shouldCompressOutput: false,
20 this.minifyLocalVariables: false, 21 this.minifyLocalVariables: false,
21 this.preferSemicolonToNewlineInMinifiedOutput: false, 22 this.preferSemicolonToNewlineInMinifiedOutput: false,
23 this.printTypes: false,
22 this.allowKeywordsInProperties: false, 24 this.allowKeywordsInProperties: false,
23 this.allowSingleLineIfStatements: false}); 25 this.allowSingleLineIfStatements: false});
24 } 26 }
25 27
26 28
27 /// An environment in which JavaScript printing is done. Provides emitting of 29 /// An environment in which JavaScript printing is done. Provides emitting of
28 /// text and pre- and post-visit callbacks. 30 /// text and pre- and post-visit callbacks.
29 abstract class JavaScriptPrintingContext { 31 abstract class JavaScriptPrintingContext {
30 /// Signals an error. This should happen only for serious internal errors. 32 /// Signals an error. This should happen only for serious internal errors.
31 void error(String message) { throw message; } 33 void error(String message) { throw message; }
(...skipping 13 matching lines...) Expand all
45 final StringBuffer buffer = new StringBuffer(); 47 final StringBuffer buffer = new StringBuffer();
46 48
47 void emit(String string) { 49 void emit(String string) {
48 buffer.write(string); 50 buffer.write(string);
49 } 51 }
50 52
51 String getText() => buffer.toString(); 53 String getText() => buffer.toString();
52 } 54 }
53 55
54 56
55 class Printer implements NodeVisitor { 57 class Printer extends TypeScriptTypePrinter implements NodeVisitor {
Jennifer Messerly 2016/02/09 01:21:34 Hmmm. I haven't seen the other class yet, but this
ochafik 2016/02/10 18:12:45 Good point, left a TODO for when/if we drop Closur
56 final JavaScriptPrintingOptions options; 58 final JavaScriptPrintingOptions options;
57 final JavaScriptPrintingContext context; 59 final JavaScriptPrintingContext context;
58 final bool shouldCompressOutput; 60 final bool shouldCompressOutput;
59 final DanglingElseVisitor danglingElseVisitor; 61 final DanglingElseVisitor danglingElseVisitor;
60 final LocalNamer localNamer; 62 final LocalNamer localNamer;
61 63
62 bool inForInit = false; 64 bool inForInit = false;
63 bool atStatementBegin = false; 65 bool atStatementBegin = false;
64 bool inNewTarget = false; 66 bool inNewTarget = false;
65 bool pendingSemicolon = false; 67 bool pendingSemicolon = false;
(...skipping 468 matching lines...) Expand 10 before | Expand all | Expand 10 after
534 void functionOut(Fun fun, Node name) { 536 void functionOut(Fun fun, Node name) {
535 out("function"); 537 out("function");
536 if (fun.isGenerator) out("*"); 538 if (fun.isGenerator) out("*");
537 if (name != null) { 539 if (name != null) {
538 out(" "); 540 out(" ");
539 // Name must be a [Decl]. Therefore only test for primary expressions. 541 // Name must be a [Decl]. Therefore only test for primary expressions.
540 visitNestedExpression(name, PRIMARY, 542 visitNestedExpression(name, PRIMARY,
541 newInForInit: false, newAtStatementBegin: false); 543 newInForInit: false, newAtStatementBegin: false);
542 } 544 }
543 localNamer.enterScope(fun); 545 localNamer.enterScope(fun);
546 outTypeArgs(fun.typeArgs);
544 out("("); 547 out("(");
545 if (fun.params != null) { 548 if (fun.params != null) {
546 visitCommaSeparated(fun.params, PRIMARY, 549 visitCommaSeparated(fun.params, PRIMARY,
547 newInForInit: false, newAtStatementBegin: false); 550 newInForInit: false, newAtStatementBegin: false);
548 } 551 }
549 out(")"); 552 out(")");
553 outTypeAnnotation(fun.returnType);
550 switch (fun.asyncModifier) { 554 switch (fun.asyncModifier) {
551 case const AsyncModifier.sync(): 555 case const AsyncModifier.sync():
552 break; 556 break;
553 case const AsyncModifier.async(): 557 case const AsyncModifier.async():
554 out(' async'); 558 out(' async');
555 break; 559 break;
556 case const AsyncModifier.syncStar(): 560 case const AsyncModifier.syncStar():
557 out(' sync*'); 561 out(' sync*');
558 break; 562 break;
559 case const AsyncModifier.asyncStar(): 563 case const AsyncModifier.asyncStar():
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
594 out(")"); 598 out(")");
595 } else { 599 } else {
596 inForInit = newInForInit; 600 inForInit = newInForInit;
597 atStatementBegin = newAtStatementBegin; 601 atStatementBegin = newAtStatementBegin;
598 visit(node); 602 visit(node);
599 } 603 }
600 } 604 }
601 605
602 visitVariableDeclarationList(VariableDeclarationList list) { 606 visitVariableDeclarationList(VariableDeclarationList list) {
603 outClosureAnnotation(list); 607 outClosureAnnotation(list);
604 out(list.keyword); 608 // Note: keyword can be null for non-static field declarations.
605 out(" "); 609 if (list.keyword != null) {
610 out(list.keyword);
611 out(" ");
612 }
606 visitCommaSeparated(list.declarations, ASSIGNMENT, 613 visitCommaSeparated(list.declarations, ASSIGNMENT,
607 newInForInit: inForInit, newAtStatementBegin: false); 614 newInForInit: inForInit, newAtStatementBegin: false);
608 } 615 }
609 616
610 visitArrayBindingPattern(ArrayBindingPattern node) { 617 visitArrayBindingPattern(ArrayBindingPattern node) {
611 out("["); 618 out("[");
612 visitCommaSeparated(node.variables, EXPRESSION, 619 visitCommaSeparated(node.variables, EXPRESSION,
613 newInForInit: false, newAtStatementBegin: false); 620 newInForInit: false, newAtStatementBegin: false);
614 out("]"); 621 out("]");
615 } 622 }
616 visitObjectBindingPattern(ObjectBindingPattern node) { 623 visitObjectBindingPattern(ObjectBindingPattern node) {
617 out("{"); 624 out("{");
618 visitCommaSeparated(node.variables, EXPRESSION, 625 visitCommaSeparated(node.variables, EXPRESSION,
619 newInForInit: false, newAtStatementBegin: false); 626 newInForInit: false, newAtStatementBegin: false);
620 out("}"); 627 out("}");
621 } 628 }
622 629
623 visitDestructuredVariable(DestructuredVariable node) { 630 visitDestructuredVariable(DestructuredVariable node) {
624 var hasName = node.name != null; 631 var hasName = node.name != null;
625 if (hasName) visit(node.name); 632 if (hasName) visit(node.name);
626 if (node.structure != null) { 633 if (node.structure != null) {
627 if (hasName) { 634 if (hasName) {
628 out(":"); 635 out(":");
629 spaceOut(); 636 spaceOut();
630 } 637 }
631 visit(node.structure); 638 visit(node.structure);
632 } 639 }
640 outTypeAnnotation(node.type);
633 if (node.defaultValue != null) { 641 if (node.defaultValue != null) {
634 spaceOut(); 642 spaceOut();
635 out("="); 643 out("=");
636 spaceOut(); 644 spaceOut();
637 visitNestedExpression(node.defaultValue, EXPRESSION, 645 visitNestedExpression(node.defaultValue, EXPRESSION,
638 newInForInit: false, newAtStatementBegin: false); 646 newInForInit: false, newAtStatementBegin: false);
639 } 647 }
640 } 648 }
641 649
642 visitAssignment(Assignment assignment) { 650 visitAssignment(Assignment assignment) {
(...skipping 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
849 visitThis(This node) { 857 visitThis(This node) {
850 out("this"); 858 out("this");
851 } 859 }
852 860
853 visitSuper(Super node) { 861 visitSuper(Super node) {
854 out("super"); 862 out("super");
855 } 863 }
856 864
857 visitIdentifier(Identifier node) { 865 visitIdentifier(Identifier node) {
858 out(localNamer.getName(node)); 866 out(localNamer.getName(node));
867 outTypeAnnotation(node.type);
859 } 868 }
860 869
861 visitRestParameter(RestParameter node) { 870 visitRestParameter(RestParameter node) {
862 out('...'); 871 out('...');
863 visitIdentifier(node.parameter); 872 visitIdentifier(node.parameter);
864 } 873 }
865 874
866 bool isDigit(int charCode) { 875 bool isDigit(int charCode) {
867 return charCodes.$0 <= charCode && charCode <= charCodes.$9; 876 return charCodes.$0 <= charCode && charCode <= charCodes.$9;
868 } 877 }
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
914 visitNamedFunction(NamedFunction namedFunction) { 923 visitNamedFunction(NamedFunction namedFunction) {
915 functionOut(namedFunction.function, namedFunction.name); 924 functionOut(namedFunction.function, namedFunction.name);
916 } 925 }
917 926
918 visitFun(Fun fun) { 927 visitFun(Fun fun) {
919 functionOut(fun, null); 928 functionOut(fun, null);
920 } 929 }
921 930
922 visitArrowFun(ArrowFun fun) { 931 visitArrowFun(ArrowFun fun) {
923 localNamer.enterScope(fun); 932 localNamer.enterScope(fun);
924 if (fun.params.length == 1) { 933 if (fun.params.length == 1 &&
934 (fun.params.single.type == null || !options.printTypes)) {
925 visitNestedExpression(fun.params.single, SPREAD, 935 visitNestedExpression(fun.params.single, SPREAD,
926 newInForInit: false, newAtStatementBegin: false); 936 newInForInit: false, newAtStatementBegin: false);
927 } else { 937 } else {
928 out("("); 938 out("(");
929 visitCommaSeparated(fun.params, SPREAD, 939 visitCommaSeparated(fun.params, SPREAD,
930 newInForInit: false, newAtStatementBegin: false); 940 newInForInit: false, newAtStatementBegin: false);
931 out(")"); 941 out(")");
932 } 942 }
943 outTypeAnnotation(fun.returnType);
933 spaceOut(); 944 spaceOut();
934 out("=>"); 945 out("=>");
935 if (fun.body is Expression) { 946 if (fun.body is Expression) {
936 spaceOut(); 947 spaceOut();
937 // Object initializers require parenthesis to disambiguate 948 // Object initializers require parenthesis to disambiguate
938 // AssignmentExpression from FunctionBody. See: 949 // AssignmentExpression from FunctionBody. See:
939 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-arrow-functio n-definitions 950 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-arrow-functio n-definitions
940 var needsParen = fun.body is ObjectInitializer; 951 var needsParen = fun.body is ObjectInitializer;
941 if (needsParen) out("("); 952 if (needsParen) out("(");
942 visitNestedExpression(fun.body, ASSIGNMENT, 953 visitNestedExpression(fun.body, ASSIGNMENT,
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after
1061 visit(node.tag); 1072 visit(node.tag);
1062 visit(node.template); 1073 visit(node.template);
1063 } 1074 }
1064 1075
1065 visitClassDeclaration(ClassDeclaration node) { 1076 visitClassDeclaration(ClassDeclaration node) {
1066 indent(); 1077 indent();
1067 visit(node.classExpr); 1078 visit(node.classExpr);
1068 lineOut(); 1079 lineOut();
1069 } 1080 }
1070 1081
1082 outTypeArgs(List<Identifier> typeArgs) {
1083 if (options.printTypes && typeArgs != null && typeArgs.isNotEmpty) {
Jennifer Messerly 2016/02/09 01:21:33 null check on variable/param is probably fastest,
ochafik 2016/02/10 18:12:45 Done.
1084 out("<");
Jennifer Messerly 2016/02/09 01:21:33 does typescript have any cases where precedence co
ochafik 2016/02/10 18:12:45 It *looks* fine in TS (since the : would announce
1085 var first = true;
1086 for (var typeParam in typeArgs) {
1087 if (!first) out(", ");
1088 first = false;
1089 visit(typeParam);
1090 }
1091 out(">");
1092 }
1093 }
1094
1071 visitClassExpression(ClassExpression node) { 1095 visitClassExpression(ClassExpression node) {
1072 out('class '); 1096 out('class ');
1073 visit(node.name); 1097 visit(node.name);
1098 outTypeArgs(node.typeArgs);
1074 if (node.heritage != null) { 1099 if (node.heritage != null) {
1075 out(' extends '); 1100 out(' extends ');
1076 visit(node.heritage); 1101 visit(node.heritage);
1077 } 1102 }
1078 spaceOut(); 1103 spaceOut();
1079 if (node.methods.isNotEmpty) { 1104 if (node.methods.isNotEmpty) {
1080 out('{'); 1105 out('{');
1081 lineOut(); 1106 lineOut();
1082 indentMore(); 1107 indentMore();
1108 if (options.printTypes) {
1109 for (var field in node.fields) {
1110 indent();
1111 visit(field);
1112 out(";");
1113 lineOut();
1114 }
1115 }
1083 for (var method in node.methods) { 1116 for (var method in node.methods) {
1084 indent(); 1117 indent();
1085 visit(method); 1118 visit(method);
1086 lineOut(); 1119 lineOut();
1087 } 1120 }
1088 indentLess(); 1121 indentLess();
1089 indent(); 1122 indent();
1090 out('}'); 1123 out('}');
1091 } else { 1124 } else {
1092 out('{}'); 1125 out('{}');
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 } else { 1337 } else {
1305 out('/* $comment */'); 1338 out('/* $comment */');
1306 } 1339 }
1307 visit(node.expression); 1340 visit(node.expression);
1308 } 1341 }
1309 1342
1310 void visitAwait(Await node) { 1343 void visitAwait(Await node) {
1311 out("await "); 1344 out("await ");
1312 visit(node.expression); 1345 visit(node.expression);
1313 } 1346 }
1347
1348 void outTypeAnnotation(TypeRef node) {
1349 if (!options.printTypes || node == null || node.isUnknown) return;
Jennifer Messerly 2016/02/09 01:21:33 silly micro opt: check null first
ochafik 2016/02/10 18:12:45 Done.
1350
1351 if (node is OptionalTypeRef) {
1352 out("?: ");
1353 visit(node.type);
1354 } else {
1355 out(": ");
1356 visit(node);
1357 }
1358 }
1314 } 1359 }
1315 1360
1316 // Collects all the var declarations in the function. We need to do this in a 1361 // Collects all the var declarations in the function. We need to do this in a
1317 // separate pass because JS vars are lifted to the top of the function. 1362 // separate pass because JS vars are lifted to the top of the function.
1318 class VarCollector extends BaseVisitor { 1363 class VarCollector extends BaseVisitor {
1319 bool nested; 1364 bool nested;
1320 final Set<String> vars; 1365 final Set<String> vars;
1321 final Set<String> params; 1366 final Set<String> params;
1322 1367
1323 VarCollector() : nested = false, 1368 VarCollector() : nested = false,
(...skipping 289 matching lines...) Expand 10 before | Expand all | Expand 10 after
1613 declare(node.name); 1658 declare(node.name);
1614 node.function.accept(this); 1659 node.function.accept(this);
1615 } 1660 }
1616 1661
1617 visitClassExpression(ClassExpression node) { 1662 visitClassExpression(ClassExpression node) {
1618 declare(node.name); 1663 declare(node.name);
1619 if (node.heritage != null) node.heritage.accept(this); 1664 if (node.heritage != null) node.heritage.accept(this);
1620 for (Method element in node.methods) element.accept(this); 1665 for (Method element in node.methods) element.accept(this);
1621 } 1666 }
1622 } 1667 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698