OLD | NEW |
| (Empty) |
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 | |
3 // BSD-style license that can be found in the LICENSE file. | |
4 | |
5 class Unparser implements Visitor { | |
6 StringBuffer sb; | |
7 final bool printDebugInfo; | |
8 | |
9 Unparser([this.printDebugInfo = false]); | |
10 | |
11 String unparse(Node node) { | |
12 sb = new StringBuffer(); | |
13 visit(node); | |
14 return sb.toString(); | |
15 } | |
16 | |
17 void add(SourceString string) { | |
18 string.printOn(sb); | |
19 } | |
20 | |
21 visit(Node node) { | |
22 if (node !== null) { | |
23 if (printDebugInfo) sb.add('[${node.getObjectDescription()}: '); | |
24 node.accept(this); | |
25 if (printDebugInfo) sb.add(']'); | |
26 } else if (printDebugInfo) { | |
27 sb.add('[null]'); | |
28 } | |
29 } | |
30 | |
31 visitBlock(Block node) { | |
32 visit(node.statements); | |
33 } | |
34 | |
35 visitClassNode(ClassNode node) { | |
36 node.beginToken.value.printOn(sb); | |
37 sb.add(' '); | |
38 visit(node.name); | |
39 sb.add(' '); | |
40 if (node.extendsKeyword !== null) { | |
41 node.extendsKeyword.value.printOn(sb); | |
42 sb.add(' '); | |
43 visit(node.superclass); | |
44 sb.add(' '); | |
45 } | |
46 visit(node.interfaces); | |
47 if (node.defaultClause !== null) { | |
48 visit(node.defaultClause); | |
49 sb.add(' '); | |
50 } | |
51 sb.add('{\n'); | |
52 sb.add('}\n'); | |
53 } | |
54 | |
55 visitConditional(Conditional node) { | |
56 visit(node.condition); | |
57 add(node.questionToken.value); | |
58 visit(node.thenExpression); | |
59 add(node.colonToken.value); | |
60 visit(node.elseExpression); | |
61 } | |
62 | |
63 visitExpressionStatement(ExpressionStatement node) { | |
64 visit(node.expression); | |
65 add(node.endToken.value); | |
66 } | |
67 | |
68 visitFor(For node) { | |
69 add(node.forToken.value); | |
70 sb.add('('); | |
71 visit(node.initializer); | |
72 visit(node.conditionStatement); | |
73 visit(node.update); | |
74 sb.add(')'); | |
75 visit(node.body); | |
76 } | |
77 | |
78 visitFunctionDeclaration(FunctionDeclaration node) { | |
79 visit(node.function); | |
80 } | |
81 | |
82 visitFunctionExpression(FunctionExpression node) { | |
83 if (node.returnType !== null) { | |
84 visit(node.returnType); | |
85 sb.add(' '); | |
86 } | |
87 visit(node.name); | |
88 visit(node.parameters); | |
89 visit(node.body); | |
90 } | |
91 | |
92 visitIdentifier(Identifier node) { | |
93 add(node.token.value); | |
94 } | |
95 | |
96 visitIf(If node) { | |
97 add(node.ifToken.value); | |
98 visit(node.condition); | |
99 visit(node.thenPart); | |
100 if (node.hasElsePart) { | |
101 add(node.elseToken.value); | |
102 visit(node.elsePart); | |
103 } | |
104 } | |
105 | |
106 visitLiteralBool(LiteralBool node) { | |
107 add(node.token.value); | |
108 } | |
109 | |
110 visitLiteralDouble(LiteralDouble node) { | |
111 add(node.token.value); | |
112 } | |
113 | |
114 visitLiteralInt(LiteralInt node) { | |
115 add(node.token.value); | |
116 } | |
117 | |
118 visitLiteralString(LiteralString node) { | |
119 add(node.token.value); | |
120 } | |
121 | |
122 visitStringJuxtaposition(LiteralStringJuxtaposition node) { | |
123 visit(node.first); | |
124 sb.add(" "); | |
125 visit(node.second); | |
126 } | |
127 | |
128 visitLiteralNull(LiteralNull node) { | |
129 add(node.token.value); | |
130 } | |
131 | |
132 visitNewExpression(NewExpression node) { | |
133 add(node.newToken.value); | |
134 sb.add(' '); | |
135 visit(node.send); | |
136 } | |
137 | |
138 visitLiteralList(LiteralList node) { | |
139 if (node.type !== null) { | |
140 sb.add('<'); | |
141 visit(node.type); | |
142 sb.add('>'); | |
143 } | |
144 sb.add(' '); | |
145 visit(node.elements); | |
146 } | |
147 | |
148 visitModifiers(Modifiers node) => node.visitChildren(this); | |
149 | |
150 visitNodeList(NodeList node) { | |
151 if (node.beginToken !== null) add(node.beginToken.value); | |
152 if (node.nodes !== null) { | |
153 String delimiter = (node.delimiter === null) ? " " : "${node.delimiter} "; | |
154 node.nodes.printOn(sb, delimiter); | |
155 } | |
156 if (node.endToken !== null) add(node.endToken.value); | |
157 } | |
158 | |
159 visitOperator(Operator node) { | |
160 visitIdentifier(node); | |
161 } | |
162 | |
163 visitReturn(Return node) { | |
164 add(node.beginToken.value); | |
165 if (node.hasExpression) { | |
166 sb.add(' '); | |
167 visit(node.expression); | |
168 } | |
169 if (node.endToken !== null) add(node.endToken.value); | |
170 } | |
171 | |
172 | |
173 unparseSendPart(Send node) { | |
174 if (node.isPrefix) { | |
175 visit(node.selector); | |
176 } | |
177 if (node.receiver !== null) { | |
178 visit(node.receiver); | |
179 if (node.selector is !Operator) sb.add('.'); | |
180 } | |
181 if (!node.isPrefix) { | |
182 visit(node.selector); | |
183 } | |
184 } | |
185 | |
186 visitSend(Send node) { | |
187 unparseSendPart(node); | |
188 visit(node.argumentsNode); | |
189 } | |
190 | |
191 visitSendSet(SendSet node) { | |
192 unparseSendPart(node); | |
193 add(node.assignmentOperator.token.value); | |
194 visit(node.argumentsNode); | |
195 } | |
196 | |
197 visitThrow(Throw node) { | |
198 add(node.throwToken.value); | |
199 if (node.expression !== null) { | |
200 sb.add(' '); | |
201 visit(node.expression); | |
202 } | |
203 node.endToken.value.printOn(sb); | |
204 } | |
205 | |
206 visitTypeAnnotation(TypeAnnotation node) { | |
207 node.visitChildren(this); | |
208 } | |
209 | |
210 visitTypeVariable(TypeVariable node) { | |
211 visit(node.name); | |
212 if (node.bound !== null) { | |
213 sb.add(' extends '); | |
214 visit(node.bound); | |
215 } | |
216 } | |
217 | |
218 visitVariableDefinitions(VariableDefinitions node) { | |
219 if (node.type !== null) { | |
220 visit(node.type); | |
221 } else { | |
222 sb.add('var'); | |
223 } | |
224 sb.add(' '); | |
225 // TODO(karlklose): print modifiers. | |
226 visit(node.definitions); | |
227 if (node.endToken.value == const SourceString(';')) { | |
228 add(node.endToken.value); | |
229 } | |
230 } | |
231 | |
232 visitDoWhile(DoWhile node) { | |
233 add(node.doKeyword.value); | |
234 sb.add(' '); | |
235 visit(node.body); | |
236 sb.add(' '); | |
237 add(node.whileKeyword.value); | |
238 sb.add(' '); | |
239 visit(node.condition); | |
240 sb.add(node.endToken.value); | |
241 } | |
242 | |
243 visitWhile(While node) { | |
244 add(node.whileKeyword.value); | |
245 sb.add(' '); | |
246 visit(node.condition); | |
247 sb.add(' '); | |
248 visit(node.body); | |
249 } | |
250 | |
251 visitParenthesizedExpression(ParenthesizedExpression node) { | |
252 add(node.getBeginToken().value); | |
253 visit(node.expression); | |
254 add(node.getEndToken().value); | |
255 } | |
256 | |
257 visitStringInterpolation(StringInterpolation node) { | |
258 visit(node.string); | |
259 visit(node.parts); | |
260 } | |
261 | |
262 visitStringInterpolationPart(StringInterpolationPart node) { | |
263 sb.add('\${'); // TODO(ahe): Preserve the real tokens. | |
264 visit(node.expression); | |
265 sb.add('}'); | |
266 visit(node.string); | |
267 } | |
268 | |
269 visitEmptyStatement(EmptyStatement node) { | |
270 add(node.semicolonToken.value); | |
271 } | |
272 | |
273 visitGotoStatement(GotoStatement node) { | |
274 add(node.keywordToken.value); | |
275 if (node.target !== null) { | |
276 sb.add(' '); | |
277 visit(node.target); | |
278 } | |
279 add(node.semicolonToken.value); | |
280 } | |
281 | |
282 visitBreakStatement(BreakStatement node) { | |
283 visitGotoStatement(node); | |
284 } | |
285 | |
286 visitContinueStatement(ContinueStatement node) { | |
287 visitGotoStatement(node); | |
288 } | |
289 | |
290 visitForInStatement(ForInStatement node) { | |
291 add(node.forToken.value); | |
292 sb.add(' ('); | |
293 visit(node.declaredIdentifier); | |
294 add(node.inToken.value); | |
295 visit(node.expression); | |
296 sb.add(') '); | |
297 visit(node.body); | |
298 } | |
299 | |
300 visitLabeledStatement(LabeledStatement node) { | |
301 visit(node.label); | |
302 add(node.colonToken.value); | |
303 sb.add(' '); | |
304 visit(node.statement); | |
305 } | |
306 | |
307 visitLiteralMap(LiteralMap node) { | |
308 if (node.typeArguments !== null) visit(node.typeArguments); | |
309 visit(node.entries); | |
310 } | |
311 | |
312 visitLiteralMapEntry(LiteralMapEntry node) { | |
313 visit(node.key); | |
314 add(node.colonToken.value); | |
315 sb.add(' '); | |
316 visit(node.value); | |
317 } | |
318 | |
319 visitNamedArgument(NamedArgument node) { | |
320 visit(node.name); | |
321 add(node.colonToken.value); | |
322 sb.add(' '); | |
323 visit(node.expression); | |
324 } | |
325 | |
326 visitSwitchStatement(SwitchStatement node) { | |
327 add(node.switchKeyword.value); | |
328 sb.add(' '); | |
329 visit(node.parenthesizedExpression); | |
330 sb.add(' '); | |
331 visit(node.cases); | |
332 } | |
333 | |
334 visitSwitchCase(SwitchCase node) { | |
335 if (node.label !== null) { | |
336 visit(node.label); | |
337 sb.add(': '); | |
338 } | |
339 for (Expression expression in node.expressions) { | |
340 sb.add('case '); | |
341 visit(expression); | |
342 sb.add(': '); | |
343 } | |
344 if (node.isDefaultCase) { | |
345 sb.add('default:'); | |
346 } | |
347 visit(node.statements); | |
348 } | |
349 | |
350 visitScriptTag(ScriptTag node) { | |
351 add(node.beginToken.value); | |
352 visit(node.tag); | |
353 sb.add('('); | |
354 visit(node.argument); | |
355 if (node.prefixIdentifier !== null) { | |
356 visit(node.prefixIdentifier); | |
357 sb.add(': '); | |
358 visit(node.prefix); | |
359 } | |
360 sb.add(')'); | |
361 add(node.endToken.value); | |
362 } | |
363 | |
364 visitTryStatement(TryStatement node) { | |
365 add(node.tryKeyword.value); | |
366 sb.add(' '); | |
367 visit(node.tryBlock); | |
368 visit(node.catchBlocks); | |
369 if (node.finallyKeyword !== null) { | |
370 sb.add(' '); | |
371 add(node.finallyKeyword.value); | |
372 sb.add(' '); | |
373 visit(node.finallyBlock); | |
374 } | |
375 } | |
376 | |
377 visitCatchBlock(CatchBlock node) { | |
378 add(node.catchKeyword.value); | |
379 sb.add(' '); | |
380 visit(node.formals); | |
381 sb.add(' '); | |
382 visit(node.block); | |
383 } | |
384 | |
385 visitTypedef(Typedef node) { | |
386 add(node.typedefKeyword.value); | |
387 sb.add(' '); | |
388 if (node.returnType !== null) { | |
389 visit(node.returnType); | |
390 sb.add(' '); | |
391 } | |
392 visit(node.name); | |
393 if (node.typeParameters !== null) { | |
394 visit(node.typeParameters); | |
395 } | |
396 visit(node.formals); | |
397 add(node.endToken.value); | |
398 } | |
399 } | |
OLD | NEW |