// Copyright (c) 2012, 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.

part of js_ast;

abstract class NodeVisitor<T> {
  T visitProgram(Program node);

  T visitBlock(Block node);
  T visitExpressionStatement(ExpressionStatement node);
  T visitEmptyStatement(EmptyStatement node);
  T visitIf(If node);
  T visitFor(For node);
  T visitForIn(ForIn node);
  T visitWhile(While node);
  T visitDo(Do node);
  T visitContinue(Continue node);
  T visitBreak(Break node);
  T visitReturn(Return node);
  T visitThrow(Throw node);
  T visitTry(Try node);
  T visitCatch(Catch node);
  T visitSwitch(Switch node);
  T visitCase(Case node);
  T visitDefault(Default node);
  T visitFunctionDeclaration(FunctionDeclaration node);
  T visitLabeledStatement(LabeledStatement node);
  T visitLiteralStatement(LiteralStatement node);
  T visitDartYield(DartYield node);

  T visitLiteralExpression(LiteralExpression node);
  T visitVariableDeclarationList(VariableDeclarationList node);
  T visitAssignment(Assignment node);
  T visitVariableInitialization(VariableInitialization node);
  T visitConditional(Conditional cond);
  T visitNew(New node);
  T visitCall(Call node);
  T visitBinary(Binary node);
  T visitPrefix(Prefix node);
  T visitPostfix(Postfix node);

  T visitVariableUse(VariableUse node);
  T visitThis(This node);
  T visitVariableDeclaration(VariableDeclaration node);
  T visitParameter(Parameter node);
  T visitAccess(PropertyAccess node);

  T visitNamedFunction(NamedFunction node);
  T visitFun(Fun node);
  T visitArrowFunction(ArrowFunction node);

  T visitDeferredStatement(DeferredStatement node);
  T visitDeferredExpression(DeferredExpression node);
  T visitDeferredNumber(DeferredNumber node);
  T visitDeferredString(DeferredString node);

  T visitLiteralBool(LiteralBool node);
  T visitLiteralString(LiteralString node);
  T visitLiteralNumber(LiteralNumber node);
  T visitLiteralNull(LiteralNull node);

  T visitStringConcatenation(StringConcatenation node);

  T visitName(Name node);

  T visitParentheses(Parentheses node);

  T visitArrayInitializer(ArrayInitializer node);
  T visitArrayHole(ArrayHole node);
  T visitObjectInitializer(ObjectInitializer node);
  T visitProperty(Property node);
  T visitMethodDefinition(MethodDefinition node);
  T visitRegExpLiteral(RegExpLiteral node);

  T visitAwait(Await node);

  T visitComment(Comment node);

  T visitInterpolatedExpression(InterpolatedExpression node);
  T visitInterpolatedLiteral(InterpolatedLiteral node);
  T visitInterpolatedParameter(InterpolatedParameter node);
  T visitInterpolatedSelector(InterpolatedSelector node);
  T visitInterpolatedStatement(InterpolatedStatement node);
  T visitInterpolatedDeclaration(InterpolatedDeclaration node);
}

class BaseVisitor<T> implements NodeVisitor<T> {
  const BaseVisitor();

  T visitNode(Node node) {
    node.visitChildren(this);
    return null;
  }

  T visitProgram(Program node) => visitNode(node);

  T visitStatement(Statement node) => visitNode(node);
  T visitLoop(Loop node) => visitStatement(node);
  T visitJump(Statement node) => visitStatement(node);

  T visitBlock(Block node) => visitStatement(node);
  T visitExpressionStatement(ExpressionStatement node) => visitStatement(node);
  T visitEmptyStatement(EmptyStatement node) => visitStatement(node);
  T visitIf(If node) => visitStatement(node);
  T visitFor(For node) => visitLoop(node);
  T visitForIn(ForIn node) => visitLoop(node);
  T visitWhile(While node) => visitLoop(node);
  T visitDo(Do node) => visitLoop(node);
  T visitContinue(Continue node) => visitJump(node);
  T visitBreak(Break node) => visitJump(node);
  T visitReturn(Return node) => visitJump(node);
  T visitThrow(Throw node) => visitJump(node);
  T visitTry(Try node) => visitStatement(node);
  T visitSwitch(Switch node) => visitStatement(node);
  T visitFunctionDeclaration(FunctionDeclaration node) => visitStatement(node);
  T visitLabeledStatement(LabeledStatement node) => visitStatement(node);
  T visitLiteralStatement(LiteralStatement node) => visitStatement(node);

  T visitCatch(Catch node) => visitNode(node);
  T visitCase(Case node) => visitNode(node);
  T visitDefault(Default node) => visitNode(node);

  T visitExpression(Expression node) => visitNode(node);
  T visitVariableReference(VariableReference node) => visitExpression(node);

  T visitLiteralExpression(LiteralExpression node) => visitExpression(node);
  T visitVariableDeclarationList(VariableDeclarationList node) =>
      visitExpression(node);
  T visitAssignment(Assignment node) => visitExpression(node);
  T visitVariableInitialization(VariableInitialization node) {
    if (node.value != null) {
      return visitAssignment(node);
    } else {
      return visitExpression(node);
    }
  }

  T visitConditional(Conditional node) => visitExpression(node);
  T visitNew(New node) => visitExpression(node);
  T visitCall(Call node) => visitExpression(node);
  T visitBinary(Binary node) => visitExpression(node);
  T visitPrefix(Prefix node) => visitExpression(node);
  T visitPostfix(Postfix node) => visitExpression(node);
  T visitAccess(PropertyAccess node) => visitExpression(node);

  T visitVariableUse(VariableUse node) => visitVariableReference(node);
  T visitVariableDeclaration(VariableDeclaration node) =>
      visitVariableReference(node);
  T visitParameter(Parameter node) => visitVariableDeclaration(node);
  T visitThis(This node) => visitParameter(node);

  T visitNamedFunction(NamedFunction node) => visitExpression(node);
  T visitFunctionExpression(FunctionExpression node) => visitExpression(node);
  T visitFun(Fun node) => visitFunctionExpression(node);
  T visitArrowFunction(ArrowFunction node) => visitFunctionExpression(node);

  T visitToken(DeferredToken node) => visitExpression(node);

  T visitDeferredStatement(DeferredStatement node) => visitStatement(node);
  T visitDeferredExpression(DeferredExpression node) => visitExpression(node);
  T visitDeferredNumber(DeferredNumber node) => visitToken(node);
  T visitDeferredString(DeferredString node) => visitToken(node);

  T visitLiteral(Literal node) => visitExpression(node);

  T visitLiteralBool(LiteralBool node) => visitLiteral(node);
  T visitLiteralString(LiteralString node) => visitLiteral(node);
  T visitLiteralNumber(LiteralNumber node) => visitLiteral(node);
  T visitLiteralNull(LiteralNull node) => visitLiteral(node);

  T visitStringConcatenation(StringConcatenation node) => visitLiteral(node);

  T visitName(Name node) => visitNode(node);

  T visitParentheses(Parentheses node) => visitExpression(node);

  T visitArrayInitializer(ArrayInitializer node) => visitExpression(node);
  T visitArrayHole(ArrayHole node) => visitExpression(node);
  T visitObjectInitializer(ObjectInitializer node) => visitExpression(node);
  T visitProperty(Property node) => visitNode(node);
  T visitMethodDefinition(MethodDefinition node) => visitNode(node);
  T visitRegExpLiteral(RegExpLiteral node) => visitExpression(node);

  T visitInterpolatedNode(InterpolatedNode node) => visitNode(node);

  T visitInterpolatedExpression(InterpolatedExpression node) =>
      visitInterpolatedNode(node);
  T visitInterpolatedLiteral(InterpolatedLiteral node) =>
      visitInterpolatedNode(node);
  T visitInterpolatedParameter(InterpolatedParameter node) =>
      visitInterpolatedNode(node);
  T visitInterpolatedSelector(InterpolatedSelector node) =>
      visitInterpolatedNode(node);
  T visitInterpolatedStatement(InterpolatedStatement node) =>
      visitInterpolatedNode(node);
  T visitInterpolatedDeclaration(InterpolatedDeclaration node) {
    return visitInterpolatedNode(node);
  }

  // Ignore comments by default.
  T visitComment(Comment node) => null;

  T visitAwait(Await node) => visitExpression(node);
  T visitDartYield(DartYield node) => visitStatement(node);
}

abstract class NodeVisitor1<R, A> {
  R visitProgram(Program node, A arg);

  R visitBlock(Block node, A arg);
  R visitExpressionStatement(ExpressionStatement node, A arg);
  R visitEmptyStatement(EmptyStatement node, A arg);
  R visitIf(If node, A arg);
  R visitFor(For node, A arg);
  R visitForIn(ForIn node, A arg);
  R visitWhile(While node, A arg);
  R visitDo(Do node, A arg);
  R visitContinue(Continue node, A arg);
  R visitBreak(Break node, A arg);
  R visitReturn(Return node, A arg);
  R visitThrow(Throw node, A arg);
  R visitTry(Try node, A arg);
  R visitCatch(Catch node, A arg);
  R visitSwitch(Switch node, A arg);
  R visitCase(Case node, A arg);
  R visitDefault(Default node, A arg);
  R visitFunctionDeclaration(FunctionDeclaration node, A arg);
  R visitLabeledStatement(LabeledStatement node, A arg);
  R visitLiteralStatement(LiteralStatement node, A arg);
  R visitDartYield(DartYield node, A arg);

  R visitLiteralExpression(LiteralExpression node, A arg);
  R visitVariableDeclarationList(VariableDeclarationList node, A arg);
  R visitAssignment(Assignment node, A arg);
  R visitVariableInitialization(VariableInitialization node, A arg);
  R visitConditional(Conditional cond, A arg);
  R visitNew(New node, A arg);
  R visitCall(Call node, A arg);
  R visitBinary(Binary node, A arg);
  R visitPrefix(Prefix node, A arg);
  R visitPostfix(Postfix node, A arg);

  R visitVariableUse(VariableUse node, A arg);
  R visitThis(This node, A arg);
  R visitVariableDeclaration(VariableDeclaration node, A arg);
  R visitParameter(Parameter node, A arg);
  R visitAccess(PropertyAccess node, A arg);

  R visitNamedFunction(NamedFunction node, A arg);
  R visitFun(Fun node, A arg);
  R visitArrowFunction(ArrowFunction node, A arg);

  R visitDeferredStatement(DeferredStatement node, A arg);
  R visitDeferredExpression(DeferredExpression node, A arg);
  R visitDeferredNumber(DeferredNumber node, A arg);
  R visitDeferredString(DeferredString node, A arg);

  R visitLiteralBool(LiteralBool node, A arg);
  R visitLiteralString(LiteralString node, A arg);
  R visitLiteralNumber(LiteralNumber node, A arg);
  R visitLiteralNull(LiteralNull node, A arg);

  R visitStringConcatenation(StringConcatenation node, A arg);

  R visitName(Name node, A arg);

  R visitParentheses(Parentheses node, A arg);

  R visitArrayInitializer(ArrayInitializer node, A arg);
  R visitArrayHole(ArrayHole node, A arg);
  R visitObjectInitializer(ObjectInitializer node, A arg);
  R visitProperty(Property node, A arg);
  R visitMethodDefinition(MethodDefinition node, A arg);
  R visitRegExpLiteral(RegExpLiteral node, A arg);

  R visitAwait(Await node, A arg);

  R visitComment(Comment node, A arg);

  R visitInterpolatedExpression(InterpolatedExpression node, A arg);
  R visitInterpolatedLiteral(InterpolatedLiteral node, A arg);
  R visitInterpolatedParameter(InterpolatedParameter node, A arg);
  R visitInterpolatedSelector(InterpolatedSelector node, A arg);
  R visitInterpolatedStatement(InterpolatedStatement node, A arg);
  R visitInterpolatedDeclaration(InterpolatedDeclaration node, A arg);
}

class BaseVisitor1<R, A> implements NodeVisitor1<R, A> {
  const BaseVisitor1();

  R visitNode(Node node, A arg) {
    node.visitChildren1(this, arg);
    return null;
  }

  R visitProgram(Program node, A arg) => visitNode(node, arg);

  R visitStatement(Statement node, A arg) => visitNode(node, arg);
  R visitLoop(Loop node, A arg) => visitStatement(node, arg);
  R visitJump(Statement node, A arg) => visitStatement(node, arg);

  R visitBlock(Block node, A arg) => visitStatement(node, arg);
  R visitExpressionStatement(ExpressionStatement node, A arg) =>
      visitStatement(node, arg);
  R visitEmptyStatement(EmptyStatement node, A arg) =>
      visitStatement(node, arg);
  R visitIf(If node, A arg) => visitStatement(node, arg);
  R visitFor(For node, A arg) => visitLoop(node, arg);
  R visitForIn(ForIn node, A arg) => visitLoop(node, arg);
  R visitWhile(While node, A arg) => visitLoop(node, arg);
  R visitDo(Do node, A arg) => visitLoop(node, arg);
  R visitContinue(Continue node, A arg) => visitJump(node, arg);
  R visitBreak(Break node, A arg) => visitJump(node, arg);
  R visitReturn(Return node, A arg) => visitJump(node, arg);
  R visitThrow(Throw node, A arg) => visitJump(node, arg);
  R visitTry(Try node, A arg) => visitStatement(node, arg);
  R visitSwitch(Switch node, A arg) => visitStatement(node, arg);
  R visitFunctionDeclaration(FunctionDeclaration node, A arg) =>
      visitStatement(node, arg);
  R visitLabeledStatement(LabeledStatement node, A arg) =>
      visitStatement(node, arg);
  R visitLiteralStatement(LiteralStatement node, A arg) =>
      visitStatement(node, arg);

  R visitCatch(Catch node, A arg) => visitNode(node, arg);
  R visitCase(Case node, A arg) => visitNode(node, arg);
  R visitDefault(Default node, A arg) => visitNode(node, arg);

  R visitExpression(Expression node, A arg) => visitNode(node, arg);
  R visitVariableReference(VariableReference node, A arg) =>
      visitExpression(node, arg);

  R visitLiteralExpression(LiteralExpression node, A arg) =>
      visitExpression(node, arg);
  R visitVariableDeclarationList(VariableDeclarationList node, A arg) =>
      visitExpression(node, arg);
  R visitAssignment(Assignment node, A arg) => visitExpression(node, arg);
  R visitVariableInitialization(VariableInitialization node, A arg) {
    if (node.value != null) {
      return visitAssignment(node, arg);
    } else {
      return visitExpression(node, arg);
    }
  }

  R visitConditional(Conditional node, A arg) => visitExpression(node, arg);
  R visitNew(New node, A arg) => visitExpression(node, arg);
  R visitCall(Call node, A arg) => visitExpression(node, arg);
  R visitBinary(Binary node, A arg) => visitExpression(node, arg);
  R visitPrefix(Prefix node, A arg) => visitExpression(node, arg);
  R visitPostfix(Postfix node, A arg) => visitExpression(node, arg);
  R visitAccess(PropertyAccess node, A arg) => visitExpression(node, arg);

  R visitVariableUse(VariableUse node, A arg) =>
      visitVariableReference(node, arg);
  R visitVariableDeclaration(VariableDeclaration node, A arg) =>
      visitVariableReference(node, arg);
  R visitParameter(Parameter node, A arg) =>
      visitVariableDeclaration(node, arg);
  R visitThis(This node, A arg) => visitParameter(node, arg);

  R visitNamedFunction(NamedFunction node, A arg) => visitExpression(node, arg);
  R visitFun(Fun node, A arg) => visitExpression(node, arg);
  R visitArrowFunction(ArrowFunction node, A arg) => visitExpression(node, arg);

  R visitToken(DeferredToken node, A arg) => visitExpression(node, arg);

  R visitDeferredStatement(DeferredStatement node, A arg) =>
      visitStatement(node, arg);
  R visitDeferredExpression(DeferredExpression node, A arg) =>
      visitExpression(node, arg);
  R visitDeferredNumber(DeferredNumber node, A arg) => visitToken(node, arg);
  R visitDeferredString(DeferredString node, A arg) => visitToken(node, arg);

  R visitLiteral(Literal node, A arg) => visitExpression(node, arg);

  R visitLiteralBool(LiteralBool node, A arg) => visitLiteral(node, arg);
  R visitLiteralString(LiteralString node, A arg) => visitLiteral(node, arg);
  R visitLiteralNumber(LiteralNumber node, A arg) => visitLiteral(node, arg);
  R visitLiteralNull(LiteralNull node, A arg) => visitLiteral(node, arg);

  R visitStringConcatenation(StringConcatenation node, A arg) =>
      visitLiteral(node, arg);

  R visitName(Name node, A arg) => visitNode(node, arg);

  R visitParentheses(Parentheses node, A arg) => visitExpression(node, arg);

  R visitArrayInitializer(ArrayInitializer node, A arg) =>
      visitExpression(node, arg);
  R visitArrayHole(ArrayHole node, A arg) => visitExpression(node, arg);
  R visitObjectInitializer(ObjectInitializer node, A arg) =>
      visitExpression(node, arg);
  R visitProperty(Property node, A arg) => visitNode(node, arg);
  R visitMethodDefinition(MethodDefinition node, A arg) => visitNode(node, arg);
  R visitRegExpLiteral(RegExpLiteral node, A arg) => visitExpression(node, arg);

  R visitInterpolatedNode(InterpolatedNode node, A arg) => visitNode(node, arg);

  R visitInterpolatedExpression(InterpolatedExpression node, A arg) =>
      visitInterpolatedNode(node, arg);
  R visitInterpolatedLiteral(InterpolatedLiteral node, A arg) =>
      visitInterpolatedNode(node, arg);
  R visitInterpolatedParameter(InterpolatedParameter node, A arg) =>
      visitInterpolatedNode(node, arg);
  R visitInterpolatedSelector(InterpolatedSelector node, A arg) =>
      visitInterpolatedNode(node, arg);
  R visitInterpolatedStatement(InterpolatedStatement node, A arg) =>
      visitInterpolatedNode(node, arg);
  R visitInterpolatedDeclaration(InterpolatedDeclaration node, A arg) {
    return visitInterpolatedNode(node, arg);
  }

  // Ignore comments by default.
  R visitComment(Comment node, A arg) => null;

  R visitAwait(Await node, A arg) => visitExpression(node, arg);
  R visitDartYield(DartYield node, A arg) => visitStatement(node, arg);
}

/// This tag interface has no behaviour but must be implemented by any class
/// that is to be stored on a [Node] as source information.
abstract class JavaScriptNodeSourceInformation {
  const JavaScriptNodeSourceInformation();
}

abstract class Node {
  JavaScriptNodeSourceInformation get sourceInformation => _sourceInformation;

  JavaScriptNodeSourceInformation _sourceInformation;

  T accept<T>(NodeVisitor<T> visitor);
  void visitChildren<T>(NodeVisitor<T> visitor);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg);
  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg);

  /// Shallow clone of node.  Does not clone positions since the only use of
  /// this private method is create a copy with a new position.
  Node _clone();

  /// Returns a node equivalent to [this], but with new source position and end
  /// source position.
  Node withSourceInformation(
      JavaScriptNodeSourceInformation sourceInformation) {
    if (sourceInformation == _sourceInformation) {
      return this;
    }
    Node clone = _clone();
    // TODO(sra): Should existing data be 'sticky' if we try to overwrite with
    // `null`?
    clone._sourceInformation = sourceInformation;
    return clone;
  }

  bool get isCommaOperator => false;

  Statement toStatement() {
    throw UnsupportedError('toStatement');
  }

  String debugPrint() => DebugPrint(this);

  /// Some nodes, e.g. DeferredExpression, become finalized in a 'linking'
  /// phase.
  bool get isFinalized => true;

  /// If a node is not finalized, debug printing can print something indicative
  /// of the node instead of the finalized AST. This method returns the
  /// replacement text.
  String nonfinalizedDebugText() {
    assert(!isFinalized);
    return '$runtimeType';
  }
}

class Program extends Node {
  final List<Statement> body;
  Program(this.body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitProgram(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitProgram(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    for (Statement statement in body) statement.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    for (Statement statement in body) statement.accept1(visitor, arg);
  }

  Program _clone() => Program(body);
}

abstract class Statement extends Node {
  Statement toStatement() => this;
}

/// Interface for a deferred [Statement] value. An implementation has to provide
/// a value via the [statement] getter the latest when the ast is printed.
abstract class DeferredStatement extends Statement {
  T accept<T>(NodeVisitor<T> visitor) => visitor.visitDeferredStatement(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitDeferredStatement(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    statement.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    statement.accept1(visitor, arg);
  }

  Statement get statement;
}

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

  Block(this.statements);

  Block.empty() : this.statements = [];

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitBlock(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitBlock(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    for (Statement statement in statements) statement.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    for (Statement statement in statements) statement.accept1(visitor, arg);
  }

  Block _clone() => Block(statements);
}

class ExpressionStatement extends Statement {
  final Expression expression;

  ExpressionStatement(this.expression) {
    assert(this.expression != null);
  }

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitExpressionStatement(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitExpressionStatement(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    expression.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    expression.accept1(visitor, arg);
  }

  ExpressionStatement _clone() => ExpressionStatement(expression);
}

class EmptyStatement extends Statement {
  EmptyStatement();

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitEmptyStatement(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitEmptyStatement(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  EmptyStatement _clone() => EmptyStatement();
}

class If extends Statement {
  final Expression condition;
  final Statement then;
  final Statement otherwise;

  If(this.condition, this.then, this.otherwise);

  If.noElse(this.condition, this.then) : this.otherwise = EmptyStatement();

  bool get hasElse => otherwise is! EmptyStatement;

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitIf(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitIf(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    condition.accept(visitor);
    then.accept(visitor);
    otherwise.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    condition.accept1(visitor, arg);
    then.accept1(visitor, arg);
    otherwise.accept1(visitor, arg);
  }

  If _clone() => If(condition, then, otherwise);
}

abstract class Loop extends Statement {
  final Statement body;

  Loop(this.body);
}

class For extends Loop {
  final Expression init;
  final Expression condition;
  final Expression update;

  For(this.init, this.condition, this.update, Statement body) : super(body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitFor(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitFor(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    if (init != null) init.accept(visitor);
    if (condition != null) condition.accept(visitor);
    if (update != null) update.accept(visitor);
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    if (init != null) init.accept1(visitor, arg);
    if (condition != null) condition.accept1(visitor, arg);
    if (update != null) update.accept1(visitor, arg);
    body.accept1(visitor, arg);
  }

  For _clone() => For(init, condition, update, body);
}

class ForIn extends Loop {
  // Note that [VariableDeclarationList] is a subclass of [Expression].
  // Therefore we can type the leftHandSide as [Expression].
  final Expression leftHandSide;
  final Expression object;

  ForIn(this.leftHandSide, this.object, Statement body) : super(body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitForIn(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitForIn(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    leftHandSide.accept(visitor);
    object.accept(visitor);
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    leftHandSide.accept1(visitor, arg);
    object.accept1(visitor, arg);
    body.accept1(visitor, arg);
  }

  ForIn _clone() => ForIn(leftHandSide, object, body);
}

class While extends Loop {
  final Node condition;

  While(this.condition, Statement body) : super(body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitWhile(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitWhile(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    condition.accept(visitor);
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    condition.accept1(visitor, arg);
    body.accept1(visitor, arg);
  }

  While _clone() => While(condition, body);
}

class Do extends Loop {
  final Expression condition;

  Do(Statement body, this.condition) : super(body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitDo(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitDo(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    body.accept(visitor);
    condition.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    body.accept1(visitor, arg);
    condition.accept1(visitor, arg);
  }

  Do _clone() => Do(body, condition);
}

class Continue extends Statement {
  final String targetLabel; // Can be null.

  Continue(this.targetLabel);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitContinue(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitContinue(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  Continue _clone() => Continue(targetLabel);
}

class Break extends Statement {
  final String targetLabel; // Can be null.

  Break(this.targetLabel);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitBreak(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitBreak(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  Break _clone() => Break(targetLabel);
}

class Return extends Statement {
  final Expression value; // Can be null.

  Return([this.value = null]);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitReturn(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitReturn(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    if (value != null) value.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    if (value != null) value.accept1(visitor, arg);
  }

  Return _clone() => Return(value);
}

class Throw extends Statement {
  final Expression expression;

  Throw(this.expression);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitThrow(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitThrow(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    expression.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    expression.accept1(visitor, arg);
  }

  Throw _clone() => Throw(expression);
}

class Try extends Statement {
  final Block body;
  final Catch catchPart; // Can be null if [finallyPart] is non-null.
  final Block finallyPart; // Can be null if [catchPart] is non-null.

  Try(this.body, this.catchPart, this.finallyPart) {
    assert(catchPart != null || finallyPart != null);
  }

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitTry(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitTry(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    body.accept(visitor);
    if (catchPart != null) catchPart.accept(visitor);
    if (finallyPart != null) finallyPart.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    body.accept1(visitor, arg);
    if (catchPart != null) catchPart.accept1(visitor, arg);
    if (finallyPart != null) finallyPart.accept1(visitor, arg);
  }

  Try _clone() => Try(body, catchPart, finallyPart);
}

class Catch extends Node {
  final Declaration declaration;
  final Block body;

  Catch(this.declaration, this.body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitCatch(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitCatch(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    declaration.accept(visitor);
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    declaration.accept1(visitor, arg);
    body.accept1(visitor, arg);
  }

  Catch _clone() => Catch(declaration, body);
}

class Switch extends Statement {
  final Expression key;
  final List<SwitchClause> cases;

  Switch(this.key, this.cases);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitSwitch(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitSwitch(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    key.accept(visitor);
    for (SwitchClause clause in cases) clause.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    key.accept1(visitor, arg);
    for (SwitchClause clause in cases) clause.accept1(visitor, arg);
  }

  Switch _clone() => Switch(key, cases);
}

abstract class SwitchClause extends Node {
  final Block body;

  SwitchClause(this.body);
}

class Case extends SwitchClause {
  final Expression expression;

  Case(this.expression, Block body) : super(body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitCase(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitCase(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    expression.accept(visitor);
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    expression.accept1(visitor, arg);
    body.accept1(visitor, arg);
  }

  Case _clone() => Case(expression, body);
}

class Default extends SwitchClause {
  Default(Block body) : super(body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitDefault(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitDefault(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    body.accept1(visitor, arg);
  }

  Default _clone() => Default(body);
}

class FunctionDeclaration extends Statement {
  final Declaration name;
  final Fun function;

  FunctionDeclaration(this.name, this.function);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitFunctionDeclaration(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitFunctionDeclaration(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    name.accept(visitor);
    function.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    name.accept1(visitor, arg);
    function.accept1(visitor, arg);
  }

  FunctionDeclaration _clone() => FunctionDeclaration(name, function);
}

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

  LabeledStatement(this.label, this.body);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitLabeledStatement(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitLabeledStatement(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    body.accept1(visitor, arg);
  }

  LabeledStatement _clone() => LabeledStatement(label, body);
}

class LiteralStatement extends Statement {
  final String code;

  LiteralStatement(this.code);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralStatement(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitLiteralStatement(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  LiteralStatement _clone() => LiteralStatement(code);
}

// Not a real JavaScript node, but represents the yield statement from a dart
// program translated to JavaScript.
class DartYield extends Statement {
  final Expression expression;

  final bool hasStar;

  DartYield(this.expression, this.hasStar);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitDartYield(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitDartYield(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    expression.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    expression.accept1(visitor, arg);
  }

  DartYield _clone() => DartYield(expression, hasStar);
}

abstract class Expression extends Node {
  // [precedenceLevel] must not be used before printing, as deferred nodes can
  // have precedence depending on how the deferred node is resolved.
  int get precedenceLevel;

  Statement toStatement() => ExpressionStatement(this);
}

abstract class Declaration implements VariableReference {}

/// [Name] is an extension point to allow a JavaScript AST to contain
/// identifiers that are bound later. This is used in minification.
///
/// [Name] is a [Literal] so that it can occur as a property access selector.
//
// TODO(sra): Figure out why [Name] is a Declaration and Parameter, and where
// that is used. How should the printer know if an occurrence of a Name is meant
// to be a Literal or a Declaration (which includes a VariableUse)?
abstract class Name extends Literal implements Declaration, Parameter {
  T accept<T>(NodeVisitor<T> visitor) => visitor.visitName(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitName(this, arg);

  Name _clone();

  /// Returns the text of this name.
  ///
  /// May throw if the text has not been decided. Typically the text is decided
  /// in some finalization phase that happens before the AST is printed.
  String get name;

  /// Returns a unique [key] for this name.
  ///
  /// The key is unrelated to the actual name and is not intended for human
  /// consumption. As such, it might be long or cryptic.
  String get key;

  bool get allowRename => false;
}

class LiteralStringFromName extends LiteralString {
  final Name name;

  LiteralStringFromName(this.name) : super(null) {
    ArgumentError.checkNotNull(name, 'name');
  }

  @override
  bool get isFinalized => name.isFinalized;

  @override
  String get value => name.name;

  void visitChildren<T>(NodeVisitor<T> visitor) {
    name.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    name.accept1(visitor, arg);
  }
}

class LiteralExpression extends Expression {
  final String template;
  LiteralExpression(this.template);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralExpression(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitLiteralExpression(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  LiteralExpression _clone() => LiteralExpression(template);

  // Code that uses LiteralExpression must take care of operator precedences,
  // and put parenthesis if needed.
  int get precedenceLevel => PRIMARY;
}

/// [VariableDeclarationList] is a subclass of [Expression] to simplify the
/// AST.
class VariableDeclarationList extends Expression {
  final List<VariableInitialization> declarations;

  /// When pretty-printing a declaration list with multiple declarations over
  /// several lines, the declarations are usually indented with respect to the
  /// `var` keyword. Set [indentSplits] to `false` to suppress the indentation.
  final bool indentSplits;

  VariableDeclarationList(this.declarations, {this.indentSplits = true});

  T accept<T>(NodeVisitor<T> visitor) =>
      visitor.visitVariableDeclarationList(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitVariableDeclarationList(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    for (VariableInitialization declaration in declarations) {
      declaration.accept(visitor);
    }
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    for (VariableInitialization declaration in declarations) {
      declaration.accept1(visitor, arg);
    }
  }

  VariableDeclarationList _clone() => VariableDeclarationList(declarations);

  int get precedenceLevel => EXPRESSION;
}

/// Forced parenthesized expression. Pretty-printing will emit parentheses based
/// on need, so this node is very rarely needed.
class Parentheses extends Expression {
  final Expression enclosed;

  Parentheses(this.enclosed);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitParentheses(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitParentheses(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    enclosed.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    enclosed.accept1(visitor, arg);
  }

  Parentheses _clone() => Parentheses(enclosed);

  int get precedenceLevel => PRIMARY;
}

class Assignment extends Expression {
  final Expression leftHandSide;
  final String op; // Null, if the assignment is not compound.
  final Expression value; // May be null, for [VariableInitialization]s.

  Assignment(leftHandSide, value) : this.compound(leftHandSide, null, value);

  // If `this.op == null` this will be a non-compound assignment.
  Assignment.compound(this.leftHandSide, this.op, this.value);

  int get precedenceLevel => ASSIGNMENT;

  bool get isCompound => op != null;

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitAssignment(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitAssignment(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    leftHandSide.accept(visitor);
    if (value != null) value.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    leftHandSide.accept1(visitor, arg);
    if (value != null) value.accept1(visitor, arg);
  }

  Assignment _clone() => Assignment.compound(leftHandSide, op, value);
}

class VariableInitialization extends Assignment {
  /// [value] may be null.
  VariableInitialization(Declaration declaration, Expression value)
      : super(declaration, value);

  Declaration get declaration => leftHandSide;

  T accept<T>(NodeVisitor<T> visitor) =>
      visitor.visitVariableInitialization(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitVariableInitialization(this, arg);

  VariableInitialization _clone() => VariableInitialization(declaration, value);
}

class Conditional extends Expression {
  final Expression condition;
  final Expression then;
  final Expression otherwise;

  Conditional(this.condition, this.then, this.otherwise);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitConditional(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitConditional(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    condition.accept(visitor);
    then.accept(visitor);
    otherwise.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    condition.accept1(visitor, arg);
    then.accept1(visitor, arg);
    otherwise.accept1(visitor, arg);
  }

  Conditional _clone() => Conditional(condition, then, otherwise);

  int get precedenceLevel => ASSIGNMENT;
}

class Call extends Expression {
  Expression target;
  List<Expression> arguments;

  Call(this.target, this.arguments,
      {JavaScriptNodeSourceInformation sourceInformation}) {
    this._sourceInformation = sourceInformation;
  }

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitCall(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitCall(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    target.accept(visitor);
    for (Expression arg in arguments) {
      arg.accept(visitor);
    }
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    target.accept1(visitor, arg);
    for (Expression arg in arguments) {
      arg.accept1(visitor, arg);
    }
  }

  Call _clone() => Call(target, arguments);

  int get precedenceLevel => CALL;
}

class New extends Call {
  New(Expression cls, List<Expression> arguments) : super(cls, arguments);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitNew(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitNew(this, arg);

  New _clone() => New(target, arguments);
}

class Binary extends Expression {
  final String op;
  final Expression left;
  final Expression right;

  Binary(this.op, this.left, this.right);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitBinary(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitBinary(this, arg);

  Binary _clone() => Binary(op, left, right);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    left.accept(visitor);
    right.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    left.accept1(visitor, arg);
    right.accept1(visitor, arg);
  }

  bool get isCommaOperator => op == ',';

  int get precedenceLevel {
    // TODO(floitsch): switch to constant map.
    switch (op) {
      case "*":
      case "/":
      case "%":
        return MULTIPLICATIVE;
      case "+":
      case "-":
        return ADDITIVE;
      case "<<":
      case ">>":
      case ">>>":
        return SHIFT;
      case "<":
      case ">":
      case "<=":
      case ">=":
      case "instanceof":
      case "in":
        return RELATIONAL;
      case "==":
      case "===":
      case "!=":
      case "!==":
        return EQUALITY;
      case "&":
        return BIT_AND;
      case "^":
        return BIT_XOR;
      case "|":
        return BIT_OR;
      case "&&":
        return LOGICAL_AND;
      case "||":
        return LOGICAL_OR;
      case ',':
        return EXPRESSION;
      default:
        throw "Internal Error: Unhandled binary operator: $op";
    }
  }
}

class Prefix extends Expression {
  final String op;
  final Expression argument;

  Prefix(this.op, this.argument);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitPrefix(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitPrefix(this, arg);

  Prefix _clone() => Prefix(op, argument);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    argument.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    argument.accept1(visitor, arg);
  }

  int get precedenceLevel => UNARY;
}

class Postfix extends Expression {
  final String op;
  final Expression argument;

  Postfix(this.op, this.argument);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitPostfix(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitPostfix(this, arg);

  Postfix _clone() => Postfix(op, argument);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    argument.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    argument.accept1(visitor, arg);
  }

  int get precedenceLevel => UNARY;
}

RegExp _identifierRE = RegExp(r'^[A-Za-z_$][A-Za-z_$0-9]*$');

abstract class VariableReference extends Expression {
  final String name;

  VariableReference(this.name) {
    assert(_identifierRE.hasMatch(name), "Non-identifier name '$name'");
  }

  T accept<T>(NodeVisitor<T> visitor);

  int get precedenceLevel => PRIMARY;

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}
}

class VariableUse extends VariableReference {
  VariableUse(String name) : super(name);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitVariableUse(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitVariableUse(this, arg);

  VariableUse _clone() => VariableUse(name);

  String toString() => 'VariableUse($name)';
}

class VariableDeclaration extends VariableReference implements Declaration {
  final bool allowRename;

  VariableDeclaration(String name, {this.allowRename = true}) : super(name);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitVariableDeclaration(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitVariableDeclaration(this, arg);

  VariableDeclaration _clone() => VariableDeclaration(name);
}

class Parameter extends VariableDeclaration {
  Parameter(String name) : super(name);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitParameter(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitParameter(this, arg);

  Parameter _clone() => Parameter(name);
}

class This extends Parameter {
  This() : super("this");

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitThis(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitThis(this, arg);

  This _clone() => This();
}

class NamedFunction extends Expression {
  final Declaration name;
  final Fun function;

  NamedFunction(this.name, this.function);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitNamedFunction(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitNamedFunction(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    name.accept(visitor);
    function.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    name.accept1(visitor, arg);
    function.accept1(visitor, arg);
  }

  NamedFunction _clone() => NamedFunction(name, function);

  int get precedenceLevel => LEFT_HAND_SIDE;
}

abstract class FunctionExpression extends Expression {
  Node body;
  List<Parameter> params;
  AsyncModifier asyncModifier;
}

class Fun extends FunctionExpression {
  @override
  final Block body;
  @override
  final List<Parameter> params;
  @override
  final AsyncModifier asyncModifier;

  Fun(this.params, this.body, {this.asyncModifier = AsyncModifier.sync});

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitFun(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitFun(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    for (Parameter param in params) param.accept(visitor);
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    for (Parameter param in params) param.accept1(visitor, arg);
    body.accept1(visitor, arg);
  }

  Fun _clone() => Fun(params, body, asyncModifier: asyncModifier);

  int get precedenceLevel => LEFT_HAND_SIDE;
}

class ArrowFunction extends FunctionExpression {
  @override
  final Node body;
  @override
  final List<Parameter> params;
  @override
  final AsyncModifier asyncModifier;

  /// Indicates whether it is permissible to try to emit this arrow function
  /// in a form with an implicit 'return'.
  final bool implicitReturnAllowed;

  ArrowFunction(this.params, this.body,
      {this.asyncModifier = AsyncModifier.sync,
      this.implicitReturnAllowed = true});

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrowFunction(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitArrowFunction(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    for (Parameter param in params) param.accept(visitor);
    body.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    for (Parameter param in params) param.accept1(visitor, arg);
    body.accept1(visitor, arg);
  }

  ArrowFunction _clone() => ArrowFunction(params, body,
      asyncModifier: asyncModifier,
      implicitReturnAllowed: implicitReturnAllowed);

  int get precedenceLevel => ASSIGNMENT;
}

class AsyncModifier {
  final int index;
  final bool isAsync;
  final bool isYielding;
  final String description;

  const AsyncModifier(this.index, this.description,
      {this.isAsync, this.isYielding});

  static const AsyncModifier sync =
      AsyncModifier(0, "sync", isAsync: false, isYielding: false);
  static const AsyncModifier async =
      AsyncModifier(1, "async", isAsync: true, isYielding: false);
  static const AsyncModifier asyncStar =
      AsyncModifier(2, "async*", isAsync: true, isYielding: true);
  static const AsyncModifier syncStar =
      AsyncModifier(3, "sync*", isAsync: false, isYielding: true);

  static const List<AsyncModifier> values = [sync, async, asyncStar, syncStar];

  String toString() => description;
}

class PropertyAccess extends Expression {
  final Expression receiver;
  final Expression selector;

  PropertyAccess(this.receiver, this.selector);

  PropertyAccess.field(this.receiver, String fieldName)
      : selector = LiteralString(fieldName);

  PropertyAccess.indexed(this.receiver, int index)
      : selector = LiteralNumber('$index');

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitAccess(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitAccess(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    receiver.accept(visitor);
    selector.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    receiver.accept1(visitor, arg);
    selector.accept1(visitor, arg);
  }

  PropertyAccess _clone() => PropertyAccess(receiver, selector);

  int get precedenceLevel => LEFT_HAND_SIDE;
}

/// A [DeferredToken] is a placeholder for some [Expression] that is not known
/// at construction time of an ast. Unlike [InterpolatedExpression],
/// [DeferredToken] is not limited to templates but may also occur in
/// fully instantiated asts.
abstract class DeferredToken extends Expression {
  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  DeferredToken _clone() => this;
}

/// Interface for a deferred integer value. An implementation has to provide
/// a value via the [value] getter the latest when the ast is printed.
abstract class DeferredNumber extends DeferredToken implements Literal {
  T accept<T>(NodeVisitor<T> visitor) => visitor.visitDeferredNumber(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitDeferredNumber(this, arg);

  int get value;

  int get precedenceLevel => value.isNegative ? UNARY : PRIMARY;
}

/// Interface for a deferred string value. An implementation has to provide
/// a value via the [value] getter the latest when the ast is printed.
abstract class DeferredString extends DeferredToken implements Literal {
  T accept<T>(NodeVisitor<T> visitor) => visitor.visitDeferredString(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitDeferredString(this, arg);

  String get value;

  int get precedenceLevel => PRIMARY;
}

/// Interface for a deferred [Expression] value. An implementation has to provide
/// a value via the [value] getter the latest when the ast is printed.
/// Also, [precedenceLevel] has to return the same value that
/// [value.precedenceLevel] returns once [value] is bound to an [Expression].
abstract class DeferredExpression extends DeferredToken {
  T accept<T>(NodeVisitor<T> visitor) => visitor.visitDeferredExpression(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitDeferredExpression(this, arg);

  Expression get value;
}

abstract class Literal extends Expression {
  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  int get precedenceLevel => PRIMARY;
}

class LiteralBool extends Literal {
  final bool value;

  LiteralBool(this.value);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralBool(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitLiteralBool(this, arg);

  // [visitChildren] inherited from [Literal].

  LiteralBool _clone() => LiteralBool(value);
}

class LiteralNull extends Literal {
  LiteralNull();

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralNull(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitLiteralNull(this, arg);

  LiteralNull _clone() => LiteralNull();
}

class LiteralString extends Literal {
  final String value;

  /// Constructs a LiteralString for a string containing the characters of
  /// `value`.
  ///
  /// When printed, the string will be escaped and quoted according to the
  /// printer's settings.
  LiteralString(this.value);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralString(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitLiteralString(this, arg);

  LiteralString _clone() => LiteralString(value);

  @override
  String toString() {
    final sb = StringBuffer('$runtimeType("');
    String end = '"';
    int count = 0;
    for (int rune in value.runes) {
      if (++count > 20) {
        end = '"...';
        break;
      }
      if (32 <= rune && rune < 127) {
        sb.writeCharCode(rune);
      } else {
        sb.write(r'\u{');
        sb.write(rune.toRadixString(16));
        sb.write(r'}');
      }
    }
    sb.write(end);
    sb.write(')');
    return sb.toString();
  }
}

class StringConcatenation extends Literal {
  final List<Literal> parts;

  /// Constructs a StringConcatenation from a list of Literal elements.
  ///
  /// The constructor does not add surrounding quotes to the resulting
  /// concatenated string.
  StringConcatenation(this.parts);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitStringConcatenation(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitStringConcatenation(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    for (Literal part in parts) part.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    for (Literal part in parts) part.accept1(visitor, arg);
  }

  StringConcatenation _clone() => StringConcatenation(this.parts);
}

class LiteralNumber extends Literal {
  final String value; // Must be a valid JavaScript number literal.

  LiteralNumber(this.value);

  int get precedenceLevel => value.startsWith('-') ? UNARY : PRIMARY;

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitLiteralNumber(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitLiteralNumber(this, arg);

  LiteralNumber _clone() => LiteralNumber(value);
}

class ArrayInitializer extends Expression {
  final List<Expression> elements;

  ArrayInitializer(this.elements) : assert(!elements.contains(null));

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrayInitializer(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitArrayInitializer(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    for (Expression element in elements) element.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    for (Expression element in elements) element.accept1(visitor, arg);
  }

  ArrayInitializer _clone() => ArrayInitializer(elements);

  int get precedenceLevel => PRIMARY;
}

/// An empty place in an [ArrayInitializer].
/// For example the list [1, , , 2] would contain two holes.
class ArrayHole extends Expression {
  T accept<T>(NodeVisitor<T> visitor) => visitor.visitArrayHole(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitArrayHole(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  ArrayHole _clone() => ArrayHole();

  int get precedenceLevel => PRIMARY;
}

class ObjectInitializer extends Expression {
  final List<Property> properties;
  final bool isOneLiner;

  /// Constructs a new object-initializer containing the given [properties].
  ///
  /// [isOneLiner] describes the behaviour when pretty-printing (non-minified).
  /// If true print all properties on the same line.
  /// If false print each property on a seperate line.
  ObjectInitializer(this.properties, {this.isOneLiner = true});

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitObjectInitializer(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitObjectInitializer(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    for (Property init in properties) init.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    for (Property init in properties) init.accept1(visitor, arg);
  }

  ObjectInitializer _clone() =>
      ObjectInitializer(properties, isOneLiner: isOneLiner);

  int get precedenceLevel => PRIMARY;
}

class Property extends Node {
  final Expression name;
  final Expression value;

  Property(this.name, this.value)
      : assert(name is Literal || name is DeferredExpression);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitProperty(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitProperty(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {
    name.accept(visitor);
    value.accept(visitor);
  }

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    name.accept1(visitor, arg);
    value.accept1(visitor, arg);
  }

  Property _clone() => Property(name, value);
}

class MethodDefinition extends Node implements Property {
  @override
  final Expression name;
  final Fun function;

  MethodDefinition(this.name, this.function);

  @override
  Fun get value => function;

  @override
  T accept<T>(NodeVisitor<T> visitor) => visitor.visitMethodDefinition(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitMethodDefinition(this, arg);

  @override
  void visitChildren<T>(NodeVisitor<T> visitor) {
    name.accept(visitor);
    function.accept(visitor);
  }

  @override
  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {
    name.accept1(visitor, arg);
    function.accept1(visitor, arg);
  }

  @override
  MethodDefinition _clone() => MethodDefinition(name, function);
}

/// Tag class for all interpolated positions.
abstract class InterpolatedNode implements Node {
  get nameOrPosition;

  bool get isNamed => nameOrPosition is String;

  bool get isPositional => nameOrPosition is int;
}

class InterpolatedExpression extends Expression with InterpolatedNode {
  final nameOrPosition;

  InterpolatedExpression(this.nameOrPosition);

  T accept<T>(NodeVisitor<T> visitor) =>
      visitor.visitInterpolatedExpression(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitInterpolatedExpression(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  InterpolatedExpression _clone() => InterpolatedExpression(nameOrPosition);

  int get precedenceLevel => PRIMARY;
}

class InterpolatedLiteral extends Literal with InterpolatedNode {
  final nameOrPosition;

  InterpolatedLiteral(this.nameOrPosition);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitInterpolatedLiteral(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitInterpolatedLiteral(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  InterpolatedLiteral _clone() => InterpolatedLiteral(nameOrPosition);
}

class InterpolatedParameter extends Expression
    with InterpolatedNode
    implements Parameter {
  final nameOrPosition;

  InterpolatedParameter(this.nameOrPosition);

  String get name {
    throw "InterpolatedParameter.name must not be invoked";
  }

  bool get allowRename => false;

  T accept<T>(NodeVisitor<T> visitor) =>
      visitor.visitInterpolatedParameter(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitInterpolatedParameter(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  InterpolatedParameter _clone() => InterpolatedParameter(nameOrPosition);

  int get precedenceLevel => PRIMARY;
}

class InterpolatedSelector extends Expression with InterpolatedNode {
  final nameOrPosition;

  InterpolatedSelector(this.nameOrPosition);

  T accept<T>(NodeVisitor<T> visitor) =>
      visitor.visitInterpolatedSelector(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitInterpolatedSelector(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  InterpolatedSelector _clone() => InterpolatedSelector(nameOrPosition);

  int get precedenceLevel => PRIMARY;
}

class InterpolatedStatement extends Statement with InterpolatedNode {
  final nameOrPosition;

  InterpolatedStatement(this.nameOrPosition);

  T accept<T>(NodeVisitor<T> visitor) =>
      visitor.visitInterpolatedStatement(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitInterpolatedStatement(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  InterpolatedStatement _clone() => InterpolatedStatement(nameOrPosition);
}

class InterpolatedDeclaration extends Expression
    with InterpolatedNode
    implements Declaration {
  final nameOrPosition;

  InterpolatedDeclaration(this.nameOrPosition);

  T accept<T>(NodeVisitor<T> visitor) =>
      visitor.visitInterpolatedDeclaration(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitInterpolatedDeclaration(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  InterpolatedDeclaration _clone() {
    return InterpolatedDeclaration(nameOrPosition);
  }

  @override
  String get name => throw "No name for the interpolated node";

  @override
  int get precedenceLevel => PRIMARY;
}

/// [RegExpLiteral]s, despite being called "Literal", do not inherit from
/// [Literal]. Indeed, regular expressions in JavaScript have a side-effect and
/// are thus not in the same category as numbers or strings.
class RegExpLiteral extends Expression {
  /// Contains the pattern and the flags.
  final String pattern;

  RegExpLiteral(this.pattern);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitRegExpLiteral(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitRegExpLiteral(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}

  RegExpLiteral _clone() => RegExpLiteral(pattern);

  int get precedenceLevel => PRIMARY;
}

/// An asynchronous await.
///
/// Not part of JavaScript. We desugar this expression before outputting.
/// Should only occur in a [Fun] with `asyncModifier` async or asyncStar.
class Await extends Expression {
  /// The awaited expression.
  final Expression expression;

  Await(this.expression);

  int get precedenceLevel => UNARY;

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitAwait(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitAwait(this, arg);

  void visitChildren<T>(NodeVisitor<T> visitor) => expression.accept(visitor);

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      expression.accept1(visitor, arg);

  Await _clone() => Await(expression);
}

/// A comment.
///
/// Extends [Statement] so we can add comments before statements in
/// [Block] and [Program].
class Comment extends Statement {
  final String comment;

  Comment(this.comment);

  T accept<T>(NodeVisitor<T> visitor) => visitor.visitComment(this);

  R accept1<R, A>(NodeVisitor1<R, A> visitor, A arg) =>
      visitor.visitComment(this, arg);

  Comment _clone() => Comment(comment);

  void visitChildren<T>(NodeVisitor<T> visitor) {}

  void visitChildren1<R, A>(NodeVisitor1<R, A> visitor, A arg) {}
}

/// Returns the value of [node] if it is a [DeferredExpression]. Otherwise
/// returns the [node] itself.
Node undefer(Node node) {
  return node is DeferredExpression ? undefer(node.value) : node;
}
