// 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 backend_ast_nodes;

import '../constants/values.dart' as values;
import '../dart_types.dart' as types;
import '../elements/elements.dart' as elements;
import '../tree/tree.dart' as tree;
import '../util/characters.dart' as characters;

/// The following nodes correspond to [tree.Send] expressions:
/// [FieldExpression], [IndexExpression], [Assignment], [Increment],
/// [CallFunction], [CallMethod], [CallNew], [CallStatic], [UnaryOperator],
/// [BinaryOperator], and [TypeOperator].
abstract class Node {}

/// Receiver is an [Expression] or the [SuperReceiver].
abstract class Receiver extends Node {}

/// Argument is an [Expression] or a [NamedArgument].
abstract class Argument extends Node {}

abstract class Expression extends Node implements Receiver, Argument {
  bool get assignable => false;
}

abstract class Statement extends Node {}

/// Used as receiver in expressions that dispatch to the super class.
/// For instance, an expression such as `super.f()` is represented
/// by a [CallMethod] node with [SuperReceiver] as its receiver.
class SuperReceiver extends Receiver {
  static final SuperReceiver _instance = new SuperReceiver._create();

  factory SuperReceiver() => _instance;
  SuperReceiver._create();
}

/// Named arguments may occur in the argument list of
/// [CallFunction], [CallMethod], [CallNew], and [CallStatic].
class NamedArgument extends Argument {
  final String name;
  final Expression expression;

  NamedArgument(this.name, this.expression);
}

class TypeAnnotation extends Node {
  final String name;
  final List<TypeAnnotation> typeArguments;

  types.DartType dartType;

  TypeAnnotation(this.name, [this.typeArguments = const <TypeAnnotation>[]]);
}

// STATEMENTS


class Block extends Statement {
  final List<Statement> statements;

  Block(this.statements);
}

class Break extends Statement {
  final String label;

  Break([this.label]);
}

class Continue extends Statement {
  final String label;

  Continue([this.label]);
}

class EmptyStatement extends Statement {
  static final EmptyStatement _instance = new EmptyStatement._create();

  factory EmptyStatement() => _instance;
  EmptyStatement._create();
}

class ExpressionStatement extends Statement {
  final Expression expression;

  ExpressionStatement(this.expression);
}

class For extends Statement {
  final Node initializer;
  final Expression condition;
  final List<Expression> updates;
  final Statement body;

  /// Initializer must be [VariableDeclarations] or [Expression] or null.
  For(this.initializer, this.condition, this.updates, this.body) {
    assert(initializer == null
        || initializer is VariableDeclarations
        || initializer is Expression);
  }
}

class ForIn extends Statement {
  final Node leftHandValue;
  final Expression expression;
  final Statement body;

  /// [leftHandValue] must be [Identifier] or [VariableDeclarations] with
  /// exactly one definition, and that variable definition must have no
  /// initializer.
  ForIn(Node leftHandValue, this.expression, this.body)
      : this.leftHandValue = leftHandValue {
    assert(leftHandValue is Identifier
        || (leftHandValue is VariableDeclarations
            && leftHandValue.declarations.length == 1
            && leftHandValue.declarations[0].initializer == null));
  }
}

class While extends Statement {
  final Expression condition;
  final Statement body;

  While(this.condition, this.body);
}

class DoWhile extends Statement {
  final Statement body;
  final Expression condition;

  DoWhile(this.body, this.condition);
}

class If extends Statement {
  final Expression condition;
  final Statement thenStatement;
  final Statement elseStatement;

  If(this.condition, this.thenStatement, [this.elseStatement]);
}

class LabeledStatement extends Statement {
  final String label;
  final Statement statement;

  LabeledStatement(this.label, this.statement);
}

class Rethrow extends Statement {
}

class Return extends Statement {
  final Expression expression;

  Return([this.expression]);
}

class Switch extends Statement {
  final Expression expression;
  final List<SwitchCase> cases;

  Switch(this.expression, this.cases);
}

/// A sequence of case clauses followed by a sequence of statements.
/// Represents the default case if [expressions] is null.
///
/// NOTE:
/// Control will never fall through to the following SwitchCase, even if
/// the list of statements is empty. An empty list of statements will be
/// unparsed to a semicolon to guarantee this behaviour.
class SwitchCase extends Node {
  final List<Expression> expressions;
  final List<Statement> statements;

  SwitchCase(this.expressions, this.statements);
  SwitchCase.defaultCase(this.statements) : expressions = null;

  bool get isDefaultCase => expressions == null;
}

/// A try statement. The try, catch and finally blocks will automatically
/// be printed inside a block statement if necessary.
class Try extends Statement {
  final Statement tryBlock;
  final List<CatchBlock> catchBlocks;
  final Statement finallyBlock;

  Try(this.tryBlock, this.catchBlocks, [this.finallyBlock]) {
    assert(catchBlocks.length > 0 || finallyBlock != null);
  }
}

class CatchBlock extends Node {
  final TypeAnnotation onType;
  final String exceptionVar;
  final String stackVar;
  final Statement body;

  /// At least onType or exceptionVar must be given.
  /// stackVar may only be given if exceptionVar is also given.
  CatchBlock(this.body, {this.onType, this.exceptionVar, this.stackVar}) {
    // Must specify at least a type or an exception binding.
    assert(onType != null || exceptionVar != null);

    // We cannot bind the stack trace without binding the exception too.
    assert(stackVar == null || exceptionVar != null);
  }
}

class VariableDeclarations extends Statement {
  final TypeAnnotation type;
  final bool isFinal;
  final bool isConst;
  final List<VariableDeclaration> declarations;

  VariableDeclarations(this.declarations,
                      { this.type,
                        this.isFinal: false,
                        this.isConst: false }) {
    // Cannot be both final and const.
    assert(!isFinal || !isConst);
  }
}

class VariableDeclaration extends Node {
  final String name;
  final Expression initializer;

  elements.Element element;

  VariableDeclaration(this.name, [this.initializer]);
}


class FunctionDeclaration extends Statement {
  final FunctionExpression function;

  TypeAnnotation get returnType => function.returnType;
  Parameters get parameters => function.parameters;
  String get name => function.name;
  Statement get body => function.body;

  FunctionDeclaration(this.function);
}

class Parameters extends Node {
  final List<Parameter> requiredParameters;
  final List<Parameter> optionalParameters;
  final bool hasNamedParameters;

  Parameters(this.requiredParameters,
             [ this.optionalParameters,
               this.hasNamedParameters = false ]);

  Parameters.named(this.requiredParameters, this.optionalParameters)
      : hasNamedParameters = true;

  Parameters.positional(this.requiredParameters, this.optionalParameters)
        : hasNamedParameters = false;

  bool get hasOptionalParameters =>
      optionalParameters != null && optionalParameters.length > 0;
}

class Parameter extends Node {
  final String name;

  /// Type of parameter, or return type of function parameter.
  final TypeAnnotation type;

  Expression defaultValue;

  /// Parameters to function parameter. Null for non-function parameters.
  final Parameters parameters;

  elements.FormalElement element;

  Parameter(this.name, {this.type, this.defaultValue})
      : parameters = null;

  Parameter.function(this.name,
                     TypeAnnotation returnType,
                     this.parameters,
                     [ this.defaultValue ]) : type = returnType {
    assert(parameters != null);
  }

  /// True if this is a function parameter.
  bool get isFunction => parameters != null;
}

// EXPRESSIONS

class FunctionExpression extends Expression {
  final TypeAnnotation returnType;
  String name;
  final Parameters parameters;
  final Statement body;
  final bool isGetter;
  final bool isSetter;

  elements.FunctionElement element;

  FunctionExpression(this.parameters,
                     this.body,
                     { this.name,
                       this.returnType,
                       this.isGetter: false,
                       this.isSetter: false }) {
    // Function must have a name if it has a return type
    assert(returnType == null || name != null);
  }
}

class Conditional extends Expression {
  final Expression condition;
  final Expression thenExpression;
  final Expression elseExpression;

  Conditional(this.condition, this.thenExpression, this.elseExpression);
}

/// An identifier expression.
/// The unparser does not concern itself with scoping rules, and it is the
/// responsibility of the AST creator to ensure that the identifier resolves
/// to the proper definition.
/// For the time being, this class is also used to reference static fields and
/// top-level variables that are qualified with a class and/or library name,
/// assuming the [element] is set. This is likely to change when the old backend
/// is replaced.
class Identifier extends Expression {
  final String name;

  elements.Element element;

  Identifier(this.name);

  bool get assignable => true;
}

class Literal extends Expression {
  final values.PrimitiveConstantValue value;

  Literal(this.value);
}

class LiteralList extends Expression {
  final bool isConst;
  final TypeAnnotation typeArgument;
  final List<Expression> values;

  LiteralList(this.values, { this.typeArgument, this.isConst: false });
}

class LiteralMap extends Expression {
  final bool isConst;
  final List<TypeAnnotation> typeArguments;
  final List<LiteralMapEntry> entries;

  LiteralMap(this.entries, { this.typeArguments, this.isConst: false }) {
    assert(this.typeArguments == null
        || this.typeArguments.length == 0
        || this.typeArguments.length == 2);
  }
}

class LiteralMapEntry extends Node {
  final Expression key;
  final Expression value;

  LiteralMapEntry(this.key, this.value);
}

class LiteralSymbol extends Expression {
  final String id;

  /// [id] should not include the # symbol
  LiteralSymbol(this.id);
}

/// A type literal. This is distinct from [Identifier] since the unparser
/// needs to this distinguish a static invocation from a method invocation
/// on a type literal.
class LiteralType extends Expression {
  final String name;

  types.DartType type;

  LiteralType(this.name);
}

/// Reference to a type variable.
/// This is distinct from [Identifier] since the unparser needs to this
/// distinguish a function invocation `T()` from a type variable invocation
/// `(T)()` (the latter is invalid, but must be generated anyway).
class ReifyTypeVar extends Expression {
  final String name;

  elements.TypeVariableElement element;

  ReifyTypeVar(this.name);
}

/// StringConcat is used in place of string interpolation and juxtaposition.
/// Semantically, each subexpression is evaluated and converted to a string
/// by `toString()`. These string are then concatenated and returned.
/// StringConcat unparses to a string literal, possibly with interpolations.
/// The unparser will flatten nested StringConcats.
/// A StringConcat node may have any number of children, including zero and one.
class StringConcat extends Expression {
  final List<Expression> expressions;

  StringConcat(this.expressions);
}

/// Expression of form `e.f`.
class FieldExpression extends Expression {
  final Receiver object;
  final String fieldName;

  FieldExpression(this.object, this.fieldName);

  bool get assignable => true;
}

/// Expression of form `e1[e2]`.
class IndexExpression extends Expression {
  final Receiver object;
  final Expression index;

  IndexExpression(this.object, this.index);

  bool get assignable => true;
}

/// Expression of form `e(..)`
/// Note that if [callee] is a [FieldExpression] this will translate into
/// `(e.f)(..)` and not `e.f(..)`. Use a [CallMethod] to generate
/// the latter type of expression.
class CallFunction extends Expression {
  final Expression callee;
  final List<Argument> arguments;

  CallFunction(this.callee, this.arguments);
}

/// Expression of form `e.f(..)`.
class CallMethod extends Expression {
  final Receiver object;
  final String methodName;
  final List<Argument> arguments;

  CallMethod(this.object, this.methodName, this.arguments);
}

/// Expression of form `new T(..)`, `new T.f(..)`, `const T(..)`,
/// or `const T.f(..)`.
class CallNew extends Expression {
  final bool isConst;
  final TypeAnnotation type;
  final String constructorName;
  final List<Argument> arguments;

  elements.FunctionElement constructor;
  types.DartType dartType;

  CallNew(this.type,
          this.arguments,
         { this.constructorName,
           this.isConst: false });
}

/// Expression of form `T.f(..)`.
class CallStatic extends Expression {
  final String className;
  final String methodName;
  final List<Argument> arguments;

  elements.Element element;

  CallStatic(this.className, this.methodName, this.arguments);
}

/// Expression of form `!e` or `-e` or `~e`.
class UnaryOperator extends Expression {
  final String operatorName;
  final Receiver operand;

  UnaryOperator(this.operatorName, this.operand) {
    assert(isUnaryOperator(operatorName));
  }
}

/// Expression of form `e1 + e2`, `e1 - e2`, etc.
/// This node also represents application of the logical operators && and ||.
class BinaryOperator extends Expression {
  final Receiver left;
  final String operator;
  final Expression right;

  BinaryOperator(this.left, this.operator, this.right) {
    assert(isBinaryOperator(operator));
  }
}

/// Expression of form `e is T` or `e is! T` or `e as T`.
class TypeOperator extends Expression {
  final Expression expression;
  final String operator;
  final TypeAnnotation type;

  TypeOperator(this.expression, this.operator, this.type) {
    assert(operator == 'is'
        || operator == 'as'
        || operator == 'is!');
  }
}

class Increment extends Expression {
  final Expression expression;
  final String operator;
  final bool isPrefix;

  Increment(this.expression, this.operator, this.isPrefix) {
    assert(operator == '++' || operator == '--');
    assert(expression.assignable);
  }

  Increment.prefix(Expression expression, String operator)
      : this(expression, operator, true);

  Increment.postfix(Expression expression, String operator)
      : this(expression, operator, false);
}

class Assignment extends Expression {
  static final _operators =
      new Set.from(['=', '|=', '^=', '&=', '<<=', '>>=',
                    '+=', '-=', '*=', '/=', '%=', '~/=']);

  final Expression left;
  final String operator;
  final Expression right;

  Assignment(this.left, this.operator, this.right) {
    assert(_operators.contains(operator));
    assert(left.assignable);
  }
}

class Throw extends Expression {
  final Expression expression;

  Throw(this.expression);
}

class This extends Expression {
  static final This _instance = new This._create();

  factory This() => _instance;
  This._create();
}

// UNPARSER

bool isUnaryOperator(String op) {
  return op == '!' || op == '-' || op == '~';
}
bool isBinaryOperator(String op) {
  return BINARY_PRECEDENCE.containsKey(op);
}
/// True if the given operator can be converted to a compound assignment.
bool isCompoundableOperator(String op) {
  switch (BINARY_PRECEDENCE[op]) {
    case BITWISE_OR:
    case BITWISE_XOR:
    case BITWISE_AND:
    case SHIFT:
    case ADDITIVE:
    case MULTIPLICATIVE:
      return true;
    default:
      return false;
  }
}


// Precedence levels
const int EXPRESSION = 1;
const int CONDITIONAL = 2;
const int LOGICAL_OR = 3;
const int LOGICAL_AND = 4;
const int EQUALITY = 6;
const int RELATIONAL = 7;
const int BITWISE_OR = 8;
const int BITWISE_XOR = 9;
const int BITWISE_AND = 10;
const int SHIFT = 11;
const int ADDITIVE = 12;
const int MULTIPLICATIVE = 13;
const int UNARY = 14;
const int POSTFIX_INCREMENT = 15;
const int TYPE_LITERAL = 19;
const int PRIMARY = 20;

/// Precedence level required for the callee in a [FunctionCall].
const int CALLEE = 21;

const Map<String,int> BINARY_PRECEDENCE = const {
  '&&': LOGICAL_AND,
  '||': LOGICAL_OR,

  '==': EQUALITY,
  '!=': EQUALITY,

  '>': RELATIONAL,
  '>=': RELATIONAL,
  '<': RELATIONAL,
  '<=': RELATIONAL,

  '|': BITWISE_OR,
  '^': BITWISE_XOR,
  '&': BITWISE_AND,

  '>>': SHIFT,
  '<<': SHIFT,

  '+': ADDITIVE,
  '-': ADDITIVE,

  '*': MULTIPLICATIVE,
  '%': MULTIPLICATIVE,
  '/': MULTIPLICATIVE,
  '~/': MULTIPLICATIVE,
};

/// Return true if binary operators with the given precedence level are
/// (left) associative. False if they are non-associative.
bool isAssociativeBinaryOperator(int precedence) {
  return precedence != EQUALITY && precedence != RELATIONAL;
}

/// True if [x] is a letter, digit, or underscore.
/// Such characters may not follow a shorthand string interpolation.
bool isIdentifierPartNoDollar(dynamic x) {
  if (x is! int) {
    return false;
  }
  return (characters.$0 <= x && x <= characters.$9) ||
         (characters.$A <= x && x <= characters.$Z) ||
         (characters.$a <= x && x <= characters.$z) ||
         (x == characters.$_);
}

/// The unparser will apply the following syntactic rewritings:
///   Use short-hand function returns:
///     foo(){return E} ==> foo() => E;
///   Remove empty else branch:
///     if (E) S else ; ==> if (E) S
///   Flatten nested blocks:
///     {S; {S; S}; S} ==> {S; S; S; S}
///   Remove empty statements from block:
///     {S; ; S} ==> {S; S}
///   Unfold singleton blocks:
///     {S} ==> S
///   Empty block to empty statement:
///     {} ==> ;
///   Introduce not-equals operator:
///     !(E == E) ==> E != E
///   Introduce is-not operator:
///     !(E is T) ==> E is!T
///
/// The following transformations will NOT be applied here:
///   Use implicit this:
///     this.foo ==> foo              (preconditions too complex for unparser)
///   Merge adjacent variable definitions:
///     var x; var y  ==> var x,y;    (hoisting will be done elsewhere)
///   Merge adjacent labels:
///     foo: bar: S ==> foobar: S     (scoping is categorically ignored)
///
/// The following transformations might be applied here in the future:
///   Use implicit dynamic types:
///     dynamic x = E ==> var x = E
///     <dynamic>[]   ==> []
class Unparser {
  StringSink output;

  Unparser(this.output);


  void write(String s) {
    output.write(s);
  }

  /// Outputs each element from [items] separated by [separator].
  /// The actual printing must be performed by the [callback].
  void writeEach(String separator, Iterable items, void callback(any)) {
    bool first = true;
    for (var x in items) {
      if (first) {
        first = false;
      } else {
        write(separator);
      }
      callback(x);
    }
  }

  void writeOperator(String operator) {
    write(" "); // TODO(sigurdm,kmillikin): Minimize use of whitespace.
    write(operator);
    write(" ");
  }

  /// Unfolds singleton blocks and returns the inner statement.
  /// If an empty block is found, the [EmptyStatement] is returned instead.
  Statement unfoldBlocks(Statement stmt) {
    while (stmt is Block && stmt.statements.length == 1) {
      Statement inner = (stmt as Block).statements[0];
      if (definesVariable(inner)) {
        return stmt; // Do not unfold block with lexical scope.
      }
      stmt = inner;
    }
    if (stmt is Block && stmt.statements.length == 0)
      return new EmptyStatement();
    return stmt;
  }

  void writeArgument(Argument arg) {
    if (arg is NamedArgument) {
      write(arg.name);
      write(':');
      writeExpression(arg.expression);
    } else {
      writeExpression(arg);
    }
  }

  /// Prints the expression [e].
  void writeExpression(Expression e) {
    writeExp(e, EXPRESSION);
  }

  /// Prints [e] as an expression with precedence of at least [minPrecedence],
  /// using parentheses if necessary to raise the precedence level.
  /// Abusing terminology slightly, the function accepts a [Receiver] which
  /// may also be the [SuperReceiver] object.
  void writeExp(Receiver e, int minPrecedence, {beginStmt:false}) {
    // TODO(kmillikin,sigurdm): it might be faster to use a Visitor.
    void withPrecedence(int actual, void action()) {
      if (actual < minPrecedence) {
        write("(");
        beginStmt = false;
        action();
        write(")");
      } else {
        action();
      }
    }
    if (e is SuperReceiver) {
      write('super');
    } else if (e is FunctionExpression) {
      assert(!e.isGetter && !e.isSetter);
      Statement stmt = unfoldBlocks(e.body);
      int precedence = stmt is Return ? EXPRESSION : PRIMARY;
      withPrecedence(precedence, () {
        // A named function expression at the beginning of a statement
        // can be mistaken for a function declaration.
        // (Note: Functions with a return type also have a name)
        bool needParen = beginStmt && e.name != null;
        if (needParen) {
          write('(');
        }
        if (e.returnType != null) {
          writeType(e.returnType);
          write(' ');
        }
        if (e.name != null) {
          write(e.name);
        }
        writeParameters(e.parameters);
        // TODO(sigurdm,kmillikin): Print {} for "return null;"
        if (stmt is Return) {
          write('=> ');
          writeExp(stmt.expression, EXPRESSION);
        } else {
          writeBlock(stmt);
        }
        if (needParen) {
          write(')');
        }
      });
    } else if (e is Conditional) {
      withPrecedence(CONDITIONAL, () {
        writeExp(e.condition, LOGICAL_OR, beginStmt: beginStmt);
        write(' ? ');
        writeExp(e.thenExpression, EXPRESSION);
        write(' : ');
        writeExp(e.elseExpression, EXPRESSION);
      });
    } else if (e is Identifier) {
      write(e.name);
    } else if (e is Literal) {
      if (e.value.isString) {
        writeStringLiteral(e);
      }
      else if (e.value.isDouble) {
        double v = e.value.primitiveValue;
        if (v == double.INFINITY) {
          withPrecedence(MULTIPLICATIVE, () {
            write('1/0.0');
          });
        } else if (v == double.NEGATIVE_INFINITY) {
          withPrecedence(MULTIPLICATIVE, () {
            write('-1/0.0');
          });
        } else if (v.isNaN) {
          withPrecedence(MULTIPLICATIVE, () {
            write('0/0.0');
          });
        } else {
          write(v.toString());
        }
      } else {
        // TODO(sigurdm): Use [ConstExp] to generate valid code for any
        // constant.
        write(e.value.unparse());
      }
    } else if (e is LiteralList) {
      if (e.isConst) {
        write(' const ');
      }
      if (e.typeArgument != null) {
        write('<');
        writeType(e.typeArgument);
        write('>');
      }
      write('[');
      writeEach(',', e.values, writeExpression);
      write(']');
    }
    else if (e is LiteralMap) {
      // The curly brace can be mistaken for a block statement if we
      // are at the beginning of a statement.
      bool needParen = beginStmt;
      if (e.isConst) {
        write(' const ');
        needParen = false;
      }
      if (e.typeArguments.length > 0) {
        write('<');
        writeEach(',', e.typeArguments, writeType);
        write('>');
        needParen = false;
      }
      if (needParen) {
        write('(');
      }
      write('{');
      writeEach(',', e.entries, (LiteralMapEntry en) {
        writeExp(en.key, EXPRESSION);
        write(' : ');
        writeExp(en.value, EXPRESSION);
      });
      write('}');
      if (needParen) {
        write(')');
      }
    } else if (e is LiteralSymbol) {
      write('#');
      write(e.id);
    } else if (e is LiteralType) {
      withPrecedence(TYPE_LITERAL, () {
        write(e.name);
      });
    } else if (e is ReifyTypeVar) {
      withPrecedence(PRIMARY, () {
        write(e.name);
      });
    } else if (e is StringConcat) {
      writeStringLiteral(e);
    } else if (e is UnaryOperator) {
      Receiver operand = e.operand;
      // !(x == y) ==> x != y.
      if (e.operatorName == '!' &&
          operand is BinaryOperator && operand.operator == '==') {
        withPrecedence(EQUALITY, () {
          writeExp(operand.left, RELATIONAL);
          writeOperator('!=');
          writeExp(operand.right, RELATIONAL);
        });
      }
      // !(x is T) ==> x is!T
      else if (e.operatorName == '!' &&
          operand is TypeOperator && operand.operator == 'is') {
        withPrecedence(RELATIONAL, () {
          writeExp(operand.expression, BITWISE_OR, beginStmt: beginStmt);
          write(' is!');
          writeType(operand.type);
        });
      }
      else {
        withPrecedence(UNARY, () {
          writeOperator(e.operatorName);
          writeExp(e.operand, UNARY);
        });
      }
    } else if (e is BinaryOperator) {
      int precedence = BINARY_PRECEDENCE[e.operator];
      withPrecedence(precedence, () {
        // All binary operators are left-associative or non-associative.
        // For each operand, we use either the same precedence level as
        // the current operator, or one higher.
        int deltaLeft = isAssociativeBinaryOperator(precedence) ? 0 : 1;
        writeExp(e.left, precedence + deltaLeft, beginStmt: beginStmt);
        writeOperator(e.operator);
        writeExp(e.right, precedence + 1);
      });
    } else if (e is TypeOperator) {
      withPrecedence(RELATIONAL, () {
        writeExp(e.expression, BITWISE_OR, beginStmt: beginStmt);
        write(' ');
        write(e.operator);
        write(' ');
        writeType(e.type);
      });
    } else if (e is Assignment) {
      withPrecedence(EXPRESSION, () {
        writeExp(e.left, PRIMARY, beginStmt: beginStmt);
        writeOperator(e.operator);
        writeExp(e.right, EXPRESSION);
      });
    } else if (e is FieldExpression) {
      withPrecedence(PRIMARY, () {
        writeExp(e.object, PRIMARY, beginStmt: beginStmt);
        write('.');
        write(e.fieldName);
      });
    } else if (e is IndexExpression) {
      withPrecedence(CALLEE, () {
        writeExp(e.object, PRIMARY, beginStmt: beginStmt);
        write('[');
        writeExp(e.index, EXPRESSION);
        write(']');
      });
    } else if (e is CallFunction) {
      withPrecedence(CALLEE, () {
        writeExp(e.callee, CALLEE, beginStmt: beginStmt);
        write('(');
        writeEach(',', e.arguments, writeArgument);
        write(')');
      });
    } else if (e is CallMethod) {
      withPrecedence(CALLEE, () {
        writeExp(e.object, PRIMARY, beginStmt: beginStmt);
        write('.');
        write(e.methodName);
        write('(');
        writeEach(',', e.arguments, writeArgument);
        write(')');
      });
    } else if (e is CallNew) {
      withPrecedence(CALLEE, () {
        write(' ');
        write(e.isConst ? 'const ' : 'new ');
        writeType(e.type);
        if (e.constructorName != null) {
          write('.');
          write(e.constructorName);
        }
        write('(');
        writeEach(',', e.arguments, writeArgument);
        write(')');
      });
    } else if (e is CallStatic) {
      withPrecedence(CALLEE, () {
        write(e.className);
        write('.');
        write(e.methodName);
        write('(');
        writeEach(',', e.arguments, writeArgument);
        write(')');
      });
    } else if (e is Increment) {
      int precedence = e.isPrefix ? UNARY : POSTFIX_INCREMENT;
      withPrecedence(precedence, () {
        if (e.isPrefix) {
          write(e.operator);
          writeExp(e.expression, PRIMARY);
        } else {
          writeExp(e.expression, PRIMARY, beginStmt: beginStmt);
          write(e.operator);
        }
      });
    } else if (e is Throw) {
      withPrecedence(EXPRESSION, () {
        write('throw ');
        writeExp(e.expression, EXPRESSION);
      });
    } else if (e is This) {
      write('this');
    } else {
      throw "Unexpected expression: $e";
    }
  }

  void writeParameters(Parameters params) {
    write('(');
    bool first = true;
    writeEach(',', params.requiredParameters, (Parameter p) {
      if (p.type != null) {
        writeType(p.type);
        write(' ');
      }
      write(p.name);
      if (p.parameters != null) {
        writeParameters(p.parameters);
      }
    });
    if (params.hasOptionalParameters) {
      if (params.requiredParameters.length > 0) {
        write(',');
      }
      write(params.hasNamedParameters ? '{' : '[');
      writeEach(',', params.optionalParameters, (Parameter p) {
        if (p.type != null) {
          writeType(p.type);
          write(' ');
        }
        write(p.name);
        if (p.parameters != null) {
          writeParameters(p.parameters);
        }
        if (p.defaultValue != null) {
          write(params.hasNamedParameters ? ':' : '=');
          writeExp(p.defaultValue, EXPRESSION);
        }
      });
      write(params.hasNamedParameters ? '}' : ']');
    }
    write(')');
  }

  void writeStatement(Statement stmt, {bool shortIf: true}) {
    stmt = unfoldBlocks(stmt);
    if (stmt is Block) {
      write('{');
      stmt.statements.forEach(writeBlockMember);
      write('}');
    } else if (stmt is Break) {
      write('break');
      if (stmt.label != null) {
        write(' ');
        write(stmt.label);
      }
      write(';');
    } else if (stmt is Continue) {
      write('continue');
      if (stmt.label != null) {
        write(' ');
        write(stmt.label);
      }
      write(';');
    } else if (stmt is EmptyStatement) {
      write(';');
    } else if (stmt is ExpressionStatement) {
      writeExp(stmt.expression, EXPRESSION, beginStmt:true);
      write(';');
    } else if (stmt is For) {
      write('for(');
      Node init = stmt.initializer;
      if (init is Expression) {
        writeExp(init, EXPRESSION);
      } else if (init is VariableDeclarations) {
        writeVariableDefinitions(init);
      }
      write(';');
      if (stmt.condition != null) {
        writeExp(stmt.condition, EXPRESSION);
      }
      write(';');
      writeEach(',', stmt.updates, writeExpression);
      write(')');
      writeStatement(stmt.body, shortIf: shortIf);
    } else if (stmt is ForIn) {
      write('for(');
      Node lhv = stmt.leftHandValue;
      if (lhv is Identifier) {
        write(lhv.name);
      } else {
        writeVariableDefinitions(lhv as VariableDeclarations);
      }
      write(' in ');
      writeExp(stmt.expression, EXPRESSION);
      write(')');
      writeStatement(stmt.body, shortIf: shortIf);
    } else if (stmt is While) {
      write('while(');
      writeExp(stmt.condition, EXPRESSION);
      write(')');
      writeStatement(stmt.body, shortIf: shortIf);
    } else if (stmt is DoWhile) {
      write('do ');
      writeStatement(stmt.body);
      write('while(');
      writeExp(stmt.condition, EXPRESSION);
      write(');');
    } else if (stmt is If) {
      // if (E) S else ; ==> if (E) S
      Statement elsePart = unfoldBlocks(stmt.elseStatement);
      if (elsePart is EmptyStatement) {
        elsePart = null;
      }
      if (!shortIf && elsePart == null) {
        write('{');
      }
      write('if(');
      writeExp(stmt.condition, EXPRESSION);
      write(')');
      writeStatement(stmt.thenStatement, shortIf: elsePart == null);
      if (elsePart != null) {
        write('else ');
        writeStatement(elsePart, shortIf: shortIf);
      }
      if (!shortIf && elsePart == null) {
        write('}');
      }
    } else if (stmt is LabeledStatement) {
      write(stmt.label);
      write(':');
      writeStatement(stmt.statement, shortIf: shortIf);
    } else if (stmt is Rethrow) {
      write('rethrow;');
    } else if (stmt is Return) {
      write('return');
      if (stmt.expression != null) {
        write(' ');
        writeExp(stmt.expression, EXPRESSION);
      }
      write(';');
    } else if (stmt is Switch) {
      write('switch(');
      writeExp(stmt.expression, EXPRESSION);
      write('){');
      for (SwitchCase caze in stmt.cases) {
        if (caze.isDefaultCase) {
          write('default:');
        } else {
          for (Expression exp in caze.expressions) {
            write('case ');
            writeExp(exp, EXPRESSION);
            write(':');
          }
        }
        if (caze.statements.isEmpty) {
          write(';'); // Prevent fall-through.
        } else {
          caze.statements.forEach(writeBlockMember);
        }
      }
      write('}');
    } else if (stmt is Try) {
      write('try');
      writeBlock(stmt.tryBlock);
      for (CatchBlock block in stmt.catchBlocks) {
        if (block.onType != null) {
          write('on ');
          writeType(block.onType);
        }
        if (block.exceptionVar != null) {
          write('catch(');
          write(block.exceptionVar);
          if (block.stackVar != null) {
            write(',');
            write(block.stackVar);
          }
          write(')');
        }
        writeBlock(block.body);
      }
      if (stmt.finallyBlock != null) {
        write('finally');
        writeBlock(stmt.finallyBlock);
      }
    } else if (stmt is VariableDeclarations) {
      writeVariableDefinitions(stmt);
      write(';');
    } else if (stmt is FunctionDeclaration) {
      assert(!stmt.function.isGetter && !stmt.function.isSetter);
      if (stmt.returnType != null) {
        writeType(stmt.returnType);
        write(' ');
      }
      write(stmt.name);
      writeParameters(stmt.parameters);
      Statement body = unfoldBlocks(stmt.body);
      if (body is Return) {
        write('=> ');
        writeExp(body.expression, EXPRESSION);
        write(';');
      } else {
        writeBlock(body);
      }
    } else {
      throw "Unexpected statement: $stmt";
    }
  }

  /// Writes a variable definition statement without the trailing semicolon
  void writeVariableDefinitions(VariableDeclarations vds) {
    if (vds.isConst)
      write('const ');
    else if (vds.isFinal)
      write('final ');
    if (vds.type != null) {
      writeType(vds.type);
      write(' ');
    }
    if (!vds.isConst && !vds.isFinal && vds.type == null) {
      write('var ');
    }
    writeEach(',', vds.declarations, (VariableDeclaration vd) {
      write(vd.name);
      if (vd.initializer != null) {
        write('=');
        writeExp(vd.initializer, EXPRESSION);
      }
    });
  }

  /// True of statements that introduce variables in the scope of their
  /// surrounding block. Blocks containing such statements cannot be unfolded.
  static bool definesVariable(Statement s) {
    return s is VariableDeclarations || s is FunctionDeclaration;
  }

  /// Writes the given statement in a context where only blocks are allowed.
  void writeBlock(Statement stmt) {
    if (stmt is Block) {
      writeStatement(stmt);
    } else {
      write('{');
      writeBlockMember(stmt);
      write('}');
    }
  }

  /// Outputs a statement that is a member of a block statement (or a similar
  /// sequence of statements, such as in switch statement).
  /// This will flatten blocks and skip empty statement.
  void writeBlockMember(Statement stmt) {
    if (stmt is Block && !stmt.statements.any(definesVariable)) {
      stmt.statements.forEach(writeBlockMember);
    } else if (stmt is EmptyStatement) {
      // do nothing
    } else {
      writeStatement(stmt);
    }
  }

  void writeType(TypeAnnotation type) {
    write(type.name);
    if (type.typeArguments != null && type.typeArguments.length > 0) {
      write('<');
      writeEach(',', type.typeArguments, writeType);
      write('>');
    }
  }

  /// A list of string quotings that the printer may use to quote strings.
  // Ignore multiline quotings for now. Would need to make sure that no
  // newline (potentially prefixed by whitespace) follows the quoting.
  // TODO(sigurdm,kmillikin): Include multiline quotation schemes.
  static const _QUOTINGS = const <tree.StringQuoting>[
      const tree.StringQuoting(characters.$DQ, raw: false, leftQuoteLength: 1),
      const tree.StringQuoting(characters.$DQ, raw: true, leftQuoteLength: 1),
      const tree.StringQuoting(characters.$SQ, raw: false, leftQuoteLength: 1),
      const tree.StringQuoting(characters.$SQ, raw: true, leftQuoteLength: 1),
  ];

  static StringLiteralOutput analyzeStringLiteral(Expression node) {
    // TODO(sigurdm,kmillikin): This might be a bit too expensive. Benchmark.
    // Flatten the StringConcat tree.
    List parts = []; // Expression or int (char node)
    void collectParts(Expression e) {
      if (e is StringConcat) {
        e.expressions.forEach(collectParts);
      } else if (e is Literal && e.value.isString) {
        for (int char in e.value.primitiveValue) {
          parts.add(char);
        }
      } else {
        parts.add(e);
      }
    }
    collectParts(node);

    // We use a dynamic algorithm to compute the optimal way of printing
    // the string literal.
    //
    // Using string juxtapositions, it is possible to switch from one quoting
    // to another, e.g. the constant "''''" '""""' uses this trick.
    //
    // As we move through the string from left to right, we maintain a strategy
    // for each StringQuoting Q, denoting the best way to print the current
    // prefix so that we end with a string literal quoted with Q.
    // At every step, each strategy is either:
    //  1) Updated to include the cost of printing the next character.
    //  2) Abandoned because it is cheaper to use another strategy as prefix,
    //     and then switching quotation using a juxtaposition.

    int getQuoteCost(tree.StringQuoting quot) {
      return quot.leftQuoteLength + quot.rightQuoteLength;
    }

    // Create initial scores for each StringQuoting and index them
    // into raw/non-raw and single-quote/double-quote.
    List<OpenStringChunk> best = <OpenStringChunk>[];
    List<int> raws = <int>[];
    List<int> nonRaws = <int>[];
    List<int> sqs = <int>[];
    List<int> dqs = <int>[];
    for (tree.StringQuoting q in _QUOTINGS) {
      OpenStringChunk chunk = new OpenStringChunk(null, q, getQuoteCost(q));
      int index = best.length;
      best.add(chunk);

      if (q.raw) {
        raws.add(index);
      } else {
        nonRaws.add(index);
      }
      if (q.quote == characters.$SQ) {
        sqs.add(index);
      } else {
        dqs.add(index);
      }
    }


    /// Applies additional cost to each track in [penalized], and considers
    /// switching from each [penalized] to a [nonPenalized] track.
    void penalize(List<int> penalized,
                  List<int> nonPenalized,
                  int endIndex,
                  num cost(tree.StringQuoting q)) {
      for (int j in penalized) {
        // Check if another track can benefit from switching from this track.
        for (int k in nonPenalized) {
          num newCost = best[j].cost
                      + 1             // Whitespace in string juxtaposition
                      + getQuoteCost(best[k].quoting);
          if (newCost < best[k].cost) {
            best[k] = new OpenStringChunk(
                best[j].end(endIndex),
                best[k].quoting,
                newCost);
          }
        }
        best[j].cost += cost(best[j].quoting);
      }
    }

    // Iterate through the string and update the score for each StringQuoting.
    for (int i = 0; i < parts.length; i++) {
      var part = parts[i];
      if (part is int) {
        int char = part;
        switch (char) {
          case characters.$$:
          case characters.$BACKSLASH:
            penalize(nonRaws, raws, i, (q) => 1);
            break;
          case characters.$DQ:
            penalize(dqs, sqs, i, (q) => q.raw ? double.INFINITY : 1);
            break;
          case characters.$SQ:
            penalize(sqs, dqs, i, (q) => q.raw ? double.INFINITY : 1);
            break;
          case characters.$LF:
          case characters.$CR:
          case characters.$FF:
          case characters.$BS:
          case characters.$VTAB:
          case characters.$TAB:
          case characters.$EOF:
            penalize(raws, nonRaws, i, (q) => double.INFINITY);
            break;
        }
      } else {
        // Penalize raw literals for string interpolation.
        penalize(raws, nonRaws, i, (q) => double.INFINITY);

        // Splitting a string can sometimes allow us to use a shorthand
        // string interpolation that would otherwise be illegal.
        // E.g. "...${foo}x..." -> "...$foo" 'x...'
        // If are other factors that make splitting advantageous,
        // we can gain even more by doing the split here.
        if (part is Identifier &&
            !part.name.contains(r'$') &&
            i + 1 < parts.length &&
            isIdentifierPartNoDollar(parts[i+1])) {
          for (int j in nonRaws) {
            for (int k = 0; k < best.length; k++) {
              num newCost = best[j].cost
                          + 1             // Whitespace in string juxtaposition
                          - 2             // Save two curly braces
                          + getQuoteCost(best[k].quoting);
              if (newCost < best[k].cost) {
                best[k] = new OpenStringChunk(
                    best[j].end(i+1),
                    best[k].quoting,
                    newCost);
              }
            }
          }
        }
      }
    }

    // Select the cheapest strategy
    OpenStringChunk bestChunk = best[0];
    for (OpenStringChunk chunk in best) {
      if (chunk.cost < bestChunk.cost) {
        bestChunk = chunk;
      }
    }

    return new StringLiteralOutput(parts, bestChunk.end(parts.length));
  }

  void writeStringLiteral(Expression node) {
    StringLiteralOutput output = analyzeStringLiteral(node);
    List parts = output.parts;
    void printChunk(StringChunk chunk) {
      int startIndex;
      if (chunk.previous != null) {
        printChunk(chunk.previous);
        write(' '); // String juxtaposition requires a space between literals.
        startIndex = chunk.previous.endIndex;
      } else {
        startIndex = 0;
      }
      if (chunk.quoting.raw) {
        write('r');
      }
      write(chunk.quoting.quoteChar);
      bool raw = chunk.quoting.raw;
      int quoteCode = chunk.quoting.quote;
      for (int i=startIndex; i<chunk.endIndex; i++) {
        var part = parts[i];
        if (part is int) {
          int char = part;
          write(getEscapedCharacter(char, quoteCode, raw));
        } else if (part is Identifier &&
                   !part.name.contains(r'$') &&
                   (i == chunk.endIndex - 1 ||
                    !isIdentifierPartNoDollar(parts[i+1]))) {
          write(r'$');
          write(part.name);
        } else {
          write(r'${');
          writeExpression(part);
          write('}');
        }
      }
      write(chunk.quoting.quoteChar);
    }
    printChunk(output.chunk);
  }

  static String getEscapedCharacter(int char, int quoteCode, bool raw) {
    switch (char) {
      case characters.$$:
        return raw ? r'$' : r'\$';
      case characters.$BACKSLASH:
        return raw ? r'\' : r'\\';
      case characters.$DQ:
        return quoteCode == char ? r'\"' : r'"';
      case characters.$SQ:
        return quoteCode == char ? r"\'" : r"'";
      case characters.$LF:
        return r'\n';
      case characters.$CR:
        return r'\r';
      case characters.$FF:
        return r'\f';
      case characters.$BS:
        return r'\b';
      case characters.$TAB:
        return r'\t';
      case characters.$VTAB:
        return r'\v';
      case characters.$EOF:
        return r'\x00';
      default:
        return new String.fromCharCode(char);
    }
  }

}

/// The contents of a string literal together with a strategy for printing it.
class StringLiteralOutput {
  /// Mix of [Expression] and `int`. Each expression is a string interpolation,
  /// and each `int` is the character code of a character in a string literal.
  final List parts;
  final StringChunk chunk;

  StringLiteralOutput(this.parts, this.chunk);
}


/// Strategy for printing a prefix of a string literal.
/// A chunk represents the substring going from [:previous.endIndex:] to
/// [endIndex] (or from 0 to [endIndex] if [previous] is null).
class StringChunk {
  final StringChunk previous;
  final tree.StringQuoting quoting;
  final int endIndex;

  StringChunk(this.previous, this.quoting, this.endIndex);
}

/// [StringChunk] that has not yet been assigned an [endIndex].
/// It additionally has a [cost] denoting the number of auxilliary characters
/// (quotes, spaces, etc) needed to print the literal using this strategy
class OpenStringChunk {
  final StringChunk previous;
  final tree.StringQuoting quoting;
  num cost;

  OpenStringChunk(this.previous, this.quoting, this.cost);

  StringChunk end(int endIndex) {
    return new StringChunk(previous, quoting, endIndex);
  }
}