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

Side by Side Diff: lib/compiler/implementation/tree/unparser.dart

Issue 10836128: A visitor that builds a map from node to "Usage". (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 4 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 | Annotate | Revision Log
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 // Returns null if no need to rename a node.
6 typedef String Renamer(Node node);
7
5 class Unparser implements Visitor { 8 class Unparser implements Visitor {
6 final Renamer renamer; 9 Renamer rename;
Anton Muhin 2012/08/08 08:27:20 why it's not final any more?
Roman 2012/08/09 05:02:35 Done.
7 StringBuffer sb; 10 StringBuffer sb;
8 11
9 Unparser([this.renamer = const Renamer()]); 12 Unparser() : this.withRenamer((Node) => null);
13 Unparser.withRenamer(this.rename);
10 14
11 String unparse(Node node) { 15 String unparse(Node node) {
12 sb = new StringBuffer(); 16 sb = new StringBuffer();
13 visit(node); 17 visit(node);
14 return sb.toString(); 18 return sb.toString();
15 } 19 }
16 20
17 void add(SourceString string) { 21 void add(SourceString string) {
18 string.printOn(sb); 22 string.printOn(sb);
19 } 23 }
20 24
21 void addToken(Token token) { 25 void addToken(Token token) {
22 if (token === null) return; 26 if (token === null) return;
23 add(token.value); 27 add(token.value);
24 if (token.kind === KEYWORD_TOKEN || token.kind === IDENTIFIER_TOKEN) { 28 if (token.kind === KEYWORD_TOKEN || token.kind === IDENTIFIER_TOKEN) {
25 sb.add(' '); 29 sb.add(' ');
26 } 30 }
27 } 31 }
28 32
29 visit(Node node) { 33 visit(Node node) {
30 if (node !== null) node.accept(this); 34 if (node === null) return;
35 String renamed = rename(node);
36 if (renamed !== null) {
37 sb.add(renamed);
38 } else {
39 // Fallback.
40 node.accept(this);
41 }
31 } 42 }
32 43
33 visitBlock(Block node) { 44 visitBlock(Block node) {
34 visit(node.statements); 45 visit(node.statements);
35 } 46 }
36 47
37 visitCascade(Cascade node) { 48 visitCascade(Cascade node) {
38 visit(node.expression); 49 visit(node.expression);
39 } 50 }
40 51
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
99 sb.add(' '); 110 sb.add(' ');
100 } 111 }
101 if (node.getOrSet !== null) { 112 if (node.getOrSet !== null) {
102 add(node.getOrSet.value); 113 add(node.getOrSet.value);
103 sb.add(' '); 114 sb.add(' ');
104 } 115 }
105 // TODO(antonm): that's a workaround as currently FunctionExpression 116 // TODO(antonm): that's a workaround as currently FunctionExpression
106 // names are modelled with Send and it emits operator[] as only 117 // names are modelled with Send and it emits operator[] as only
107 // operator, without [] which are expected to be emitted with 118 // operator, without [] which are expected to be emitted with
108 // arguments. 119 // arguments.
109 emitName(Identifier name) {
110 final newName = renamer.renameIdentifier(name);
111 if (newName === null) {
112 visit(name);
113 } else {
114 sb.add(newName);
115 }
116 }
117 if (node.name is Send) { 120 if (node.name is Send) {
118 Send send = node.name; 121 Send send = node.name;
119 assert(send is !SendSet); 122 assert(send is !SendSet);
120 if (!send.isOperator) { 123 if (!send.isOperator) {
121 // Looks like a factory method. 124 // Looks like a factory method.
122 emitName(send.receiver); 125 visit(send.receiver);
123 sb.add('.'); 126 sb.add('.');
124 } else { 127 } else {
125 visit(send.receiver); 128 visit(send.receiver);
126 if (send.selector.token.kind === KEYWORD_TOKEN) sb.add(' '); 129 if (send.selector.token.kind === KEYWORD_TOKEN) sb.add(' ');
127 } 130 }
128 visit(send.selector); 131 visit(send.selector);
129 } else { 132 } else {
130 if (node.name !== null) emitName(node.name); 133 if (node.name !== null) visit(node.name);
Anton Muhin 2012/08/08 08:27:20 no need in !== null check, but after rebase this d
131 } 134 }
132 visit(node.parameters); 135 visit(node.parameters);
133 visit(node.initializers); 136 visit(node.initializers);
134 visit(node.body); 137 visit(node.body);
135 } 138 }
136 139
137 visitIdentifier(Identifier node) { 140 visitIdentifier(Identifier node) {
138 add(node.token.value); 141 add(node.token.value);
139 } 142 }
140 143
(...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after
230 } 233 }
231 234
232 unparseSendPart(Send node) { 235 unparseSendPart(Send node) {
233 Operator op = node.selector.asOperator(); 236 Operator op = node.selector.asOperator();
234 bool spacesNeeded = op !== null && 237 bool spacesNeeded = op !== null &&
235 (op.source.stringValue === 'is' || op.source.stringValue == 'as'); 238 (op.source.stringValue === 'is' || op.source.stringValue == 'as');
236 239
237 if (node.isPrefix) { 240 if (node.isPrefix) {
238 visit(node.selector); 241 visit(node.selector);
239 } 242 }
240 if (node.receiver !== null) { 243 // TODO(smok): Remove ugly hack for library preferences.
244 // Check that renamer does not want to omit receiver at all,
245 // in that case we don't need spaces or dot.
246 if (node.receiver !== null && rename(node.receiver) != '') {
241 visit(node.receiver); 247 visit(node.receiver);
242 CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver(); 248 CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver();
243 if (asCascadeReceiver !== null) { 249 if (asCascadeReceiver !== null) {
244 add(asCascadeReceiver.cascadeOperator.value); 250 add(asCascadeReceiver.cascadeOperator.value);
245 } else if (op === null) { 251 } else if (op === null) {
246 sb.add('.'); 252 sb.add('.');
247 } else if (spacesNeeded) { 253 } else if (spacesNeeded) {
248 sb.add(' '); 254 sb.add(' ');
249 } 255 }
250 } 256 }
251 if (!node.isPrefix && !node.isIndex) { 257 if (!node.isPrefix && !node.isIndex) {
252 visit(node.selector); 258 visit(node.selector);
253 } 259 }
254 if (spacesNeeded) { 260 if (spacesNeeded) {
255 sb.add(' '); 261 sb.add(' ');
256 } 262 }
257 } 263 }
258 264
259 unparseSend(Send node) { 265 unparseSend(Send node) {
260 unparseSendPart(node); 266 unparseSendPart(node);
261 visit(node.argumentsNode); 267 visit(node.argumentsNode);
262 } 268 }
263 269
264 visitSend(Send node) { 270 visitSend(Send node) {
265 String newMethodName = renamer.renameSendMethod(node); 271 unparseSendPart(node);
266 if (newMethodName !== null) { 272 visit(node.argumentsNode);
267 sb.add(newMethodName);
268 visit(node.argumentsNode);
269 } else {
270 unparseSendPart(node);
271 visit(node.argumentsNode);
272 }
273 } 273 }
274 274
275 /** 275 /**
276 * Special case for assignments like "list[0] = 1". 276 * Special case for assignments like "list[0] = 1".
277 */ 277 */
278 unparseIndexedSet(SendSet node) { 278 unparseIndexedSet(SendSet node) {
279 if (node.isPrefix) { 279 if (node.isPrefix) {
280 add(node.assignmentOperator.token.value); 280 add(node.assignmentOperator.token.value);
281 } 281 }
282 visit(node.receiver); 282 visit(node.receiver);
(...skipping 28 matching lines...) Expand all
311 visitThrow(Throw node) { 311 visitThrow(Throw node) {
312 add(node.throwToken.value); 312 add(node.throwToken.value);
313 if (node.expression !== null) { 313 if (node.expression !== null) {
314 sb.add(' '); 314 sb.add(' ');
315 visit(node.expression); 315 visit(node.expression);
316 } 316 }
317 node.endToken.value.printOn(sb); 317 node.endToken.value.printOn(sb);
318 } 318 }
319 319
320 visitTypeAnnotation(TypeAnnotation node) { 320 visitTypeAnnotation(TypeAnnotation node) {
321 String newName = renamer.renameTypeName(node); 321 visit(node.typeName);
Anton Muhin 2012/08/08 08:27:20 what about TODO as was discussed before?
Roman 2012/08/09 05:02:35 As discussed, keeping as is.
322 if (newName !== null) { 322 visit(node.typeArguments);
323 sb.add(newName);
324 visit(node.typeArguments);
325 } else {
326 // Fallback to default unparse without renaming.
327 node.visitChildren(this);
328 }
329 } 323 }
330 324
331 visitTypeVariable(TypeVariable node) { 325 visitTypeVariable(TypeVariable node) {
332 visit(node.name); 326 visit(node.name);
333 if (node.bound !== null) { 327 if (node.bound !== null) {
334 sb.add(' extends '); 328 sb.add(' extends ');
335 visit(node.bound); 329 visit(node.bound);
336 } 330 }
337 } 331 }
338 332
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
510 sb.add(' '); 504 sb.add(' ');
511 } 505 }
512 visit(node.name); 506 visit(node.name);
513 if (node.typeParameters !== null) { 507 if (node.typeParameters !== null) {
514 visit(node.typeParameters); 508 visit(node.typeParameters);
515 } 509 }
516 visit(node.formals); 510 visit(node.formals);
517 add(node.endToken.value); 511 add(node.endToken.value);
518 } 512 }
519 } 513 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698