| 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 String unparse(Node node) { | 5 String unparse(Node node) { |
| 9 Unparser unparser = new Unparser(); | 6 Unparser unparser = new Unparser(); |
| 10 unparser.unparse(node); | 7 unparser.unparse(node); |
| 11 return unparser.result; | 8 return unparser.result; |
| 12 } | 9 } |
| 13 | 10 |
| 14 class Unparser implements Visitor { | 11 class Unparser implements Visitor { |
| 15 Renamer rename; | |
| 16 final StringBuffer sb; | 12 final StringBuffer sb; |
| 17 | 13 |
| 18 String get result => sb.toString(); | 14 String get result => sb.toString(); |
| 19 | 15 |
| 20 Unparser() : sb = new StringBuffer() { | 16 Unparser() : sb = new StringBuffer(); |
| 21 // TODO(smok): Move this to initializer once dart2js stops complaining | |
| 22 // about closures in initializers. | |
| 23 rename = (Node node) => null; | |
| 24 } | |
| 25 Unparser.withRenamer(this.rename) : sb = new StringBuffer(); | |
| 26 | 17 |
| 27 void add(SourceString string) { | 18 void add(SourceString string) { |
| 28 string.printOn(sb); | 19 string.printOn(sb); |
| 29 } | 20 } |
| 30 | 21 |
| 31 void addToken(Token token) { | 22 void addToken(Token token) { |
| 32 if (token === null) return; | 23 if (token === null) return; |
| 33 add(token.value); | 24 add(token.value); |
| 34 if (token.kind === KEYWORD_TOKEN || token.kind === IDENTIFIER_TOKEN) { | 25 if (token.kind === KEYWORD_TOKEN || token.kind === IDENTIFIER_TOKEN) { |
| 35 sb.add(' '); | 26 sb.add(' '); |
| 36 } | 27 } |
| 37 } | 28 } |
| 38 | 29 |
| 39 unparse(Node node) { visit(node); } | 30 unparse(Node node) { visit(node); } |
| 40 | 31 |
| 41 visit(Node node) { | 32 visit(Node node) { |
| 42 if (node === null) return; | 33 if (node !== null) node.accept(this); |
| 43 String renamed = rename(node); | |
| 44 if (renamed !== null) { | |
| 45 sb.add(renamed); | |
| 46 } else { | |
| 47 // Fallback. | |
| 48 node.accept(this); | |
| 49 } | |
| 50 } | 34 } |
| 51 | 35 |
| 52 visitBlock(Block node) { | 36 visitBlock(Block node) { |
| 53 visit(node.statements); | 37 visit(node.statements); |
| 54 } | 38 } |
| 55 | 39 |
| 56 visitCascade(Cascade node) { | 40 visitCascade(Cascade node) { |
| 57 visit(node.expression); | 41 visit(node.expression); |
| 58 } | 42 } |
| 59 | 43 |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 visitReturn(Return node) { | 238 visitReturn(Return node) { |
| 255 add(node.beginToken.value); | 239 add(node.beginToken.value); |
| 256 if (node.hasExpression && node.beginToken.stringValue != '=>') { | 240 if (node.hasExpression && node.beginToken.stringValue != '=>') { |
| 257 sb.add(' '); | 241 sb.add(' '); |
| 258 } | 242 } |
| 259 visit(node.expression); | 243 visit(node.expression); |
| 260 if (node.endToken !== null) add(node.endToken.value); | 244 if (node.endToken !== null) add(node.endToken.value); |
| 261 } | 245 } |
| 262 | 246 |
| 263 unparseSendReceiver(Send node, [bool spacesNeeded=false]) { | 247 unparseSendReceiver(Send node, [bool spacesNeeded=false]) { |
| 264 // TODO(smok): Remove ugly hack for library preferences. | 248 if (node.receiver === null) return; |
| 265 // Check that renamer does not want to omit receiver at all, | 249 visit(node.receiver); |
| 266 // in that case we don't need spaces or dot. | 250 CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver(); |
| 267 if (node.receiver !== null && rename(node.receiver) != '') { | 251 if (asCascadeReceiver !== null) { |
| 268 visit(node.receiver); | 252 add(asCascadeReceiver.cascadeOperator.value); |
| 269 CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver(); | 253 } else if (node.selector.asOperator() === null) { |
| 270 if (asCascadeReceiver !== null) { | 254 sb.add('.'); |
| 271 add(asCascadeReceiver.cascadeOperator.value); | 255 } else if (spacesNeeded) { |
| 272 } else if (node.selector.asOperator() === null) { | 256 sb.add(' '); |
| 273 sb.add('.'); | |
| 274 } else if (spacesNeeded) { | |
| 275 sb.add(' '); | |
| 276 } | |
| 277 } | 257 } |
| 278 } | 258 } |
| 279 | 259 |
| 280 visitSend(Send node) { | 260 visitSend(Send node) { |
| 281 Operator op = node.selector.asOperator(); | 261 Operator op = node.selector.asOperator(); |
| 282 bool spacesNeeded = op !== null && | 262 bool spacesNeeded = op !== null && |
| 283 (op.source.stringValue === 'is' || op.source.stringValue == 'as'); | 263 (op.source.stringValue === 'is' || op.source.stringValue == 'as'); |
| 284 | 264 |
| 285 if (node.isPrefix) visit(node.selector); | 265 if (node.isPrefix) visit(node.selector); |
| 286 unparseSendReceiver(node, spacesNeeded: spacesNeeded); | 266 unparseSendReceiver(node, spacesNeeded: spacesNeeded); |
| (...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 509 sb.add(' '); | 489 sb.add(' '); |
| 510 } | 490 } |
| 511 visit(node.name); | 491 visit(node.name); |
| 512 if (node.typeParameters !== null) { | 492 if (node.typeParameters !== null) { |
| 513 visit(node.typeParameters); | 493 visit(node.typeParameters); |
| 514 } | 494 } |
| 515 visit(node.formals); | 495 visit(node.formals); |
| 516 add(node.endToken.value); | 496 add(node.endToken.value); |
| 517 } | 497 } |
| 518 } | 498 } |
| OLD | NEW |