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