OLD | NEW |
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 allowSingleLineIfStatements; | 12 final bool allowSingleLineIfStatements; |
13 | 13 |
14 /// True to allow keywords in properties, such as `obj.var` or `obj.function` | 14 /// True to allow keywords in properties, such as `obj.var` or `obj.function` |
15 /// Modern JS engines support this. | 15 /// Modern JS engines support this. |
16 final bool allowKeywordsInProperties; | 16 final bool allowKeywordsInProperties; |
17 | 17 |
18 /// Workaround if `this` is not bound in arrow functions. | |
19 final bool arrowFnBindThisWorkaround; | |
20 | |
21 JavaScriptPrintingOptions( | 18 JavaScriptPrintingOptions( |
22 {this.shouldCompressOutput: false, | 19 {this.shouldCompressOutput: false, |
23 this.minifyLocalVariables: false, | 20 this.minifyLocalVariables: false, |
24 this.preferSemicolonToNewlineInMinifiedOutput: false, | 21 this.preferSemicolonToNewlineInMinifiedOutput: false, |
25 this.allowKeywordsInProperties: false, | 22 this.allowKeywordsInProperties: false, |
26 this.allowSingleLineIfStatements: false, | 23 this.allowSingleLineIfStatements: false}); |
27 this.arrowFnBindThisWorkaround: false}); | |
28 } | 24 } |
29 | 25 |
30 | 26 |
31 /// An environment in which JavaScript printing is done. Provides emitting of | 27 /// An environment in which JavaScript printing is done. Provides emitting of |
32 /// text and pre- and post-visit callbacks. | 28 /// text and pre- and post-visit callbacks. |
33 abstract class JavaScriptPrintingContext { | 29 abstract class JavaScriptPrintingContext { |
34 /// Signals an error. This should happen only for serious internal errors. | 30 /// Signals an error. This should happen only for serious internal errors. |
35 void error(String message) { throw message; } | 31 void error(String message) { throw message; } |
36 | 32 |
37 /// Adds [string] to the output. | 33 /// Adds [string] to the output. |
(...skipping 533 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
571 visitFunctionDeclaration(FunctionDeclaration declaration) { | 567 visitFunctionDeclaration(FunctionDeclaration declaration) { |
572 indent(); | 568 indent(); |
573 outClosureAnnotation(declaration); | 569 outClosureAnnotation(declaration); |
574 functionOut(declaration.function, declaration.name); | 570 functionOut(declaration.function, declaration.name); |
575 lineOut(); | 571 lineOut(); |
576 } | 572 } |
577 | 573 |
578 visitNestedExpression(Expression node, int requiredPrecedence, | 574 visitNestedExpression(Expression node, int requiredPrecedence, |
579 {bool newInForInit, bool newAtStatementBegin}) { | 575 {bool newInForInit, bool newAtStatementBegin}) { |
580 int nodePrecedence = node.precedenceLevel; | 576 int nodePrecedence = node.precedenceLevel; |
581 if (options.arrowFnBindThisWorkaround) { | |
582 if (node is ArrowFun && node.closesOverThis) { | |
583 nodePrecedence = CALL; | |
584 } | |
585 } | |
586 bool needsParentheses = | 577 bool needsParentheses = |
587 // a - (b + c). | 578 // a - (b + c). |
588 (requiredPrecedence != EXPRESSION && | 579 (requiredPrecedence != EXPRESSION && |
589 nodePrecedence < requiredPrecedence) || | 580 nodePrecedence < requiredPrecedence) || |
590 // for (a = (x in o); ... ; ... ) { ... } | 581 // for (a = (x in o); ... ; ... ) { ... } |
591 (newInForInit && node is Binary && node.op == "in") || | 582 (newInForInit && node is Binary && node.op == "in") || |
592 // (function() { ... })(). | 583 // (function() { ... })(). |
593 // ({a: 2, b: 3}.toString()). | 584 // ({a: 2, b: 3}.toString()). |
594 (newAtStatementBegin && (node is NamedFunction || | 585 (newAtStatementBegin && (node is NamedFunction || |
595 node is FunctionExpression || | 586 node is FunctionExpression || |
(...skipping 326 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
922 | 913 |
923 visitNamedFunction(NamedFunction namedFunction) { | 914 visitNamedFunction(NamedFunction namedFunction) { |
924 functionOut(namedFunction.function, namedFunction.name); | 915 functionOut(namedFunction.function, namedFunction.name); |
925 } | 916 } |
926 | 917 |
927 visitFun(Fun fun) { | 918 visitFun(Fun fun) { |
928 functionOut(fun, null); | 919 functionOut(fun, null); |
929 } | 920 } |
930 | 921 |
931 visitArrowFun(ArrowFun fun) { | 922 visitArrowFun(ArrowFun fun) { |
932 bool bindThis = options.arrowFnBindThisWorkaround && fun.closesOverThis; | |
933 if (bindThis) { | |
934 out("("); | |
935 } | |
936 localNamer.enterScope(fun); | 923 localNamer.enterScope(fun); |
937 if (fun.params.length == 1) { | 924 if (fun.params.length == 1) { |
938 visitNestedExpression(fun.params.single, SPREAD, | 925 visitNestedExpression(fun.params.single, SPREAD, |
939 newInForInit: false, newAtStatementBegin: false); | 926 newInForInit: false, newAtStatementBegin: false); |
940 } else { | 927 } else { |
941 out("("); | 928 out("("); |
942 visitCommaSeparated(fun.params, SPREAD, | 929 visitCommaSeparated(fun.params, SPREAD, |
943 newInForInit: false, newAtStatementBegin: false); | 930 newInForInit: false, newAtStatementBegin: false); |
944 out(")"); | 931 out(")"); |
945 } | 932 } |
946 spaceOut(); | 933 spaceOut(); |
947 out("=>"); | 934 out("=>"); |
948 if (fun.body is Expression) { | 935 if (fun.body is Expression) { |
949 spaceOut(); | 936 spaceOut(); |
950 // Object initializers require parenthesis to disambiguate | 937 // Object initializers require parenthesis to disambiguate |
951 // AssignmentExpression from FunctionBody. See: | 938 // AssignmentExpression from FunctionBody. See: |
952 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-arrow-functio
n-definitions | 939 // https://people.mozilla.org/~jorendorff/es6-draft.html#sec-arrow-functio
n-definitions |
953 var needsParen = fun.body is ObjectInitializer; | 940 var needsParen = fun.body is ObjectInitializer; |
954 if (needsParen) out("("); | 941 if (needsParen) out("("); |
955 visitNestedExpression(fun.body, ASSIGNMENT, | 942 visitNestedExpression(fun.body, ASSIGNMENT, |
956 newInForInit: false, newAtStatementBegin: false); | 943 newInForInit: false, newAtStatementBegin: false); |
957 if (needsParen) out(")"); | 944 if (needsParen) out(")"); |
958 } else { | 945 } else { |
959 blockBody(fun.body, needsSeparation: false, needsNewline: false); | 946 blockBody(fun.body, needsSeparation: false, needsNewline: false); |
960 } | 947 } |
961 localNamer.leaveScope(); | 948 localNamer.leaveScope(); |
962 if (bindThis) { | |
963 out(").bind(this)"); | |
964 } | |
965 } | 949 } |
966 | 950 |
967 visitLiteralBool(LiteralBool node) { | 951 visitLiteralBool(LiteralBool node) { |
968 out(node.value ? "true" : "false"); | 952 out(node.value ? "true" : "false"); |
969 } | 953 } |
970 | 954 |
971 visitLiteralString(LiteralString node) { | 955 visitLiteralString(LiteralString node) { |
972 out(node.value); | 956 out(node.value); |
973 } | 957 } |
974 | 958 |
(...skipping 654 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1629 declare(node.name); | 1613 declare(node.name); |
1630 node.function.accept(this); | 1614 node.function.accept(this); |
1631 } | 1615 } |
1632 | 1616 |
1633 visitClassExpression(ClassExpression node) { | 1617 visitClassExpression(ClassExpression node) { |
1634 declare(node.name); | 1618 declare(node.name); |
1635 if (node.heritage != null) node.heritage.accept(this); | 1619 if (node.heritage != null) node.heritage.accept(this); |
1636 for (Method element in node.methods) element.accept(this); | 1620 for (Method element in node.methods) element.accept(this); |
1637 } | 1621 } |
1638 } | 1622 } |
OLD | NEW |