// Copyright (c) 2014, the Dart project authors.  Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.

library dart_tree_printer;

import 'dart_printer.dart';
import '../tree/tree.dart' as tree;
import '../scanner/scannerlib.dart';
import '../util/util.dart';
import '../dart2jslib.dart' as dart2js;
import '../util/characters.dart' as characters;
import '../elements/elements.dart' as elements;
import '../dart_types.dart' as types;

/// Converts backend ASTs to frontend ASTs.
class TreePrinter {
  dart2js.TreeElementMapping treeElements;

  TreePrinter([this.treeElements]);

  void setElement(tree.Node node, elements.Element element, source) {
    if (treeElements != null) {
      if (element == null) {
        throw "Missing element from ${source}";
      }
      treeElements[node] = element;
    }
  }

  void setType(tree.Node node, types.DartType type, source) {
    if (treeElements != null) {
      if (type == null) {
        throw "Missing type from ${source}";
      }
      treeElements.setType(node, type);
    }
  }

  // Group tokens: () [] {} <>
  static BeginGroupToken makeGroup(PrecedenceInfo open, PrecedenceInfo close) {
    BeginGroupToken openTok = new BeginGroupToken(open, -1);
    openTok.endGroup = new SymbolToken(close, -1);
    return openTok;
  }

  final BeginGroupToken openParen = makeGroup(OPEN_PAREN_INFO,
                                              CLOSE_PAREN_INFO);
  final BeginGroupToken openBrace = makeGroup(OPEN_CURLY_BRACKET_INFO,
                                              CLOSE_CURLY_BRACKET_INFO);
  final BeginGroupToken openBracket = makeGroup(OPEN_SQUARE_BRACKET_INFO,
                                                CLOSE_SQUARE_BRACKET_INFO);
  final BeginGroupToken lt = makeGroup(LT_INFO, GT_INFO);

  Token get closeParen => openParen.endGroup;
  Token get closeBrace => openBrace.endGroup;
  Token get closeBracket => openBracket.endGroup;
  Token get gt => lt.endGroup;

  // Symbol tokens
  final Token semicolon = new SymbolToken(SEMICOLON_INFO, -1);
  final Token indexToken = new SymbolToken(INDEX_INFO, -1); // "[]"
  final Token question = new SymbolToken(QUESTION_INFO, -1);
  final Token colon = new SymbolToken(COLON_INFO, -1);
  final Token hash = new SymbolToken(HASH_INFO, -1);
  final Token bang = new SymbolToken(BANG_INFO, -1);
  final Token eq = new SymbolToken(EQ_INFO, -1);

  // Keyword tokens
  static Token makeIdToken(String text) {
    return new StringToken.fromString(IDENTIFIER_INFO, text, -1);
  }
  final Token newToken = makeIdToken('new');
  final Token constToken = makeIdToken('const');
  final Token throwToken = makeIdToken('throw');
  final Token rethrowToken = makeIdToken('rethrow');
  final Token breakToken = makeIdToken('break');
  final Token continueToken = makeIdToken('continue');
  final Token doToken = makeIdToken('do');
  final Token whileToken = makeIdToken('while');
  final Token ifToken = makeIdToken('if');
  final Token elseToken = makeIdToken('else');
  final Token forToken = makeIdToken('for');
  final Token inToken = makeIdToken('in');
  final Token returnToken = makeIdToken('return');
  final Token switchToken = makeIdToken('switch');
  final Token caseToken = makeIdToken('case');
  final Token defaultToken = makeIdToken('default');
  final Token tryToken = makeIdToken('try');
  final Token catchToken = makeIdToken('catch');
  final Token onToken = makeIdToken('on');
  final Token finallyToken = makeIdToken('finally');

  static tree.Identifier makeIdentifier(String name) {
    return new tree.Identifier(
        new StringToken.fromString(IDENTIFIER_INFO, name, -1));
  }

  // Utilities for creating NodeLists
  Link<tree.Node> makeLink(Iterable<tree.Node> nodes) {
    LinkBuilder builder = new LinkBuilder();
    for (tree.Node node in nodes) {
      builder.addLast(node);
    }
    return builder.toLink();
  }

  tree.NodeList blankList() {
    return new tree.NodeList(null, makeLink([]), null, '');
  }
  tree.NodeList singleton(tree.Node node) {
    return new tree.NodeList(null, makeLink([node]), null, '');
  }
  tree.NodeList makeList(String delimiter,
                         Iterable<tree.Node> nodes,
                         { Token open,
                           Token close }) {
    return new tree.NodeList(open, makeLink(nodes), close, delimiter);
  }
  tree.NodeList parenList(String delimiter, Iterable<tree.Node> nodes) {
    return makeList(delimiter, nodes, open: openParen, close: closeParen);
  }
  tree.NodeList bracketList(String delimiter, Iterable<tree.Node> nodes) {
    return makeList(delimiter, nodes, open: openBracket, close: closeBracket);
  }
  tree.NodeList braceList(String delimiter, Iterable<tree.Node> nodes) {
    return makeList(delimiter, nodes, open: openBrace, close: closeBrace);
  }
  tree.NodeList argList(Iterable<tree.Node> nodes) {
    return parenList(',', nodes);
  }
  tree.NodeList typeArgList(Iterable<tree.Node> nodes) {
    return makeList(',', nodes, open: lt, close: gt);
  }

  /// Converts a qualified name into nested Sends.
  tree.Node makeName(String name) {
    if (name == null) {
      return null;
    }
    List<String> names = name.split('.').toList(growable:false);
    tree.Node node = makeIdentifier(names[0]);
    for (int i = 1; i < names.length; i++) {
      node = new tree.Send(node, makeIdentifier(names[i]));
    }
    return node;
  }

  static Token assignmentToken(String operatorName) {
    switch (operatorName) {
      case '=': return new SymbolToken(EQ_INFO, -1);
      case '+=': return new SymbolToken(PLUS_EQ_INFO, -1);
      case '-=': return new SymbolToken(MINUS_EQ_INFO, -1);
      case '*=': return new SymbolToken(STAR_EQ_INFO, -1);
      case '/=': return new SymbolToken(SLASH_EQ_INFO, -1);
      case '~/=': return new SymbolToken(TILDE_SLASH_EQ_INFO, -1);
      case '%=': return new SymbolToken(PERCENT_EQ_INFO, -1);
      case '&=': return new SymbolToken(AMPERSAND_EQ_INFO, -1);
      case '^=': return new SymbolToken(CARET_EQ_INFO, -1);
      case '|=': return new SymbolToken(BAR_EQ_INFO, -1);
      case '>>=': return new SymbolToken(GT_GT_EQ_INFO, -1);
      case '<<=': return new SymbolToken(LT_LT_EQ_INFO, -1);
      default:
        throw "Unrecognized assignment operator: $operatorName";
    }
  }

  static Token binopToken(String operatorName) {
    switch (operatorName) {
      case '+': return new SymbolToken(PLUS_INFO, -1);
      case '-': return new SymbolToken(MINUS_INFO, -1);
      case '*': return new SymbolToken(STAR_INFO, -1);
      case '/': return new SymbolToken(SLASH_INFO, -1);
      case '~/': return new SymbolToken(TILDE_SLASH_INFO, -1);
      case '%': return new SymbolToken(PERCENT_INFO, -1);
      case '&': return new SymbolToken(AMPERSAND_INFO, -1);
      case '^': return new SymbolToken(CARET_INFO, -1);
      case '|': return new SymbolToken(BAR_INFO, -1);
      case '>>': return new SymbolToken(GT_GT_INFO, -1);
      case '<<': return new SymbolToken(LT_LT_INFO, -1);
      case '==': return new SymbolToken(EQ_EQ_INFO, -1);
      case '!=': return new SymbolToken(BANG_EQ_INFO, -1);
      case '>': return new SymbolToken(GT_INFO, -1);
      case '>=': return new SymbolToken(GT_EQ_INFO, -1);
      case '<': return new SymbolToken(LT_INFO, -1);
      case '<=': return new SymbolToken(LT_EQ_INFO, -1);
      case '&&': return new SymbolToken(AMPERSAND_AMPERSAND_INFO, -1);
      case '||': return new SymbolToken(BAR_BAR_INFO, -1);
      default:
        throw "Unrecognized binary operator: $operatorName";
    }
  }

  static Token incrementToken(String operatorName) {
    switch (operatorName) {
      case '++': return new SymbolToken(PLUS_PLUS_INFO, -1);
      case '--': return new SymbolToken(MINUS_MINUS_INFO, -1);
      default:
        throw "Unrecognized increment operator: $operatorName";
    }
  }

  static Token typeOpToken(String operatorName) {
    switch (operatorName) { // "is!" is not an operator in the frontend AST.
      case 'is': return new SymbolToken(IS_INFO, -1);
      case 'as': return new SymbolToken(AS_INFO, -1);
      default:
        throw 'Unrecognized type operator: $operatorName';
    }
  }

  Token unopToken(String operatorName) {
    switch (operatorName) {
      case '-': return new SymbolToken(MINUS_INFO, -1);
      case '~': return new SymbolToken(TILDE_INFO, -1);
      case '!': return bang;
      default:
        throw "Unrecognized unary operator: $operatorName";
    }
  }

  tree.Node makeArgument(Argument arg) {
    if (arg is Expression) {
      return makeExpression(arg);
    } else if (arg is NamedArgument) {
      return new tree.NamedArgument(
          makeIdentifier(arg.name),
          colon,
          makeExpression(arg.expression));
    } else {
      throw "Unrecognized argument type: ${arg}";
    }
  }

  tree.Node makeExpression(Expression exp) {
    return makeExp(exp, EXPRESSION);
  }

  /// Converts [exp] to a [tree.Node] that unparses to an expression with
  /// a precedence level of at least [minPrecedence]. The expression will be
  /// wrapped in a parenthesis if necessary.
  tree.Node makeExp(Receiver exp, int minPrecedence, {bool beginStmt: false}) {
    tree.Node result;
    int precedence;
    bool needParen = false;
    if (exp is SuperReceiver) {
      precedence = CALLEE;
      result = makeIdentifier('super');
    } else if (exp is Assignment) {
      Expression left = exp.left;
      tree.Node receiver;
      tree.Node selector;
      tree.NodeList arguments;
      elements.Element element;
      if (left is Identifier) {
        receiver = null;
        selector = makeIdentifier(left.name);
        arguments = singleton(makeExpression(exp.right));
        element = left.element;
      } else if (left is FieldExpression) {
        receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt);
        selector = makeIdentifier(left.fieldName);
        arguments = singleton(makeExpression(exp.right));
      } else if (left is IndexExpression) {
        receiver = makeExp(left.object, PRIMARY, beginStmt: beginStmt);
        selector = new tree.Operator(indexToken);
        arguments = bracketList(',',
            [makeExpression(left.index), makeExpression(exp.right)]);
      } else {
        throw "Unexpected left-hand side of assignment: ${left}";
      }
      tree.Operator op = new tree.Operator(assignmentToken(exp.operatorName));
      result = new tree.SendSet(receiver, selector, op, arguments);
      if (left is Identifier) {
        setElement(result, element, exp);
      }
      precedence = EXPRESSION;
    } else if (exp is BinaryOperator) {
      precedence = BINARY_PRECEDENCE[exp.operatorName];
      int deltaLeft = isAssociativeBinaryOperator(precedence) ? 0 : 1;
      result = new tree.Send(
          makeExp(exp.left, precedence + deltaLeft, beginStmt: beginStmt),
          new tree.Operator(binopToken(exp.operatorName)),
          singleton(makeExp(exp.right, precedence + 1)));
    } else if (exp is CallFunction) {
      precedence = CALLEE;
      tree.Node selector;
      Expression callee = exp.callee;
      if (callee is Identifier) {
        selector = makeIdentifier(callee.name);
      } else {
        selector = makeExp(callee, CALLEE, beginStmt: beginStmt);
      }
      result = new tree.Send(
          null,
          selector,
          argList(exp.arguments.map(makeArgument)));
    } else if (exp is CallMethod) {
      precedence = CALLEE;
      result = new tree.Send(
          makeExp(exp.object, PRIMARY, beginStmt: beginStmt),
          makeIdentifier(exp.methodName),
          argList(exp.arguments.map(makeArgument)));
    } else if (exp is CallNew) {
      precedence = CALLEE;
      tree.Node selector = makeName(exp.type.name);
      if (exp.type.typeArguments.length > 0) {
        selector = new tree.TypeAnnotation(
            selector,
            typeArgList(exp.type.typeArguments.map(makeType)));
        setType(selector, exp.dartType, exp);
      }
      if (exp.constructorName != null) {
        selector = new tree.Send(
            selector,
            makeIdentifier(exp.constructorName));
      }
      tree.Send send = new tree.Send(
          null,
          selector,
          argList(exp.arguments.map(makeArgument)));
      result = new tree.NewExpression(
          exp.isConst ? constToken : newToken,
          send);
      setType(result, exp.dartType, exp);
      setElement(send, exp.constructor, exp);
    } else if (exp is CallStatic) {
      precedence = CALLEE;
      result = new tree.Send(
          makeName(exp.className),
          makeIdentifier(exp.methodName),
          argList(exp.arguments.map(makeArgument)));
      setElement(result, exp.element, exp);
    } else if (exp is Conditional) {
      precedence = CONDITIONAL;
      result = new tree.Conditional(
          makeExp(exp.condition, LOGICAL_OR, beginStmt: beginStmt),
          makeExp(exp.thenExpression, EXPRESSION),
          makeExp(exp.elseExpression, EXPRESSION),
          question,
          colon);
    } else if (exp is FieldExpression) {
      precedence = PRIMARY;
      result = new tree.Send(
          makeExp(exp.object, PRIMARY, beginStmt: beginStmt),
          makeIdentifier(exp.fieldName));
    } else if (exp is FunctionExpression) {
      precedence = PRIMARY;
      if (beginStmt && exp.name != null) {
        needParen = true; // Do not mistake for function declaration.
      }
      result = new tree.FunctionExpression(
          exp.name != null ? makeIdentifier(exp.name) : null,
          makeParameters(exp.parameters),
          makeBlock(exp.body),
          exp.returnType != null ? makeType(exp.returnType) : null,
          makeEmptyModifiers(), // TODO(asgerf): Function modifiers?
          null,  // initializers
          null); // get/set
      setElement(result, exp.element, exp);
    } else if (exp is Identifier) {
      precedence = CALLEE;
      result = new tree.Send(null, makeIdentifier(exp.name));
      setElement(result, exp.element, exp);
    } else if (exp is Increment) {
      Expression lvalue = exp.expression;
      tree.Node receiver;
      tree.Node selector;
      tree.Node argument;
      bool innerBeginStmt = beginStmt && !exp.isPrefix;
      if (lvalue is Identifier) {
        selector = makeIdentifier(lvalue.name);
      } else if (lvalue is FieldExpression) {
        receiver = makeExp(lvalue.object, PRIMARY, beginStmt: innerBeginStmt);
        selector = makeIdentifier(lvalue.fieldName);
      } else if (lvalue is IndexExpression) {
        receiver = makeExp(lvalue.object, PRIMARY, beginStmt: innerBeginStmt);
        selector = new tree.Operator(indexToken);
        argument = makeExpression(lvalue.index);
      } else {
        throw "Unrecognized left-hand side: ${lvalue}";
      }
      tree.Operator op = new tree.Operator(incrementToken(exp.operatorName));
      if (exp.isPrefix) {
        precedence = UNARY;
        result = new tree.SendSet.prefix(receiver, selector, op, argument);
      } else {
        precedence = POSTFIX_INCREMENT;
        result = new tree.SendSet.postfix(receiver, selector, op, argument);
      }
    } else if (exp is IndexExpression) {
      precedence = CALLEE;
      result = new tree.Send(
          makeExp(exp.object, PRIMARY, beginStmt: beginStmt),
          new tree.Operator(indexToken),
          bracketList(',', [makeExpression(exp.index)]));
    } else if (exp is Literal) {
      precedence = CALLEE;
      dart2js.PrimitiveConstant value = exp.value;
      Token tok = new StringToken.fromString(STRING_INFO, '${value.value}', -1);
      if (value is dart2js.StringConstant) {
        result = unparseStringLiteral(exp);
      } else if (value is dart2js.IntConstant) {
        result = new tree.LiteralInt(tok, null);
      } else if (value is dart2js.DoubleConstant) {
        if (value.value == double.INFINITY) {
          precedence = MULTIPLICATIVE;
          tok = new StringToken.fromString(STRING_INFO, '1/0.0', -1);
        } else if (value.value == double.NEGATIVE_INFINITY) {
          precedence = MULTIPLICATIVE;
          tok = new StringToken.fromString(STRING_INFO, '-1/0.0', -1);
        } else if (value.value.isNaN) {
          precedence = MULTIPLICATIVE;
          tok = new StringToken.fromString(STRING_INFO, '0/0.0', -1);
        }
        result = new tree.LiteralDouble(tok, null);
      } else if (value is dart2js.BoolConstant) {
        result = new tree.LiteralBool(tok, null);
      } else if (value is dart2js.NullConstant) {
        result = new tree.LiteralNull(tok);
      } else {
        throw "Unrecognized constant: ${value}";
      }
    } else if (exp is LiteralList) {
      precedence = PRIMARY;
      tree.NodeList typeArgs = null;
      if (exp.typeArgument != null) {
        typeArgs = typeArgList([makeType(exp.typeArgument)]);
      }
      result = new tree.LiteralList(
          typeArgs,
          bracketList(',', exp.values.map(makeExpression)),
          exp.isConst ? constToken : null);
    } else if (exp is LiteralMap) {
      precedence = PRIMARY;
      if (beginStmt) {
        // The opening brace can be confused with a block statement.
        needParen = true;
      }
      tree.NodeList typeArgs = null;
      if (exp.typeArguments != null && exp.typeArguments.length > 0) {
        typeArgs = typeArgList(exp.typeArguments.map(makeType));
      }
      result = new tree.LiteralMap(
          typeArgs,
          braceList(',', exp.entries.map(makeLiteralMapEntry)),
          exp.isConst ? constToken : null);
    } else if (exp is LiteralSymbol) {
      precedence = PRIMARY;
      result = new tree.LiteralSymbol(
          hash,
          makeList('.', exp.id.split('.').map(makeIdentifier)));
    } else if (exp is StringConcat) {
      precedence = PRIMARY;
      result = unparseStringLiteral(exp);
    } else if (exp is This) {
      precedence = CALLEE;
      result = makeIdentifier('this');
    } else if (exp is Throw) {
      precedence = EXPRESSION; // ???
      result = new tree.Throw(
          makeExpression(exp.expression),
          throwToken,
          throwToken); // endToken not used by unparser
    } else if (exp is TypeOperator) {
      precedence = RELATIONAL;
      tree.Operator operator;
      tree.Node rightOperand = makeType(exp.type);
      if (exp.operatorName == 'is!') {
        operator = new tree.Operator(typeOpToken('is'));
        rightOperand = new tree.Send(
            rightOperand,
            new tree.Operator(bang),
            blankList());
      } else {
        operator = new tree.Operator(typeOpToken(exp.operatorName));
      }
      result = new tree.Send(
          makeExp(exp.expression, BITWISE_OR, beginStmt: beginStmt),
          operator,
          singleton(rightOperand));
    } else if (exp is UnaryOperator) {
      precedence = UNARY;
      result = new tree.Send.prefix(
          makeExp(exp.operand, UNARY),
          new tree.Operator(unopToken(exp.operatorName)));
    } else {
      throw "Unknown expression type: ${exp}";
    }

    needParen = needParen || precedence < minPrecedence;
    if (needParen) {
      result = parenthesize(result);
    }
    return result;
  }

  /// Creates a LiteralString with [verbatim] as the value.
  /// No (un)quoting or (un)escaping will be performed by this method.
  /// The [DartString] inside the literal will be set to null because the
  /// code emitter does not use it.
  tree.LiteralString makeVerbatimStringLiteral(String verbatim) {
    Token tok = new StringToken.fromString(STRING_INFO, verbatim, -1);
    return new tree.LiteralString(tok, null);
  }

  tree.LiteralMapEntry makeLiteralMapEntry(LiteralMapEntry en) {
    return new tree.LiteralMapEntry(
        makeExpression(en.key),
        colon,
        makeExpression(en.value));
  }

  /// Produces a statement in a context where only blocks are allowed.
  tree.Node makeBlock(Statement stmt) {
    if (stmt is Block)
      return makeStatement(stmt);
    else {
      return new tree.Block(braceList('', [makeStatement(stmt)]));
    }
  }

  /// Adds the given statement to a block. If the statement itself is a block
  /// it will be flattened (if this does not change lexical scoping).
  void addBlockMember(Statement stmt, List<tree.Node> accumulator) {
    if (stmt is Block && !stmt.statements.any(Unparser.definesVariable)) {
      for (Statement innerStmt in stmt.statements) {
        addBlockMember(innerStmt, accumulator);
      }
    } else if (stmt is EmptyStatement) {
      // No need to include empty statements inside blocks
    } else {
      accumulator.add(makeStatement(stmt));
    }
  }

  /// True if [stmt] is equivalent to an empty statement.
  bool isEmptyStatement(Statement stmt) {
    return stmt is EmptyStatement ||
          (stmt is Block && stmt.statements.every(isEmptyStatement));
  }

  tree.Node makeStatement(Statement stmt, {bool shortIf: true}) {
    if (stmt is Block) {
      List<tree.Node> body = <tree.Node>[];
      for (Statement innerStmt in stmt.statements) {
        addBlockMember(innerStmt, body);
      }
      return new tree.Block(braceList('', body));
    } else if (stmt is Break) {
      return new tree.BreakStatement(
          stmt.label == null ? null : makeIdentifier(stmt.label),
          breakToken,
          semicolon);
    } else if (stmt is Continue) {
      return new tree.ContinueStatement(
          stmt.label == null ? null : makeIdentifier(stmt.label),
          continueToken,
          semicolon);
    } else if (stmt is DoWhile) {
      return new tree.DoWhile(
          makeStatement(stmt.body, shortIf: shortIf),
          parenthesize(makeExpression(stmt.condition)),
          doToken,
          whileToken,
          semicolon);
    } else if (stmt is EmptyStatement) {
      return new tree.EmptyStatement(semicolon);
    } else if (stmt is ExpressionStatement) {
      return new tree.ExpressionStatement(
          makeExp(stmt.expression, EXPRESSION, beginStmt: true),
          semicolon);
    } else if (stmt is For) {
      tree.Node initializer;
      if (stmt.initializer is VariableDeclarations) {
        initializer = makeVariableDeclarations(stmt.initializer);
      } else if (stmt.initializer is Expression) {
        initializer = makeExpression(stmt.initializer);
      } else {
        initializer = null;
      }
      tree.Node condition;
      if (stmt.condition != null) {
        condition = new tree.ExpressionStatement(
            makeExpression(stmt.condition),
            semicolon);
      } else {
        condition = new tree.EmptyStatement(semicolon);
      }
      return new tree.For(
          initializer,
          condition,
          makeList(',', stmt.updates.map(makeExpression)),
          makeStatement(stmt.body, shortIf: shortIf),
          forToken);
    } else if (stmt is ForIn) {
      tree.Node left;
      if (stmt.leftHandValue is Identifier) {
        left = makeExpression(stmt.leftHandValue);
      } else {
        left = makeVariableDeclarations(stmt.leftHandValue);
      }
      return new tree.ForIn(
          left,
          makeExpression(stmt.expression),
          makeStatement(stmt.body, shortIf: shortIf),
          forToken,
          inToken);
    } else if (stmt is FunctionDeclaration) {
      return new tree.FunctionDeclaration(new tree.FunctionExpression(
          stmt.name != null ? makeIdentifier(stmt.name) : null,
          makeParameters(stmt.parameters),
          makeBlock(stmt.body),
          stmt.returnType != null ? makeType(stmt.returnType) : null,
          makeEmptyModifiers(), // TODO(asgerf): Function modifiers?
          null,  // initializers
          null)); // get/set
    } else if (stmt is If) {
      if (stmt.elseStatement == null || isEmptyStatement(stmt.elseStatement)) {
        tree.Node node = new tree.If(
            parenthesize(makeExpression(stmt.condition)),
            makeStatement(stmt.thenStatement),
            null, // else statement
            ifToken,
            null); // else token
        if (shortIf)
          return node;
        else
          return new tree.Block(braceList('', [node]));
      } else {
        return new tree.If(
            parenthesize(makeExpression(stmt.condition)),
            makeStatement(stmt.thenStatement, shortIf: false),
            makeStatement(stmt.elseStatement, shortIf: shortIf),
            ifToken,
            elseToken); // else token
      }
    } else if (stmt is LabeledStatement) {
      List<tree.Label> labels = [];
      Statement inner = stmt;
      while (inner is LabeledStatement) {
        LabeledStatement lbl = inner as LabeledStatement;
        labels.add(new tree.Label(makeIdentifier(lbl.label), colon));
        inner = lbl.statement;
      }
      return new tree.LabeledStatement(
          makeList('', labels),
          makeStatement(inner, shortIf: shortIf));
    } else if (stmt is Rethrow) {
      return new tree.Rethrow(rethrowToken, semicolon);
    } else if (stmt is Return) {
      return new tree.Return(
          returnToken,
          semicolon,
          stmt.expression == null ? null : makeExpression(stmt.expression));
    } else if (stmt is Switch) {
      return new tree.SwitchStatement(
          parenthesize(makeExpression(stmt.expression)),
          braceList('', stmt.cases.map(makeSwitchCase)),
          switchToken);
    } else if (stmt is Try) {
      return new tree.TryStatement(
          makeBlock(stmt.tryBlock),
          braceList('', stmt.catchBlocks.map(makeCatchBlock)),
          stmt.finallyBlock == null ? null : makeBlock(stmt.finallyBlock),
          tryToken,
          finallyToken);
    } else if (stmt is VariableDeclarations) {
      return makeVariableDeclarations(stmt, useVar: true, endToken: semicolon);
    } else if (stmt is While) {
      return new tree.While(
          parenthesize(makeExpression(stmt.condition)),
          makeStatement(stmt.body, shortIf: shortIf),
          whileToken);
    } else {
      throw "Unrecognized statement: ${stmt}";
    }
  }

  tree.Node makeVariableDeclaration(VariableDeclaration vd) {
    tree.Node id = makeIdentifier(vd.name);
    setElement(id, vd.element, vd);
    if (vd.initializer == null) {
      return id;
    }
    tree.Node send = new tree.SendSet(
          null,
          id,
          new tree.Operator(eq),
          singleton(makeExpression(vd.initializer)));
    setElement(send, vd.element, vd);
    return send;
  }

  /// If [useVar] is true, the variable definition will use `var` as modifier
  /// if no other modifiers are present.
  /// [endToken] will be used to terminate the declaration list.
  tree.Node makeVariableDeclarations(VariableDeclarations decl,
                                      { bool useVar: false,
                                        Token endToken: null }) {
    return new tree.VariableDefinitions(
        decl.type == null ? null : makeType(decl.type),
        makeVarModifiers(isConst: decl.isConst,
                          isFinal: decl.isFinal,
                          useVar: useVar && decl.type == null),
        makeList(',',
            decl.declarations.map(makeVariableDeclaration),
            close: endToken));
  }

  tree.CatchBlock makeCatchBlock(CatchBlock block) {
    List<tree.VariableDefinitions> formals = [];
    if (block.exceptionVar != null) {
      formals.add(new tree.VariableDefinitions(
          null,
          makeEmptyModifiers(),
          singleton(makeIdentifier(block.exceptionVar))));
    }
    if (block.stackVar != null) {
      formals.add(new tree.VariableDefinitions(
          null,
          makeEmptyModifiers(),
          singleton(makeIdentifier(block.stackVar))));
    }
    return new tree.CatchBlock(
        block.onType == null ? null : makeType(block.onType),
        block.exceptionVar == null ? null : argList(formals),
        makeBlock(block.body),
        block.onType == null ? null : onToken,
        block.exceptionVar == null ? null : catchToken);
  }

  tree.SwitchCase makeSwitchCase(SwitchCase caze) {
    if (caze.isDefaultCase) {
      return new tree.SwitchCase(
          blankList(),
          defaultToken,
          makeList('', caze.statements.map(makeStatement)),
          null); // startToken unused by unparser
    } else {
      return new tree.SwitchCase(
          makeList('', caze.expressions.map(makeCaseMatch)),
          null, // defaultKeyword,
          makeList('', caze.statements.map(makeStatement)),
          null); // startToken unused by unparser
    }
  }

  tree.CaseMatch makeCaseMatch(Expression exp) {
    return new tree.CaseMatch(caseToken, makeExpression(exp), colon);
  }

  tree.TypeAnnotation makeType(TypeAnnotation type) {
    tree.NodeList typeArgs;
    if (type.typeArguments.length > 0) {
      typeArgs = typeArgList(type.typeArguments.map(makeType));
    } else {
      typeArgs = null;
    }
    tree.TypeAnnotation result =
        new tree.TypeAnnotation(makeIdentifier(type.name), typeArgs);
    setType(result, type.dartType, type);
    return result;
  }

  tree.NodeList makeParameters(Parameters params) {
    List<tree.Node> nodes =
        params.requiredParameters.map(makeParameter).toList();
    if (params.hasOptionalParameters) {
      Token assign = params.hasNamedParameters ? colon : eq;
      Token open = params.hasNamedParameters ? openBrace : openBracket;
      Token close = params.hasNamedParameters ? closeBrace : closeBracket;
      List opt = params.optionalParameters.map((p) => makeParameter(p,assign));
      nodes.add(new tree.NodeList(open, makeLink(opt), close, ','));
    }
    return argList(nodes);
  }

  /// [assignOperator] is used for writing the default value.
  tree.Node makeParameter(Parameter param, [Token assignOperator]) {
    if (param.isFunction) {
      tree.Node definition = new tree.FunctionExpression(
          makeIdentifier(param.name),
          makeParameters(param.parameters),
          null, // body
          param.type == null ? null : makeType(param.type),
          makeEmptyModifiers(), // TODO: Function parameter modifiers?
          null, // initializers
          null); // get/set
      if (param.defaultValue != null) {
        return new tree.SendSet(
            null,
            definition,
            new tree.Operator(assignOperator),
            singleton(makeExpression(param.defaultValue)));
      } else {
        return definition;
      }
    } else {
      tree.Node definition;
      if (param.defaultValue != null) {
        definition = new tree.SendSet(
            null,
            makeIdentifier(param.name),
            new tree.Operator(assignOperator),
            singleton(makeExpression(param.defaultValue)));
      } else {
        definition = makeIdentifier(param.name);
      }
      setElement(definition, param.element, param);
      return new tree.VariableDefinitions(
          param.type == null ? null : makeType(param.type),
          makeEmptyModifiers(), // TODO: Parameter modifiers?
          singleton(definition));
    }
  }

  tree.Modifiers makeEmptyModifiers() {
    return new tree.Modifiers(blankList());
  }

  tree.Modifiers makeVarModifiers({bool isConst: false,
                               bool isFinal: false,
                               bool useVar: false}) {
    List<tree.Node> nodes = [];
    if (isConst) {
      nodes.add(makeIdentifier('const'));
    }
    if (isFinal) {
      nodes.add(makeIdentifier('final'));
    }
    if (useVar && nodes.isEmpty) {
      nodes.add(makeIdentifier('var'));
    }
    return new tree.Modifiers(makeList('', nodes));
  }

  tree.Node parenthesize(tree.Node node) {
    return new tree.ParenthesizedExpression(node, openParen);
  }

  tree.Node unparseStringLiteral(Expression exp) {
    StringLiteralOutput output = Unparser.analyzeStringLiteral(exp);
    List parts = output.parts;
    tree.Node printStringChunk(StringChunk chunk) {
      bool raw = chunk.quoting.raw;
      int quoteCode = chunk.quoting.quote;

      List<tree.StringInterpolationPart> literalParts = [];
      tree.LiteralString firstLiteral;
      tree.Node currentInterpolation;

      // sb contains the current unfinished LiteralString
      StringBuffer sb = new StringBuffer();
      if (raw) {
        sb.write('r');
      }
      for (int i = 0; i < chunk.quoting.leftQuoteCharCount; i++) {
        sb.write(chunk.quoting.quoteChar);
      }

      // Print every character and string interpolation
      int startIndex = chunk.previous != null ? chunk.previous.endIndex : 0;
      for (int i = startIndex; i < chunk.endIndex; i++) {
        var part = parts[i];
        if (part is Expression) {
          // Finish the previous string interpolation, if there is one.
          tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString());
          if (currentInterpolation != null) {
            literalParts.add(new tree.StringInterpolationPart(
                currentInterpolation,
                lit));
          } else {
            firstLiteral = lit;
          }
          sb.clear();
          currentInterpolation = makeExpression(part);
        } else {
          int char = part;
          sb.write(Unparser.getEscapedCharacter(char, quoteCode, raw));
        }
      }

      // Print ending quotes
      for (int i = 0; i < chunk.quoting.rightQuoteLength; i++) {
        sb.write(chunk.quoting.quoteChar);
      }

      // Finish the previous string interpolation, if there is one.
      // Then wrap everything in a StringInterpolation, if relevant.
      tree.LiteralString lit = makeVerbatimStringLiteral(sb.toString());
      tree.Node node;
      if (firstLiteral == null) {
        node = lit;
      } else {
        literalParts.add(new tree.StringInterpolationPart(
            currentInterpolation,
            lit));
        node = new tree.StringInterpolation(
            firstLiteral,
            makeList('', literalParts));
      }

      // Juxtapose with the previous string chunks, if any.
      if (chunk.previous != null) {
        return new tree.StringJuxtaposition(
            printStringChunk(chunk.previous),
            node);
      } else {
        return node;
      }
    }
    return printStringChunk(output.chunk);
  }

}
