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 '../common.dart'; | 10 import '../common.dart'; |
11 import '../compiler.dart' show | 11 import '../compiler.dart' show Compiler; |
12 Compiler; | 12 import '../dump_info.dart' show DumpInfoTask; |
13 import '../dump_info.dart' show | 13 import '../io/code_output.dart' show CodeBuffer, CodeOutput; |
14 DumpInfoTask; | 14 import '../js_emitter/js_emitter.dart' show USE_LAZY_EMITTER; |
15 import '../io/code_output.dart' show | |
16 CodeBuffer, | |
17 CodeOutput; | |
18 import '../js_emitter/js_emitter.dart' show | |
19 USE_LAZY_EMITTER; | |
20 | 15 |
21 import 'js_source_mapping.dart'; | 16 import 'js_source_mapping.dart'; |
22 | 17 |
23 String prettyPrint( | 18 String prettyPrint(Node node, Compiler compiler, |
24 Node node, | |
25 Compiler compiler, | |
26 {bool allowVariableMinification: true, | 19 {bool allowVariableMinification: true, |
27 Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) { | 20 Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) { |
28 // TODO(johnniwinther): Do we need all the options here? | 21 // TODO(johnniwinther): Do we need all the options here? |
29 JavaScriptPrintingOptions options = new JavaScriptPrintingOptions( | 22 JavaScriptPrintingOptions options = new JavaScriptPrintingOptions( |
30 shouldCompressOutput: compiler.options.enableMinification, | 23 shouldCompressOutput: compiler.options.enableMinification, |
31 minifyLocalVariables: allowVariableMinification, | 24 minifyLocalVariables: allowVariableMinification, |
32 preferSemicolonToNewlineInMinifiedOutput: USE_LAZY_EMITTER, | 25 preferSemicolonToNewlineInMinifiedOutput: USE_LAZY_EMITTER, |
33 renamerForNames: renamerForNames); | 26 renamerForNames: renamerForNames); |
34 SimpleJavaScriptPrintingContext context = | 27 SimpleJavaScriptPrintingContext context = |
35 new SimpleJavaScriptPrintingContext(); | 28 new SimpleJavaScriptPrintingContext(); |
36 Printer printer = new Printer(options, context); | 29 Printer printer = new Printer(options, context); |
37 printer.visit(node); | 30 printer.visit(node); |
38 return context.getText(); | 31 return context.getText(); |
39 } | 32 } |
40 | 33 |
41 CodeBuffer createCodeBuffer( | 34 CodeBuffer createCodeBuffer(Node node, Compiler compiler, |
42 Node node, | |
43 Compiler compiler, | |
44 {DumpInfoTask monitor, | 35 {DumpInfoTask monitor, |
45 bool allowVariableMinification: true, | 36 bool allowVariableMinification: true, |
46 Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) { | 37 Renamer renamerForNames: JavaScriptPrintingOptions.identityRenamer}) { |
47 JavaScriptSourceInformationStrategy sourceInformationFactory = | 38 JavaScriptSourceInformationStrategy sourceInformationFactory = |
48 compiler.backend.sourceInformationStrategy; | 39 compiler.backend.sourceInformationStrategy; |
49 JavaScriptPrintingOptions options = new JavaScriptPrintingOptions( | 40 JavaScriptPrintingOptions options = new JavaScriptPrintingOptions( |
50 shouldCompressOutput: compiler.options.enableMinification, | 41 shouldCompressOutput: compiler.options.enableMinification, |
51 minifyLocalVariables: allowVariableMinification, | 42 minifyLocalVariables: allowVariableMinification, |
52 preferSemicolonToNewlineInMinifiedOutput: USE_LAZY_EMITTER, | 43 preferSemicolonToNewlineInMinifiedOutput: USE_LAZY_EMITTER, |
53 renamerForNames: renamerForNames); | 44 renamerForNames: renamerForNames); |
54 CodeBuffer outBuffer = new CodeBuffer(); | 45 CodeBuffer outBuffer = new CodeBuffer(); |
55 SourceInformationProcessor sourceInformationProcessor = | 46 SourceInformationProcessor sourceInformationProcessor = |
56 sourceInformationFactory.createProcessor( | 47 sourceInformationFactory |
57 new SourceLocationsMapper(outBuffer)); | 48 .createProcessor(new SourceLocationsMapper(outBuffer)); |
58 Dart2JSJavaScriptPrintingContext context = | 49 Dart2JSJavaScriptPrintingContext context = |
59 new Dart2JSJavaScriptPrintingContext( | 50 new Dart2JSJavaScriptPrintingContext( |
60 compiler.reporter, monitor, outBuffer, sourceInformationProcessor); | 51 compiler.reporter, monitor, outBuffer, sourceInformationProcessor); |
61 Printer printer = new Printer(options, context); | 52 Printer printer = new Printer(options, context); |
62 printer.visit(node); | 53 printer.visit(node); |
63 sourceInformationProcessor.process(node, outBuffer); | 54 sourceInformationProcessor.process(node, outBuffer); |
64 return outBuffer; | 55 return outBuffer; |
65 } | 56 } |
66 | 57 |
67 class Dart2JSJavaScriptPrintingContext implements JavaScriptPrintingContext { | 58 class Dart2JSJavaScriptPrintingContext implements JavaScriptPrintingContext { |
68 final DiagnosticReporter reporter; | 59 final DiagnosticReporter reporter; |
69 final DumpInfoTask monitor; | 60 final DumpInfoTask monitor; |
70 final CodeBuffer outBuffer; | 61 final CodeBuffer outBuffer; |
71 final CodePositionListener codePositionListener; | 62 final CodePositionListener codePositionListener; |
72 | 63 |
73 Dart2JSJavaScriptPrintingContext( | 64 Dart2JSJavaScriptPrintingContext( |
74 this.reporter, | 65 this.reporter, this.monitor, this.outBuffer, this.codePositionListener); |
75 this.monitor, | |
76 this.outBuffer, | |
77 this.codePositionListener); | |
78 | 66 |
79 @override | 67 @override |
80 void error(String message) { | 68 void error(String message) { |
81 reporter.internalError(NO_LOCATION_SPANNABLE, message); | 69 reporter.internalError(NO_LOCATION_SPANNABLE, message); |
82 } | 70 } |
83 | 71 |
84 @override | 72 @override |
85 void emit(String string) { | 73 void emit(String string) { |
86 outBuffer.add(string); | 74 outBuffer.add(string); |
87 } | 75 } |
88 | 76 |
89 @override | 77 @override |
90 void enterNode(Node, int startPosition) {} | 78 void enterNode(Node, int startPosition) {} |
91 | 79 |
92 @override | 80 @override |
93 void exitNode(Node node, | 81 void exitNode( |
94 int startPosition, | 82 Node node, int startPosition, int endPosition, int closingPosition) { |
95 int endPosition, | |
96 int closingPosition) { | |
97 if (monitor != null) { | 83 if (monitor != null) { |
98 monitor.recordAstSize(node, endPosition - startPosition); | 84 monitor.recordAstSize(node, endPosition - startPosition); |
99 } | 85 } |
100 codePositionListener.onPositions( | 86 codePositionListener.onPositions( |
101 node, startPosition, endPosition, closingPosition); | 87 node, startPosition, endPosition, closingPosition); |
102 } | 88 } |
103 } | 89 } |
104 | 90 |
105 /// Interface for ast nodes that encapsulate an ast that needs to be | 91 /// Interface for ast nodes that encapsulate an ast that needs to be |
106 /// traversed when counting tokens. | 92 /// traversed when counting tokens. |
(...skipping 28 matching lines...) Expand all Loading... |
135 abstract class ReferenceCountedAstNode implements Node { | 121 abstract class ReferenceCountedAstNode implements Node { |
136 markSeen(TokenCounter visitor); | 122 markSeen(TokenCounter visitor); |
137 } | 123 } |
138 | 124 |
139 /// Represents the LiteralString resulting from unparsing [expression]. The | 125 /// Represents the LiteralString resulting from unparsing [expression]. The |
140 /// actual unparsing is done on demand when requesting the [value] of this | 126 /// actual unparsing is done on demand when requesting the [value] of this |
141 /// node. | 127 /// node. |
142 /// | 128 /// |
143 /// This is used when generated code needs to be represented as a string, | 129 /// This is used when generated code needs to be represented as a string, |
144 /// for example by the lazy emitter or when generating code generators. | 130 /// for example by the lazy emitter or when generating code generators. |
145 class UnparsedNode extends DeferredString | 131 class UnparsedNode extends DeferredString implements AstContainer { |
146 implements AstContainer { | |
147 @override | 132 @override |
148 final Node tree; | 133 final Node tree; |
149 final Compiler _compiler; | 134 final Compiler _compiler; |
150 final bool _protectForEval; | 135 final bool _protectForEval; |
151 LiteralString _cachedLiteral; | 136 LiteralString _cachedLiteral; |
152 | 137 |
153 Iterable<Node> get containedNodes => [tree]; | 138 Iterable<Node> get containedNodes => [tree]; |
154 | 139 |
155 /// A [js.Literal] that represents the string result of unparsing [ast]. | 140 /// A [js.Literal] that represents the string result of unparsing [ast]. |
156 /// | 141 /// |
157 /// When its string [value] is requested, the node pretty-prints the given | 142 /// When its string [value] is requested, the node pretty-prints the given |
158 /// [ast] and, if [protectForEval] is true, wraps the resulting string in | 143 /// [ast] and, if [protectForEval] is true, wraps the resulting string in |
159 /// parenthesis. The result is also escaped. | 144 /// parenthesis. The result is also escaped. |
160 UnparsedNode(this.tree, this._compiler, this._protectForEval); | 145 UnparsedNode(this.tree, this._compiler, this._protectForEval); |
161 | 146 |
162 LiteralString get _literal { | 147 LiteralString get _literal { |
163 if (_cachedLiteral == null) { | 148 if (_cachedLiteral == null) { |
164 String text = prettyPrint(tree, _compiler); | 149 String text = prettyPrint(tree, _compiler); |
165 if (_protectForEval) { | 150 if (_protectForEval) { |
166 if (tree is Fun) text = '($text)'; | 151 if (tree is Fun) text = '($text)'; |
167 if (tree is LiteralExpression) { | 152 if (tree is LiteralExpression) { |
168 LiteralExpression literalExpression = tree; | 153 LiteralExpression literalExpression = tree; |
169 String template = literalExpression.template; | 154 String template = literalExpression.template; |
170 if (template.startsWith("function ") || | 155 if (template.startsWith("function ") || template.startsWith("{")) { |
171 template.startsWith("{")) { | |
172 text = '($text)'; | 156 text = '($text)'; |
173 } | 157 } |
174 } | 158 } |
175 } | 159 } |
176 _cachedLiteral = js.escapedString(text); | 160 _cachedLiteral = js.escapedString(text); |
177 } | 161 } |
178 return _cachedLiteral; | 162 return _cachedLiteral; |
179 } | 163 } |
180 | 164 |
181 @override | 165 @override |
(...skipping 21 matching lines...) Expand all Loading... |
203 } | 187 } |
204 if (node is PropertyAccess) { | 188 if (node is PropertyAccess) { |
205 PropertyAccess access = node; | 189 PropertyAccess access = node; |
206 if (access.receiver is InterpolatedExpression) { | 190 if (access.receiver is InterpolatedExpression) { |
207 InterpolatedExpression hole = access.receiver; | 191 InterpolatedExpression hole = access.receiver; |
208 return hole.isPositional && hole.nameOrPosition == 0; | 192 return hole.isPositional && hole.nameOrPosition == 0; |
209 } | 193 } |
210 } | 194 } |
211 return false; | 195 return false; |
212 } | 196 } |
OLD | NEW |