Chromium Code Reviews| Index: lib/compiler/implementation/js/printer.dart |
| diff --git a/lib/compiler/implementation/js/printer.dart b/lib/compiler/implementation/js/printer.dart |
| index 958435332dbbd31204916b45e24b56bc2a734eb7..6b5d5e02a11fbfb52544f9c7a6506ee144922f58 100644 |
| --- a/lib/compiler/implementation/js/printer.dart |
| +++ b/lib/compiler/implementation/js/printer.dart |
| @@ -137,22 +137,14 @@ class Printer implements NodeVisitor { |
| Node then = node.then; |
| Node elsePart = node.otherwise; |
| bool hasElse = node.hasElse; |
| + |
| // Handle dangling elses. |
| - // If the then-branch is an if, which has no else-branch, but we do |
| - // have one, then we need to put the nested if into braces. |
| - if (hasElse && then is If) { |
| - Node nested = then; |
| - do { |
| - If nestedIf = nested; |
| - if (!nestedIf.hasElse) { |
| - then = new Block(<Statement>[then]); |
| - break; |
| - } |
| - nested = nestedIf.otherwise; |
| - } while (nested is If); |
| - } |
| - if (then is If && !(then as If).hasElse && hasElse) { |
| - then = new Block(<Statement>[then]); |
| + if (hasElse) { |
| + NodeVisitor danglingElseVisitor = new DanglingElseVisitor(compiler); |
|
kasperl
2012/08/14 13:42:24
Can this be reused? There's no state in the visito
floitsch
2012/08/14 13:46:48
Done.
|
| + bool needsBraces = node.then.accept(danglingElseVisitor); |
| + if (needsBraces) { |
| + then = new Block(<Statement>[then]); |
| + } |
| } |
| if (shouldIndent) indent(); |
| out("if"); |
| @@ -769,6 +761,56 @@ class Printer implements NodeVisitor { |
| } |
| } |
| +/** |
| + * Returns true, if the given node must be wrapped into braces when used |
| + * as then-statement in an [If] that has an else branch. |
| + */ |
| +class DanglingElseVisitor extends BaseVisitor<bool> { |
| + leg.Compiler compiler; |
| + |
| + DanglingElseVisitor(this.compiler); |
| + |
| + bool visitProgram(Program node) => false; |
| + |
| + bool visitNode(Statement node) { |
| + compiler.internalError("Forgot node: $node"); |
| + } |
| + |
| + bool visitBlock(Block node) => false; |
| + bool visitExpressionStatement(ExpressionStatement node) => false; |
| + bool visitEmptyStatement(EmptyStatement node) => false; |
| + bool visitIf(If node) { |
| + if (!node.hasElse) return true; |
| + return node.otherwise.accept(this); |
| + } |
| + bool visitFor(For node) => node.body.accept(this); |
| + bool visitForIn(ForIn node) => node.body.accept(this); |
| + bool visitWhile(While node) => node.body.accept(this); |
| + bool visitDo(Do node) => false; |
| + bool visitContinue(Continue node) => false; |
| + bool visitBreak(Break node) => false; |
| + bool visitReturn(Return node) => false; |
| + bool visitThrow(Throw node) => false; |
| + bool visitTry(Try node) { |
| + if (node.finallyPart != null) { |
| + return node.finallyPart.accept(this); |
| + } else { |
| + return node.catchPart.accept(this); |
| + } |
| + } |
| + bool visitCatch(Catch node) => node.body.accept(this); |
| + bool visitSwitch(Switch node) => false; |
| + bool visitCase(Case node) => false; |
| + bool visitDefault(Default node) => false; |
| + bool visitFunctionDeclaration(FunctionDeclaration node) => false; |
| + bool visitLabeledStatement(LabeledStatement node) |
| + => node.body.accept(this); |
| + bool visitLiteralStatement(LiteralStatement node) => true; |
| + |
| + bool visitExpression(Expression node) => false; |
| +} |
| + |
| + |
| leg.CodeBuffer prettyPrint(Node node, |
| leg.Compiler compiler, |
| Dynamic positionElement) { |