| 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 // Returns null if no need to rename a node. | |
| 6 typedef String Renamer(Node node); | |
| 7 | |
| 8 class Unparser implements Visitor { | 5 class Unparser implements Visitor { |
| 9 Renamer rename; | |
| 10 StringBuffer sb; | 6 StringBuffer sb; |
| 11 | 7 |
| 12 Unparser() { | |
| 13 // TODO(smok): Move this to initializer once dart2js stops complaining | |
| 14 // about closures in initializers. | |
| 15 rename = (Node node) => null; | |
| 16 } | |
| 17 Unparser.withRenamer(this.rename); | |
| 18 | |
| 19 String unparse(Node node) { | 8 String unparse(Node node) { |
| 20 sb = new StringBuffer(); | 9 sb = new StringBuffer(); |
| 21 visit(node); | 10 visit(node); |
| 22 return sb.toString(); | 11 return sb.toString(); |
| 23 } | 12 } |
| 24 | 13 |
| 25 void add(SourceString string) { | 14 void add(SourceString string) { |
| 26 string.printOn(sb); | 15 string.printOn(sb); |
| 27 } | 16 } |
| 28 | 17 |
| 29 void addToken(Token token) { | 18 void addToken(Token token) { |
| 30 if (token === null) return; | 19 if (token === null) return; |
| 31 add(token.value); | 20 add(token.value); |
| 32 if (token.kind === KEYWORD_TOKEN || token.kind === IDENTIFIER_TOKEN) { | 21 if (token.kind === KEYWORD_TOKEN || token.kind === IDENTIFIER_TOKEN) { |
| 33 sb.add(' '); | 22 sb.add(' '); |
| 34 } | 23 } |
| 35 } | 24 } |
| 36 | 25 |
| 37 visit(Node node) { | 26 visit(Node node) { |
| 38 if (node === null) return; | 27 if (node !== null) node.accept(this); |
| 39 String renamed = rename(node); | |
| 40 if (renamed !== null) { | |
| 41 sb.add(renamed); | |
| 42 } else { | |
| 43 // Fallback. | |
| 44 node.accept(this); | |
| 45 } | |
| 46 } | 28 } |
| 47 | 29 |
| 48 visitBlock(Block node) { | 30 visitBlock(Block node) { |
| 49 visit(node.statements); | 31 visit(node.statements); |
| 50 } | 32 } |
| 51 | 33 |
| 52 visitCascade(Cascade node) { | 34 visitCascade(Cascade node) { |
| 53 visit(node.expression); | 35 visit(node.expression); |
| 54 } | 36 } |
| 55 | 37 |
| (...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 245 visitReturn(Return node) { | 227 visitReturn(Return node) { |
| 246 add(node.beginToken.value); | 228 add(node.beginToken.value); |
| 247 if (node.hasExpression && node.beginToken.stringValue != '=>') { | 229 if (node.hasExpression && node.beginToken.stringValue != '=>') { |
| 248 sb.add(' '); | 230 sb.add(' '); |
| 249 } | 231 } |
| 250 visit(node.expression); | 232 visit(node.expression); |
| 251 if (node.endToken !== null) add(node.endToken.value); | 233 if (node.endToken !== null) add(node.endToken.value); |
| 252 } | 234 } |
| 253 | 235 |
| 254 unparseSendReceiver(Send node, [bool spacesNeeded=false]) { | 236 unparseSendReceiver(Send node, [bool spacesNeeded=false]) { |
| 255 // TODO(smok): Remove ugly hack for library preferences. | 237 if (node.receiver === null) return; |
| 256 // Check that renamer does not want to omit receiver at all, | 238 visit(node.receiver); |
| 257 // in that case we don't need spaces or dot. | 239 CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver(); |
| 258 if (node.receiver !== null && rename(node.receiver) != '') { | 240 if (asCascadeReceiver !== null) { |
| 259 visit(node.receiver); | 241 add(asCascadeReceiver.cascadeOperator.value); |
| 260 CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver(); | 242 } else if (node.selector.asOperator() === null) { |
| 261 if (asCascadeReceiver !== null) { | 243 sb.add('.'); |
| 262 add(asCascadeReceiver.cascadeOperator.value); | 244 } else if (spacesNeeded) { |
| 263 } else if (node.selector.asOperator() === null) { | 245 sb.add(' '); |
| 264 sb.add('.'); | |
| 265 } else if (spacesNeeded) { | |
| 266 sb.add(' '); | |
| 267 } | |
| 268 } | 246 } |
| 269 } | 247 } |
| 270 | 248 |
| 271 visitSend(Send node) { | 249 visitSend(Send node) { |
| 272 Operator op = node.selector.asOperator(); | 250 Operator op = node.selector.asOperator(); |
| 273 bool spacesNeeded = op !== null && | 251 bool spacesNeeded = op !== null && |
| 274 (op.source.stringValue === 'is' || op.source.stringValue == 'as'); | 252 (op.source.stringValue === 'is' || op.source.stringValue == 'as'); |
| 275 | 253 |
| 276 if (node.isPrefix) visit(node.selector); | 254 if (node.isPrefix) visit(node.selector); |
| 277 unparseSendReceiver(node, spacesNeeded: spacesNeeded); | 255 unparseSendReceiver(node, spacesNeeded: spacesNeeded); |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 sb.add(' '); | 473 sb.add(' '); |
| 496 } | 474 } |
| 497 visit(node.name); | 475 visit(node.name); |
| 498 if (node.typeParameters !== null) { | 476 if (node.typeParameters !== null) { |
| 499 visit(node.typeParameters); | 477 visit(node.typeParameters); |
| 500 } | 478 } |
| 501 visit(node.formals); | 479 visit(node.formals); |
| 502 add(node.endToken.value); | 480 add(node.endToken.value); |
| 503 } | 481 } |
| 504 } | 482 } |
| OLD | NEW |