| 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 Printer implements NodeVisitor { | 5 class Printer implements NodeVisitor { |
| 6 final bool shouldCompressOutput = false; | 6 final bool shouldCompressOutput = false; |
| 7 leg.Compiler compiler; | 7 leg.Compiler compiler; |
| 8 var positionElement; | 8 var positionElement; |
| 9 leg.CodeBuffer outBuffer; | 9 leg.CodeBuffer outBuffer; |
| 10 int indentLevel = 0; | 10 int indentLevel = 0; |
| 11 bool inForInit = false; | 11 bool inForInit = false; |
| 12 bool atStatementBegin = false; | 12 bool atStatementBegin = false; |
| 13 final DanglingElseVisitor danglingElseVisitor; |
| 13 | 14 |
| 14 Printer(this.compiler, this.positionElement) | 15 Printer(leg.Compiler compiler, this.positionElement) |
| 15 : outBuffer = new leg.CodeBuffer(); | 16 : this.compiler = compiler, |
| 17 outBuffer = new leg.CodeBuffer(), |
| 18 danglingElseVisitor = new DanglingElseVisitor(compiler); |
| 16 | 19 |
| 17 void spaceOut() { | 20 void spaceOut() { |
| 18 if (!shouldCompressOutput) out(" "); | 21 if (!shouldCompressOutput) out(" "); |
| 19 } | 22 } |
| 20 void lineOut() { | 23 void lineOut() { |
| 21 if (!shouldCompressOutput) out("\n"); | 24 if (!shouldCompressOutput) out("\n"); |
| 22 } | 25 } |
| 23 | 26 |
| 24 String lastAddedString = null; | 27 String lastAddedString = null; |
| 25 int get lastCharCode() { | 28 int get lastCharCode() { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 130 } | 133 } |
| 131 | 134 |
| 132 visitEmptyStatement(EmptyStatement nop) { | 135 visitEmptyStatement(EmptyStatement nop) { |
| 133 outIndentLn(";"); | 136 outIndentLn(";"); |
| 134 } | 137 } |
| 135 | 138 |
| 136 void ifOut(If node, bool shouldIndent) { | 139 void ifOut(If node, bool shouldIndent) { |
| 137 Node then = node.then; | 140 Node then = node.then; |
| 138 Node elsePart = node.otherwise; | 141 Node elsePart = node.otherwise; |
| 139 bool hasElse = node.hasElse; | 142 bool hasElse = node.hasElse; |
| 143 |
| 140 // Handle dangling elses. | 144 // Handle dangling elses. |
| 141 // If the then-branch is an if, which has no else-branch, but we do | 145 if (hasElse) { |
| 142 // have one, then we need to put the nested if into braces. | 146 bool needsBraces = node.then.accept(danglingElseVisitor); |
| 143 if (hasElse && then is If) { | 147 if (needsBraces) { |
| 144 Node nested = then; | 148 then = new Block(<Statement>[then]); |
| 145 do { | 149 } |
| 146 If nestedIf = nested; | |
| 147 if (!nestedIf.hasElse) { | |
| 148 then = new Block(<Statement>[then]); | |
| 149 break; | |
| 150 } | |
| 151 nested = nestedIf.otherwise; | |
| 152 } while (nested is If); | |
| 153 } | |
| 154 if (then is If && !(then as If).hasElse && hasElse) { | |
| 155 then = new Block(<Statement>[then]); | |
| 156 } | 150 } |
| 157 if (shouldIndent) indent(); | 151 if (shouldIndent) indent(); |
| 158 out("if"); | 152 out("if"); |
| 159 spaceOut(); | 153 spaceOut(); |
| 160 out("("); | 154 out("("); |
| 161 visitNestedExpression(node.condition, EXPRESSION, | 155 visitNestedExpression(node.condition, EXPRESSION, |
| 162 newInForInit: false, newAtStatementBegin: false); | 156 newInForInit: false, newAtStatementBegin: false); |
| 163 out(")"); | 157 out(")"); |
| 164 bool thenWasBlock = | 158 bool thenWasBlock = |
| 165 blockBody(then, needsSeparation: false, needsNewline: !hasElse); | 159 blockBody(then, needsSeparation: false, needsNewline: !hasElse); |
| (...skipping 596 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 762 out(parts[i + 1]); | 756 out(parts[i + 1]); |
| 763 } | 757 } |
| 764 out(")"); | 758 out(")"); |
| 765 } | 759 } |
| 766 | 760 |
| 767 visitLiteralStatement(LiteralStatement node) { | 761 visitLiteralStatement(LiteralStatement node) { |
| 768 outLn(node.code); | 762 outLn(node.code); |
| 769 } | 763 } |
| 770 } | 764 } |
| 771 | 765 |
| 766 /** |
| 767 * Returns true, if the given node must be wrapped into braces when used |
| 768 * as then-statement in an [If] that has an else branch. |
| 769 */ |
| 770 class DanglingElseVisitor extends BaseVisitor<bool> { |
| 771 leg.Compiler compiler; |
| 772 |
| 773 DanglingElseVisitor(this.compiler); |
| 774 |
| 775 bool visitProgram(Program node) => false; |
| 776 |
| 777 bool visitNode(Statement node) { |
| 778 compiler.internalError("Forgot node: $node"); |
| 779 } |
| 780 |
| 781 bool visitBlock(Block node) => false; |
| 782 bool visitExpressionStatement(ExpressionStatement node) => false; |
| 783 bool visitEmptyStatement(EmptyStatement node) => false; |
| 784 bool visitIf(If node) { |
| 785 if (!node.hasElse) return true; |
| 786 return node.otherwise.accept(this); |
| 787 } |
| 788 bool visitFor(For node) => node.body.accept(this); |
| 789 bool visitForIn(ForIn node) => node.body.accept(this); |
| 790 bool visitWhile(While node) => node.body.accept(this); |
| 791 bool visitDo(Do node) => false; |
| 792 bool visitContinue(Continue node) => false; |
| 793 bool visitBreak(Break node) => false; |
| 794 bool visitReturn(Return node) => false; |
| 795 bool visitThrow(Throw node) => false; |
| 796 bool visitTry(Try node) { |
| 797 if (node.finallyPart != null) { |
| 798 return node.finallyPart.accept(this); |
| 799 } else { |
| 800 return node.catchPart.accept(this); |
| 801 } |
| 802 } |
| 803 bool visitCatch(Catch node) => node.body.accept(this); |
| 804 bool visitSwitch(Switch node) => false; |
| 805 bool visitCase(Case node) => false; |
| 806 bool visitDefault(Default node) => false; |
| 807 bool visitFunctionDeclaration(FunctionDeclaration node) => false; |
| 808 bool visitLabeledStatement(LabeledStatement node) |
| 809 => node.body.accept(this); |
| 810 bool visitLiteralStatement(LiteralStatement node) => true; |
| 811 |
| 812 bool visitExpression(Expression node) => false; |
| 813 } |
| 814 |
| 815 |
| 772 leg.CodeBuffer prettyPrint(Node node, | 816 leg.CodeBuffer prettyPrint(Node node, |
| 773 leg.Compiler compiler, | 817 leg.Compiler compiler, |
| 774 Dynamic positionElement) { | 818 Dynamic positionElement) { |
| 775 Printer printer = new Printer(compiler, positionElement); | 819 Printer printer = new Printer(compiler, positionElement); |
| 776 printer.visit(node); | 820 printer.visit(node); |
| 777 return printer.outBuffer; | 821 return printer.outBuffer; |
| 778 } | 822 } |
| OLD | NEW |