OLD | NEW |
---|---|
1 // Copyright (c) 2015, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2015, 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 library js; | 5 library js; |
6 | 6 |
7 import 'package:js_ast/js_ast.dart'; | 7 import 'package:js_ast/js_ast.dart'; |
8 export 'package:js_ast/js_ast.dart'; | 8 export 'package:js_ast/js_ast.dart'; |
9 | 9 |
10 import '../io/code_output.dart' show CodeBuffer; | 10 import '../io/code_output.dart' show CodeBuffer; |
11 import '../io/source_information.dart' show SourceInformation; | 11 import '../io/source_information.dart' show SourceInformation; |
12 import '../js_emitter/js_emitter.dart' show USE_NEW_EMITTER; | 12 import '../js_emitter/js_emitter.dart' show USE_NEW_EMITTER; |
13 import '../dart2jslib.dart' as leg; | 13 import '../dart2jslib.dart' as leg; |
14 import '../util/util.dart' show NO_LOCATION_SPANNABLE; | 14 import '../util/util.dart' show NO_LOCATION_SPANNABLE; |
15 import '../dump_info.dart' show DumpInfoTask; | 15 import '../dump_info.dart' show DumpInfoTask; |
16 | 16 |
17 CodeBuffer prettyPrint(Node node, leg.Compiler compiler, | 17 CodeBuffer prettyPrint(Node node, leg.Compiler compiler, |
18 {DumpInfoTask monitor, | 18 {DumpInfoTask monitor, |
19 bool allowVariableMinification: true}) { | 19 bool allowVariableMinification: true, |
20 Renamer renamerForNames: | |
21 JavaScriptPrintingOptions.identityRenamer}) { | |
20 JavaScriptPrintingOptions options = new JavaScriptPrintingOptions( | 22 JavaScriptPrintingOptions options = new JavaScriptPrintingOptions( |
21 shouldCompressOutput: compiler.enableMinification, | 23 shouldCompressOutput: compiler.enableMinification, |
22 minifyLocalVariables: allowVariableMinification, | 24 minifyLocalVariables: allowVariableMinification, |
23 preferSemicolonToNewlineInMinifiedOutput: USE_NEW_EMITTER); | 25 preferSemicolonToNewlineInMinifiedOutput: USE_NEW_EMITTER, |
26 renamerForNames: renamerForNames); | |
24 Dart2JSJavaScriptPrintingContext context = | 27 Dart2JSJavaScriptPrintingContext context = |
25 new Dart2JSJavaScriptPrintingContext(compiler, monitor); | 28 new Dart2JSJavaScriptPrintingContext(compiler, monitor); |
26 Printer printer = new Printer(options, context); | 29 Printer printer = new Printer(options, context); |
27 printer.visit(node); | 30 printer.visit(node); |
28 return context.outBuffer; | 31 return context.outBuffer; |
29 } | 32 } |
30 | 33 |
31 class Dart2JSJavaScriptPrintingContext implements JavaScriptPrintingContext { | 34 class Dart2JSJavaScriptPrintingContext implements JavaScriptPrintingContext { |
32 final leg.Compiler compiler; | 35 final leg.Compiler compiler; |
33 final DumpInfoTask monitor; | 36 final DumpInfoTask monitor; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
78 if (rootNode == node) { | 81 if (rootNode == node) { |
79 outBuffer.addSourceLocation(endPosition, null); | 82 outBuffer.addSourceLocation(endPosition, null); |
80 rootNode = null; | 83 rootNode = null; |
81 } | 84 } |
82 } | 85 } |
83 if (monitor != null) { | 86 if (monitor != null) { |
84 monitor.recordAstSize(node, endPosition - startPosition); | 87 monitor.recordAstSize(node, endPosition - startPosition); |
85 } | 88 } |
86 } | 89 } |
87 } | 90 } |
91 | |
92 /// Interface for ast nodes that encapsulate an ast that needs to be | |
93 /// traversed when counting tokens. | |
94 abstract class AstContainer implements Node { | |
95 Iterable<Node> get containedNodes; | |
96 } | |
97 | |
98 /// Interface for tasks in the compiler that need to finalize tokens after | |
99 /// counting them. | |
100 abstract class TokenFinalizer { | |
101 void finalizeTokens(); | |
102 } | |
103 | |
104 /// Implements reference counting for instances of [ReferenceCountedAstNode] | |
105 class TokenCounter extends BaseVisitor { | |
106 @override | |
107 visitNode(Node node) { | |
108 if (node is AstContainer) { | |
109 for (Node element in node.containedNodes) { | |
110 element.accept(this); | |
111 } | |
112 } else if (node is ReferenceCountedAstNode) { | |
113 node.markSeen(this); | |
114 } else { | |
115 super.visitNode(node); | |
116 } | |
117 } | |
118 | |
119 void countTokens(Node node) => node.accept(this); | |
120 } | |
121 | |
122 abstract class ReferenceCountedAstNode implements Node { | |
123 markSeen(TokenCounter visitor); | |
124 } | |
125 | |
126 /// Represents the LiteralString resulting from unparsing [expression]. The | |
127 /// actual unparsing is done on demand when requesting the [value] of this | |
128 /// node. | |
sra1
2015/07/01 04:11:09
Perhaps say here why you might want such a strange
herhut
2015/07/02 08:54:51
Done.
| |
129 class UnparsedNode extends DeferredString | |
130 implements AstContainer { | |
131 @override | |
132 final Node tree; | |
133 final leg.Compiler _compiler; | |
134 final bool _protectForEval; | |
135 LiteralString _cachedLiteral; | |
136 | |
137 Iterable<Node> get containedNodes => [tree]; | |
138 | |
139 /// A [js.Literal] that represents the string result of unparsing [ast]. | |
140 /// | |
141 /// When its string [value] is requested, the node pretty-prints the given | |
142 /// [ast] and, if [protectForEval] is true, wraps the resulting | |
143 /// string in parenthesis. The result is also escaped. | |
144 UnparsedNode(this.tree, this._compiler, this._protectForEval); | |
145 | |
146 LiteralString get _literal { | |
147 if (_cachedLiteral == null) { | |
148 String text = prettyPrint(tree, _compiler).getText(); | |
149 if (_protectForEval) { | |
150 if (tree is Fun) text = '($text)'; | |
151 if (tree is LiteralExpression) { | |
152 LiteralExpression literalExpression = tree; | |
153 String template = literalExpression.template; | |
154 if (template.startsWith("function ") || | |
155 template.startsWith("{")) { | |
156 text = '($text)'; | |
157 } | |
158 } | |
159 } | |
160 _cachedLiteral = js.escapedString(text); | |
161 } | |
162 return _cachedLiteral; | |
163 } | |
164 | |
165 @override | |
166 String get value => _literal.value; | |
167 } | |
OLD | NEW |