// Copyright (c) 2020, 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 js.size_estimator;

import 'package:js_ast/js_ast.dart';
import 'package:js_ast/src/characters.dart' as charCodes;
import 'package:js_ast/src/precedence.dart';

import '../js_backend/deferred_holder_expression.dart';
import '../js_backend/string_reference.dart';
import '../js_backend/type_reference.dart';
import '../js_emitter/metadata_collector.dart';

/// Estimates the size of the Javascript AST represented by the provided [Node].
int estimateSize(Node node) {
  var estimator = SizeEstimator();
  estimator.visit(node);
  return estimator.charCount;
}

/// [SizeEstimator] is a [NodeVisitor] designed to produce a consistent size
/// estimate for a given JavaScript AST. [SizeEstimator] trades accuracy for
/// stability and performance. In addition, [SizeEstimator] assumes we will emit
/// production quality minified JavaScript.
class SizeEstimator implements NodeVisitor {
  int charCount = 0;
  bool inForInit = false;
  bool atStatementBegin = false;
  bool pendingSemicolon = false;
  bool pendingSpace = false;

  static final String variableSizeEstimate = '#';
  static final String nameSizeEstimate = '###';

  String sizeEstimate(Node node) {
    if (node is VariableDeclaration || node is VariableUse) {
      // We assume all [VariableDeclaration] and [VariableUse] nodes are
      // locals.
      return variableSizeEstimate;
    } else if (node is Name ||
        node is Parameter ||
        node is VariableDeclaration ||
        node is VariableUse) {
      return nameSizeEstimate;
    } else if (node is LiteralString) {
      assert(!node.isFinalized);
      // We assume all non-final literal strings are minified names, and thus
      // use the nameSizeEstimate.
      return nameSizeEstimate;
    } else if (node is BoundMetadataEntry) {
      // Value is an int.
      return '####';
    } else if (node is TypeReference) {
      // Type references vary in size. Some references look like:
      // '<typeHolder>$.<type>' where <typeHolder> is a one byte local and
      // <type> is roughly 3 bytes. However, we also have to initialize the type
      // in the holder, some like ab:f("QQ<b7c>"), ie 16 bytes. For two
      // occurences we will have on average 13 bytes. For a more detailed
      // estimate, we'd have to partially finalize the results.
      return '###_###_###_#';
    } else if (node is StringReference) {
      // Worst case we have to inline the string so size of string + 2 bytes for
      // quotes.
      return "'${node.constant.toDartString()}'";
    } else if (node is DeferredHolderExpression) {
      // 1 byte holder + dot + nameSizeEstimate
      return '#.$nameSizeEstimate';
    } else {
      throw UnsupportedError('$node type is not supported');
    }
  }

  String literalStringToString(LiteralString node) {
    if (node.isFinalized) {
      return node.value;
    } else {
      return sizeEstimate(node);
    }
  }

  /// Always emit a newline, even under `enableMinification`.
  void forceLine() {
    out('\n'); // '\n'
  }

  void out(String s) {
    if (s.length > 0) {
      // We can elide a semicolon in some cases, but for simplicity we
      // assume a semicolon is needed here.
      if (pendingSemicolon) {
        emit(';'); // ';'
      }

      // We can elide a pending space in some cases, but for simplicity we
      // assume a space is needed here.
      if (pendingSpace) {
        emit(' '); // ' '
      }
      pendingSpace = false;
      pendingSemicolon = false;
      emit(s); // str
    }
  }

  void outSemicolonLn() {
    pendingSemicolon = true;
  }

  void emit(String s) {
    charCount += s.length;
  }

  void visit(Node node) {
    node.accept(this);
  }

  void visitCommaSeparated(List<Node> nodes, int hasRequiredType,
      {bool newInForInit, bool newAtStatementBegin}) {
    for (int i = 0; i < nodes.length; i++) {
      if (i != 0) {
        atStatementBegin = false;
        out(','); // ','
      }
      visitNestedExpression(nodes[i], hasRequiredType,
          newInForInit: newInForInit, newAtStatementBegin: newAtStatementBegin);
    }
  }

  void visitAll(List<Node> nodes) {
    nodes.forEach(visit);
  }

  @override
  void visitProgram(Program program) {
    if (program.body.isNotEmpty) {
      visitAll(program.body);
    }
  }

  Statement unwrapBlockIfSingleStatement(Statement body) {
    Statement result = body;
    while (result is Block) {
      Block block = result;
      if (block.statements.length != 1) break;
      result = block.statements.single;
    }
    return result;
  }

  bool blockBody(Statement body, {bool needsSeparation}) {
    if (body is Block) {
      blockOut(body);
      return true;
    }
    if (needsSeparation) {
      out(' '); // ' '
    }
    visit(body);
    return false;
  }

  void blockOutWithoutBraces(Node node) {
    if (node is Block) {
      Block block = node;
      block.statements.forEach(blockOutWithoutBraces);
    } else {
      visit(node);
    }
  }

  int blockOut(Block node) {
    out('{'); // '{'
    node.statements.forEach(blockOutWithoutBraces);
    out('}'); // '}'
    int closingPosition = charCount - 1;
    return closingPosition;
  }

  @override
  void visitBlock(Block block) {
    blockOut(block);
  }

  @override
  void visitExpressionStatement(ExpressionStatement node) {
    visitNestedExpression(node.expression, EXPRESSION,
        newInForInit: false, newAtStatementBegin: true);
    outSemicolonLn();
  }

  @override
  void visitEmptyStatement(EmptyStatement node) {
    out(';'); // ';'
  }

  void ifOut(If node) {
    Statement then = unwrapBlockIfSingleStatement(node.then);
    Statement elsePart = node.otherwise;
    bool hasElse = node.hasElse;

    out('if('); // 'if('
    visitNestedExpression(node.condition, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out(')'); // ')'
    blockBody(then, needsSeparation: false);
    if (hasElse) {
      out('else'); // 'else'
      if (elsePart is If) {
        pendingSpace = true;
        ifOut(elsePart);
      } else {
        blockBody(unwrapBlockIfSingleStatement(elsePart),
            needsSeparation: true);
      }
    }
  }

  @override
  void visitIf(If node) {
    ifOut(node);
  }

  @override
  void visitFor(For loop) {
    out('for('); // 'for('
    if (loop.init != null) {
      visitNestedExpression(loop.init, EXPRESSION,
          newInForInit: true, newAtStatementBegin: false);
    }
    out(';'); // ';'
    if (loop.condition != null) {
      visitNestedExpression(loop.condition, EXPRESSION,
          newInForInit: false, newAtStatementBegin: false);
    }
    out(';'); // ';'
    if (loop.update != null) {
      visitNestedExpression(loop.update, EXPRESSION,
          newInForInit: false, newAtStatementBegin: false);
    }
    out(')'); // ')'
    blockBody(unwrapBlockIfSingleStatement(loop.body), needsSeparation: false);
  }

  @override
  void visitForIn(ForIn loop) {
    out('for('); // 'for('
    visitNestedExpression(loop.leftHandSide, EXPRESSION,
        newInForInit: true, newAtStatementBegin: false);
    out(' in'); // ' in'
    pendingSpace = true;
    visitNestedExpression(loop.object, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out(')'); // ')'
    blockBody(unwrapBlockIfSingleStatement(loop.body), needsSeparation: false);
  }

  @override
  void visitWhile(While loop) {
    out('while('); // 'while('
    visitNestedExpression(loop.condition, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out(')'); // ')'
    blockBody(unwrapBlockIfSingleStatement(loop.body), needsSeparation: false);
  }

  @override
  void visitDo(Do loop) {
    out('do'); // 'do'
    if (blockBody(unwrapBlockIfSingleStatement(loop.body),
        needsSeparation: true)) {}
    out('while('); // 'while('
    visitNestedExpression(loop.condition, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out(')'); // ')'
    outSemicolonLn();
  }

  @override
  void visitContinue(Continue node) {
    if (node.targetLabel == null) {
      out('continue'); // 'continue'
    } else {
      out('continue ${node.targetLabel}'); // 'continue ${node.targetLabel}'
    }
    outSemicolonLn();
  }

  @override
  void visitBreak(Break node) {
    if (node.targetLabel == null) {
      out('break');
    } else {
      out('break ${node.targetLabel}');
    }
    outSemicolonLn();
  }

  @override
  void visitReturn(Return node) {
    out('return'); // 'return'
    if (node.value != null) {
      pendingSpace = true;
      visitNestedExpression(node.value, EXPRESSION,
          newInForInit: false, newAtStatementBegin: false);
    }
    outSemicolonLn();
  }

  @override
  void visitDartYield(DartYield node) {
    if (node.hasStar) {
      out('yield*'); // 'yield*'
    } else {
      out('yield'); // 'yield'
    }
    pendingSpace = true;
    visitNestedExpression(node.expression, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    outSemicolonLn();
  }

  @override
  void visitThrow(Throw node) {
    out('throw'); // 'throw'
    pendingSpace = true;
    visitNestedExpression(node.expression, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    outSemicolonLn();
  }

  @override
  void visitTry(Try node) {
    out('try'); // 'try'
    blockBody(node.body, needsSeparation: true);
    if (node.catchPart != null) {
      visit(node.catchPart);
    }
    if (node.finallyPart != null) {
      out('finally'); // 'finally'
      blockBody(node.finallyPart, needsSeparation: true);
    }
  }

  @override
  void visitCatch(Catch node) {
    out('catch('); // 'catch('
    visitNestedExpression(node.declaration, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out(')'); // ')'
    blockBody(node.body, needsSeparation: false);
  }

  @override
  void visitSwitch(Switch node) {
    out('switch('); // 'switch('
    visitNestedExpression(node.key, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out('){'); // '){
    visitAll(node.cases);
    out('}'); // '}'
  }

  @override
  void visitCase(Case node) {
    out('case'); // 'case'
    pendingSpace = true;
    visitNestedExpression(node.expression, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out(':'); // ':'
    if (!node.body.statements.isEmpty) {
      blockOutWithoutBraces(node.body);
    }
  }

  @override
  void visitDefault(Default node) {
    out('default:'); // 'default:'
    if (!node.body.statements.isEmpty) {
      blockOutWithoutBraces(node.body);
    }
  }

  @override
  void visitLabeledStatement(LabeledStatement node) {
    Statement body = unwrapBlockIfSingleStatement(node.body);
    // `label: break label;`
    // Does not work on IE. The statement is a nop, so replace it by an empty
    // statement.
    // See:
    // https://connect.microsoft.com/IE/feedback/details/891889/parser-bugs
    if (body is Break && body.targetLabel == node.label) {
      visit(EmptyStatement());
      return;
    }
    out('${node.label}:');
    blockBody(body, needsSeparation: false);
  }

  int functionOut(Fun fun, Node name, VarCollector vars) {
    out('function'); // 'function'
    if (name != null) {
      out(' '); // ' '
      // Name must be a [Decl]. Therefore only test for primary expressions.
      visitNestedExpression(name, PRIMARY,
          newInForInit: false, newAtStatementBegin: false);
    }
    out('('); // '('
    if (fun.params != null) {
      visitCommaSeparated(fun.params, PRIMARY,
          newInForInit: false, newAtStatementBegin: false);
    }
    out(')'); // ')'
    switch (fun.asyncModifier) {
      case AsyncModifier.sync:
        break;
      case AsyncModifier.async:
        out(' async'); // ' async'
        break;
      case AsyncModifier.syncStar:
        out(' sync*'); // ' sync*'
        break;
      case AsyncModifier.asyncStar:
        out(' async*'); // ' async*'
        break;
    }
    int closingPosition = blockOut(fun.body);
    return closingPosition;
  }

  @override
  visitFunctionDeclaration(FunctionDeclaration declaration) {
    VarCollector vars = VarCollector();
    vars.visitFunctionDeclaration(declaration);
    functionOut(declaration.function, declaration.name, vars);
  }

  visitNestedExpression(Expression node, int requiredPrecedence,
      {bool newInForInit, bool newAtStatementBegin}) {
    bool needsParentheses = !node.isFinalized ||
        // a - (b + c).
        (requiredPrecedence != EXPRESSION &&
            node.precedenceLevel < requiredPrecedence) ||
        // for (a = (x in o); ... ; ... ) { ... }
        (newInForInit && node is Binary && node.op == "in") ||
        // (function() { ... })().
        // ({a: 2, b: 3}.toString()).
        (newAtStatementBegin &&
            (node is NamedFunction ||
                node is FunctionExpression ||
                node is ObjectInitializer));
    if (needsParentheses) {
      inForInit = false;
      atStatementBegin = false;
      out('('); // '('
      visit(node);
      out(')'); // ')'
    } else {
      inForInit = newInForInit;
      atStatementBegin = newAtStatementBegin;
      visit(node);
    }
  }

  @override
  visitVariableDeclarationList(VariableDeclarationList list) {
    out('var '); // 'var '
    List<Node> nodes = list.declarations;
    if (inForInit) {
      visitCommaSeparated(nodes, ASSIGNMENT,
          newInForInit: inForInit, newAtStatementBegin: false);
    } else {
      for (int i = 0; i < nodes.length; i++) {
        Node node = nodes[i];
        if (i > 0) {
          atStatementBegin = false;
          out(','); // ','
        }
        visitNestedExpression(node, ASSIGNMENT,
            newInForInit: inForInit, newAtStatementBegin: false);
      }
    }
  }

  void _outputIncDec(String op, Expression variable, [Expression alias]) {
    // We can eliminate the space preceding the inc/dec in some cases,
    // but for estimation purposes we assume the worst case.
    if (op == '+') {
      out(' ++');
    } else {
      out(' --');
    }
    visitNestedExpression(variable, UNARY,
        newInForInit: inForInit, newAtStatementBegin: false);
  }

  @override
  visitAssignment(Assignment assignment) {
    /// To print assignments like `a = a + 1` and `a = a + b` compactly as
    /// `++a` and `a += b` in the face of [DeferredExpression]s we detect the
    /// pattern of the undeferred assignment.
    String op = assignment.op;
    Node leftHandSide = assignment.leftHandSide;
    Node rightHandSide = assignment.value;
    if ((op == '+' || op == '-') &&
        leftHandSide is VariableUse &&
        rightHandSide is LiteralNumber &&
        rightHandSide.value == "1") {
      // Output 'a += 1' as '++a' and 'a -= 1' as '--a'.
      _outputIncDec(op, assignment.leftHandSide);
      return;
    }
    if (!assignment.isCompound &&
        leftHandSide is VariableUse &&
        rightHandSide is Binary) {
      Node rLeft = rightHandSide.left;
      Node rRight = rightHandSide.right;
      String op = rightHandSide.op;
      if (op == '+' ||
          op == '-' ||
          op == '/' ||
          op == '*' ||
          op == '%' ||
          op == '^' ||
          op == '&' ||
          op == '|') {
        if (rLeft is VariableUse && rLeft.name == leftHandSide.name) {
          // Output 'a = a + 1' as '++a' and 'a = a - 1' as '--a'.
          if ((op == '+' || op == '-') &&
              rRight is LiteralNumber &&
              rRight.value == "1") {
            _outputIncDec(op, assignment.leftHandSide, rightHandSide.left);
            return;
          }
          // Output 'a = a + b' as 'a += b'.
          visitNestedExpression(assignment.leftHandSide, CALL,
              newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
          assert(op.length == 1);
          out('$op='); // '$op='
          visitNestedExpression(rRight, ASSIGNMENT,
              newInForInit: inForInit, newAtStatementBegin: false);
          return;
        }
      }
    }
    visitNestedExpression(assignment.leftHandSide, CALL,
        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
    if (assignment.value != null) {
      if (op != null) out(op);
      out('='); // '='
      visitNestedExpression(assignment.value, ASSIGNMENT,
          newInForInit: inForInit, newAtStatementBegin: false);
    }
  }

  @override
  visitVariableInitialization(VariableInitialization initialization) {
    visitAssignment(initialization);
  }

  @override
  visitConditional(Conditional cond) {
    visitNestedExpression(cond.condition, LOGICAL_OR,
        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
    out('?'); // '?'
    // The then part is allowed to have an 'in'.
    visitNestedExpression(cond.then, ASSIGNMENT,
        newInForInit: false, newAtStatementBegin: false);
    out(':'); // ':'
    visitNestedExpression(cond.otherwise, ASSIGNMENT,
        newInForInit: inForInit, newAtStatementBegin: false);
  }

  @override
  visitNew(New node) {
    out('new'); // 'new'
    visitNestedExpression(node.target, LEFT_HAND_SIDE,
        newInForInit: inForInit, newAtStatementBegin: false);
    out('('); // '('
    visitCommaSeparated(node.arguments, ASSIGNMENT,
        newInForInit: false, newAtStatementBegin: false);
    out(')'); // ')'
  }

  @override
  visitCall(Call call) {
    visitNestedExpression(call.target, CALL,
        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
    out('('); // '('
    visitCommaSeparated(call.arguments, ASSIGNMENT,
        newInForInit: false, newAtStatementBegin: false);
    out(')'); // ')'
  }

  @override
  void visitBinary(Binary binary) {
    Expression left = binary.left;
    Expression right = binary.right;
    String op = binary.op;
    int leftPrecedenceRequirement;
    int rightPrecedenceRequirement;
    switch (op) {
      case ',':
        //  x, (y, z) <=> (x, y), z.
        leftPrecedenceRequirement = EXPRESSION;
        rightPrecedenceRequirement = EXPRESSION;
        break;
      case "||":
        leftPrecedenceRequirement = LOGICAL_OR;
        // x || (y || z) <=> (x || y) || z.
        rightPrecedenceRequirement = LOGICAL_OR;
        break;
      case "&&":
        leftPrecedenceRequirement = LOGICAL_AND;
        // x && (y && z) <=> (x && y) && z.
        rightPrecedenceRequirement = LOGICAL_AND;
        break;
      case "|":
        leftPrecedenceRequirement = BIT_OR;
        // x | (y | z) <=> (x | y) | z.
        rightPrecedenceRequirement = BIT_OR;
        break;
      case "^":
        leftPrecedenceRequirement = BIT_XOR;
        // x ^ (y ^ z) <=> (x ^ y) ^ z.
        rightPrecedenceRequirement = BIT_XOR;
        break;
      case "&":
        leftPrecedenceRequirement = BIT_AND;
        // x & (y & z) <=> (x & y) & z.
        rightPrecedenceRequirement = BIT_AND;
        break;
      case "==":
      case "!=":
      case "===":
      case "!==":
        leftPrecedenceRequirement = EQUALITY;
        rightPrecedenceRequirement = RELATIONAL;
        break;
      case "<":
      case ">":
      case "<=":
      case ">=":
      case "instanceof":
      case "in":
        leftPrecedenceRequirement = RELATIONAL;
        rightPrecedenceRequirement = SHIFT;
        break;
      case ">>":
      case "<<":
      case ">>>":
        leftPrecedenceRequirement = SHIFT;
        rightPrecedenceRequirement = ADDITIVE;
        break;
      case "+":
      case "-":
        leftPrecedenceRequirement = ADDITIVE;
        // We cannot remove parenthesis for "+" because
        //   x + (y + z) <!=> (x + y) + z:
        // Example:
        //   "a" + (1 + 2) => "a3";
        //   ("a" + 1) + 2 => "a12";
        rightPrecedenceRequirement = MULTIPLICATIVE;
        break;
      case "*":
      case "/":
      case "%":
        leftPrecedenceRequirement = MULTIPLICATIVE;
        // We cannot remove parenthesis for "*" because of precision issues.
        rightPrecedenceRequirement = UNARY;
        break;
      default:
        throw UnsupportedError("Forgot operator: $op");
    }

    visitNestedExpression(left, leftPrecedenceRequirement,
        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);

    if (op == "in" || op == "instanceof") {
      // There are cases where the space is not required but without further
      // analysis we cannot know.
      out(' $op '); // ' $op '
    } else {
      out(op); // '$op'
    }
    visitNestedExpression(right, rightPrecedenceRequirement,
        newInForInit: inForInit, newAtStatementBegin: false);
  }

  @override
  void visitPrefix(Prefix unary) {
    String op = unary.op;
    switch (op) {
      case "delete":
      case "void":
      case "typeof":
      case "+":
      case "++":
      case "-":
      case "--":
        // We may be able to eliminate the space in some cases, but for
        // estimation we assume the worst case.
        out('$op '); // '$op '
        break;
      default:
        out('$op'); // '$op'
    }
    visitNestedExpression(unary.argument, UNARY,
        newInForInit: inForInit, newAtStatementBegin: false);
  }

  @override
  void visitPostfix(Postfix postfix) {
    visitNestedExpression(postfix.argument, CALL,
        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
    out(postfix.op); // '${postfix.op}'
  }

  @override
  void visitVariableUse(VariableUse ref) {
    // For simplicity and stability we use a constant name size estimate.
    // In production this is:
    // '${localNamer.getName(ref.name)'
    out(sizeEstimate(ref));
  }

  @override
  void visitThis(This node) {
    out('this'); // 'this'
  }

  @override
  void visitVariableDeclaration(VariableDeclaration decl) {
    // '${localNamer.getName(decl.name)'
    out(sizeEstimate(decl));
  }

  @override
  void visitParameter(Parameter param) {
    // For simplicity and stability we use a constant name size estimate.
    // In production this is:
    // '${localNamer.getName(param.name)'
    out(sizeEstimate(param));
  }

  bool isDigit(int charCode) {
    return charCodes.$0 <= charCode && charCode <= charCodes.$9;
  }

  bool isValidJavaScriptId(String field) {
    if (field.length == 0) return false;
    // Ignore the leading and trailing string-delimiter.
    for (int i = 0; i < field.length; i++) {
      // TODO(floitsch): allow more characters.
      int charCode = field.codeUnitAt(i);
      if (!(charCodes.$a <= charCode && charCode <= charCodes.$z ||
          charCodes.$A <= charCode && charCode <= charCodes.$Z ||
          charCode == charCodes.$$ ||
          charCode == charCodes.$_ ||
          i > 0 && isDigit(charCode))) {
        return false;
      }
    }
    // TODO(floitsch): normally we should also check that the field is not a
    // reserved word.  We don't generate fields with reserved word names except
    // for 'super'.
    if (field == 'super') return false;
    if (field == 'catch') return false;
    return true;
  }

  @override
  void visitAccess(PropertyAccess access) {
    visitNestedExpression(access.receiver, CALL,
        newInForInit: inForInit, newAtStatementBegin: atStatementBegin);
    Node selector = access.selector;
    if (selector is LiteralString) {
      String field = literalStringToString(selector);
      if (isValidJavaScriptId(field)) {
        if (access.receiver is LiteralNumber) {
          // We can eliminate the space in some cases, but for simplicity we
          // always assume it is necessary.
          out(' '); // ' '
        }

        // '.${field}'
        out('.');
        out(field);
        return;
      }
    } else if (selector is Name) {
      Node receiver = access.receiver;
      if (receiver is LiteralNumber) {
        // We can eliminate the space in some cases, but for simplicity we
        // always assume it is necessary.
        out(' '); // ' '
      }
      out('.'); // '.'
      selector.accept(this);
      return;
    }
    out('['); // '['
    visitNestedExpression(access.selector, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out(']'); // ']
  }

  @override
  void visitNamedFunction(NamedFunction namedFunction) {
    VarCollector vars = VarCollector();
    vars.visitNamedFunction(namedFunction);
    functionOut(namedFunction.function, namedFunction.name, vars);
  }

  @override
  void visitFun(Fun fun) {
    VarCollector vars = VarCollector();
    vars.visitFun(fun);
    functionOut(fun, null, vars);
  }

  @override
  void visitArrowFunction(ArrowFunction fun) {
    VarCollector vars = VarCollector();
    vars.visitArrowFunction(fun);
    arrowFunctionOut(fun, vars);
  }

  int arrowFunctionOut(ArrowFunction fun, VarCollector vars) {
    // TODO: support static, get/set, async, and generators.
    if (fun.params.length == 1 && fun.params.first is VariableReference) {
      visitNestedExpression(fun.params.single, ASSIGNMENT,
          newInForInit: false, newAtStatementBegin: false);
    } else {
      out("(");
      if (fun.params != null) {
        visitCommaSeparated(fun.params, PRIMARY,
            newInForInit: false, newAtStatementBegin: false);
      }
      out(")");
    }
    out("=>");
    int closingPosition;
    Node body = fun.body;
    if (body is Block) {
      closingPosition = blockOut(body);
    } else {
      // Object initializers require parentheses to disambiguate
      // AssignmentExpression from FunctionBody. See:
      // https://tc39.github.io/ecma262/#sec-arrow-function-definitions
      bool needsParens = body is ObjectInitializer;
      if (needsParens) out("(");
      visitNestedExpression(body, ASSIGNMENT,
          newInForInit: false, newAtStatementBegin: false);
      if (needsParens) out(")");
      closingPosition = charCount - 1;
    }
    return closingPosition;
  }

  @override
  visitDeferredExpression(DeferredExpression node) {
    if (node.isFinalized) {
      // Continue printing with the expression value.
      assert(node.precedenceLevel == node.value.precedenceLevel);
      node.value.accept(this);
    } else {
      out(sizeEstimate(node));
    }
  }

  @override
  visitDeferredStatement(DeferredStatement node) {
    if (node.isFinalized) {
      // Continue printing with the statement value.
      node.statement.accept(this);
    } else {
      sizeEstimate(node);
    }
  }

  outputNumberWithRequiredWhitespace(String number) {
    int charCode = number.codeUnitAt(0);
    if (charCode == charCodes.$MINUS) {
      // We can eliminate the space in some cases, but for simplicity we
      // always assume it is necessary.
      out(' ');
    }
    out(number); // '${number}'
  }

  @override
  visitDeferredNumber(DeferredNumber node) {
    if (node.isFinalized) {
      outputNumberWithRequiredWhitespace("${node.value}");
    } else {
      out(sizeEstimate(node));
    }
  }

  @override
  visitDeferredString(DeferredString node) {
    if (node.isFinalized) {
      out(node.value);
    } else {
      out(sizeEstimate(node));
    }
  }

  @override
  visitLiteralBool(LiteralBool node) {
    out(node.value ? '!0' : '!1');
  }

  @override
  void visitLiteralString(LiteralString node) {
    out('"');
    out(literalStringToString(node));
    out('"');
  }

  @override
  visitStringConcatenation(StringConcatenation node) {
    node.visitChildren(this);
  }

  @override
  visitName(Name node) {
    // For simplicity and stability we use a constant name size estimate.
    out(sizeEstimate(node));
  }

  @override
  visitParentheses(Parentheses node) {
    out('('); // '('
    visitNestedExpression(node.enclosed, EXPRESSION,
        newInForInit: false, newAtStatementBegin: false);
    out(')'); // ')'
  }

  @override
  visitLiteralNumber(LiteralNumber node) {
    outputNumberWithRequiredWhitespace(node.value);
  }

  @override
  void visitLiteralNull(LiteralNull node) {
    out('null'); // 'null'
  }

  @override
  void visitArrayInitializer(ArrayInitializer node) {
    out('['); // '['
    List<Expression> elements = node.elements;
    for (int i = 0; i < elements.length; i++) {
      Expression element = elements[i];
      if (element is ArrayHole) {
        // Note that array holes must have a trailing "," even if they are
        // in last position. Otherwise `[,]` (having length 1) would become
        // equal to `[]` (the empty array)
        // and [1,,] (array with 1 and a hole) would become [1,] = [1].
        out(','); // ','
        continue;
      }
      visitNestedExpression(element, ASSIGNMENT,
          newInForInit: false, newAtStatementBegin: false);
      // We can skip the trailing "," for the last element (since it's not
      // an array hole).
      if (i != elements.length - 1) out(','); // ','
    }
    out(']'); // ']'
  }

  @override
  void visitArrayHole(ArrayHole node) {
    throw UnsupportedError("Unreachable");
  }

  @override
  void visitObjectInitializer(ObjectInitializer node) {
    // Print all the properties on one line until we see a function-valued
    // property.  Ideally, we would use a proper pretty-printer to make the
    // decision based on layout.
    bool exitOneLinerMode(Expression value) {
      return value is Fun ||
          value is ArrayInitializer && value.elements.any((e) => e is Fun);
    }

    bool isOneLiner = true;
    List<Property> properties = node.properties;
    out('{'); // '{'
    for (int i = 0; i < properties.length; i++) {
      Node value = properties[i].value;
      if (isOneLiner && exitOneLinerMode(value)) isOneLiner = false;
      if (i != 0) {
        out(','); // ','
      }
      if (!isOneLiner) {
        forceLine();
      }
      visit(properties[i]);
    }
    out('}'); // '}'
  }

  @override
  void visitProperty(Property node) {
    propertyNameOut(node);
    out(':'); // ':'
    visitNestedExpression(node.value, ASSIGNMENT,
        newInForInit: false, newAtStatementBegin: false);
  }

  @override
  void visitMethodDefinition(MethodDefinition node) {
    propertyNameOut(node);
    VarCollector vars = VarCollector();
    vars.visitMethodDefinition(node);
    methodOut(node, vars);
  }

  int methodOut(MethodDefinition node, VarCollector vars) {
    // TODO: support static, get/set, async, and generators.
    Fun fun = node.function;
    out("(");
    if (fun.params != null) {
      visitCommaSeparated(fun.params, PRIMARY,
          newInForInit: false, newAtStatementBegin: false);
    }
    out(")");
    int closingPosition = blockOut(fun.body);
    return closingPosition;
  }

  void propertyNameOut(Property node) {
    Node name = node.name;
    if (name is LiteralString) {
      String text = literalStringToString(name);
      if (isValidJavaScriptId(text)) {
        out(text);
      } else {
        // Approximation to `_handleString(text)`.
        out('"');
        out(text);
        out('"');
      }
    } else if (name is Name) {
      node.name.accept(this);
    } else if (name is DeferredExpression) {
      out(sizeEstimate(name));
    } else {
      assert(name is LiteralNumber);
      LiteralNumber nameNumber = node.name;
      out(nameNumber.value); // '${nameNumber.value}'
    }
  }

  @override
  void visitRegExpLiteral(RegExpLiteral node) {
    out(node.pattern); // '${node.pattern}'
  }

  @override
  void visitLiteralExpression(LiteralExpression node) {
    out(node.template); // '${node.template}'
  }

  @override
  void visitLiteralStatement(LiteralStatement node) {
    out(node.code); // '${node.code}'
  }

  void visitInterpolatedNode(InterpolatedNode node) {
    throw UnsupportedError('InterpolatedStatements are not supported');
  }

  @override
  void visitInterpolatedExpression(InterpolatedExpression node) =>
      visitInterpolatedNode(node);

  @override
  void visitInterpolatedLiteral(InterpolatedLiteral node) =>
      visitInterpolatedNode(node);

  @override
  void visitInterpolatedParameter(InterpolatedParameter node) =>
      visitInterpolatedNode(node);

  @override
  void visitInterpolatedSelector(InterpolatedSelector node) =>
      visitInterpolatedNode(node);

  @override
  void visitInterpolatedStatement(InterpolatedStatement node) {
    throw UnsupportedError('InterpolatedStatements are not supported');
  }

  @override
  void visitInterpolatedDeclaration(InterpolatedDeclaration node) {
    visitInterpolatedNode(node);
  }

  @override
  void visitComment(Comment node) {
    // We assume output is compressed and thus do not output comments.
  }

  @override
  void visitAwait(Await node) {
    out('await '); // 'await '
    visit(node.expression);
  }
}
