// 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 RootNode extends Node {
  elements.Element get element;
}

class FieldDefinition extends RootNode {
  final elements.Element element;
  final Expression initializer;
  FieldDefinition(this.element, this.initializer);
}

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 VariableDeclaration exceptionVar;
  final VariableDeclaration 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

abstract class Initializer extends Expression {}

class FieldInitializer extends Initializer {
  final elements.FieldElement element;
  final Expression body;

  FieldInitializer(this.element, this.body);
}

class SuperInitializer extends Initializer {
  final elements.ConstructorElement target;
  final List<Argument> arguments;

  SuperInitializer(this.target, this.arguments);
}

class FunctionExpression extends Expression implements RootNode {
  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 ConstructorDefinition extends FunctionExpression {
  final List<Initializer> initializers;
  final bool isConst;

  ConstructorDefinition(Parameters parameters, Statement body,
      this.initializers, String name, this.isConst)
      : super(parameters, body, name: name);
}

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(" ");
    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}) {
    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);
        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 {
        write(e.value.toDartText());
      }
    } 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('(');
    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.name);
          if (block.stackVar != null) {
            write(',');
            write(block.stackVar.name);
          }
          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.
  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) {
    // 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);
  }
}
