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 import '../tokens/token.dart' show BeginGroupToken, Token; | 5 import '../tokens/token.dart' show BeginGroupToken, Token; |
6 import '../tokens/token_constants.dart' as Tokens show IDENTIFIER_TOKEN, KEYWORD
_TOKEN, PLUS_TOKEN; | 6 import '../tokens/token_constants.dart' as Tokens |
| 7 show IDENTIFIER_TOKEN, KEYWORD_TOKEN, PLUS_TOKEN; |
7 import '../util/util.dart'; | 8 import '../util/util.dart'; |
8 import 'nodes.dart'; | 9 import 'nodes.dart'; |
9 | 10 |
10 String unparse(Node node, {minify: true}) { | 11 String unparse(Node node, {minify: true}) { |
11 Unparser unparser = new Unparser(minify: minify); | 12 Unparser unparser = new Unparser(minify: minify); |
12 unparser.unparse(node); | 13 unparser.unparse(node); |
13 return unparser.result; | 14 return unparser.result; |
14 } | 15 } |
15 | 16 |
16 class Unparser extends Indentation implements Visitor { | 17 class Unparser extends Indentation implements Visitor { |
(...skipping 13 matching lines...) Expand all Loading... |
30 } | 31 } |
31 } | 32 } |
32 | 33 |
33 void space([String token = " "]) { | 34 void space([String token = " "]) { |
34 write(minify ? "" : token); | 35 write(minify ? "" : token); |
35 } | 36 } |
36 | 37 |
37 void addToken(Token token) { | 38 void addToken(Token token) { |
38 if (token == null) return; | 39 if (token == null) return; |
39 write(token.value); | 40 write(token.value); |
40 if (identical(token.kind, Tokens.KEYWORD_TOKEN) | 41 if (identical(token.kind, Tokens.KEYWORD_TOKEN) || |
41 || identical(token.kind, Tokens.IDENTIFIER_TOKEN)) { | 42 identical(token.kind, Tokens.IDENTIFIER_TOKEN)) { |
42 write(' '); | 43 write(' '); |
43 } | 44 } |
44 } | 45 } |
45 | 46 |
46 bool onEmptyLine = true; | 47 bool onEmptyLine = true; |
47 | 48 |
48 write(object) { | 49 write(object) { |
49 String s = object.toString(); | 50 String s = object.toString(); |
50 if (s == '') return; | 51 if (s == '') return; |
51 if (onEmptyLine) { | 52 if (onEmptyLine) { |
52 sb.write(indentation); | 53 sb.write(indentation); |
53 } | 54 } |
54 sb.write(s); | 55 sb.write(s); |
55 onEmptyLine = false; | 56 onEmptyLine = false; |
56 } | 57 } |
57 | 58 |
58 unparse(Node node) { visit(node); } | 59 unparse(Node node) { |
| 60 visit(node); |
| 61 } |
59 | 62 |
60 visit(Node node) { | 63 visit(Node node) { |
61 if (node != null) node.accept(this); | 64 if (node != null) node.accept(this); |
62 } | 65 } |
63 | 66 |
64 visitAssert(Assert node) { | 67 visitAssert(Assert node) { |
65 write(node.assertToken.value); | 68 write(node.assertToken.value); |
66 write('('); | 69 write('('); |
67 visit(node.condition); | 70 visit(node.condition); |
68 if (node.hasMessage) { | 71 if (node.hasMessage) { |
(...skipping 19 matching lines...) Expand all Loading... |
88 visit(link.head); | 91 visit(link.head); |
89 } | 92 } |
90 indentLess(); | 93 indentLess(); |
91 newline(); | 94 newline(); |
92 } | 95 } |
93 if (statements.endToken != null) { | 96 if (statements.endToken != null) { |
94 write(statements.endToken.value); | 97 write(statements.endToken.value); |
95 } | 98 } |
96 } | 99 } |
97 | 100 |
98 | |
99 visitCascade(Cascade node) { | 101 visitCascade(Cascade node) { |
100 visit(node.expression); | 102 visit(node.expression); |
101 } | 103 } |
102 | 104 |
103 visitCascadeReceiver(CascadeReceiver node) { | 105 visitCascadeReceiver(CascadeReceiver node) { |
104 visit(node.expression); | 106 visit(node.expression); |
105 } | 107 } |
106 | 108 |
107 unparseClassWithBody(ClassNode node, members) { | 109 unparseClassWithBody(ClassNode node, members) { |
108 if (!node.modifiers.nodes.isEmpty) { | 110 if (!node.modifiers.nodes.isEmpty) { |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
209 visit(node.function); | 211 visit(node.function); |
210 } | 212 } |
211 | 213 |
212 void unparseFunctionName(Node name) { | 214 void unparseFunctionName(Node name) { |
213 // TODO(antonm): that's a workaround as currently FunctionExpression | 215 // TODO(antonm): that's a workaround as currently FunctionExpression |
214 // names are modelled with Send and it emits operator[] as only | 216 // names are modelled with Send and it emits operator[] as only |
215 // operator, without [] which are expected to be emitted with | 217 // operator, without [] which are expected to be emitted with |
216 // arguments. | 218 // arguments. |
217 if (name is Send) { | 219 if (name is Send) { |
218 Send send = name; | 220 Send send = name; |
219 assert(send is !SendSet); | 221 assert(send is! SendSet); |
220 if (!send.isOperator) { | 222 if (!send.isOperator) { |
221 // Looks like a factory method. | 223 // Looks like a factory method. |
222 visit(send.receiver); | 224 visit(send.receiver); |
223 write('.'); | 225 write('.'); |
224 } else { | 226 } else { |
225 visit(send.receiver); | 227 visit(send.receiver); |
226 Identifier identifier = send.selector.asIdentifier(); | 228 Identifier identifier = send.selector.asIdentifier(); |
227 if (identical(identifier.token.kind, Tokens.KEYWORD_TOKEN)) { | 229 if (identical(identifier.token.kind, Tokens.KEYWORD_TOKEN)) { |
228 write(' '); | 230 write(' '); |
229 } else if (identifier.source == 'negate') { | 231 } else if (identifier.source == 'negate') { |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
288 visitIf(If node) { | 290 visitIf(If node) { |
289 write(node.ifToken.value); | 291 write(node.ifToken.value); |
290 space(); | 292 space(); |
291 visit(node.condition); | 293 visit(node.condition); |
292 space(); | 294 space(); |
293 visit(node.thenPart); | 295 visit(node.thenPart); |
294 if (node.hasElsePart) { | 296 if (node.hasElsePart) { |
295 space(); | 297 space(); |
296 write(node.elseToken.value); | 298 write(node.elseToken.value); |
297 space(); | 299 space(); |
298 if (node.elsePart is !Block && minify) write(' '); | 300 if (node.elsePart is! Block && minify) write(' '); |
299 visit(node.elsePart); | 301 visit(node.elsePart); |
300 } | 302 } |
301 } | 303 } |
302 | 304 |
303 visitLiteralBool(LiteralBool node) { | 305 visitLiteralBool(LiteralBool node) { |
304 write(node.token.value); | 306 write(node.token.value); |
305 } | 307 } |
306 | 308 |
307 visitLiteralDouble(LiteralDouble node) { | 309 visitLiteralDouble(LiteralDouble node) { |
308 write(node.token.value); | 310 write(node.token.value); |
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
419 visitYield(Yield node) { | 421 visitYield(Yield node) { |
420 write(node.yieldToken.value); | 422 write(node.yieldToken.value); |
421 if (node.starToken != null) { | 423 if (node.starToken != null) { |
422 write(node.starToken.value); | 424 write(node.starToken.value); |
423 } | 425 } |
424 write(' '); | 426 write(' '); |
425 visit(node.expression); | 427 visit(node.expression); |
426 write(node.endToken.value); | 428 write(node.endToken.value); |
427 } | 429 } |
428 | 430 |
429 | |
430 unparseSendReceiver(Send node, {bool spacesNeeded: false}) { | 431 unparseSendReceiver(Send node, {bool spacesNeeded: false}) { |
431 if (node.receiver == null) return; | 432 if (node.receiver == null) return; |
432 visit(node.receiver); | 433 visit(node.receiver); |
433 CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver(); | 434 CascadeReceiver asCascadeReceiver = node.receiver.asCascadeReceiver(); |
434 if (asCascadeReceiver != null) { | 435 if (asCascadeReceiver != null) { |
435 newline(); | 436 newline(); |
436 indentMore(); | 437 indentMore(); |
437 indentMore(); | 438 indentMore(); |
438 write(asCascadeReceiver.cascadeOperator.value); | 439 write(asCascadeReceiver.cascadeOperator.value); |
439 indentLess(); | 440 indentLess(); |
440 indentLess(); | 441 indentLess(); |
441 } else if (node.selector.asOperator() == null) { | 442 } else if (node.selector.asOperator() == null) { |
442 write(node.isConditional ? '?.' : '.'); | 443 write(node.isConditional ? '?.' : '.'); |
443 } else if (spacesNeeded) { | 444 } else if (spacesNeeded) { |
444 write(' '); | 445 write(' '); |
445 } | 446 } |
446 } | 447 } |
447 | 448 |
448 unparseSendArgument(Send node, {bool spacesNeeded: false}) { | 449 unparseSendArgument(Send node, {bool spacesNeeded: false}) { |
449 if (node.argumentsNode == null) return; | 450 if (node.argumentsNode == null) return; |
450 | 451 |
451 if(node.isIsNotCheck) { | 452 if (node.isIsNotCheck) { |
452 Send argNode = node.arguments.head; | 453 Send argNode = node.arguments.head; |
453 visit(argNode.selector); | 454 visit(argNode.selector); |
454 space(); | 455 space(); |
455 visit(argNode.receiver); | 456 visit(argNode.receiver); |
456 } else { | 457 } else { |
457 if (spacesNeeded) write(' '); | 458 if (spacesNeeded) write(' '); |
458 visit(node.argumentsNode); | 459 visit(node.argumentsNode); |
459 } | 460 } |
460 } | 461 } |
461 | 462 |
462 visitSend(Send node) { | 463 visitSend(Send node) { |
463 Operator op = node.selector.asOperator(); | 464 Operator op = node.selector.asOperator(); |
464 String opString = op != null ? op.source : null; | 465 String opString = op != null ? op.source : null; |
465 bool spacesNeeded = minify | 466 bool spacesNeeded = minify |
466 ? identical(opString, 'is') || identical(opString, 'as') | 467 ? identical(opString, 'is') || identical(opString, 'as') |
467 : (opString != null && !node.isPrefix && !node.isIndex); | 468 : (opString != null && !node.isPrefix && !node.isIndex); |
468 | 469 |
469 void minusMinusSpace(Node other) { | 470 void minusMinusSpace(Node other) { |
470 if (other != null && opString == '-') { | 471 if (other != null && opString == '-') { |
471 Token beginToken = other.getBeginToken(); | 472 Token beginToken = other.getBeginToken(); |
472 if (beginToken != null && beginToken.stringValue != null && beginToken.s
tringValue.startsWith('-')) { | 473 if (beginToken != null && |
| 474 beginToken.stringValue != null && |
| 475 beginToken.stringValue.startsWith('-')) { |
473 sb.write(' '); | 476 sb.write(' '); |
474 spacesNeeded = false; | 477 spacesNeeded = false; |
475 } | 478 } |
476 } | 479 } |
477 } | 480 } |
478 | 481 |
479 if (node.isPrefix) { | 482 if (node.isPrefix) { |
480 visit(node.selector); | 483 visit(node.selector); |
481 // Add a space for sequences like - -x (double unary minus). | 484 // Add a space for sequences like - -x (double unary minus). |
482 minusMinusSpace(node.receiver); | 485 minusMinusSpace(node.receiver); |
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
569 // it if the 'type; is var. | 572 // it if the 'type; is var. |
570 if (node.type != null) { | 573 if (node.type != null) { |
571 visit(node.type); | 574 visit(node.type); |
572 write(' '); | 575 write(' '); |
573 } | 576 } |
574 visit(node.definitions); | 577 visit(node.definitions); |
575 } | 578 } |
576 | 579 |
577 visitDoWhile(DoWhile node) { | 580 visitDoWhile(DoWhile node) { |
578 write(node.doKeyword.value); | 581 write(node.doKeyword.value); |
579 if (node.body is !Block) { | 582 if (node.body is! Block) { |
580 write(' '); | 583 write(' '); |
581 } else { | 584 } else { |
582 space(); | 585 space(); |
583 } | 586 } |
584 visit(node.body); | 587 visit(node.body); |
585 space(); | 588 space(); |
586 write(node.whileKeyword.value); | 589 write(node.whileKeyword.value); |
587 space(); | 590 space(); |
588 visit(node.condition); | 591 visit(node.condition); |
589 write(node.endToken.value); | 592 write(node.endToken.value); |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
644 write('('); | 647 write('('); |
645 visit(node.declaredIdentifier); | 648 visit(node.declaredIdentifier); |
646 write(' '); | 649 write(' '); |
647 addToken(node.inToken); | 650 addToken(node.inToken); |
648 visit(node.expression); | 651 visit(node.expression); |
649 write(')'); | 652 write(')'); |
650 space(); | 653 space(); |
651 visit(node.body); | 654 visit(node.body); |
652 } | 655 } |
653 | 656 |
654 | |
655 visitSyncForIn(SyncForIn node) { | 657 visitSyncForIn(SyncForIn node) { |
656 write(node.forToken.value); | 658 write(node.forToken.value); |
657 space(); | 659 space(); |
658 write('('); | 660 write('('); |
659 visit(node.declaredIdentifier); | 661 visit(node.declaredIdentifier); |
660 write(' '); | 662 write(' '); |
661 addToken(node.inToken); | 663 addToken(node.inToken); |
662 visit(node.expression); | 664 visit(node.expression); |
663 write(')'); | 665 write(')'); |
664 space(); | 666 space(); |
665 visit(node.body); | 667 visit(node.body); |
666 } | 668 } |
667 | 669 |
668 visitLabel(Label node) { | 670 visitLabel(Label node) { |
669 visit(node.identifier); | 671 visit(node.identifier); |
670 write(node.colonToken.value); | 672 write(node.colonToken.value); |
671 } | 673 } |
672 | 674 |
673 visitLabeledStatement(LabeledStatement node) { | 675 visitLabeledStatement(LabeledStatement node) { |
674 visit(node.labels); | 676 visit(node.labels); |
675 visit(node.statement); | 677 visit(node.statement); |
676 } | 678 } |
677 | 679 |
678 visitLiteralMap(LiteralMap node) { | 680 visitLiteralMap(LiteralMap node) { |
679 if (node.constKeyword != null) write(node.constKeyword.value); | 681 if (node.constKeyword != null) write(node.constKeyword.value); |
680 if (node.typeArguments != null) visit(node.typeArguments); | 682 if (node.typeArguments != null) visit(node.typeArguments); |
681 visit(node.entries); | 683 visit(node.entries); |
(...skipping 29 matching lines...) Expand all Loading... |
711 } | 713 } |
712 unparseBlockStatements(node.statements); | 714 unparseBlockStatements(node.statements); |
713 indentLess(); | 715 indentLess(); |
714 } | 716 } |
715 | 717 |
716 unparseLibraryName(String libraryName) { | 718 unparseLibraryName(String libraryName) { |
717 write('library $libraryName;'); | 719 write('library $libraryName;'); |
718 newline(); | 720 newline(); |
719 } | 721 } |
720 | 722 |
721 unparseImportTag(String uri, {String prefix, | 723 unparseImportTag(String uri, |
722 List<String> shows: const <String>[], | 724 {String prefix, |
723 bool isDeferred: false}) { | 725 List<String> shows: const <String>[], |
| 726 bool isDeferred: false}) { |
724 String deferredString = isDeferred ? ' deferred' : ''; | 727 String deferredString = isDeferred ? ' deferred' : ''; |
725 String prefixString = prefix == null ? '' : ' as $prefix'; | 728 String prefixString = prefix == null ? '' : ' as $prefix'; |
726 String showString = shows.isEmpty ? '' : ' show ${shows.join(", ")}'; | 729 String showString = shows.isEmpty ? '' : ' show ${shows.join(", ")}'; |
727 write('import "$uri"$deferredString$prefixString$showString;'); | 730 write('import "$uri"$deferredString$prefixString$showString;'); |
728 newline(); | 731 newline(); |
729 } | 732 } |
730 | 733 |
731 unparseExportTag(String uri, {List<String> shows: const []}) { | 734 unparseExportTag(String uri, {List<String> shows: const []}) { |
732 String suffix = shows.isEmpty ? '' : ' show ${shows.join(", ")}'; | 735 String suffix = shows.isEmpty ? '' : ' show ${shows.join(", ")}'; |
733 write('export "$uri"$suffix;'); | 736 write('export "$uri"$suffix;'); |
(...skipping 164 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
898 } | 901 } |
899 | 902 |
900 visitStatement(Statement node) { | 903 visitStatement(Statement node) { |
901 throw 'internal error'; // Should not be called. | 904 throw 'internal error'; // Should not be called. |
902 } | 905 } |
903 | 906 |
904 visitStringNode(StringNode node) { | 907 visitStringNode(StringNode node) { |
905 throw 'internal error'; // Should not be called. | 908 throw 'internal error'; // Should not be called. |
906 } | 909 } |
907 } | 910 } |
OLD | NEW |