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

import 'package:js_shared/synced/async_status_codes.dart' as status_codes;

import '../js_ast/js_ast.dart' as js_ast;
import 'js_names.dart';

/// Rewrites a [js_ast.Fun] with async/sync*/async* functions and await and
/// yield (with dart-like semantics) to an equivalent function without these.
/// await-for is not handled and must be rewritten before (currently lowered to
/// a normal for loop in compiler.dart).
///
/// Look at [_rewriteFunction], [visitDartYield] and [visitAwait] for more
/// explanation.
abstract class AsyncRewriterBase extends js_ast.NodeVisitor<Object?> {
  // Local variables are hoisted to the top of the function, so they are
  // collected here.
  final List<js_ast.VariableBinding> _localVariables = [];

  final Map<js_ast.Node, int> _continueLabels = {};
  final Map<js_ast.Node, int> _breakLabels = {};

  /// The label of a finally part.
  final Map<js_ast.Block, int> _finallyLabels = {};

  /// The label of the catch handler of a [js_ast.Try] or a [js_ast.Fun] or
  /// [js_ast.Catch].
  ///
  /// These mark the points an error can be consumed.
  ///
  /// - The handler of a [js_ast.Fun] is the outermost and will rethrow the
  ///   error.
  /// - The handler of a [js_ast.Try] will run the catch handler.
  /// - The handler of a [js_ast.Catch] is a synthetic handler that ensures the
  ///   right finally blocks are run if an error is thrown inside a
  ///   catch-handler.
  final Map<js_ast.Node, int> _handlerLabels = {};

  /// The label index for the return clause. Only included in functions that
  /// have one or more explicit return statements or any async* function to
  /// handle the finally clause clean up.
  late final int _exitLabel = _newLabel('return');

  /// The label exit for the error case. If an async/sync*/async* function
  /// throws this label captures the error and rethrows it to the correct
  /// context.
  late final int _rethrowLabel = _newLabel('rethrow');

  /// A stack of all (surrounding) jump targets.
  ///
  /// Jump targets are:
  ///
  /// * The function, signalling a return or uncaught throw.
  /// * Loops.
  /// * LabeledStatements (also used for 'continue' when attached to loops).
  /// * Try statements, for catch and finally handlers.
  /// * Catch handlers, when inside a catch-part of a try, the catch-handler is
  ///   used to associate with a synthetic handler that will ensure the right
  ///   finally blocks are visited.
  ///
  /// When jumping to a target it is necessary to visit all finallies that
  /// are on the way to target (i.e. more nested than the jump target).
  final List<js_ast.Node> _jumpTargets = [];

  late final PreTranslationAnalysis _analysis;

  /// Contains the result of an awaited expression, or a conditional or
  /// lazy boolean operator.
  ///
  /// For example a conditional expression is roughly translated like:
  /// [[cond ? a : b]]
  ///
  /// Becomes:
  ///
  /// while true { // outer while loop
  ///   switch (goto) { // Simulates goto
  ///     ...
  ///       goto = [[cond]] ? thenLabel : elseLabel
  ///       break;
  ///     case thenLabel:
  ///       result = [[a]];
  ///       goto = joinLabel;
  ///       break;
  ///     case elseLabel:
  ///       result = [[b]];
  ///     case joinLabel:
  ///       // Now the result of computing the condition is in result.
  ///     ....
  ///   }
  /// }
  ///
  /// It is a parameter to the [body] function, so that [awaitStatement] can
  /// call [body] with the result of an awaited Future.
  late final js_ast.Identifier _result = ScopedId('t\$result');

  /// A parameter to the [bodyName] function. Indicating if we are in success
  /// or error case.
  late final js_ast.Identifier _errorCode = ScopedId('t\$errorCode');

  /// The inner function that is scheduled to do each await/yield,
  /// and called to do a new iteration for sync*.
  final js_ast.Identifier bodyName;

  /// Used to simulate a goto.
  ///
  /// To "goto" a label, the label is assigned to this variable, and break out
  /// of the switch to take another iteration in the while loop. See [_addGoto]
  late final js_ast.Identifier _goto = ScopedId('t\$goto');

  /// Variable containing the label of the current error handler.
  late final js_ast.Identifier _handler = ScopedId('t\$handler');

  /// Set to `true` if any of the switch statement labels is a handler. At the
  /// end of rewriting this is used to see if a shorter form of error handling
  /// can be used. The shorter form could be a change in the method boilerplate,
  /// in the state machine wrapper, or not implemented. [addErrorExit] can test
  /// this to elide the error exit handler when there are no other handlers, or
  /// set it to `true` if there is no shorter form.
  bool _hasHandlerLabels = false;

  /// A stack of labels of finally blocks to visit, and the label to go to after
  /// the last.
  late final js_ast.Identifier _next = ScopedId('t\$next');

  /// The current returned value (a finally block may overwrite it).
  late final js_ast.Identifier _returnValue = ScopedId('t\$returnValue');

  /// Stores a stack of the current set of errors when we are in the process of
  /// handling an error. Errors are pushed onto this stack when error handling
  /// begins and the current error is popped off when error handling ends. This
  /// prevents nested error handling from overwriting state.
  late final js_ast.Identifier _errorStack = ScopedId('t\$errorStack');

  /// The label of the outer loop.
  ///
  /// Used if there are untransformed loops containing break or continues to
  /// targets outside the loop.
  late final String _outerLabelName;

  int _currentLabel = 0;

  bool get _isAsync => false;
  bool get _isSyncStar => false;
  bool get _isAsyncStar => false;

  /// Visitor that collects scopes for the function passed to [rewrite]. Used
  /// to initialize and reset scope objects where necessary.
  late _ScopeCollector _scopeCollector;

  AsyncRewriterBase({required this.bodyName});

  /// Main entry point. Rewrites a sync*/async/async* function to an equivalent
  /// normal function.
  ///
  /// [bodyPrefix] will get prepended to the body of the rewritten function and
  /// any references to parameters within it will be replaced with the correct
  /// temporary ID for that parameter.
  js_ast.Fun rewrite(
    js_ast.Fun node,
    Object? bodySourceInformation,
    Object? exitSourceInformation, {
    List<js_ast.Statement>? bodyPrefix,
  }) {
    _analysis = PreTranslationAnalysis(_unsupported, node)..analyze();
    _scopeCollector = _ScopeCollector(_analysis)..collect(node);

    _outerLabelName = _freshLabelName('outer');

    final rewrittenFunction = _rewriteFunction(
      node,
      bodySourceInformation,
      exitSourceInformation,
      bodyPrefix: bodyPrefix,
    );
    if (bodyPrefix != null) {
      // Prepend the body prefix to the start of the rewritten function.
      rewrittenFunction.body.statements.insertAll(0, bodyPrefix);
    }
    return rewrittenFunction;
  }

  js_ast.Expression get _currentErrorHandler {
    return js_ast.number(
      _handlerLabels[_jumpTargets.lastWhere(
        (node) => _handlerLabels[node] != null,
      )]!,
    );
  }

  /// Generates a label name based on [originalName] with a suffix to
  /// guarantee it does not collide with already used names.
  String _freshLabelName(String originalName) {
    var result = originalName;
    var counter = 1;
    while (_analysis.usedLabelNames.contains(result)) {
      result = '$counter';
      ++counter;
    }
    _analysis.usedLabelNames.add(result);
    return result;
  }

  /// All the pieces are collected in this map, to create a switch with a case
  /// for each label.
  ///
  /// The order is important due to fall-through control flow, therefore the
  /// type is explicitly LinkedHashMap.
  Map<int, List<js_ast.Statement>> labelledParts = {};

  /// Description of each label for readability of the non-minified output.
  Map<int, String> labelComments = {};

  /// True if the function has any try blocks containing await.
  bool hasTryBlocks = false;

  /// True if the traversion currently is inside a loop or switch for which
  /// [_shouldTransform] is false.
  bool insideUntranslatedBreakable = false;

  /// True if a label is used to break to an outer switch-statement.
  bool hasJumpThoughOuterLabel = false;

  /// True if there is a catch-handler protected by a finally with no enclosing
  /// catch-handlers.
  bool needsRethrow = false;

  /// Buffer for collecting translated statements belonging to the same switch
  /// case.
  List<js_ast.Statement> currentStatementBuffer = [];

  /// Hoisted variables get declared in the outer scope of the function body
  /// being rewritten. Most variables get hoisted via a scope object. See
  /// [_ScopeCollector] for more info on scope objects. Temporary ids are
  /// already unique to a given scope so we can just hoist them directly.
  void _hoistIfNecessary(js_ast.Expression node) {
    if (node is ScopedId) {
      _localVariables.add(node);
    }
  }

  // Labels will become cases in the big switch expression, and `goto label`
  // is expressed by assigning to the switch key [gotoName] and breaking out of
  // the switch.

  int _newLabel(String comment) {
    var result = _currentLabel++;
    labelComments[result] = comment;
    return result;
  }

  /// Begins outputting statements to a new buffer with label [label].
  ///
  /// Each buffer ends up as its own case part in the big state-switch.
  void _beginLabel(int label) {
    assert(!labelledParts.containsKey(label));
    currentStatementBuffer = [];
    labelledParts[label] = currentStatementBuffer;
    _addStatement(js_ast.Comment(labelComments[label]!));
  }

  /// Returns a statement assigning to the variable named [gotoName].
  /// This should be followed by a break for the goto to be executed. Use
  /// [_gotoAndBreak] or [_addGoto] for this.
  js_ast.Statement _setGotoVariable(int label, Object? sourceInformation) {
    return js_ast.ExpressionStatement(
      js_ast
          .js('# = #', [_goto, js_ast.number(label)])
          .withSourceInformation(sourceInformation),
    );
  }

  /// Returns a block that has a goto to [label] including the break.
  ///
  /// Also inserts a comment describing the label if available.
  js_ast.Block _gotoAndBreak(int label, Object? sourceInformation) {
    var statements = <js_ast.Statement>[];
    if (labelComments.containsKey(label)) {
      statements.add(js_ast.Comment('goto ${labelComments[label]}'));
    }
    statements.add(_setGotoVariable(label, sourceInformation));
    if (insideUntranslatedBreakable) {
      hasJumpThoughOuterLabel = true;
      statements.add(
        js_ast.Break(_outerLabelName).withSourceInformation(sourceInformation),
      );
    } else {
      statements.add(
        js_ast.Break(null).withSourceInformation(sourceInformation),
      );
    }
    return js_ast.Block(statements);
  }

  /// Adds a goto to [label] including the break.
  ///
  /// Also inserts a comment describing the label if available.
  void _addGoto(int label, Object? sourceInformation) {
    if (labelComments.containsKey(label)) {
      _addStatement(js_ast.Comment('goto ${labelComments[label]}'));
    }
    _addStatement(_setGotoVariable(label, sourceInformation));

    _addBreak(sourceInformation);
  }

  void _addStatement(js_ast.Statement node) {
    currentStatementBuffer.add(node);
  }

  void _addExpressionStatement(
    js_ast.Expression node, [
    Object? sourceInformation,
  ]) {
    _addStatement(
      js_ast.ExpressionStatement(node)..sourceInformation = sourceInformation,
    );
  }

  /// True if there is an await or yield in [node] or some subexpression.
  bool _shouldTransform(js_ast.Node? node) {
    return _analysis.hasAwaitOrYield.contains(node);
  }

  Never _unsupported(js_ast.Node node) {
    throw UnsupportedError(
      'Node $node cannot be transformed by the await-sync transformer',
    );
  }

  Never _unreachable(js_ast.Node node) {
    throw StateError('Internal error, trying to visit $node');
  }

  void _visitStatement(js_ast.Statement node) {
    node.accept(this);
  }

  /// Visits [node] to ensure its side effects are performed, but throwing away
  /// the result.
  ///
  /// If the return value of visiting [node] is an expression guaranteed to have
  /// no side effect, it is dropped.
  void _visitExpressionIgnoreResult(js_ast.Expression node) {
    var result = node.accept(this) as js_ast.Expression;
    if (!(result is js_ast.Literal || result is js_ast.Identifier)) {
      _addExpressionStatement(result);
    }
  }

  js_ast.Expression visitExpression(js_ast.Expression node) {
    return node.accept(this) as js_ast.Expression;
  }

  /// Calls [fn] with the value of evaluating [node1] and [node2].
  ///
  /// Both nodes are evaluated in order.
  ///
  /// If node2 must be transformed (see [_shouldTransform]), then the evaluation
  /// of node1 is added to the current statement-list and the result is stored
  /// in a temporary variable. The evaluation of node2 is then free to emit
  /// statements without affecting the result of node1.
  ///
  /// This is necessary, because await or yield expressions have to emit
  /// statements, and these statements could affect the value of node1.
  ///
  /// For example:
  ///
  /// - _storeIfNecessary(someLiteral) returns someLiteral.
  /// - _storeIfNecessary(someVariable)
  ///   inserts: var tempX = someVariable
  ///   returns: tempX
  ///   where tempX is a fresh temporary variable.
  js_ast.Expression _storeIfNecessary(js_ast.Expression result) {
    // Note that RegExes, js_ast.ArrayInitializer and js_ast.ObjectInitializer
    // are not [js_ast.Literal]s.
    if (result is js_ast.Literal) return result;

    var tempVar = ScopedId('t\$temp');
    _localVariables.add(tempVar);
    _addStatement(js_ast.js.statement('# = #;', [tempVar, result]));
    return tempVar;
  }

  // TODO(sra): Many calls to this method use `store: false`, and could be
  // replaced with calls to `visitExpression`.
  T _withExpression<T>(
    js_ast.Expression node,
    T Function(js_ast.Expression result) fn, {
    required bool store,
  }) {
    var visited = visitExpression(node);
    if (store) {
      visited = _storeIfNecessary(visited);
    }
    var result = fn(visited);
    return result;
  }

  /// Calls [fn] with the result of evaluating [node]. Taking special care of
  /// property accesses.
  ///
  /// If [store] is true the result of evaluating [node] is stored in a
  /// temporary.
  ///
  /// We might need to compute and store the receiver of a call expression if
  /// the arguments include an 'await' expression. Due to expression evaluation
  /// order we must first evaluate the receiver, then the arguments, and finally
  /// invoke the call. With this async lowering the argument evaluation might
  /// cause us to break out of the current function. We therefore need to store
  /// the receiver in a temporary variable to use after we re-enter the function
  /// body.
  ///
  /// We cannot simply rewrite `<receiver>.m()` to:
  ///
  ///     temp = <receiver>.m;
  ///     temp();
  ///
  /// Because this leaves `this` unbound in the call. To solve this we `bind`
  /// the receiver to the tear-off to re-establish the `this` context.
  ///
  /// [isCall] determines if the node is a [js_ast.Call] or a [js_ast.New]. We
  /// cannot `bind` to a constructor tear-off as it would no longer be a
  /// constructor. However, constructors have no `this` context anyway so they
  /// are safe to tear-off without binding.
  js_ast.Expression withCallTargetExpression(
    js_ast.Expression node,
    js_ast.Expression Function(js_ast.Expression result) fn, {
    required bool store,
    required bool isCall,
  }) {
    var visited = visitExpression(node);
    js_ast.Expression storedIfNeeded;
    if (store) {
      if (visited is js_ast.PropertyAccess) {
        final storedReceiver = _storeIfNecessary(visited.receiver);
        // We handle the `super` literal specially since the bound object in
        // that case is `this`. `super` cannot be passed to `bind`.
        final bindTarget = storedReceiver is js_ast.Super
            ? js_ast.This()
            : storedReceiver;
        final jsTearOff = isCall
            ? js_ast.Call(
                js_ast.PropertyAccess.field(
                  js_ast.PropertyAccess(storedReceiver, visited.selector),
                  'bind',
                ),
                [bindTarget],
              )
            : visited;
        storedIfNeeded = _storeIfNecessary(jsTearOff);
      } else {
        storedIfNeeded = _storeIfNecessary(visited);
      }
    } else {
      storedIfNeeded = visited;
    }
    return fn(storedIfNeeded);
  }

  /// Calls [fn] with the value of evaluating [node1] and [node2].
  ///
  /// If `shouldTransform(node2)` the first expression is stored in a temporary
  /// variable.
  ///
  /// This is because node1 must be evaluated before visiting node2,
  /// because the evaluation of an await or yield cannot be expressed as
  /// an expression, visiting node2 it will output statements that
  /// might have an influence on the value of node1.
  js_ast.Expression withExpression2(
    js_ast.Expression node1,
    js_ast.Expression node2,
    js_ast.Expression Function(
      js_ast.Expression result1,
      js_ast.Expression result2,
    )
    fn,
  ) {
    var r1 = visitExpression(node1);
    if (_shouldTransform(node2)) {
      r1 = _storeIfNecessary(r1);
    }
    var r2 = visitExpression(node2);
    var result = fn(r1, r2);
    return result;
  }

  /// Calls [fn] with the value of evaluating all [nodes].
  ///
  /// All results before the last node where `shouldTransform(node)` are stored
  /// in temporary variables.
  ///
  /// See more explanation on [withExpression2].
  T withExpressions<T>(
    List<js_ast.Expression> nodes,
    T Function(List<js_ast.Expression> results) fn,
  ) {
    var visited = <js_ast.Expression>[];
    _collectVisited(nodes, visited);
    final result = fn(visited);
    return result;
  }

  /// Like [withExpressions], but permitting `null` nodes. If any of the nodes
  /// are null, they are ignored, and a null is passed to [fn] in that place.
  T withNullableExpressions<T>(
    List<js_ast.Expression?> nodes,
    T Function(List<js_ast.Expression?> results) fn,
  ) {
    var visited = <js_ast.Expression?>[];
    _collectVisited(nodes, visited);
    final result = fn(visited);
    return result;
  }

  void _collectVisited(
    List<js_ast.Expression?> nodes,
    List<js_ast.Expression?> visited,
  ) {
    // Find last occurrence of a 'transform' expression in [nodes].
    // All expressions before that must be stored in temp-vars.
    var lastTransformIndex = 0;
    for (var i = nodes.length - 1; i >= 0; --i) {
      if (nodes[i] == null) continue;
      if (_shouldTransform(nodes[i])) {
        lastTransformIndex = i;
        break;
      }
    }
    for (var i = 0; i < nodes.length; i++) {
      var node = nodes[i];
      if (node != null) {
        node = visitExpression(node);
        if (i < lastTransformIndex) {
          node = _storeIfNecessary(node);
        }
      }
      visited.add(node);
    }
  }

  /// Makes an empty scope object for captured variables.
  ///
  /// Uses `Object.create(null)` to ensure none of the JS Object prototype chain
  /// pollutes the namespace.
  js_ast.Expression _makeEmptyScopeObject() {
    return js_ast.js('Object.create(null)');
  }

  /// Creates a new scope object for [node] if it needs one.
  ///
  /// Only scopes that are captured need to be reset on re-entry. Otherwise the
  /// scope object becomes obsolete when the end of the scope is reached as
  /// there is no way to reference it anymore.
  ///
  /// This should be invoked whenever a scope is collected by [_ScopeCollector]
  /// and the scope would be re-entered by a loop in control flow.
  void _resetScopeIfNecessary(js_ast.Node node) {
    final nodeScope = _scopeCollector.scopeMapping[node];
    // Also exclude scopes with no declarations, these don't even have an
    // associated object.
    if (nodeScope != null &&
        nodeScope.isCaptured &&
        nodeScope.hasDeclarations) {
      _addExpressionStatement(
        js_ast.Assignment(nodeScope.scopeObject, _makeEmptyScopeObject()),
      );
    }
  }

  /// Emits the return block that all returns jump to (after going
  /// through all the enclosing finally blocks). The jump to here is made in
  /// [visitReturn].
  void addSuccessExit(Object? sourceInformation);

  /// Emits the block that control flows to if an error has been thrown
  /// but not caught. (after going through all the enclosing finally blocks).
  void addErrorExit(Object? sourceInformation);

  void addFunctionExits(Object? sourceInformation) {
    addSuccessExit(sourceInformation);
    addErrorExit(sourceInformation);
  }

  /// Returns the rewritten function.
  js_ast.Fun _finishFunction(
    List<js_ast.Parameter> parameters,
    js_ast.Statement rewrittenBody,
    js_ast.VariableDeclarationList variableDeclarationLists,
    Object? functionSourceInformation,
    Object? bodySourceInformation,
  );

  Iterable<js_ast.VariableInitialization> variableInitializations(
    Object? sourceInformation,
  );

  /// Rewrites an async/sync*/async* function to a normal JavaScript function.
  ///
  /// The control flow is flattened by simulating 'goto' using a switch in a
  /// loop and a state variable [_goto] inside a nested function [body]
  /// that can be called back by [asyncStarHelper]/[asyncStarHelper]/the
  /// [Iterator].
  ///
  /// Local variables are hoisted outside the helper.
  ///
  /// Awaits in async/async* are translated to code that remembers the current
  /// location (so the function can resume from where it was) followed by a
  /// [awaitStatement]. The helper sets up the waiting for the awaited
  /// value and returns a future which is immediately returned by the
  /// [awaitStatement].
  ///
  /// Yields in sync*/async* are translated to a calls to helper functions.
  /// (see [visitYield])
  ///
  /// Simplified examples (not the exact translation, but intended to show the
  /// ideas):
  ///
  /// function (x, y, z) async {
  ///   var p = await foo();
  ///   return bar(p);
  /// }
  ///
  /// Becomes (without error handling):
  ///
  /// function(x, y, z) {
  ///   var goto = 0, returnValue, completer = new Completer(), p;
  ///   function body(result) {
  ///     while (true) {
  ///       switch (goto) {
  ///         case 0:
  ///           goto = 1 // Remember where to continue when the future succeeds.
  ///           return thenHelper(foo(), helper, completer);
  ///         case 1:
  ///           p = result;
  ///           returnValue = bar(p);
  ///           goto = 2;
  ///           break;
  ///         case 2:
  ///           return thenHelper(returnValue, null, completer)
  ///       }
  ///     }
  ///     return thenHelper(null, helper, completer);
  ///   }
  /// }
  ///
  /// Try/catch is implemented by maintaining [_handler] to contain the label
  /// of the current handler. If [body] throws, the caller should catch the
  /// error and recall [body] with first argument [status_codes.ERROR] and
  /// second argument the error.
  ///
  /// A `finally` clause is compiled similar to normal code, with the additional
  /// complexity that `finally` clauses need to know where to jump to after the
  /// clause is done. In the translation, each flow-path that enters a `finally`
  /// sets up the variable [_next] with a stack of finally-blocks and a final
  /// jump-target (exit, catch, ...).
  ///
  /// function(x, y, z) async {
  ///   try {
  ///     try {
  ///       throw "error";
  ///     } finally {
  ///       finalize1();
  ///     }
  ///   } catch (e) {
  ///     handle(e);
  ///   } finally {
  ///     finalize2();
  ///   }
  /// }
  ///
  /// Translates into (besides the fact that structures not containing
  /// await/yield/yield* are left intact):
  ///
  /// function(x, y, z) {
  ///   var goto = 0;
  ///   var returnValue;
  ///   var completer = new Completer();
  ///   var handler = 8; // Outside try-blocks go to the rethrow label.
  ///   var p;
  ///   var currentError;
  ///   // The result can be either the result of an awaited future, or an
  ///   // error if the future completed with an error.
  ///   function body(errorCode, result) {
  ///     if (errorCode == 1) {
  ///       currentError = result;
  ///       goto = handler;
  ///     }
  ///     while (true) {
  ///       switch (goto) {
  ///         case 0:
  ///           handler = 4; // The outer catch-handler
  ///           handler = 1; // The inner (implicit) catch-handler
  ///           throw "error";
  ///           next = [3];
  ///           // After the finally (2) continue normally after the try.
  ///           goto = 2;
  ///           break;
  ///         case 1: // (implicit) catch handler for inner try.
  ///           next = [3]; // destination after the finally.
  ///           // fall-though to the finally handler.
  ///         case 2: // finally for inner try
  ///           handler = 4; // catch-handler for outer try.
  ///           finalize1();
  ///           goto = next.pop();
  ///           break;
  ///         case 3: // exiting inner try.
  ///           next = [6];
  ///           goto = 5; // finally handler for outer try.
  ///           break;
  ///         case 4: // catch handler for outer try.
  ///           handler = 5; // If the handler throws, do the finally ..
  ///           next = [8] // ... and rethrow.
  ///           e = storedError;
  ///           handle(e);
  ///           // Fall through to finally.
  ///         case 5: // finally handler for outer try.
  ///           handler = null;
  ///           finalize2();
  ///           goto = next.pop();
  ///           break;
  ///         case 6: // Exiting outer try.
  ///         case 7: // return
  ///           return thenHelper(returnValue, 0, completer);
  ///         case 8: // Rethrow
  ///           return thenHelper(currentError, 1, completer);
  ///       }
  ///     }
  ///     return thenHelper(null, helper, completer);
  ///   }
  /// }
  ///
  /// [bodySourceInformation] is used on code generated to execute the function
  /// body and [exitSourceInformation] is used on code generated to exit the
  /// function.
  js_ast.Fun _rewriteFunction(
    js_ast.Fun node,
    Object? bodySourceInformation,
    Object? exitSourceInformation, {
    List<js_ast.Statement>? bodyPrefix,
  }) {
    _beginLabel(_newLabel('Function start'));
    _handlerLabels[node] = _rethrowLabel;
    var body = node.body;
    _jumpTargets.add(node);
    _visitStatement(body);
    _jumpTargets.removeLast();
    addFunctionExits(exitSourceInformation);

    var clauses = <js_ast.SwitchClause>[
      for (final entry in labelledParts.entries)
        js_ast.Case(js_ast.number(entry.key), js_ast.Block(entry.value)),
    ];
    var rewrittenBody = js_ast.Switch(
      _goto,
      clauses,
    ).withSourceInformation(bodySourceInformation);
    if (hasJumpThoughOuterLabel) {
      rewrittenBody = js_ast.LabeledStatement(_outerLabelName, rewrittenBody);
    }
    rewrittenBody = js_ast.js
        .statement('while (true) #', rewrittenBody)
        .withSourceInformation(bodySourceInformation);
    var variables = <js_ast.VariableInitialization>[];

    variables.add(
      _makeVariableInitializer(
        _goto,
        js_ast.number(0).withSourceInformation(bodySourceInformation),
        bodySourceInformation,
      ),
    );
    variables.addAll(variableInitializations(bodySourceInformation));
    if (_hasHandlerLabels) {
      variables.add(
        _makeVariableInitializer(
          _handler,
          js_ast.number(_rethrowLabel),
          bodySourceInformation,
        ),
      );
      variables.add(
        _makeVariableInitializer(
          _errorStack,
          js_ast.ArrayInitializer(const []),
          bodySourceInformation,
        ),
      );
    }
    if (_analysis.hasFinally || (_isAsyncStar && _analysis.hasYield)) {
      variables.add(
        _makeVariableInitializer(
          _next,
          js_ast.ArrayInitializer([]),
          bodySourceInformation,
        ),
      );
    }
    variables.addAll(
      _localVariables.map((js_ast.VariableBinding declaration) {
        return js_ast.VariableInitialization(declaration, null);
      }),
    );
    variables.addAll(
      [
        for (final scope in _scopeCollector.scopeMapping.values)
          if (scope.hasDeclarations)
            js_ast.VariableInitialization(
              scope.scopeObject,
              _makeEmptyScopeObject(),
            ),
      ].reversed,
    );
    var variableDeclarationLists = js_ast.VariableDeclarationList(
      'let',
      variables,
    );

    // Names are already safe when added.
    return _finishFunction(
      node.params,
      rewrittenBody,
      variableDeclarationLists,
      exitSourceInformation,
      bodySourceInformation,
    );
  }

  js_ast.Expression _visitFunctionExpression(js_ast.FunctionExpression node) {
    if (node.asyncModifier.isAsync || node.asyncModifier.isYielding) {
      // The translation does not handle nested functions that are generators
      // or asynchronous.  These functions should only be ones that are
      // introduced by JS foreign code from our own libraries.
      throw StateError('Nested function is a generator or asynchronous.');
    }

    final captureInfo = _scopeCollector.scopeCaptures[node]!;
    // If this closure does not capture any variables from an outside scope
    // then we can leave it as-is.
    if (!captureInfo.hasCapture) return node;

    // Rename any references to captured variables so they are instead looked
    // up via the captured scope object.
    node = _ClosureRenamer(_scopeCollector, captureInfo).visit(node);
    final scopeVariableList = <js_ast.Expression>[];
    final capturedScopeVariableList = <js_ast.Parameter>[];

    captureInfo.usedScopes.forEach((scope, capturedScopeVariable) {
      scopeVariableList.add(scope.scopeObject);
      capturedScopeVariableList.add(capturedScopeVariable);
    });

    // Wrap the closure in an IIFE that captures the necessary scope objects.
    // This ensures the closure grabs the scope before it gets reset (e.g. by
    // a loop iteration).
    //
    // Code that originally looked like:
    //   var foo = 3;
    //   function(x) {
    //     console.log(foo);
    //   }
    //
    // Would be transformed to:
    //    var asyncScope = {};
    //    asyncScope.foo = 3;
    //    ((capturedAsyncScope) =>
    //      function (x) {
    //        console.log(capturedAsyncScope.foo);
    //      })(asyncScope);
    return js_ast.Call(
      js_ast.ArrowFun(capturedScopeVariableList, node),
      scopeVariableList,
    );
  }

  @override
  js_ast.Expression visitFun(js_ast.Fun node) {
    return _visitFunctionExpression(node);
  }

  @override
  js_ast.Expression visitArrowFun(js_ast.ArrowFun node) {
    return _visitFunctionExpression(node);
  }

  @override
  js_ast.Expression visitAccess(js_ast.PropertyAccess node) {
    return withExpression2(
      node.receiver,
      node.selector,
      (receiver, selector) => js_ast.PropertyAccess(
        receiver,
        selector,
      ).withSourceInformation(node.sourceInformation),
    );
  }

  @override
  js_ast.Expression visitArrayHole(js_ast.ArrayHole node) {
    return node;
  }

  @override
  js_ast.Expression visitArrayInitializer(js_ast.ArrayInitializer node) {
    return withExpressions(node.elements, (elements) {
      return js_ast.ArrayInitializer(elements);
    });
  }

  @override
  js_ast.Expression visitAssignment(js_ast.Assignment node) {
    if (!_shouldTransform(node)) {
      return js_ast.Assignment.compound(
        visitExpression(node.leftHandSide),
        node.op,
        visitExpression(node.value),
      );
    }
    var leftHandSide = node.leftHandSide;
    if (leftHandSide is js_ast.Identifier) {
      return _withExpression(node.value, (js_ast.Expression value) {
        // A non-compound [js_ast.Assignment] has `op==null`. So it works out to
        // use [js_ast.Assignment.compound] for all cases.
        // Visit the [js_ast.Identifier] to ensure renaming is done correctly.
        return js_ast.Assignment.compound(
          visitExpression(leftHandSide),
          node.op,
          value,
        );
      }, store: false);
    } else if (leftHandSide is js_ast.PropertyAccess) {
      return withExpressions(
        [leftHandSide.receiver, leftHandSide.selector, node.value],
        (evaluated) {
          return js_ast.Assignment.compound(
            js_ast.PropertyAccess(evaluated[0], evaluated[1]),
            node.op,
            evaluated[2],
          );
        },
      );
    } else {
      throw 'Unexpected assignment left hand side $leftHandSide';
    }
  }

  js_ast.Statement awaitStatement(
    js_ast.Expression value,
    Object? sourceInformation,
  );

  /// An await is translated to an [awaitStatement].
  ///
  /// See the comments of [_rewriteFunction] for an example.
  @override
  js_ast.Expression visitAwait(js_ast.Await node) {
    assert(_isAsync || _isAsyncStar);
    var afterAwait = _newLabel('returning from await.');
    _withExpression(node.expression, (js_ast.Expression value) {
      _addStatement(_setGotoVariable(afterAwait, node.sourceInformation));
      _addStatement(awaitStatement(value, node.sourceInformation));
    }, store: false);
    _beginLabel(afterAwait);
    return _result;
  }

  /// Checks if [node] is the variable for [_result].
  ///
  /// [_result] is used to hold the result of a transformed computation
  /// for example the result of awaiting, or the result of a conditional or
  /// short-circuiting expression.
  /// If the subexpression of some transformed node already is transformed and
  /// visiting it returns [_result], it is not redundantly assigned to itself
  /// again.
  bool isResult(js_ast.Expression node) {
    return node == _result;
  }

  @override
  js_ast.Expression visitBinary(js_ast.Binary node) {
    if (_shouldTransform(node.right) && (node.op == '||' || node.op == '&&')) {
      var thenLabel = _newLabel('then');
      var joinLabel = _newLabel('join');
      _withExpression(node.left, (js_ast.Expression left) {
        var assignLeft = isResult(left)
            ? js_ast.Block.empty()
            : js_ast.js.statement('# = #;', [_result, left]);
        if (node.op == '&&') {
          _addStatement(
            js_ast.js.statement('if (#) #; else #', [
              left,
              _gotoAndBreak(thenLabel, node.sourceInformation),
              assignLeft,
            ]),
          );
        } else {
          assert(node.op == '||');
          _addStatement(
            js_ast.js.statement('if (#) #; else #', [
              left,
              assignLeft,
              _gotoAndBreak(thenLabel, node.sourceInformation),
            ]),
          );
        }
      }, store: true);
      _addGoto(joinLabel, node.sourceInformation);
      _beginLabel(thenLabel);
      _withExpression(node.right, (js_ast.Expression value) {
        if (!isResult(value)) {
          _addStatement(js_ast.js.statement('# = #;', [_result, value]));
        }
      }, store: false);
      _beginLabel(joinLabel);
      return _result;
    }

    return withExpression2(
      node.left,
      node.right,
      (left, right) => js_ast.Binary(node.op, left, right),
    );
  }

  @override
  void visitBlock(js_ast.Block node) {
    _resetScopeIfNecessary(node);
    for (var statement in node.statements) {
      _visitStatement(statement);
    }
  }

  @override
  void visitBreak(js_ast.Break node) {
    var target = _analysis.targets[node]!;
    if (!_shouldTransform(target)) {
      _addStatement(node);
      return;
    }
    _translateJump(target, _breakLabels[target], node.sourceInformation);
  }

  @override
  js_ast.Expression visitCall(js_ast.Call node) {
    var storeTarget = node.arguments.any(_shouldTransform);
    return withCallTargetExpression(
      node.target,
      (target) {
        return withExpressions(node.arguments, (
          List<js_ast.Expression> arguments,
        ) {
          return js_ast.Call(
            target,
            arguments,
          ).withSourceInformation(node.sourceInformation);
        });
      },
      store: storeTarget,
      isCall: true,
    );
  }

  @override
  void visitCase(js_ast.Case node) {
    _unreachable(node);
  }

  @override
  void visitCatch(js_ast.Catch node) {
    _unreachable(node);
  }

  @override
  void visitComment(js_ast.Comment node) {
    _addStatement(node);
  }

  @override
  js_ast.Expression visitConditional(js_ast.Conditional node) {
    if (!_shouldTransform(node.then) && !_shouldTransform(node.otherwise)) {
      return js_ast
          .js('# ? # : #', [
            visitExpression(node.condition),
            visitExpression(node.then),
            visitExpression(node.otherwise),
          ])
          .withSourceInformation(node.sourceInformation);
    }
    var thenLabel = _newLabel('then');
    var joinLabel = _newLabel('join');
    var elseLabel = _newLabel('else');
    _withExpression(node.condition, (js_ast.Expression condition) {
      _addStatement(
        js_ast.js.statement('# = # ? # : #;', [
          _goto,
          condition,
          js_ast.number(thenLabel),
          js_ast.number(elseLabel),
        ]),
      );
    }, store: false);
    _addBreak(node.sourceInformation);
    _beginLabel(thenLabel);
    _withExpression(node.then, (js_ast.Expression value) {
      if (!isResult(value)) {
        _addStatement(js_ast.js.statement('# = #;', [_result, value]));
      }
    }, store: false);
    _addGoto(joinLabel, node.sourceInformation);
    _beginLabel(elseLabel);
    _withExpression(node.otherwise, (js_ast.Expression value) {
      if (!isResult(value)) {
        _addStatement(js_ast.js.statement('# = #;', [_result, value]));
      }
    }, store: false);
    _beginLabel(joinLabel);
    return _result;
  }

  @override
  void visitContinue(js_ast.Continue node) {
    var target = _analysis.targets[node];
    if (!_shouldTransform(target)) {
      _addStatement(node);
      return;
    }
    _translateJump(target, _continueLabels[target!], node.sourceInformation);
  }

  /// Emits a break statement that exits the big switch statement.
  void _addBreak(Object? sourceInformation) {
    if (insideUntranslatedBreakable) {
      hasJumpThoughOuterLabel = true;
      _addStatement(
        js_ast.Break(_outerLabelName).withSourceInformation(sourceInformation),
      );
    } else {
      _addStatement(
        js_ast.Break(null).withSourceInformation(sourceInformation),
      );
    }
  }

  /// Common code for handling break, continue, return.
  ///
  /// It is necessary to run all nesting finally-handlers between the jump and
  /// the target. For that [_next] is used as a stack of places to go.
  ///
  /// See also [_rewriteFunction].
  void _translateJump(
    js_ast.Node? target,
    int? targetLabel,
    Object? sourceInformation,
  ) {
    // Compute a stack of all the 'finally' nodes that must be visited before
    // the jump.
    // The bottom of the stack is the label where the jump goes to.
    var jumpStack = <int>[];
    for (var node in _jumpTargets.reversed) {
      if (_finallyLabels[node] != null) {
        jumpStack.add(_finallyLabels[node]!);
      } else if (node == target) {
        jumpStack.add(targetLabel!);
        break;
      }
      // Ignore other nodes.
    }
    jumpStack = jumpStack.reversed.toList();
    // As the program jumps directly to the top of the stack, it is taken off
    // now.
    var firstTarget = jumpStack.removeLast();
    if (jumpStack.isNotEmpty) {
      var jsJumpStack = js_ast.ArrayInitializer(
        jumpStack.map((int label) => js_ast.number(label)).toList(),
      );
      _addStatement(
        js_ast.ExpressionStatement(
          js_ast
              .js('# = #', [_next, jsJumpStack])
              .withSourceInformation(sourceInformation),
        ),
      );
    }
    _addGoto(firstTarget, sourceInformation);
  }

  @override
  void visitDefault(js_ast.Default node) => _unreachable(node);

  @override
  void visitDo(js_ast.Do node) {
    if (!_shouldTransform(node)) {
      var oldInsideUntranslatedBreakable = insideUntranslatedBreakable;
      insideUntranslatedBreakable = true;
      _addStatement(
        js_ast.js.statement('do {#} while (#)', [
          _translateToStatement(node.body),
          visitExpression(node.condition),
        ]),
      );
      insideUntranslatedBreakable = oldInsideUntranslatedBreakable;
      return;
    }
    var startLabel = _newLabel('do body');

    var continueLabel = _newLabel('do condition');
    _continueLabels[node] = continueLabel;

    var afterLabel = _newLabel('after do');
    _breakLabels[node] = afterLabel;

    _beginLabel(startLabel);

    _jumpTargets.add(node);
    _visitStatement(node.body);
    _jumpTargets.removeLast();

    _beginLabel(continueLabel);
    _withExpression(node.condition, (js_ast.Expression condition) {
      _addStatement(
        js_ast.js.statement('if (#) #', [
          condition,
          _gotoAndBreak(startLabel, node.sourceInformation),
        ]),
      );
    }, store: false);
    _beginLabel(afterLabel);
  }

  @override
  void visitEmptyStatement(js_ast.EmptyStatement node) {
    _addStatement(node);
  }

  @override
  void visitExpressionStatement(js_ast.ExpressionStatement node) {
    _visitExpressionIgnoreResult(node.expression);
  }

  @override
  void visitFor(js_ast.For node) {
    if (!_shouldTransform(node)) {
      var oldInsideUntranslated = insideUntranslatedBreakable;
      insideUntranslatedBreakable = true;

      // Handle init specially as it might be a VariableDeclarationList.
      // These declarations should not be hoisted in an untransformed for loop.
      final init = node.init;
      js_ast.Expression? newInit;
      if (init is js_ast.VariableDeclarationList) {
        final newInitializationList = <js_ast.VariableInitialization>[];
        for (final initialization in init.declarations) {
          final value = initialization.value;
          newInitializationList.add(
            js_ast.VariableInitialization(
              initialization.declaration,
              value != null ? visitExpression(value) : null,
            ),
          );
        }
        newInit = js_ast.VariableDeclarationList(
          init.keyword,
          newInitializationList,
        );
      } else {
        newInit = init != null ? visitExpression(init) : null;
      }
      withNullableExpressions([node.condition, node.update], (
        List<js_ast.Expression?> transformed,
      ) {
        _addStatement(
          js_ast.For(
            newInit,
            transformed[0],
            transformed[1],
            _translateToStatement(node.body),
          ),
        );
      });
      insideUntranslatedBreakable = oldInsideUntranslated;
      return;
    }

    _resetScopeIfNecessary(node);
    if (node.init != null) {
      _visitExpressionIgnoreResult(node.init!);
    }
    var startLabel = _newLabel('for condition');
    // If there is no update, continuing the loop is the same as going to the
    // start.
    var continueLabel = (node.update == null)
        ? startLabel
        : _newLabel('for update');
    _continueLabels[node] = continueLabel;
    var afterLabel = _newLabel('after for');
    _breakLabels[node] = afterLabel;
    _beginLabel(startLabel);
    var condition = node.condition;
    if (condition == null ||
        (condition is js_ast.LiteralBool && condition.value == true)) {
      _addStatement(js_ast.Comment('trivial condition'));
    } else {
      _withExpression(condition, (js_ast.Expression condition) {
        _addStatement(
          js_ast.If.noElse(
            js_ast.Prefix('!', condition),
            _gotoAndBreak(afterLabel, node.sourceInformation),
          ),
        );
      }, store: false);
    }
    _jumpTargets.add(node);
    _visitStatement(node.body);
    _jumpTargets.removeLast();
    if (node.update != null) {
      _beginLabel(continueLabel);
      _visitExpressionIgnoreResult(node.update!);
    }
    _addGoto(startLabel, node.sourceInformation);
    _beginLabel(afterLabel);
  }

  @override
  void visitForIn(js_ast.ForIn node) {
    // The dart output currently never uses for-in loops.
    throw 'JavaScript for-in not implemented yet in the await transformation';
  }

  @override
  void visitFunctionDeclaration(js_ast.FunctionDeclaration node) {
    _withExpression(node.function, (js_ast.Expression function) {
      final name = visitExpression(node.name);
      _hoistIfNecessary(name);
      _addExpressionStatement(
        js_ast.Assignment(visitExpression(name), function),
      );
    }, store: false);
  }

  List<js_ast.Statement> _translateToStatementSequence(js_ast.Statement node) {
    assert(!_shouldTransform(node));
    var oldBuffer = currentStatementBuffer;
    currentStatementBuffer = [];
    var resultBuffer = currentStatementBuffer;
    _visitStatement(node);
    currentStatementBuffer = oldBuffer;
    return resultBuffer;
  }

  js_ast.Statement _translateToStatement(js_ast.Statement node) {
    var statements = _translateToStatementSequence(node);
    if (statements.length == 1) return statements.single;
    return js_ast.Block(statements);
  }

  js_ast.Block translateToBlock(js_ast.Statement node) {
    return js_ast.Block(_translateToStatementSequence(node));
  }

  @override
  void visitIf(js_ast.If node) {
    if (!_shouldTransform(node.then) && !_shouldTransform(node.otherwise)) {
      _withExpression(node.condition, (js_ast.Expression condition) {
        var translatedThen = _translateToStatement(node.then);
        var translatedElse = _translateToStatement(node.otherwise);
        _addStatement(js_ast.If(condition, translatedThen, translatedElse));
      }, store: false);
      return;
    }
    var thenLabel = _newLabel('then');
    var joinLabel = _newLabel('join');
    var elseLabel = (node.otherwise is js_ast.EmptyStatement)
        ? joinLabel
        : _newLabel('else');

    _withExpression(node.condition, (js_ast.Expression condition) {
      _addExpressionStatement(
        js_ast.Assignment(
          _goto,
          js_ast.Conditional(
            condition,
            js_ast.number(thenLabel),
            js_ast.number(elseLabel),
          ),
        ),
      );
    }, store: false);
    _addBreak(node.sourceInformation);
    _beginLabel(thenLabel);
    _visitStatement(node.then);
    if (node.otherwise is! js_ast.EmptyStatement) {
      _addGoto(joinLabel, node.sourceInformation);
      _beginLabel(elseLabel);
      _visitStatement(node.otherwise);
    }
    _beginLabel(joinLabel);
  }

  @override
  Never visitInterpolatedExpression(js_ast.InterpolatedExpression node) {
    _unsupported(node);
  }

  @override
  Never visitInterpolatedLiteral(js_ast.InterpolatedLiteral node) {
    _unsupported(node);
  }

  @override
  Never visitInterpolatedParameter(js_ast.InterpolatedParameter node) {
    _unsupported(node);
  }

  @override
  Never visitInterpolatedSelector(js_ast.InterpolatedSelector node) {
    _unsupported(node);
  }

  @override
  Never visitInterpolatedStatement(js_ast.InterpolatedStatement node) {
    _unsupported(node);
  }

  @override
  void visitLabeledStatement(js_ast.LabeledStatement node) {
    if (!_shouldTransform(node)) {
      _addStatement(
        js_ast.LabeledStatement(node.label, _translateToStatement(node.body)),
      );
      return;
    }
    // `continue label` is really continuing the nested loop.
    // This is set up in [PreTranslationAnalysis.visitContinue].
    // Here we only need a breakLabel:
    var breakLabel = _newLabel('break ${node.label}');
    _breakLabels[node] = breakLabel;

    _jumpTargets.add(node);
    _visitStatement(node.body);
    _jumpTargets.removeLast();
    _beginLabel(breakLabel);
  }

  @override
  js_ast.Expression visitLiteralBool(js_ast.LiteralBool node) => node;

  @override
  Never visitLiteralExpression(js_ast.LiteralExpression node) =>
      _unsupported(node);

  @override
  js_ast.Expression visitLiteralNull(js_ast.LiteralNull node) => node;

  @override
  js_ast.Expression visitLiteralNumber(js_ast.LiteralNumber node) => node;

  @override
  Never visitLiteralStatement(js_ast.LiteralStatement node) =>
      _unsupported(node);

  @override
  js_ast.Expression visitLiteralString(js_ast.LiteralString node) => node;

  @override
  Never visitNamedFunction(js_ast.NamedFunction node) {
    _unsupported(node);
  }

  @override
  js_ast.Expression visitNew(js_ast.New node) {
    var storeTarget = node.arguments.any(_shouldTransform);
    return withCallTargetExpression(
      node.target,
      (target) {
        return withExpressions(node.arguments, (
          List<js_ast.Expression> arguments,
        ) {
          return js_ast.New(target, arguments);
        });
      },
      store: storeTarget,
      isCall: false,
    );
  }

  @override
  js_ast.Expression visitObjectInitializer(js_ast.ObjectInitializer node) {
    return withExpressions(
      node.properties
          .map((js_ast.Property property) => property.value)
          .toList(),
      (List<js_ast.Expression> values) {
        var properties = List<js_ast.Property>.generate(values.length, (int i) {
          if (node.properties[i] is js_ast.Method) {
            return js_ast.Method(
              node.properties[i].name,
              values[i] as js_ast.Fun,
            );
          }
          return js_ast.Property(node.properties[i].name, values[i]);
        });
        return js_ast.ObjectInitializer(properties);
      },
    );
  }

  @override
  js_ast.Expression visitPostfix(js_ast.Postfix node) {
    if (node.op == '++' || node.op == '--') {
      var argument = node.argument;
      if (argument is js_ast.Identifier) {
        return js_ast.Postfix(node.op, visitExpression(argument));
      } else if (argument is js_ast.PropertyAccess) {
        return withExpression2(argument.receiver, argument.selector, (
          receiver,
          selector,
        ) {
          return js_ast.Postfix(
            node.op,
            js_ast.PropertyAccess(receiver, selector),
          );
        });
      } else {
        throw 'Unexpected postfix ${node.op} '
            'operator argument ${node.argument}';
      }
    }
    return _withExpression(
      node.argument,
      (js_ast.Expression argument) => js_ast.Postfix(node.op, argument),
      store: false,
    );
  }

  @override
  js_ast.Expression visitPrefix(js_ast.Prefix node) {
    if (node.op == '++' || node.op == '--') {
      var argument = node.argument;
      if (argument is js_ast.Identifier) {
        return js_ast.Prefix(node.op, visitExpression(argument));
      } else if (argument is js_ast.PropertyAccess) {
        return withExpression2(argument.receiver, argument.selector, (
          receiver,
          selector,
        ) {
          return js_ast.Prefix(
            node.op,
            js_ast.PropertyAccess(receiver, selector),
          );
        });
      } else {
        throw 'Unexpected prefix ${node.op} operator '
            'argument ${node.argument}';
      }
    }
    return _withExpression(
      node.argument,
      (js_ast.Expression argument) => js_ast.Prefix(node.op, argument),
      store: false,
    );
  }

  @override
  Never visitProgram(js_ast.Program node) => _unsupported(node);

  @override
  js_ast.Property visitProperty(js_ast.Property node) {
    assert(node.runtimeType == js_ast.Property);
    return _withExpression(
      node.value,
      (js_ast.Expression value) => js_ast.Property(node.name, value),
      store: false,
    );
  }

  @override
  js_ast.Method visitMethod(js_ast.Method node) {
    return _withExpression(
      node.function,
      (js_ast.Expression value) =>
          js_ast.Method(node.name, value as js_ast.Fun),
      store: false,
    );
  }

  @override
  js_ast.Expression visitRegExpLiteral(js_ast.RegExpLiteral node) => node;

  @override
  void visitReturn(js_ast.Return node) {
    var target = _analysis.targets[node];
    final expression = node.value;
    if (expression != null) {
      if (_isSyncStar || _isAsyncStar) {
        // Even though `return expr;` is not allowed in the dart sync* and
        // async*  code, the backend sometimes generates code like this, but
        // only when it is known that the 'expr' throws, and the return is just
        // to tell the JavaScript VM that the code won't continue here.
        // It is therefore interpreted as `expr; return;`
        _visitExpressionIgnoreResult(expression);
      } else {
        _withExpression(expression, (js_ast.Expression value) {
          _addStatement(
            js_ast.js
                .statement('# = #;', [_returnValue, value])
                .withSourceInformation(node.sourceInformation),
          );
        }, store: false);
      }
    }
    _translateJump(target, _exitLabel, node.sourceInformation);
  }

  @override
  void visitSwitch(js_ast.Switch node) {
    if (!_shouldTransform(node)) {
      // TODO(sra): If only the key has an await, translation can be simplified.
      var oldInsideUntranslated = insideUntranslatedBreakable;
      insideUntranslatedBreakable = true;
      _withExpression(node.key, (js_ast.Expression key) {
        var cases = node.cases.map((js_ast.SwitchClause clause) {
          if (clause is js_ast.Case) {
            return js_ast.Case(
              clause.expression,
              translateToBlock(clause.body),
            );
          } else {
            return js_ast.Default(
              translateToBlock((clause as js_ast.Default).body),
            );
          }
        }).toList();
        _addStatement(js_ast.Switch(key, cases));
      }, store: false);
      insideUntranslatedBreakable = oldInsideUntranslated;
      return;
    }
    var before = _newLabel('switch');
    var after = _newLabel('after switch');
    _breakLabels[node] = after;

    _beginLabel(before);
    var labels = List<int>.filled(node.cases.length, -1);

    var anyCaseExpressionTransformed = node.cases.any(
      (js_ast.SwitchClause x) =>
          x is js_ast.Case && _shouldTransform(x.expression),
    );
    if (anyCaseExpressionTransformed) {
      int? defaultIndex; // Null means no default was found.
      // If there is an await in one of the keys, a chain of ifs has to be used.

      _withExpression(node.key, (js_ast.Expression key) {
        var i = 0;
        for (var clause in node.cases) {
          if (clause is js_ast.Default) {
            // The goto for the default case is added after all non-default
            // clauses have been handled.
            defaultIndex = i;
            labels[i] = _newLabel('default');
            continue;
          } else if (clause is js_ast.Case) {
            labels[i] = _newLabel('case');
            _withExpression(clause.expression, (expression) {
              _addStatement(
                js_ast.If.noElse(
                  js_ast.Binary('===', key, expression),
                  _gotoAndBreak(labels[i], clause.sourceInformation),
                ),
              );
            }, store: false);
          }
          i++;
        }
      }, store: true);

      if (defaultIndex == null) {
        _addGoto(after, node.sourceInformation);
      } else {
        _addGoto(labels[defaultIndex!], node.sourceInformation);
      }
    } else {
      var hasDefault = false;
      var i = 0;
      var clauses = <js_ast.SwitchClause>[];
      for (var clause in node.cases) {
        if (clause is js_ast.Case) {
          labels[i] = _newLabel('case');
          clauses.add(
            js_ast.Case(
              visitExpression(clause.expression),
              _gotoAndBreak(labels[i], clause.sourceInformation),
            ),
          );
        } else if (clause is js_ast.Default) {
          labels[i] = _newLabel('default');
          clauses.add(
            js_ast.Default(_gotoAndBreak(labels[i], clause.sourceInformation)),
          );
          hasDefault = true;
        } else {
          throw StateError('Unknown clause type $clause');
        }
        i++;
      }
      if (!hasDefault) {
        clauses.add(
          js_ast.Default(_gotoAndBreak(after, node.sourceInformation)),
        );
      }
      _withExpression(node.key, (js_ast.Expression key) {
        _addStatement(js_ast.Switch(key, clauses));
      }, store: false);

      _addBreak(node.sourceInformation);
    }

    _jumpTargets.add(node);
    for (var i = 0; i < labels.length; i++) {
      _beginLabel(labels[i]);
      _visitStatement(node.cases[i].body);
    }
    _beginLabel(after);
    _jumpTargets.removeLast();
  }

  @override
  js_ast.Expression visitThis(js_ast.This node) => node;

  @override
  void visitThrow(js_ast.Throw node) {
    _withExpression(node.expression, (js_ast.Expression expression) {
      _addStatement(
        js_ast.Throw(expression).withSourceInformation(node.sourceInformation),
      );
    }, store: false);
  }

  void _setErrorHandler([int? errorHandler]) {
    _hasHandlerLabels = true; // TODO(sra): Add short form error handler.
    var label = (errorHandler == null)
        ? _currentErrorHandler
        : js_ast.number(errorHandler);
    _addStatement(js_ast.js.statement('# = #;', [_handler, label]));
  }

  List<int> _finalliesUpToAndEnclosingHandler() {
    var result = <int>[];
    for (var i = _jumpTargets.length - 1; i >= 0; i--) {
      var node = _jumpTargets[i];
      var handlerLabel = _handlerLabels[node];
      if (handlerLabel != null) {
        result.add(handlerLabel);
        break;
      }
      var finallyLabel = _finallyLabels[node];
      if (finallyLabel != null) {
        result.add(finallyLabel);
      }
    }
    return result.reversed.toList();
  }

  /// See the comments of [_rewriteFunction] for more explanation.
  @override
  void visitTry(js_ast.Try node) {
    final catchPart = node.catchPart;
    final finallyPart = node.finallyPart;

    if (!_shouldTransform(node)) {
      var body = translateToBlock(node.body);
      js_ast.Catch? translatedCatchPart;
      if (catchPart != null) {
        translatedCatchPart = js_ast.Catch(
          catchPart.declaration,
          translateToBlock(catchPart.body),
        );
      }
      var translatedFinallyPart = (finallyPart == null)
          ? null
          : translateToBlock(finallyPart);
      _addStatement(
        js_ast.Try(body, translatedCatchPart, translatedFinallyPart),
      );
      return;
    }

    hasTryBlocks = true;
    var uncaughtLabel = _newLabel('uncaught');
    var handlerLabel = (catchPart == null) ? uncaughtLabel : _newLabel('catch');

    var finallyLabel = _newLabel('finally');
    var afterFinallyLabel = _newLabel('after finally');
    if (finallyPart != null) {
      _finallyLabels[finallyPart] = finallyLabel;
      _jumpTargets.add(finallyPart);
    }

    _handlerLabels[node] = handlerLabel;
    _jumpTargets.add(node);

    // Set the error handler here. It must be cleared on every path out;
    // normal and error exit.
    _setErrorHandler();

    _visitStatement(node.body);

    var last = _jumpTargets.removeLast();
    assert(last == node);

    if (finallyPart == null) {
      _setErrorHandler();
      _addGoto(afterFinallyLabel, node.sourceInformation);
    } else {
      // The handler is reset as the first thing in the finally block.
      _addStatement(
        js_ast.js.statement('#.push(#);', [
          _next,
          js_ast.number(afterFinallyLabel),
        ]),
      );
      _addGoto(finallyLabel, node.sourceInformation);
    }

    if (catchPart != null) {
      _beginLabel(handlerLabel);
      // [uncaughtLabel] is the handler for the code in the catch-part.
      // It ensures that [nextName] is set up to run the right finally blocks.
      _handlerLabels[catchPart] = uncaughtLabel;
      _jumpTargets.add(catchPart);
      _setErrorHandler();
      // The catch declaration name can shadow outer variables, so a fresh name
      // is needed to avoid collisions.  See Ecma 262, 3rd edition,
      // section 12.14.
      var errorName = visitExpression(catchPart.declaration);
      _hoistIfNecessary(errorName);
      _addStatement(
        js_ast.js.statement('# = #.pop();', [errorName, _errorStack]),
      );
      _visitStatement(catchPart.body);
      if (finallyPart != null) {
        // The error has been caught, so after the finally, continue after the
        // try.
        _addStatement(
          js_ast.js.statement('#.push(#);', [
            _next,
            js_ast.number(afterFinallyLabel),
          ]),
        );
        _addGoto(finallyLabel, node.sourceInformation);
      } else {
        _addGoto(afterFinallyLabel, node.sourceInformation);
      }
      var last = _jumpTargets.removeLast();
      assert(last == catchPart);
    }

    // The "uncaught"-handler tells the finally-block to continue with
    // the enclosing finally-blocks until the current catch-handler.
    _beginLabel(uncaughtLabel);

    var enclosingFinallies = _finalliesUpToAndEnclosingHandler();

    var nextLabel = enclosingFinallies.removeLast();
    if (enclosingFinallies.isNotEmpty) {
      // [enclosingFinallies] can be empty if there is no surrounding finally
      // blocks. Then [nextLabel] will be [rethrowLabel].
      _addStatement(
        js_ast.js.statement('# = #;', [
          _next,
          js_ast.ArrayInitializer(
            enclosingFinallies.map(js_ast.number).toList(),
          ),
        ]),
      );
    }
    if (finallyPart == null) {
      // The finally-block belonging to [node] will be visited because of
      // fallthrough. If it does not exist, add an explicit goto.
      _addGoto(nextLabel, node.sourceInformation);
    }
    if (finallyPart != null) {
      var last = _jumpTargets.removeLast();
      assert(last == finallyPart);

      _beginLabel(finallyLabel);
      _setErrorHandler();
      _visitStatement(finallyPart);
      _addStatement(js_ast.Comment('// goto the next finally handler'));
      _addStatement(js_ast.js.statement('# = #.pop();', [_goto, _next]));
      _addBreak(node.sourceInformation);
    }
    _beginLabel(afterFinallyLabel);
  }

  @override
  js_ast.Expression visitVariableDeclarationList(
    js_ast.VariableDeclarationList node,
  ) {
    for (final initialization in node.declarations) {
      var declaration = visitExpression(initialization.declaration);
      _hoistIfNecessary(declaration);
      if (initialization.value != null) {
        _withExpression(initialization.value!, (js_ast.Expression value) {
          _addExpressionStatement(
            js_ast.Assignment(declaration, value)
              ..sourceInformation = initialization.sourceInformation,
            node.sourceInformation,
          );
        }, store: false);
      }
    }
    return js_ast.number(0); // Dummy expression.
  }

  @override
  void visitVariableInitialization(js_ast.VariableInitialization node) {
    _unreachable(node);
  }

  @override
  js_ast.Expression visitIdentifier(js_ast.Identifier node) {
    return _scopeCollector.transformIdentifier(node);
  }

  @override
  void visitWhile(js_ast.While node) {
    if (!_shouldTransform(node)) {
      var oldInsideUntranslated = insideUntranslatedBreakable;
      insideUntranslatedBreakable = true;
      _withExpression(node.condition, (js_ast.Expression condition) {
        _addStatement(
          js_ast.While(
            condition,
            _translateToStatement(node.body),
          ).withSourceInformation(node.sourceInformation),
        );
      }, store: false);
      insideUntranslatedBreakable = oldInsideUntranslated;
      return;
    }
    var continueLabel = _newLabel('while condition');
    _continueLabels[node] = continueLabel;
    _beginLabel(continueLabel);

    var afterLabel = _newLabel('after while');
    _breakLabels[node] = afterLabel;
    var condition = node.condition;
    // If the condition is `true`, a test is not needed.
    if (!(condition is js_ast.LiteralBool && condition.value == true)) {
      _withExpression(node.condition, (js_ast.Expression condition) {
        _addStatement(
          js_ast.If.noElse(
            js_ast.Prefix('!', condition),
            _gotoAndBreak(afterLabel, node.sourceInformation),
          ).withSourceInformation(node.sourceInformation),
        );
      }, store: false);
    }
    _jumpTargets.add(node);
    _visitStatement(node.body);
    _jumpTargets.removeLast();
    _addGoto(continueLabel, node.sourceInformation);
    _beginLabel(afterLabel);
  }

  void addYield(
    js_ast.DartYield node,
    js_ast.Expression expression,
    Object? sourceInformation,
  );

  @override
  void visitDartYield(js_ast.DartYield node) {
    assert(_isSyncStar || _isAsyncStar);
    var label = _newLabel('after yield');
    // Don't do a break here for the goto, but instead a return in either
    // addSynYield or addAsyncYield.
    _withExpression(node.expression, (js_ast.Expression expression) {
      _addStatement(_setGotoVariable(label, node.sourceInformation));
      addYield(node, expression, node.sourceInformation);
    }, store: false);
    _beginLabel(label);
  }

  @override
  void visitForOf(js_ast.ForOf node) {
    if (!_shouldTransform(node)) {
      var oldInsideUntranslated = insideUntranslatedBreakable;
      insideUntranslatedBreakable = true;
      _addStatement(
        js_ast.ForOf(
          node.leftHandSide,
          visitExpression(node.iterable),
          _translateToStatement(node.body),
        ),
      );
      insideUntranslatedBreakable = oldInsideUntranslated;
      return;
    }

    _visitExpressionIgnoreResult(node.leftHandSide);
    final loopVar = visitExpression(
      (node.leftHandSide as js_ast.VariableDeclarationList)
          .declarations
          .first
          .declaration,
    );

    final valueWrapperVar = ScopedId('t\$wrappedValue');
    final iteratorVar = ScopedId('t\$iterator');
    _localVariables.add(valueWrapperVar);
    _localVariables.add(iteratorVar);

    // Get the iterator object for the iterable expression.
    _withExpression(node.iterable, (js_ast.Expression iterable) {
      _addExpressionStatement(
        js_ast.Assignment(
          iteratorVar,
          js_ast.js('#[Symbol.iterator]()', [iterable])
            ..sourceInformation = node.iterable.sourceInformation,
        ),
      );
    }, store: false);

    var continueLabel = _newLabel('for-of iterator update');
    _continueLabels[node] = continueLabel;

    var afterLabel = _newLabel('after for-of');
    _breakLabels[node] = afterLabel;

    // At the start of each loop step:
    // 1) Move the iterator forward.
    // 2) Check if the current value is marked as done.
    // 3a) If no: assign the value to the loop variable and execute the body.
    // 3b) If yes: jump to after the loop body.
    _beginLabel(continueLabel);
    _resetScopeIfNecessary(node);
    _addExpressionStatement(
      js_ast.Assignment(valueWrapperVar, js_ast.js('#.next()', [iteratorVar])),
    );
    _addStatement(
      js_ast.If.noElse(
        js_ast.js('#.done', [valueWrapperVar]),
        _gotoAndBreak(afterLabel, node.sourceInformation),
      ),
    );
    _addExpressionStatement(
      js_ast.Assignment(loopVar, js_ast.js('#.value', [valueWrapperVar])),
    );
    _jumpTargets.add(node);
    _visitStatement(node.body);
    _jumpTargets.removeLast();

    _addGoto(continueLabel, node.sourceInformation);
    _beginLabel(afterLabel);
  }

  @override
  js_ast.ArrayBindingPattern visitArrayBindingPattern(
    js_ast.ArrayBindingPattern node,
  ) => node;

  @override
  Never visitClassDeclaration(js_ast.ClassDeclaration node) =>
      _unreachable(node);

  @override
  Never visitClassExpression(js_ast.ClassExpression node) => _unreachable(node);

  @override
  js_ast.CommentExpression visitCommentExpression(
    js_ast.CommentExpression node,
  ) => node;

  @override
  js_ast.DebuggerStatement visitDebuggerStatement(
    js_ast.DebuggerStatement node,
  ) => node;

  @override
  js_ast.DestructuredVariable visitDestructuredVariable(
    js_ast.DestructuredVariable node,
  ) => node;

  @override
  Never visitExportClause(js_ast.ExportClause node) => _unreachable(node);

  @override
  Never visitExportDeclaration(js_ast.ExportDeclaration node) =>
      _unreachable(node);

  @override
  Never visitImportDeclaration(js_ast.ImportDeclaration node) =>
      _unreachable(node);

  @override
  js_ast.InterpolatedIdentifier visitInterpolatedIdentifier(
    js_ast.InterpolatedIdentifier node,
  ) => node;

  @override
  js_ast.InterpolatedMethod visitInterpolatedMethod(
    js_ast.InterpolatedMethod node,
  ) => node;

  @override
  Never visitNameSpecifier(js_ast.NameSpecifier node) => _unreachable(node);

  @override
  js_ast.ObjectBindingPattern visitObjectBindingPattern(
    js_ast.ObjectBindingPattern node,
  ) => node;

  @override
  js_ast.RestParameter visitRestParameter(js_ast.RestParameter node) => node;

  @override
  js_ast.SimpleBindingPattern visitSimpleBindingPattern(
    js_ast.SimpleBindingPattern node,
  ) => node;

  @override
  js_ast.Spread visitSpread(js_ast.Spread node) => node;

  @override
  js_ast.Super visitSuper(js_ast.Super node) => node;

  @override
  js_ast.TaggedTemplate visitTaggedTemplate(js_ast.TaggedTemplate node) => node;

  @override
  js_ast.TemplateString visitTemplateString(js_ast.TemplateString node) => node;

  @override
  Never visitYield(js_ast.Yield node) => _unreachable(node);
}

js_ast.VariableInitialization _makeVariableInitializer(
  js_ast.Identifier variable,
  js_ast.Expression? initValue,
  Object? sourceInformation,
) {
  return js_ast.VariableInitialization(
        variable,
        initValue,
      ).withSourceInformation(sourceInformation)
      as js_ast.VariableInitialization;
}

class AsyncRewriter extends AsyncRewriterBase {
  @override
  bool get _isAsync => true;

  /// The Completer that will finish an async function.
  ///
  /// Not used for sync* or async* functions.
  late final js_ast.Identifier completer = ScopedId('t\$completer');

  /// The function called by an async function to initiate asynchronous
  /// execution of the body.  This is called with:
  ///
  /// - The body function [bodyName].
  /// - the completer object [completer].
  ///
  /// It returns the completer's future. Passing the completer and returning its
  /// future is a convenience to allow both the initiation and fetching the
  /// future to be compactly encoded in a return statement's expression.
  final js_ast.Expression asyncStart;

  /// Function called by the async function to simulate an `await`
  /// expression. It is called with:
  ///
  /// - The value to await
  /// - The body function [bodyName]
  final js_ast.Expression asyncAwait;

  /// Function called by the async function to simulate a return.
  /// It is called with:
  ///
  /// - The value to return
  /// - The completer object [completer]
  final js_ast.Expression asyncReturn;

  /// Function called by the async function to simulate a rethrow.
  /// It is called with:
  ///
  /// - The value containing the exception and stack
  /// - The completer object [completer]
  final js_ast.Expression asyncRethrow;

  /// Constructor used to initialize the [completer] variable.
  ///
  /// Specific to async methods.
  final js_ast.Expression completerFactory;
  final List<js_ast.Expression> completerFactoryTypeArguments;

  final js_ast.Expression wrapBody;

  AsyncRewriter({
    required this.asyncStart,
    required this.asyncAwait,
    required this.asyncReturn,
    required this.asyncRethrow,
    required this.completerFactory,
    required this.completerFactoryTypeArguments,
    required this.wrapBody,
    required super.bodyName,
  });

  @override
  void addYield(
    js_ast.DartYield node,
    js_ast.Expression expression,
    Object? sourceInformation,
  ) {
    throw StateError('Yield in non-generating async function');
  }

  @override
  void addErrorExit(Object? sourceInformation) {
    if (!_hasHandlerLabels) return; // rethrow handled in method boilerplate.
    _beginLabel(_rethrowLabel);
    var thenHelperCall = js_ast
        .js('#thenHelper(#errorStack.at(-1), #completer)', {
          'thenHelper': asyncRethrow,
          'errorStack': _errorStack,
          'completer': completer,
        })
        .withSourceInformation(sourceInformation);
    _addStatement(
      js_ast.Return(thenHelperCall).withSourceInformation(sourceInformation),
    );
  }

  /// Returning from an async method calls [asyncStarHelper] with the result.
  /// (the result might have been stored in [_returnValue] by some finally
  /// block).
  @override
  void addSuccessExit(Object? sourceInformation) {
    if (_analysis.hasExplicitReturns) {
      _beginLabel(_exitLabel);
    } else {
      _addStatement(js_ast.Comment('implicit return'));
    }

    var runtimeHelperCall = js_ast
        .js('#runtimeHelper(#returnValue, #completer)', {
          'runtimeHelper': asyncReturn,
          'returnValue': _analysis.hasExplicitReturns
              ? _returnValue
              : js_ast.LiteralNull(),
          'completer': completer,
        })
        .withSourceInformation(sourceInformation);
    _addStatement(
      js_ast.Return(runtimeHelperCall).withSourceInformation(sourceInformation),
    );
  }

  @override
  Iterable<js_ast.VariableInitialization> variableInitializations(
    Object? sourceInformation,
  ) {
    var variables = <js_ast.VariableInitialization>[];
    variables.add(
      _makeVariableInitializer(
        completer,
        js_ast
            .js('#(#)', [completerFactory, completerFactoryTypeArguments])
            .withSourceInformation(sourceInformation),
        sourceInformation,
      ),
    );
    if (_analysis.hasExplicitReturns) {
      variables.add(
        _makeVariableInitializer(_returnValue, null, sourceInformation),
      );
    }
    return variables;
  }

  @override
  js_ast.Statement awaitStatement(
    js_ast.Expression value,
    Object? sourceInformation,
  ) {
    var asyncHelperCall = js_ast
        .js('#asyncHelper(#value, #bodyName, #completer)', {
          'asyncHelper': asyncAwait,
          'value': value,
          'bodyName': bodyName,
          'completer': completer,
        })
        .withSourceInformation(sourceInformation);
    return js_ast.Return(
      asyncHelperCall,
    ).withSourceInformation(sourceInformation);
  }

  @override
  js_ast.Fun _finishFunction(
    List<js_ast.Parameter> parameters,
    js_ast.Statement rewrittenBody,
    js_ast.VariableDeclarationList variableDeclarationLists,
    Object? functionSourceInformation,
    Object? bodySourceInformation,
  ) {
    js_ast.Statement errorCheck;
    if (_hasHandlerLabels) {
      errorCheck = js_ast.js.statement(
        '''
            if (#errorCode === #ERROR) {
              #errorStack.push(#result);
              #goto = #handler;
            }''',
        {
          'errorCode': _errorCode,
          'ERROR': js_ast.number(status_codes.ERROR),
          'errorStack': _errorStack,
          'result': _result,
          'goto': _goto,
          'handler': _handler,
        },
      );
    } else {
      var asyncRethrowCall = js_ast.js('#asyncRethrow(#result, #completer)', {
        'result': _result,
        'asyncRethrow': asyncRethrow,
        'completer': completer,
      });
      var returnAsyncRethrow = js_ast.Return(asyncRethrowCall);
      errorCheck = js_ast.js.statement(
        '''
            if (#errorCode === #ERROR)
              #returnAsyncRethrow;
            ''',
        {
          'errorCode': _errorCode,
          'ERROR': js_ast.number(status_codes.ERROR),
          'returnAsyncRethrow': returnAsyncRethrow,
        },
      );
    }

    // Use an arrow function so that we can access 'this' from the outer scope.
    var innerFunction = js_ast
        .js(
          '''
      (#errorCode, #result) => {
        #errorCheck;
        #rewrittenBody;
      }''',
          {
            'errorCode': _errorCode,
            'result': _result,
            'errorCheck': errorCheck,
            'rewrittenBody': rewrittenBody,
          },
        )
        .withSourceInformation(bodySourceInformation);
    var asyncStartCall = js_ast
        .js('#asyncStart(#bodyName, #completer)', {
          'asyncStart': asyncStart,
          'bodyName': bodyName,
          'completer': completer,
        })
        .withSourceInformation(bodySourceInformation);
    var returnAsyncStart = js_ast.Return(asyncStartCall);
    var wrapBodyCall = js_ast
        .js('#wrapBody(#innerFunction)', {
          'wrapBody': wrapBody,
          'innerFunction': innerFunction,
        })
        .withSourceInformation(bodySourceInformation);
    return (js_ast
            .js(
              '''
        function (#parameters) {
          #variableDeclarationLists;
          var #bodyName = #wrapBodyCall;
          #returnAsyncStart;
        }''',
              {
                'parameters': parameters,
                'variableDeclarationLists': variableDeclarationLists,
                'bodyName': bodyName,
                'wrapBodyCall': wrapBodyCall,
                'returnAsyncStart': returnAsyncStart,
              },
            )
            .withSourceInformation(functionSourceInformation))
        as js_ast.Fun;
  }
}

class SyncStarRewriter extends AsyncRewriterBase {
  @override
  bool get _isSyncStar => true;

  /// A parameter to the [bodyName] function that passes the controlling
  /// `_SyncStarIterator`. This parameter is used to update the state of the
  /// iterator.
  late final js_ast.Identifier iterator = ScopedId('t\$iterator');

  /// Static method to create a sync star iterable.
  final js_ast.Expression makeSyncStarIterable;

  /// The type argument expression to instantiate the sync star iterable.
  final js_ast.Expression syncStarIterableTypeArgument;

  /// Property of the iterator that contains the current value.
  final js_ast.Expression iteratorCurrentValueProperty;

  /// Property of the iterator that contains the uncaught exception.
  final js_ast.Expression iteratorDatumProperty;

  /// Property of the iterator that is bound to the `_yieldStar` method.
  final js_ast.Expression yieldStarSelector;

  SyncStarRewriter({
    required this.makeSyncStarIterable,
    required this.syncStarIterableTypeArgument,
    required this.iteratorCurrentValueProperty,
    required this.iteratorDatumProperty,
    required this.yieldStarSelector,
    required super.bodyName,
  });

  /// Translates a yield/yield* in an sync*.
  @override
  void addYield(
    js_ast.DartYield node,
    js_ast.Expression expression,
    Object? sourceInformation,
  ) {
    if (node.hasStar) {
      // ``yield* expression` is translated to:
      //
      //     return $iterator._yieldStar(expression);
      //
      // The `_yieldStar` method updates the state of the Iterator to 'enter'
      // the expression and returns the SYNC_STAR_YIELD_STAR status code.
      _addStatement(
        js_ast.Return(
          js_ast.Call(js_ast.PropertyAccess(iterator, yieldStarSelector), [
            expression,
          ]).withSourceInformation(sourceInformation),
        ).withSourceInformation(sourceInformation),
      );
    } else {
      // `yield expression` is translated to:
      //
      //     return $iterator._current = expression, SYNC_STAR_YIELD;
      //
      // This sets the `_current` field of the Iterator and returns the
      // SYNC_STAR_YIELD status code.
      final store = js_ast.Assignment(
        js_ast.PropertyAccess(iterator, iteratorCurrentValueProperty),
        expression,
      );
      _addStatement(
        js_ast.Return(
          js_ast.Binary(
            ',',
            store,
            js_ast.number(status_codes.SYNC_STAR_YIELD),
          ),
        ).withSourceInformation(sourceInformation),
      );
    }
  }

  @override
  js_ast.Fun _finishFunction(
    List<js_ast.Parameter> parameters,
    js_ast.Statement rewrittenBody,
    js_ast.VariableDeclarationList variableDeclarationLists,
    Object? functionSourceInformation,
    Object? bodySourceInformation,
  ) {
    // Each iterator invocation on the iterable should work on its own copy of
    // the parameters. Since parameter initialization code at the start of the
    // function may reference the original parameter names, we create an alias
    // for each parameter. Then in the async body we shadow each parameter with
    // a copy of that alias so each iteration of the body works on it's own
    // version of the parameter in case of modification.
    var outerDeclarationsList = <js_ast.VariableInitialization>[];
    var innerDeclarationsList = <js_ast.VariableInitialization>[];
    for (var parameter in parameters) {
      final name = parameter.parameterName;
      final renamedIdentifier = ScopedId(name);
      final parameterRef = switch (parameter) {
        ScopedId() => ScopedId.from(parameter),
        js_ast.DestructuredVariable() when parameter.name is ScopedId =>
          ScopedId.from(parameter.name as ScopedId),
        _ => js_ast.Identifier(name),
      };

      innerDeclarationsList.add(
        js_ast.VariableInitialization(parameterRef, renamedIdentifier),
      );
      outerDeclarationsList.add(
        js_ast.VariableInitialization(renamedIdentifier, parameterRef),
      );
    }
    var outerDeclarations = js_ast.VariableDeclarationList(
      'let',
      outerDeclarationsList,
    );
    var innerDeclarations = js_ast.VariableDeclarationList(
      'let',
      innerDeclarationsList,
    );

    var pushError = js_ast.js('#errorStack.push(#result)', {
      'result': _result,
      'errorStack': _errorStack,
    });
    var setGoto = js_ast.js('#goto = #handler', {
      'goto': _goto,
      'handler': _handler,
    });
    var checkErrorCode = js_ast.js.statement(
      '''
          if (#errorCode === #ERROR) {
              #pushError;
              #setGoto;
          }''',
      {
        'errorCode': _errorCode,
        'ERROR': js_ast.number(status_codes.ERROR),
        'pushError': pushError,
        'setGoto': setGoto,
      },
    );
    // Use an arrow function so that we can access 'this' from the outer scope.
    var innerInnerFunction = js_ast.js(
      '''
          (#iterator, #errorCode, #result) => {
            #checkErrorCode;
            #helperBody;
          }''',
      {
        'helperBody': rewrittenBody,
        'errorCode': _errorCode,
        'iterator': iterator,
        'result': _result,
        'checkErrorCode': checkErrorCode,
      },
    );
    var returnInnerInnerFunction = js_ast.Return(innerInnerFunction);
    // Use an arrow function so that we can access 'this' from the outer scope.
    var innerInnerFunctionInvocation = js_ast.js(
      '''
          #makeSyncStarIterable(#iterableType, () => {
            if (#hasParameters) {
              #innerDeclarations;
            }
            #varDecl;
            #returnInnerInnerFunction;
          })''',
      {
        'hasParameters': parameters.isNotEmpty,
        'innerDeclarations': innerDeclarations,
        'varDecl': variableDeclarationLists,
        'returnInnerInnerFunction': returnInnerInnerFunction,
        'makeSyncStarIterable': makeSyncStarIterable,
        'iterableType': syncStarIterableTypeArgument,
      },
    );
    var returnInnerFunction = js_ast.Return(innerInnerFunctionInvocation);
    // Add the copied parameter declarations outside the inner function in case
    // one is a type parameter that gets passed to the inner function.
    return (js_ast
            .js(
              '''
          function (#parameters) {
            if (#hasParameters) {
              #outerDeclarations;
            }
            #returnInnerFunction;
          }
          ''',
              {
                'hasParameters': parameters.isNotEmpty,
                'outerDeclarations': outerDeclarations,
                'parameters': parameters,
                'returnInnerFunction': returnInnerFunction,
              },
            )
            .withSourceInformation(functionSourceInformation))
        as js_ast.Fun;
  }

  @override
  void addErrorExit(Object? sourceInformation) {
    _hasHandlerLabels = true; // TODO(sra): Add short form error handler.
    _beginLabel(_rethrowLabel);
    // Unguarded rethrow is translated to:
    //
    //     return $iterator._datum = exception, SYNC_STAR_UNCAUGHT_EXCEPTION;
    //
    // This stashes the exception on the Iterator and returns the
    // SYNC_STAR_UNCAUGHT_EXCEPTION status code.
    final store = js_ast.Assignment(
      js_ast.PropertyAccess(iterator, iteratorDatumProperty),
      js_ast.js('#.at(-1)', [_errorStack]),
    );
    _addStatement(
      js_ast.Return(
        js_ast.Binary(
          ',',
          store,
          js_ast.number(status_codes.SYNC_STAR_UNCAUGHT_EXCEPTION),
        ),
      ).withSourceInformation(sourceInformation),
    );
  }

  /// Returning from a sync* function returns the SYNC_STAR_DONE status code.
  @override
  void addSuccessExit(Object? sourceInformation) {
    if (_analysis.hasExplicitReturns) {
      _beginLabel(_exitLabel);
    } else {
      _addStatement(js_ast.Comment('implicit return'));
    }
    _addStatement(
      js_ast.Return(
        js_ast.number(status_codes.SYNC_STAR_DONE),
      ).withSourceInformation(sourceInformation),
    );
  }

  @override
  Iterable<js_ast.VariableInitialization> variableInitializations(
    Object? sourceInformation,
  ) {
    var variables = <js_ast.VariableInitialization>[];
    return variables;
  }

  @override
  js_ast.Statement awaitStatement(
    js_ast.Expression value,
    Object? sourceInformation,
  ) {
    throw StateError('Sync* functions cannot contain await statements.');
  }
}

class AsyncStarRewriter extends AsyncRewriterBase {
  @override
  bool get _isAsyncStar => true;

  /// The stack of labels of finally blocks to assign to [_next] if the
  /// async* [StreamSubscription] was canceled during a yield.
  late final js_ast.Identifier nextWhenCanceled = ScopedId(
    't\$nextWhenCanceled',
  );

  /// The StreamController that controls an async* function.
  late final js_ast.Identifier controller = ScopedId('t\$controller');

  /// The function called by an async* function to simulate an await, yield or
  /// yield*.
  ///
  /// For an await/yield/yield* it is called with:
  ///
  /// - The value to await/yieldExpression(value to yield)/
  /// yieldStarExpression(stream to yield)
  /// - The body function [bodyName]
  /// - The controller object [controller]
  ///
  /// For a return it is called with:
  ///
  /// - null
  /// - null
  /// - The [controller]
  /// - null.
  final js_ast.Expression asyncStarHelper;

  /// Constructor used to initialize the [controller] variable.
  ///
  /// Specific to async* methods.
  final js_ast.Expression newController;
  List<js_ast.Expression> newControllerTypeArguments;

  /// Used to get the `Stream` out of the [controllerName] variable.
  final js_ast.Expression streamOfController;

  /// A JS Expression that creates a marker indicating a 'yield' statement.
  ///
  /// Called with the value to yield.
  final js_ast.Expression yieldExpression;

  /// A JS Expression that creates a marker indication a 'yield*' statement.
  ///
  /// Called with the stream to yield from.
  final js_ast.Expression yieldStarExpression;

  final js_ast.Expression wrapBody;

  AsyncStarRewriter({
    required this.asyncStarHelper,
    required this.streamOfController,
    required this.newController,
    required this.newControllerTypeArguments,
    required this.yieldExpression,
    required this.yieldStarExpression,
    required this.wrapBody,
    required super.bodyName,
  });

  /// Translates a yield/yield* in an async* function.
  ///
  /// yield/yield* in an async* function is translated much like the `await` is
  /// translated in [visitAwait], only the object is wrapped in a
  /// [yieldExpression]/[yieldStarExpression] to let [asyncStarHelper]
  /// distinguish them.
  /// Also [nextWhenCanceled] is set up to contain the finally blocks that
  /// must be run in case the stream was canceled.
  @override
  void addYield(
    js_ast.DartYield node,
    js_ast.Expression expression,
    Object? sourceInformation,
  ) {
    // Find all the finally blocks that should be performed if the stream is
    // canceled during the yield.
    var enclosingFinallyLabels = <int>[
      // At the bottom of the stack is the return label.
      _exitLabel,
      for (final node in _jumpTargets)
        if (_finallyLabels[node] != null) _finallyLabels[node]!,
    ];

    _addStatement(
      js_ast.js
          .statement('# = #;', [
            nextWhenCanceled,
            js_ast.ArrayInitializer(
              enclosingFinallyLabels.map(js_ast.number).toList(),
            ),
          ])
          .withSourceInformation(sourceInformation),
    );
    var yieldExpressionCall = js_ast
        .js('#yieldExpression(#expression)', {
          'yieldExpression': node.hasStar
              ? yieldStarExpression
              : yieldExpression,
          'expression': expression,
        })
        .withSourceInformation(sourceInformation);
    var asyncStarHelperCall = js_ast
        .js('#asyncStarHelper(#yieldExpressionCall, #bodyName, #controller)', {
          'asyncStarHelper': asyncStarHelper,
          'yieldExpressionCall': yieldExpressionCall,
          'bodyName': bodyName,
          'controller': controller,
        })
        .withSourceInformation(sourceInformation);
    _addStatement(
      js_ast.Return(
        asyncStarHelperCall,
      ).withSourceInformation(sourceInformation),
    );
  }

  @override
  js_ast.Fun _finishFunction(
    List<js_ast.Parameter> parameters,
    js_ast.Statement rewrittenBody,
    js_ast.VariableDeclarationList variableDeclarationLists,
    Object? functionSourceInformation,
    Object? bodySourceInformation,
  ) {
    var updateNext = js_ast.js('#next = #nextWhenCanceled', {
      'next': _next,
      'nextWhenCanceled': nextWhenCanceled,
    });
    var callPop = js_ast.js('#next.pop()', {'next': _next});
    var gotoCancelled = js_ast.js('#goto = #callPop', {
      'goto': _goto,
      'callPop': callPop,
    });
    var pushError = js_ast.js('#errorStack.push(#result)', {
      'errorStack': _errorStack,
      'result': _result,
    });
    var gotoError = js_ast.js('#goto = #handler', {
      'goto': _goto,
      'handler': _handler,
    });
    var breakStatement = js_ast.Break(null);
    var switchCase = js_ast.js.statement(
      '''
        switch (#errorCode) {
          case #STREAM_WAS_CANCELED:
            #updateNext;
            #gotoCancelled;
            #break;
          case #ERROR:
            #pushError;
            #gotoError;
        }''',
      {
        'errorCode': _errorCode,
        'STREAM_WAS_CANCELED': js_ast.number(status_codes.STREAM_WAS_CANCELED),
        'updateNext': updateNext,
        'gotoCancelled': gotoCancelled,
        'break': breakStatement,
        'ERROR': js_ast.number(status_codes.ERROR),
        'pushError': pushError,
        'gotoError': gotoError,
      },
    );
    var ifError = js_ast.js.statement(
      '''
        if (#errorCode === #ERROR) {
          #pushError;
          #gotoError;
        }''',
      {
        'errorCode': _errorCode,
        'ERROR': js_ast.number(status_codes.ERROR),
        'pushError': pushError,
        'gotoError': gotoError,
      },
    );
    var ifHasYield = js_ast.js.statement(
      '''
        if (#hasYield) {
          #switchCase
        } else {
          #ifError;
        }
    ''',
      {
        'hasYield': _analysis.hasYield,
        'switchCase': switchCase,
        'ifError': ifError,
      },
    );
    // Use an arrow function so that we can access 'this' from the outer scope.
    var innerFunction = js_ast
        .js(
          '''
        (#errorCode, #result) => {
          #ifHasYield;
          #rewrittenBody;
        }''',
          {
            'errorCode': _errorCode,
            'result': _result,
            'ifHasYield': ifHasYield,
            'rewrittenBody': rewrittenBody,
          },
        )
        .withSourceInformation(functionSourceInformation);
    var wrapBodyCall = js_ast
        .js('#wrapBody(#innerFunction)', {
          'wrapBody': wrapBody,
          'innerFunction': innerFunction,
        })
        .withSourceInformation(bodySourceInformation);
    var declareBodyName = js_ast.js.statement(
      'var #bodyName = #wrapBodyCall;',
      {'bodyName': bodyName, 'wrapBodyCall': wrapBodyCall},
    );
    var streamOfControllerCall = js_ast.js('#streamOfController(#controller)', {
      'streamOfController': streamOfController,
      'controller': controller,
    });
    var returnStreamOfControllerCall = js_ast.Return(streamOfControllerCall);
    return (js_ast
            .js(
              '''
        function (#parameters) {
          #declareBodyName;
          #variableDeclarationLists;
          #returnStreamOfControllerCall;
        }''',
              {
                'parameters': parameters,
                'declareBodyName': declareBodyName,
                'variableDeclarationLists': variableDeclarationLists,
                'returnStreamOfControllerCall': returnStreamOfControllerCall,
              },
            )
            .withSourceInformation(functionSourceInformation))
        as js_ast.Fun;
  }

  @override
  void addErrorExit(Object? sourceInformation) {
    _hasHandlerLabels = true;
    _beginLabel(_rethrowLabel);
    var asyncHelperCall = js_ast
        .js('#asyncHelper(#errorStack.at(-1), #errorCode, #controller)', {
          'asyncHelper': asyncStarHelper,
          'errorCode': js_ast.number(status_codes.ERROR),
          'errorStack': _errorStack,
          'controller': controller,
        })
        .withSourceInformation(sourceInformation);
    _addStatement(
      js_ast.Return(asyncHelperCall).withSourceInformation(sourceInformation),
    );
  }

  /// Returning from an async* function calls the [streamHelper] with an
  /// [endOfIteration] marker.
  @override
  void addSuccessExit(Object? sourceInformation) {
    _beginLabel(_exitLabel);

    var streamHelperCall = js_ast
        .js('#streamHelper(null, #successCode, #controller)', {
          'streamHelper': asyncStarHelper,
          'successCode': js_ast.number(status_codes.SUCCESS),
          'controller': controller,
        })
        .withSourceInformation(sourceInformation);
    _addStatement(
      js_ast.Return(streamHelperCall).withSourceInformation(sourceInformation),
    );
  }

  @override
  Iterable<js_ast.VariableInitialization> variableInitializations(
    Object? sourceInformation,
  ) {
    var variables = <js_ast.VariableInitialization>[];
    variables.add(
      _makeVariableInitializer(
        controller,
        js_ast
            .js('#(#, #)', [
              newController,
              newControllerTypeArguments,
              bodyName,
            ])
            .withSourceInformation(sourceInformation),
        sourceInformation,
      ),
    );
    if (_analysis.hasYield) {
      variables.add(
        _makeVariableInitializer(nextWhenCanceled, null, sourceInformation),
      );
    }
    return variables;
  }

  @override
  js_ast.Statement awaitStatement(
    js_ast.Expression value,
    Object? sourceInformation,
  ) {
    var asyncHelperCall = js_ast
        .js('#asyncHelper(#value, #bodyName, #controller)', {
          'asyncHelper': asyncStarHelper,
          'value': value,
          'bodyName': bodyName,
          'controller': controller,
        })
        .withSourceInformation(sourceInformation);
    return js_ast.Return(
      asyncHelperCall,
    ).withSourceInformation(sourceInformation);
  }
}

/// Finds out
///
/// - which expressions have yield or await nested in them.
/// - targets of jumps
/// - a set of used label names.
class PreTranslationAnalysis extends js_ast.NodeVisitor<bool> {
  final Set<js_ast.Node> hasAwaitOrYield = {};
  final Map<js_ast.Node, js_ast.Node> targets = {};
  final List<js_ast.Node> loopsAndSwitches = [];
  final List<js_ast.LabeledStatement> labelledStatements = [];
  final Set<String> usedLabelNames = {};

  bool hasExplicitReturns = false;

  bool hasYield = false;

  bool hasFinally = false;

  // The function currently being analyzed.
  final js_ast.FunctionExpression currentFunction;

  // For error messages.
  final Never Function(js_ast.Node) unsupported;

  PreTranslationAnalysis(this.unsupported, this.currentFunction);

  bool visit(js_ast.Node node) {
    var containsAwait = node.accept(this);
    if (containsAwait) {
      hasAwaitOrYield.add(node);
    }
    return containsAwait;
  }

  void analyze() {
    currentFunction.params.forEach(visit);
    visit(currentFunction.body);
  }

  @override
  bool visitAccess(js_ast.PropertyAccess node) {
    var receiver = visit(node.receiver);
    var selector = visit(node.selector);
    return receiver || selector;
  }

  @override
  bool visitArrayHole(js_ast.ArrayHole node) {
    return false;
  }

  @override
  bool visitArrayInitializer(js_ast.ArrayInitializer node) {
    var containsAwait = false;
    for (var element in node.elements) {
      if (visit(element)) containsAwait = true;
    }
    return containsAwait;
  }

  @override
  bool visitAssignment(js_ast.Assignment node) {
    var leftHandSide = visit(node.leftHandSide);
    var value = visit(node.value);
    return leftHandSide || value;
  }

  @override
  bool visitAwait(js_ast.Await node) {
    visit(node.expression);
    return true;
  }

  @override
  bool visitBinary(js_ast.Binary node) {
    var left = visit(node.left);
    var right = visit(node.right);
    return left || right;
  }

  @override
  bool visitBlock(js_ast.Block node) {
    var containsAwait = false;
    for (var statement in node.statements) {
      if (visit(statement)) containsAwait = true;
    }
    return containsAwait;
  }

  @override
  bool visitBreak(js_ast.Break node) {
    if (node.targetLabel != null) {
      targets[node] = labelledStatements.lastWhere((
        js_ast.LabeledStatement statement,
      ) {
        return statement.label == node.targetLabel;
      });
    } else {
      targets[node] = loopsAndSwitches.last;
    }
    return false;
  }

  @override
  bool visitCall(js_ast.Call node) {
    var containsAwait = visit(node.target);
    for (var argument in node.arguments) {
      if (visit(argument)) containsAwait = true;
    }
    return containsAwait;
  }

  @override
  bool visitCase(js_ast.Case node) {
    var expression = visit(node.expression);
    var body = visit(node.body);
    return expression || body;
  }

  @override
  bool visitCatch(js_ast.Catch node) {
    var declaration = visit(node.declaration);
    var body = visit(node.body);
    return declaration || body;
  }

  @override
  bool visitComment(js_ast.Comment node) {
    return false;
  }

  @override
  bool visitConditional(js_ast.Conditional node) {
    var condition = visit(node.condition);
    var then = visit(node.then);
    var otherwise = visit(node.otherwise);
    return condition || then || otherwise;
  }

  @override
  bool visitContinue(js_ast.Continue node) {
    if (node.targetLabel != null) {
      var targetLabel = labelledStatements.lastWhere(
        (js_ast.LabeledStatement stm) => stm.label == node.targetLabel,
      );
      targets[node] = targetLabel.body;
    } else {
      targets[node] = loopsAndSwitches.lastWhere(
        (js_ast.Node node) => node is! js_ast.Switch,
      );
    }
    assert(() {
      var target = targets[node];
      return target is js_ast.Loop ||
          (target is js_ast.LabeledStatement && target.body is js_ast.Loop);
    }());
    return false;
  }

  @override
  bool visitDefault(js_ast.Default node) {
    return visit(node.body);
  }

  @override
  bool visitDo(js_ast.Do node) {
    loopsAndSwitches.add(node);
    var body = visit(node.body);
    var condition = visit(node.condition);
    loopsAndSwitches.removeLast();
    return body || condition;
  }

  @override
  bool visitEmptyStatement(js_ast.EmptyStatement node) {
    return false;
  }

  @override
  bool visitExpressionStatement(js_ast.ExpressionStatement node) {
    return visit(node.expression);
  }

  @override
  bool visitFor(js_ast.For node) {
    var init = (node.init == null) ? false : visit(node.init!);
    var condition = (node.condition == null) ? false : visit(node.condition!);
    var update = (node.update == null) ? false : visit(node.update!);
    loopsAndSwitches.add(node);
    var body = visit(node.body);
    loopsAndSwitches.removeLast();
    return init || condition || update || body;
  }

  @override
  bool visitForIn(js_ast.ForIn node) {
    var object = visit(node.object);
    loopsAndSwitches.add(node);
    var body = visit(node.body);
    loopsAndSwitches.removeLast();
    return object || body;
  }

  @override
  bool visitFun(js_ast.Fun node) {
    return false;
  }

  @override
  bool visitFunctionDeclaration(js_ast.FunctionDeclaration node) {
    return false;
  }

  @override
  bool visitArrowFun(js_ast.ArrowFun node) {
    return false;
  }

  @override
  bool visitIf(js_ast.If node) {
    var condition = visit(node.condition);
    var then = visit(node.then);
    var otherwise = visit(node.otherwise);
    return condition || then || otherwise;
  }

  @override
  bool visitInterpolatedExpression(js_ast.InterpolatedExpression node) {
    unsupported(node);
  }

  @override
  bool visitInterpolatedLiteral(js_ast.InterpolatedLiteral node) {
    unsupported(node);
  }

  @override
  bool visitInterpolatedParameter(js_ast.InterpolatedParameter node) {
    unsupported(node);
  }

  @override
  bool visitInterpolatedSelector(js_ast.InterpolatedSelector node) {
    unsupported(node);
  }

  @override
  bool visitInterpolatedStatement(js_ast.InterpolatedStatement node) {
    unsupported(node);
  }

  @override
  bool visitLabeledStatement(js_ast.LabeledStatement node) {
    usedLabelNames.add(node.label);
    labelledStatements.add(node);
    var containsAwait = visit(node.body);
    labelledStatements.removeLast();
    return containsAwait;
  }

  @override
  bool visitLiteralBool(js_ast.LiteralBool node) {
    return false;
  }

  @override
  bool visitLiteralExpression(js_ast.LiteralExpression node) {
    unsupported(node);
  }

  @override
  bool visitLiteralNull(js_ast.LiteralNull node) {
    return false;
  }

  @override
  bool visitLiteralNumber(js_ast.LiteralNumber node) {
    return false;
  }

  @override
  bool visitLiteralStatement(js_ast.LiteralStatement node) {
    unsupported(node);
  }

  @override
  bool visitLiteralString(js_ast.LiteralString node) {
    return false;
  }

  @override
  bool visitNamedFunction(js_ast.NamedFunction node) {
    return false;
  }

  @override
  bool visitNew(js_ast.New node) {
    return visitCall(node);
  }

  @override
  bool visitObjectInitializer(js_ast.ObjectInitializer node) {
    var containsAwait = false;
    for (var property in node.properties) {
      if (visit(property)) containsAwait = true;
    }
    return containsAwait;
  }

  @override
  bool visitPostfix(js_ast.Postfix node) {
    return visit(node.argument);
  }

  @override
  bool visitPrefix(js_ast.Prefix node) {
    return visit(node.argument);
  }

  @override
  bool visitProgram(js_ast.Program node) {
    throw 'Unexpected';
  }

  @override
  bool visitProperty(js_ast.Property node) {
    return visit(node.value);
  }

  @override
  bool visitMethod(js_ast.Method node) {
    return false;
  }

  @override
  bool visitRegExpLiteral(js_ast.RegExpLiteral node) {
    return false;
  }

  @override
  bool visitReturn(js_ast.Return node) {
    hasExplicitReturns = true;
    targets[node] = currentFunction;
    if (node.value == null) return false;
    return visit(node.value!);
  }

  @override
  bool visitSwitch(js_ast.Switch node) {
    loopsAndSwitches.add(node);
    // TODO(sra): If just the key has an `await` expression, do not transform
    // the body of the switch.
    var result = visit(node.key);
    for (var clause in node.cases) {
      if (visit(clause)) result = true;
    }
    loopsAndSwitches.removeLast();
    return result;
  }

  @override
  bool visitThis(js_ast.This node) {
    return false;
  }

  @override
  bool visitThrow(js_ast.Throw node) {
    return visit(node.expression);
  }

  @override
  bool visitTry(js_ast.Try node) {
    if (node.finallyPart != null) hasFinally = true;
    var body = visit(node.body);
    var catchPart = (node.catchPart == null) ? false : visit(node.catchPart!);
    var finallyPart = (node.finallyPart == null)
        ? false
        : visit(node.finallyPart!);
    return body || catchPart || finallyPart;
  }

  @override
  bool visitVariableDeclarationList(js_ast.VariableDeclarationList node) {
    var result = false;
    for (var init in node.declarations) {
      if (visit(init)) result = true;
    }
    return result;
  }

  @override
  bool visitVariableInitialization(js_ast.VariableInitialization node) {
    var leftHandSide = visit(node.declaration);
    var value = (node.value == null) ? false : visit(node.value!);
    return leftHandSide || value;
  }

  @override
  bool visitIdentifier(js_ast.Identifier node) {
    return false;
  }

  @override
  bool visitWhile(js_ast.While node) {
    loopsAndSwitches.add(node);
    var condition = visit(node.condition);
    var body = visit(node.body);
    loopsAndSwitches.removeLast();
    return condition || body;
  }

  @override
  bool visitDartYield(js_ast.DartYield node) {
    hasYield = true;
    visit(node.expression);
    return true;
  }

  @override
  bool visitCommentExpression(js_ast.CommentExpression node) {
    return false;
  }

  @override
  bool visitArrayBindingPattern(js_ast.ArrayBindingPattern node) {
    return false;
  }

  @override
  bool visitClassDeclaration(js_ast.ClassDeclaration node) {
    return false;
  }

  @override
  bool visitClassExpression(js_ast.ClassExpression node) {
    return false;
  }

  @override
  bool visitDebuggerStatement(js_ast.DebuggerStatement node) {
    return false;
  }

  @override
  bool visitDestructuredVariable(js_ast.DestructuredVariable node) {
    return false;
  }

  @override
  bool visitExportClause(js_ast.ExportClause node) {
    return false;
  }

  @override
  bool visitExportDeclaration(js_ast.ExportDeclaration node) {
    return false;
  }

  @override
  bool visitForOf(js_ast.ForOf node) {
    node.leftHandSide.accept(this);
    var iterable = node.iterable.accept(this);
    loopsAndSwitches.add(node);
    var body = node.body.accept(this);
    loopsAndSwitches.removeLast();
    return iterable || body;
  }

  @override
  bool visitImportDeclaration(js_ast.ImportDeclaration node) {
    return false;
  }

  @override
  bool visitInterpolatedIdentifier(js_ast.InterpolatedIdentifier node) {
    return false;
  }

  @override
  bool visitInterpolatedMethod(js_ast.InterpolatedMethod node) {
    return false;
  }

  @override
  bool visitNameSpecifier(js_ast.NameSpecifier node) {
    return false;
  }

  @override
  bool visitObjectBindingPattern(js_ast.ObjectBindingPattern node) {
    return false;
  }

  @override
  bool visitRestParameter(js_ast.RestParameter node) {
    return false;
  }

  @override
  bool visitSimpleBindingPattern(js_ast.SimpleBindingPattern node) {
    return false;
  }

  @override
  bool visitSpread(js_ast.Spread node) {
    return false;
  }

  @override
  bool visitSuper(js_ast.Super node) {
    return false;
  }

  @override
  bool visitTaggedTemplate(js_ast.TaggedTemplate node) {
    return false;
  }

  @override
  bool visitTemplateString(js_ast.TemplateString node) {
    return node.interpolations.any((e) => e.accept(this));
  }

  @override
  bool visitYield(js_ast.Yield node) {
    unsupported(node);
  }
}

/// Defines a scope in the async body of a function tracking all variables
/// available in the scope.
///
/// We maintain a mapping from each variable name to the scope it is declared
/// in. This allows us to refer to the correct scope object for uses of that
/// variable.
///
/// Each scope also tracks if it was captured. Only captured scopes need to be
/// reset upon re-entry, otherwise the values within them cannot leak out.
class _ScopeInfo {
  late final ScopedId scopeObject = ScopedId('asyncScope');
  bool isCaptured = false;
  bool hasDeclarations = false;
  final Map<String, _ScopeInfo> _nameDeclarations;

  _ScopeInfo([Map<String, _ScopeInfo>? nameDeclarations])
    : _nameDeclarations = {...?nameDeclarations};

  _ScopeInfo childScope() {
    return _ScopeInfo(_nameDeclarations);
  }

  void declare(js_ast.Identifier node, bool isUntrackedDeclaration) {
    final key = node.name;
    assert(
      _nameDeclarations[key] != this,
      'Name "$node" already declared in scope.',
    );
    if (isUntrackedDeclaration) {
      _nameDeclarations.remove(key);
    } else {
      _nameDeclarations[key] = this;
      hasDeclarations = true;
    }
  }

  _ScopeInfo? getDeclaringScope(js_ast.Identifier node) {
    return _nameDeclarations[node.name];
  }
}

/// Tracks [_ScopeInfo] are captured by this closure.
///
/// We use an IIFE to capture scope objects used within this closure. Capture
/// names are assigned to each captured scope, this is the parameter name in the
/// IIFE. Within the body of this closure, captured scopes will be referred to
/// by their capture name.
class _ClosureCaptureInfo {
  final _ScopeInfo scopeInfo;
  final Map<_ScopeInfo, ScopedId> usedScopes = {};
  bool get hasCapture => usedScopes.isNotEmpty;

  _ClosureCaptureInfo(this.scopeInfo);

  ScopedId useScope(_ScopeInfo scope) {
    scope.isCaptured = true;
    return usedScopes[scope] ??= ScopedId('capturedAsyncScope');
  }
}

/// Updates references to captured variables to read the value from the
/// appropriate captured scope name.
class _ClosureRenamer extends js_ast.Transformer {
  final _ScopeCollector scopeCollector;
  final _ClosureCaptureInfo closureInfo;

  _ClosureRenamer(this.scopeCollector, this.closureInfo);

  @override
  js_ast.Node visitIdentifier(js_ast.Identifier node) {
    final declaringScope = scopeCollector.useToDeclaringScope[node];
    if (declaringScope == null) return node;
    final captureVariable = closureInfo.usedScopes[declaringScope];
    return captureVariable != null
        ? (js_ast.PropertyAccess.field(captureVariable, node.name)
            ..sourceInformation = node.sourceInformation)
        : node;
  }
}

/// Collects scoped names for each variable declared within the scope of the
/// given function.
///
/// In order to support scope capture we define a [_ScopeInfo] for each scope
/// we enter. Each one will be a JS Object that we can capture in inner
/// functions. This object can also be reset when we re-enter a scoped
/// construct (e.g. different iterations of a for loop).
///
/// The [_ScopeInfo] object will get hoisted to the top of the async body so it
/// can be accessed where needed across async gaps.
///
/// This approach also works well for debugging, users will see "asyncScope"
/// objects. Since we have one scope object (roughly) per Dart scope, users will
/// see variables matching the names they've used in the source code. In the
/// future DevTools can even recognize these objects and flatten them into their
/// appropriate scopes.
///
/// We also track [_ClosureCaptureInfo] for each capturing function so that we
/// can maintain the correct captured scopes.
///
/// Variables that are not hoisted (i.e. we can maintain their control flow
/// constructs because they don't contain awaits or yields) do not need to be
/// referenced via scope objects.
class _ScopeCollector extends js_ast.VariableDeclarationVisitor {
  final PreTranslationAnalysis _analysis;

  _ScopeInfo _currentScope = _ScopeInfo(null);
  _ClosureCaptureInfo? _currentOuterClosure;
  bool skipHoisting = false;
  final Map<js_ast.Identifier, _ScopeInfo> useToDeclaringScope = {};
  final Map<js_ast.Node, _ScopeInfo> scopeMapping = {};
  final Map<js_ast.FunctionExpression, _ClosureCaptureInfo> scopeCaptures = {};
  bool get inClosure => _currentOuterClosure != null;

  _ScopeCollector(this._analysis);

  void collect(js_ast.FunctionExpression node) {
    node.body.accept(this);
    scopeMapping[node.body] = _currentScope;
  }

  js_ast.Expression transformIdentifier(js_ast.Identifier node) {
    final declaringScope = useToDeclaringScope[node];
    if (declaringScope == null) return node;
    return (js_ast.PropertyAccess.field(declaringScope.scopeObject, node.name)
      ..sourceInformation = node.sourceInformation);
  }

  void registerUsed(js_ast.Identifier node) {
    final declaringScope = _currentScope.getDeclaringScope(node);
    if (declaringScope != null) {
      useToDeclaringScope[node] = declaringScope;
      _currentOuterClosure?.useScope(declaringScope);
    }
  }

  void withNewScope(js_ast.Node node, void Function() f) {
    final savedScope = _currentScope;
    _currentScope = _currentScope.childScope();
    scopeMapping[node] = _currentScope;
    f();
    _currentScope = savedScope;
  }

  @override
  void declare(js_ast.Identifier node) {
    if (node is ScopedId && !node.needsCapture) return;
    _currentScope.declare(node, inClosure || skipHoisting);
    registerUsed(node);
  }

  @override
  void visitIdentifier(js_ast.Identifier node) {
    if (node is ScopedId && !node.needsCapture) return;
    registerUsed(node);
  }

  @override
  void visitFunctionExpression(js_ast.FunctionExpression node) {
    withNewScope(node, () {
      if (!inClosure) {
        _currentOuterClosure = _ClosureCaptureInfo(_currentScope);
        scopeCaptures[node] = _currentOuterClosure!;
        super.visitFunctionExpression(node);
        _currentOuterClosure = null;
      } else {
        super.visitFunctionExpression(node);
      }
    });
  }

  @override
  void visitBlock(js_ast.Block node) {
    if (node.isScope) {
      withNewScope(node, () => super.visitBlock(node));
    } else {
      super.visitBlock(node);
    }
  }

  @override
  void visitForIn(js_ast.ForIn node) {
    node.object.accept(this);
    withNewScope(node, () {
      final savedSkipHoisting = skipHoisting;
      skipHoisting = !_analysis.hasAwaitOrYield.contains(node);
      node.leftHandSide.accept(this);
      skipHoisting = savedSkipHoisting;
      node.body.accept(this);
    });
  }

  @override
  void visitForOf(js_ast.ForOf node) {
    node.iterable.accept(this);
    withNewScope(node, () {
      final savedSkipHoisting = skipHoisting;
      skipHoisting = !_analysis.hasAwaitOrYield.contains(node);
      node.leftHandSide.accept(this);
      skipHoisting = savedSkipHoisting;
      node.body.accept(this);
    });
  }

  @override
  void visitFor(js_ast.For node) {
    // Make sure any declared variables are scoped to this loop.
    withNewScope(node, () {
      final savedSkipHoisting = skipHoisting;
      skipHoisting = !_analysis.hasAwaitOrYield.contains(node);
      node.init?.accept(this);
      skipHoisting = savedSkipHoisting;
      node.condition?.accept(this);
      node.update?.accept(this);
      node.body.accept(this);
    });
  }

  @override
  void visitTry(js_ast.Try node) {
    node.body.accept(this);
    final savedSkipHoisting = skipHoisting;
    skipHoisting = !_analysis.hasAwaitOrYield.contains(node);
    node.catchPart?.declaration.accept(this);
    skipHoisting = savedSkipHoisting;
    node.catchPart?.body.accept(this);
    node.finallyPart?.accept(this);
  }
}
