// 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 'dart:collection';
import 'dart:convert';
import 'dart:io' as io;
import 'dart:math' show max, min;

import 'package:_js_interop_checks/src/transformations/js_util_optimizer.dart'
    show ExtensionIndex;
import 'package:front_end/src/api_unstable/ddc.dart';
import 'package:js_shared/synced/embedded_names.dart' show JsGetName, JsBuiltin;
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/clone.dart';
import 'package:kernel/core_types.dart';
import 'package:kernel/kernel.dart';
import 'package:kernel/library_index.dart';
import 'package:kernel/src/dart_type_equivalence.dart';
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
import 'package:path/path.dart' as p;
import 'package:source_span/source_span.dart' show SourceLocation;

import '../command/options.dart' show Options;
import '../compiler/js_names.dart' as js_ast;
import '../compiler/js_utils.dart' as js_ast;
import '../compiler/module_builder.dart'
    show isSdkInternalRuntimeUri, libraryUriToJsIdentifier;
import '../compiler/module_containers.dart' show ModuleItemContainer;
import '../compiler/rewrite_async.dart';
import '../js_ast/js_ast.dart' as js_ast;
import '../js_ast/js_ast.dart' show ModuleItem, js;
import '../js_ast/source_map_printer.dart'
    show NodeEnd, NodeSpan, HoverComment, continueSourceMap;
import 'compiler.dart' as old;
import 'constants.dart';
import 'future_or_normalizer.dart';
import 'hot_reload_delta_inspector.dart';
import 'js_interop.dart';
import 'js_typerep.dart';
import 'kernel_helpers.dart';
import 'native_types.dart';
import 'nullable_inference.dart';
import 'property_model.dart';
import 'target.dart' show allowedNativeTest;
import 'type_environment.dart';
import 'type_recipe_generator.dart';
import 'type_table.dart';

/// The groups of compiled arguments ready to be flattened into a single
/// [js_ast.Array] for statically sound calls or into separate packets for
/// runtime checked calls.
typedef _ArgumentGroups = ({
  List<js_ast.Expression>? typeArguments,
  List<js_ast.Expression>? positionalArguments,
  List<js_ast.Property>? namedArguments,
});

/// Name used as a prefix for extension symbols and the identifier of the object
/// used to store them.
final _extensionSymbolHolderName = 'dartx';

/// A prefix for symbols used to store lazily evaluated field values.
///
/// Names prefixed with this must not be reset across hot reloads.
final _fieldValueStorePrefix = '_#v_';

/// Symbol data used to map library members kernel nodes to identifiers used
/// in the compiled JavaScript.
///
/// This data is intended to be serialized and consumed by the debugger.
class SymbolData {
  /// Maps each `Class` node compiled in the module to the `Identifier`s used to
  /// name the class in JavaScript.
  ///
  /// This mapping is used when generating the symbol information for the
  /// module.
  final classIdentifiers = <Class, js_ast.Identifier>{};

  /// Maps each class `Member` node compiled in the module to the name used for
  /// the member in JavaScript.
  ///
  /// This mapping is used when generating the symbol information for the
  /// module.
  final memberNames = <Member, String>{};

  /// Maps each `Procedure` node compiled in the module to the `Identifier`s
  /// used to name the class in JavaScript.
  ///
  /// This mapping is used when generating the symbol information for the
  /// module.
  final procedureIdentifiers = <Procedure, js_ast.Identifier>{};

  /// Maps each `VariableDeclaration` node compiled in the module to the name
  /// used for the variable in JavaScript.
  ///
  /// This mapping is used when generating the symbol information for the
  /// module.
  final variableIdentifiers = <VariableDeclaration, js_ast.Identifier>{};
}

/// Compiles a kernel [Component] to a bundle of individual libraries.
class LibraryBundleCompiler implements old.Compiler {
  final ClassHierarchy _hierarchy;
  final Options _options;
  final Map<Library, Component> _importToSummary;
  final Map<Component, String> _summaryToModule;
  final CoreTypes _coreTypes;
  final Ticker? _ticker;
  final _symbolData = SymbolData();
  final _libraryCompilers = <Library, LibraryCompiler>{};

  LibraryBundleCompiler(
    Component component,
    this._hierarchy,
    this._options,
    this._importToSummary,
    this._summaryToModule, {
    CoreTypes? coreTypes,
    Ticker? ticker,
  }) : _coreTypes = coreTypes ?? CoreTypes(component),
       _ticker = ticker;

  @override
  Map<Class, js_ast.Identifier> get classIdentifiers =>
      _symbolData.classIdentifiers;
  @override
  Map<Member, String> get memberNames => _symbolData.memberNames;
  @override
  Map<Procedure, js_ast.Identifier> get procedureIdentifiers =>
      _symbolData.procedureIdentifiers;
  @override
  Map<VariableDeclaration, js_ast.Identifier> get variableIdentifiers =>
      _symbolData.variableIdentifiers;

  @override
  js_ast.Program emitModule(Component component) {
    assert(_options.emitLibraryBundle);
    _ticker?.logMs('Emitting library bundle');
    // When there is hot reload metadata, update the mappings to the nodes in
    // the current LibraryIndex before passing it on the library compilers.
    var repo =
        component.metadata[hotReloadLibraryMetadataTag]
            as HotReloadLibraryMetadataRepository?;
    repo?.mapToIndexedNodes(LibraryIndex.all(component));
    var metadata = repo?.mapping;
    var compiledLibraries = <js_ast.Program>[];
    for (var library in component.libraries) {
      var libraryCompiler = LibraryCompiler(
        component,
        _hierarchy,
        _options,
        _importToSummary,
        _summaryToModule,
        coreTypes: _coreTypes,
        ticker: _ticker,
        symbolData: _symbolData,
        hotReloadLibraryMetadata: metadata?[library],
        hotReloadGeneration: repo?.generation,
      );
      _libraryCompilers[library] = libraryCompiler;
      compiledLibraries.add(libraryCompiler.emitLibrary(library));
    }
    // TODO(nshahan): Nothing about these symbols requires them to be
    // represented in a library. These could be moved to a construct outside
    // of the language that is provided to libraries that need it.
    if (component.libraries.contains(_coreTypes.coreLibrary)) {
      // Collect all extension symbols from all SDK libraries.
      var allSymbols = {
        for (var compiler in _libraryCompilers.values)
          ...compiler._extensionSymbols,
      };
      // Create dartx library
      var id = js_ast.Identifier(_extensionSymbolHolderName);
      var statements = [
        for (var entry in allSymbols.entries)
          js.statement('# = Symbol(#);', [
            js_ast.PropertyAccess(id, js.string(entry.key)),
            js.string('$_extensionSymbolHolderName.${entry.key}'),
          ]),
        js.statement('# = #', [
          js_ast.PropertyAccess(id, js.call('dartDevEmbedder.linkSymbol')),
          js_ast.NamedFunction(
            js_ast.ScopedId('link__$_extensionSymbolHolderName'),
            js_ast.Fun(const [], js_ast.Block(const [])),
          ),
        ]),
      ];

      compiledLibraries.insert(
        0,
        js_ast.Program(
          statements,
          name: _extensionSymbolHolderName,
          librarySelfVar: id,
        ),
      );
    }
    return js_ast.LibraryBundle(
      compiledLibraries,
      name: _options.moduleName,
      header: _generateCompilationHeader(),
    );
  }

  @override
  js_ast.Fun emitFunctionIncremental(
    List<js_ast.ModuleItem> items,
    Library library,
    Class? cls,
    FunctionNode functionNode,
    String name,
  ) {
    return _libraryCompilers[library]!._emitFunctionIncremental(
      items,
      library,
      cls,
      functionNode,
      name,
    );
  }

  /// Creates header comments with helpful compilation information.
  List<js_ast.Comment> _generateCompilationHeader() {
    var headerOptions = [
      if (_options.canaryFeatures) 'canary',
      if (_options.emitLibraryBundle) 'emitLibraryBundle',
      'enableAsserts(${_options.enableAsserts})',
    ];
    var enabledExperiments = <String>[];
    _options.experiments.forEach((key, value) {
      if (value) enabledExperiments.add(key);
    });
    var header = [
      js_ast.Comment(
        'Generated by DDC, the Dart Development Compiler (to JavaScript).',
      ),
      js_ast.Comment('Version: ${io.Platform.version}'),
      js_ast.Comment('Module: ${_options.moduleName}'),
      js_ast.Comment('Flags: ${headerOptions.join(', ')}'),
      if (enabledExperiments.isNotEmpty)
        js_ast.Comment('Experiments: ${enabledExperiments.join(', ')}'),
    ];
    return header;
  }
}

class LibraryCompiler extends ComputeOnceConstantVisitor<js_ast.Expression>
    with OnceConstantVisitorDefaultMixin<js_ast.Expression>
    implements
        StatementVisitor<js_ast.Statement>,
        ExpressionVisitor<js_ast.Expression> {
  final Options _options;
  final SymbolData _symbolData;

  /// Maps each `Class` node compiled in the module to the `Identifier`s used to
  /// name the class in JavaScript.
  ///
  /// This mapping is used when generating the symbol information for the
  /// module.
  Map<Class, js_ast.Identifier> get classIdentifiers =>
      _symbolData.classIdentifiers;

  /// Maps every mixin application to a unique identifier.
  ///
  /// A mixin application is represented as a (mixin, class) pair, where
  /// 'mixin' is being mixed into 'class'. Anonymous mixins are already
  /// unique per mixin application and so pass themselves in as both 'mixin'
  /// and 'class'.
  ///
  /// This mapping is used when generating super property getters in mixins.
  final Map<(Class, Class), js_ast.Identifier> _mixinCache = {};

  /// Records a reference to a mixin application's passed in superclass.
  /// (see [_emitMixinStatement]).
  final Map<Class, js_ast.Identifier> _mixinSuperclassCache = {};

  /// Maps each class `Member` node compiled in the module to the name used for
  /// the member in JavaScript.
  ///
  /// This mapping is used when generating the symbol information for the
  /// module.
  Map<Member, String> get memberNames => _symbolData.memberNames;

  /// Maps each `Procedure` node compiled in the module to the `Identifier`s
  /// used to name the class in JavaScript.
  ///
  /// This mapping is used when generating the symbol information for the
  /// module.
  Map<Procedure, js_ast.Identifier> get procedureIdentifiers =>
      _symbolData.procedureIdentifiers;

  /// Maps each `VariableDeclaration` node compiled in the module to the name
  /// used for the variable in JavaScript.
  ///
  /// This mapping is used when generating the symbol information for the
  /// module.
  Map<VariableDeclaration, js_ast.Identifier> get variableIdentifiers =>
      _symbolData.variableIdentifiers;

  /// Identifiers for kernel variables with an analogous identifier in JS.
  ///
  /// [VariableDeclaration.name] is not necessarily a safe identifier for JS
  /// transpiled code. The same name can be used in shadowing contexts. We map
  /// each kernel variable to a [js_ast.ScopedId] so that at code emission
  /// time, references that would be shadowed are given a unique name. If there
  /// is no risk of shadowing, the original name will be used.
  final Map<VariableDeclaration, js_ast.ScopedId> _variableTempIds = {};

  /// Maps a library URI import, that is not in [_libraries], to the
  /// corresponding Kernel summary module we imported it with.
  ///
  /// An entry must exist for every reachable component.
  final Map<Library, Component> _importToSummary;

  /// Maps a Kernel summary to the JS import name for the module.
  ///
  /// An entry must exist for every reachable component.
  final Map<Component, String> _summaryToModule;

  /// The variable for the current catch clause
  VariableDeclaration? _rethrowParameter;

  /// Temporary variables mapped to their corresponding JavaScript variable.
  final _tempVariables = <VariableDeclaration, js_ast.ScopedId>{};

  /// Let variables collected for the given function.
  List<js_ast.ScopedId>? _letVariables;

  final _constTable = js_ast.Identifier('CT');

  /// Constant getters used to populate the constant table.
  final _constLazyAccessors = <js_ast.Method>[];

  /// Container for holding the results of lazily-evaluated constants.
  var _constTableCache = ModuleItemContainer<String>.asArray('C');

  /// Tracks the index in [_moduleItems] where the const table must be inserted.
  /// Required for SDK builds due to internal circular dependencies.
  /// E.g., dart.constList depends on JSArray.
  int _constTableInsertionIndex = 0;

  /// The class that is emitting its base class or mixin references, otherwise
  /// null.
  ///
  /// This is not used when inside the class method bodies, or for other type
  /// information such as `implements`.
  Class? _classEmittingExtends;

  /// The class that is emitting its signature information, otherwise null.
  Class? _classEmittingSignatures;

  /// The current type environment of type parameters introduced to the scope
  /// via generic classes and functions.
  DDCTypeEnvironment _currentTypeEnvironment = const EmptyTypeEnvironment();

  final TypeRecipeGenerator _typeRecipeGenerator;

  /// Visitor used for testing static invocations in the dart:_rti library to
  /// determine if they are suitable for inlining at call sites.
  final BasicInlineTester _inlineTester;

  /// The current element being loaded.
  /// We can use this to determine if we're loading top-level code or not:
  ///
  ///     _currentClass == _classEmittingTopLevel
  ///
  Class? _currentClass;

  /// The current source file URI for emitting in the source map.
  Uri? _currentUri;

  late Component _component;

  /// The current library being compiled.
  Library? _currentLibrary;

  /// The current function being compiled, if any.
  FunctionNode? _currentFunction;

  /// Library link method statements that perform class hierarchy connections
  /// like `class C extends E`.
  final List<js_ast.Statement> _classExtendsLinks = [];

  /// Library link method statements that define extension members on mixin
  /// classes.
  final List<js_ast.Statement> _mixinClassDefineExtensionMemberLinks = [];

  /// Library link method statements that define extension members on classes.
  final List<js_ast.Statement> _defineExtensionMemberLinks = [];

  /// Library link method statements that apply mixins.
  final List<js_ast.Statement> _mixinApplicationLinks = [];

  /// Library link method statements that apply extensions on native types.
  final List<js_ast.Statement> _nativeExtensionLinks = [];

  /// Library link method statements that create type rules.
  final List<js_ast.Statement> _typeRuleLinks = [];

  /// Holds additional initialization logic for enum fields.
  final List<js_ast.Statement> _enumExtensions = [];

  /// Whether the current function needs to insert parameter checks.
  ///
  /// Used to avoid adding checks for formal parameters inside a synthetic
  /// function that is generated during expression compilation in the
  /// incremental compiler, since those checks would already be done in
  /// the original code.
  bool _checkParameters = true;

  /// Whether we are currently generating code for the body of a `JS()` call.
  bool _isInForeignJS = false;

  /// Table of named and possibly hoisted types.
  late TypeTable _typeTable;

  /// The global extension type table.
  // TODO(jmesserly): rename to `_nativeTypes`
  final NativeTypeSet _extensionTypes;

  final CoreTypes _coreTypes;

  final TypeEnvironment _types;

  final StatefulStaticTypeContext _staticTypeContext;

  final ClassHierarchy _hierarchy;

  /// Information about virtual and overridden fields/getters/setters in the
  /// class we're currently compiling, or `null` if we aren't compiling a class.
  ClassPropertyModel? _classProperties;

  /// Information about virtual fields for all libraries in the current build
  /// unit.
  final _virtualFields = VirtualFieldModel();

  final JSTypeRep _typeRep;

  bool _superAllowed = true;
  bool _optimizeNonVirtualFieldAccess = true;

  final _superHelpers = <String, js_ast.Method>{};

  /// Cache for the results of calling [_requiresRtiForInstantiation].
  final _requiresRtiForInstantiationCache = <Class, bool>{};

  /// Reserved parameter used to reference RTI objects passed to generic
  /// constructors/factories and generic method signatures.
  final _rtiParam = js_ast.ScopedId('_ti');

  // Compilation of Kernel's [BreakStatement].
  //
  // Kernel represents Dart's `break` and `continue` uniformly as
  // [BreakStatement], by representing a loop continue as a break from the
  // loop's body.  [BreakStatement] always targets an enclosing
  // [LabeledStatement] statement directly without naming it.  (Continue to
  // a labeled switch case is not represented by a [BreakStatement].)
  //
  // We prefer to compile to `continue` where possible and to avoid labeling
  // statements where it is not necessary.  We maintain some state to track
  // which statements can be targets of break or continue without a label, which
  // statements must be labeled to be targets, and the labels that have been
  // assigned.

  /// A list of statements that can be the target of break without a label.
  ///
  /// A [BreakStatement] targeting any [LabeledStatement] in this list can be
  /// compiled to a break without a label.  All the statements in the list have
  /// the same effective target which must compile to something that can be
  /// targeted by break in JS.  This list and [_currentContinueTargets] are
  /// disjoint.
  List<LabeledStatement> _currentBreakTargets = [];

  /// A list of statements that can be the target of a continue without a label.
  ///
  /// A [BreakStatement] targeting any [LabeledStatement] in this list can be
  /// compiled to a continue without a label.  All the statements in this list
  /// have the same effective target which must compile to something that can be
  /// targeted by continue in JS.  This list and [_currentBreakTargets] are
  /// disjoint.
  List<LabeledStatement> _currentContinueTargets = [];

  /// A map from labeled statements to their 'effective targets'.
  ///
  /// The effective target of a labeled loop body is the enclosing loop.  A
  /// [BreakStatement] targeting this statement can be compiled to `continue`
  /// either with or without a label.  The effective target of a labeled
  /// statement that is not a loop body is the outermost non-labeled statement
  /// that it encloses.  A [BreakStatement] targeting this statement can be
  /// compiled to `break` either with or without a label.
  final _effectiveTargets = HashMap<LabeledStatement, Statement>.identity();

  /// A map from effective targets to their label names.
  ///
  /// If the target needs to be labeled when compiled to JS, because it was
  /// targeted by a break or continue with a label, then this map contains the
  /// label name that was assigned to it.
  final _labelNames = HashMap<Statement, String>.identity();

  /// Indicates that the current context exists within a switch statement that
  /// uses at least one continue statement with a target label.
  ///
  /// JS forbids labels at case statement boundaries, so these switch
  /// statements must be generated less directly.
  /// Updated from the method 'visitSwitchStatement'.
  bool _inLabeledContinueSwitch = false;

  /// A map from switch statements to their state information.
  /// State information includes the names of the switch statement's implicit
  /// label name and implicit state variable name.
  ///
  /// Entries are only created for switch statements that contain labeled
  /// continue statements and are used to simulate "jumping" to case statements.
  /// State variables hold the next constant case expression, while labels act
  /// as targets for continue and break.
  final _switchLabelStates = HashMap<Statement, _SwitchLabelState>();

  /// Maps Kernel constants to their JS aliases.
  final _constAliasCache = HashMap<Constant, js_ast.Expression>();

  /// Maps uri strings in asserts and elsewhere to hoisted identifiers.
  var _uriContainer = ModuleItemContainer<String>.asArray('I');

  /// Index of extension and extension type members in order to filter static
  /// interop members.
  // TODO(srujzs): Is there some way to share this from the js_util_optimizer to
  // avoid having to recompute?
  final ExtensionIndex _extensionIndex;

  /// When inside a `[]=` operator, this will be a non-null value that should be
  /// returned by any `return;` statement.
  ///
  /// This lets DDC use the setter method's return value directly.
  final _operatorSetResultStack = <js_ast.Identifier?>[];

  /// Private member names in this module, organized by their library.
  final _privateNames = HashMap<Library, HashMap<String, js_ast.ScopedId>>();

  /// Holds all top-level JS symbols (used for caching or indexing fields).
  final _symbolContainer = ModuleItemContainer<js_ast.Identifier>.asObject(
    'S',
    keyToString: (js_ast.Identifier i) => i.name,
  );

  /// Extension member symbols for adding Dart members to JS types.
  ///
  /// These are added to the [_extensionSymbolsLibraryId]; see that field for more
  /// information.
  final _extensionSymbols = <String, js_ast.ScopedId>{};

  /// The set of libraries we are currently compiling, and the temporaries used
  /// to refer to them.
  final _libraries = <Library, js_ast.Identifier>{};

  /// Imported libraries, and the temporaries used to refer to them.
  final _imports = <Library, js_ast.Identifier>{};

  /// Incremental mode for expression compilation.
  ///
  /// If set to true, triggers emitting all used types, symbols, libraries,
  /// constants, urs inside the generated function.
  bool _incrementalMode = false;

  /// Modules and libraries accessed during compilation in incremental mode.
  final _incrementalModules = <String, Set<String>>{};

  /// The identifier used to reference DDC's core "dart:_runtime" library from
  /// generated JS code, typically called "dart" e.g. `dart.dcall`.
  late final js_ast.Identifier _runtimeLibraryId;

  /// The library referred to by [_runtimeLibraryId].
  final Library _runtimeLibrary;

  /// The identifier used to reference DDC's "extension method" symbols, used to
  /// safely add Dart-specific member names to JavaScript classes, such as
  /// primitive types (e.g. String) or DOM types in "dart:html".
  late final js_ast.Identifier _extensionSymbolsLibraryId;

  /// The identifier used to reference DDC's core "dart:_rti" library from
  /// generated JS code.
  ///
  /// Must manually name the dart:_rti library because there are local variables
  /// within the library that inadvertently shadow the default name.
  final _rtiLibraryId = js_ast.ScopedId('dart_rti');

  /// The library referred to by [_rtiLibraryId].
  final Library _rtiLibrary;

  /// The `Rti` class defined in [_rtiLibrary].
  final Class _rtiClass;

  /// Whether we're currently building the SDK, which may require special
  /// bootstrapping logic.
  ///
  /// This is initialized by [emitModule], which must be called before
  /// accessing this field.
  late final bool _isBuildingSdk;

  /// Whether or not to move top level symbols into top-level containers.
  ///
  /// This is set in both [emitModule] and [_emitLibrary].
  /// Depends on [_isBuildingSdk].
  bool _containerizeSymbols = false;

  /// The temporary variable that stores named arguments (these are passed via a
  /// JS object literal, to match JS conventions).
  final _namedArgumentTemp = js_ast.ScopedId('opts');

  /// The list of output module items, in the order they need to be emitted in.
  final _moduleItems = <js_ast.ModuleItem>[];

  /// The entrypoint method of a dynamic module, if any.
  Procedure? _dynamicEntrypoint;

  final Class _jsArrayClass;
  final Class _privateSymbolClass;
  final Class _linkedHashMapImplClass;
  final Class _identityHashMapImplClass;
  final Class _linkedHashSetClass;
  final Class _linkedHashSetImplClass;
  final Class _identityHashSetImplClass;
  // Helpers for async function lowering
  final Member _asyncStartMember;
  final Member _asyncAwaitMember;
  final Member _asyncReturnMember;
  final Member _asyncRethrowMember;
  final Member _asyncMakeCompleterMember;
  final Member _asyncWrapJsFunctionMember;
  // Helpers for sync* function lowering
  final Member _syncStarMakeIterableMember;
  final Member _syncStarIteratorCurrentMember;
  final Member _syncStarIteratorDatumMember;
  final Member _syncStarIteratorYieldStarMember;
  // Helpers for async* function lowering
  final Member _asyncStarHelperMember;
  final Member _asyncStreamOfControllerMember;
  final Member _asyncMakeAsyncStarStreamControllerMember;
  final Member _asyncIterationMarkerYieldSingleMember;
  final Member _asyncIterationMarkerYieldStarMember;
  final Class _asyncStreamIteratorClass;

  final Procedure _assertInteropMethod;

  // The direct `_as` methods for primitive types.
  final Member _asBool;
  final Member _asDouble;
  final Member _asInt;
  final Member _asNum;
  final Member _asObject;
  final Member _asString;
  final Member _asBoolQ;
  final Member _asDoubleQ;
  final Member _asIntQ;
  final Member _asNumQ;
  final Member _asStringQ;

  final DevCompilerConstants _constants;

  final NullableInference _nullableInference;

  bool _moduleEmitted = false;

  /// Supports verbose logging with a timer.
  Ticker? _ticker;

  /// The hot reload generation for the current compile.
  ///
  /// Initial compiles are treated as generation 0.
  int _hotReloadGeneration;

  /// The hot reload metadata for the current compile.
  ///
  /// Will be `null` on the initial compile.
  final HotReloadLibraryMetadata? _hotReloadLibraryMetadata;

  /// Whether the library is being compiled for a hot reload.
  bool get _compileForHotReload => _hotReloadGeneration > 0;

  factory LibraryCompiler(
    Component component,
    ClassHierarchy hierarchy,
    Options options,
    Map<Library, Component> importToSummary,
    Map<Component, String> summaryToModule, {
    CoreTypes? coreTypes,
    Ticker? ticker,
    required SymbolData symbolData,
    HotReloadLibraryMetadata? hotReloadLibraryMetadata,
    int? hotReloadGeneration,
  }) {
    coreTypes ??= CoreTypes(component);
    var types = TypeEnvironment(coreTypes, hierarchy);
    var constants = DevCompilerConstants();
    var nativeTypes = NativeTypeSet(coreTypes, constants, component);
    var jsTypeRep = JSTypeRep(types, hierarchy);
    var staticTypeContext = StatefulStaticTypeContext.stacked(types);
    return LibraryCompiler._(
      ticker,
      coreTypes,
      coreTypes.index,
      nativeTypes,
      constants,
      types,
      hierarchy,
      jsTypeRep,
      NullableInference(jsTypeRep, staticTypeContext, options: options),
      staticTypeContext,
      options,
      importToSummary,
      summaryToModule,
      symbolData,
      hotReloadLibraryMetadata,
      hotReloadGeneration ?? 0,
    );
  }

  LibraryCompiler._(
    this._ticker,
    this._coreTypes,
    LibraryIndex sdk,
    this._extensionTypes,
    this._constants,
    this._types,
    this._hierarchy,
    this._typeRep,
    this._nullableInference,
    this._staticTypeContext,
    this._options,
    this._importToSummary,
    this._summaryToModule,
    this._symbolData,
    this._hotReloadLibraryMetadata,
    this._hotReloadGeneration,
  ) : _jsArrayClass = sdk.getClass('dart:_interceptors', 'JSArray'),
      _privateSymbolClass = sdk.getClass('dart:_js_helper', 'PrivateSymbol'),
      _linkedHashMapImplClass = sdk.getClass('dart:_js_helper', 'LinkedMap'),
      _identityHashMapImplClass = sdk.getClass(
        'dart:_js_helper',
        'IdentityMap',
      ),
      _linkedHashSetClass = sdk.getClass('dart:collection', 'LinkedHashSet'),
      _linkedHashSetImplClass = sdk.getClass('dart:_js_helper', 'LinkedSet'),
      _identityHashSetImplClass = sdk.getClass(
        'dart:_js_helper',
        'IdentitySet',
      ),
      _assertInteropMethod = sdk.getTopLevelProcedure(
        'dart:_runtime',
        'assertInterop',
      ),
      _asyncStartMember = sdk.getTopLevelMember(
        'dart:async',
        '_asyncStartSync',
      ),
      _asyncAwaitMember = sdk.getTopLevelMember('dart:async', '_asyncAwait'),
      _asyncReturnMember = sdk.getTopLevelMember('dart:async', '_asyncReturn'),
      _asyncRethrowMember = sdk.getTopLevelMember(
        'dart:async',
        '_asyncRethrow',
      ),
      _asyncMakeCompleterMember = sdk.getTopLevelMember(
        'dart:async',
        '_makeAsyncAwaitCompleter',
      ),
      _asyncWrapJsFunctionMember = sdk.getTopLevelMember(
        'dart:async',
        '_wrapJsFunctionForAsync',
      ),
      _syncStarMakeIterableMember = sdk.getTopLevelMember(
        'dart:async',
        '_makeSyncStarIterable',
      ),
      _syncStarIteratorCurrentMember = sdk.getMember(
        'dart:async',
        '_SyncStarIterator',
        '_current',
      ),
      _syncStarIteratorDatumMember = sdk.getMember(
        'dart:async',
        '_SyncStarIterator',
        '_datum',
      ),
      _syncStarIteratorYieldStarMember = sdk.getMember(
        'dart:async',
        '_SyncStarIterator',
        '_yieldStar',
      ),
      _asyncStarHelperMember = sdk.getTopLevelMember(
        'dart:async',
        '_asyncStarHelper',
      ),
      _asyncStreamOfControllerMember = sdk.getTopLevelMember(
        'dart:async',
        '_streamOfController',
      ),
      _asyncMakeAsyncStarStreamControllerMember = sdk.getTopLevelMember(
        'dart:async',
        '_makeAsyncStarStreamController',
      ),
      _asyncIterationMarkerYieldSingleMember = sdk.getMember(
        'dart:async',
        '_IterationMarker',
        'yieldSingle',
      ),
      _asyncIterationMarkerYieldStarMember = sdk.getMember(
        'dart:async',
        '_IterationMarker',
        'yieldStar',
      ),
      _asyncStreamIteratorClass = sdk.getClass('dart:async', 'StreamIterator'),
      _futureOrNormalizer = FutureOrNormalizer(_coreTypes),
      _typeRecipeGenerator = TypeRecipeGenerator(_coreTypes, _hierarchy),
      _extensionIndex = ExtensionIndex(
        _coreTypes,
        _staticTypeContext.typeEnvironment,
      ),
      _inlineTester = BasicInlineTester(_constants),
      _runtimeLibrary = sdk.getLibrary('dart:_runtime'),
      _rtiLibrary = sdk.getLibrary('dart:_rti'),
      _rtiClass = sdk.getClass('dart:_rti', 'Rti'),
      _asBool = sdk.getTopLevelMember('dart:_rti', '_asBool'),
      _asDouble = sdk.getTopLevelMember('dart:_rti', '_asDouble'),
      _asInt = sdk.getTopLevelMember('dart:_rti', '_asInt'),
      _asNum = sdk.getTopLevelMember('dart:_rti', '_asNum'),
      _asObject = sdk.getTopLevelMember('dart:_rti', '_asObject'),
      _asString = sdk.getTopLevelMember('dart:_rti', '_asString'),
      _asBoolQ = sdk.getTopLevelMember('dart:_rti', '_asBoolQ'),
      _asDoubleQ = sdk.getTopLevelMember('dart:_rti', '_asDoubleQ'),
      _asIntQ = sdk.getTopLevelMember('dart:_rti', '_asIntQ'),
      _asNumQ = sdk.getTopLevelMember('dart:_rti', '_asNumQ'),
      _asStringQ = sdk.getTopLevelMember('dart:_rti', '_asStringQ');

  /// The library for dart:core in the SDK.
  Library get _coreLibrary => _coreTypes.coreLibrary;

  /// The type used for private Dart [Symbol]s.
  InterfaceType get _privateSymbolType =>
      _coreTypes.nonNullableRawType(_privateSymbolClass);

  /// The type used for public Dart [Symbol]s.
  InterfaceType get _internalSymbolType =>
      _coreTypes.nonNullableRawType(_coreTypes.internalSymbolClass);

  final FutureOrNormalizer _futureOrNormalizer;

  bool _inFunctionExpression = false;

  /// Returns whether or not [uri] can be hot reloaded.
  ///
  /// These packages are not updated during the runtime of a standard program,
  /// allowing us to make the following optimizations:
  ///  - methods, getters, and setters are emitted without additional levels
  ///    of indirection
  ///  - fields are emitted without additional lazy initialization checks.
  bool _isNonHotReloadableResource(Uri uri) {
    return (uri.isScheme('dart')) ||
        (uri.isScheme('package') &&
            _options.nonHotReloadablePackages.contains(uri.pathSegments[0]));
  }

  /// Module can be emitted only once, and the compiler can be reused after
  /// only in incremental mode, for expression compilation only.
  js_ast.Program emitLibrary(Library library) {
    if (_moduleEmitted) {
      throw StateError('Can only call emitLibrary once.');
    }
    _ticker?.logMs('Emitting library');
    _currentLibrary = library;
    _component = library.enclosingComponent!;
    _isBuildingSdk = library.importUri.scheme == 'dart';

    // For runtime performance reasons, we only containerize SDK symbols in web
    // libraries. Otherwise, we use a 600-member cutoff before a module is
    // containerized. This is somewhat arbitrary but works promisingly for the
    // SDK and Flutter Web.
    if (!_isBuildingSdk) {
      // The number of DDC top-level symbols scales with the number of
      // non-static class members across an entire module.
      var uniqueNames = HashSet<String>();
      library.classes.forEach((Class c) {
        c.members.forEach((m) {
          var isStatic = m is Field
              ? m.isStatic
              : (m is Procedure ? m.isStatic : false);
          if (isStatic) return;
          var name = js_ast.toJSIdentifier(
            m.name.text.replaceAll(js_ast.invalidCharInIdentifier, '_'),
          );
          uniqueNames.add(name);
        });
      });
      _containerizeSymbols = uniqueNames.length > 600;
    }
    var items = _startLibrary(library);
    _nullableInference.allowNotNullDeclarations = _isBuildingSdk;
    _typeTable = TypeTable('T', _runtimeCall);
    // Insert a circular reference so neither the constant table or its cache
    // are optimized away by V8. Required for expression evaluation.
    var constTableDeclaration = js
        .statement('const # = Object.create({# : () => (#, #)});', [
          _constTable,
          js_ast.LiteralString('_'),
          _constTableCache.containerId,
          _constTable,
        ]);
    _moduleItems.add(constTableDeclaration);

    // Record a safe index after the declaration of type generators and
    // top-level symbols but before the declaration of any functions.
    // Various preliminary data structures must be inserted here prior before
    // referenced by the rest of the module.
    var safeDeclarationIndex = _moduleItems.length;
    _constTableInsertionIndex = safeDeclarationIndex;

    // Add implicit dart:core dependency so it is first.
    _emitLibraryName(_coreTypes.coreLibrary);
    _ticker?.logMs('Added table declarations');

    // Visit the library and emit its code.
    //
    // NOTE: classes are not necessarily emitted in this order.
    // Order will be changed as needed so the resulting code can execute.
    // This is done by forward declaring items.
    _emitLibrary(library);
    _ticker?.logMs('Emitted library: ${library.importUri}');

    // Emit hoisted assert strings
    _moduleItems.insertAll(safeDeclarationIndex, _uriContainer.emit());

    _moduleItems.insertAll(safeDeclarationIndex, _constTableCache.emit());

    if (_constLazyAccessors.isNotEmpty) {
      var constTableBody = _runtimeStatement('defineLazy(#, { # })', [
        _constTable,
        _constLazyAccessors,
      ]);
      _moduleItems.insert(_constTableInsertionIndex, constTableBody);
      _constLazyAccessors.clear();
    }

    // Register the local const cache for this module so it can be cleared on a
    // hot restart.
    if (_constTableCache.isNotEmpty) {
      _moduleItems.add(
        _runtimeCall('moduleConstCaches.set(#, #)', [
          js_ast.string(_options.moduleName),
          _constTableCache.containerId,
        ]).toStatement(),
      );
    }
    _ticker?.logMs('Added table caches');
    // Add all type hierarchy rules for the interface types used in this module.
    // TODO(nshahan) This is likely more information than the application
    // really uses. It could be reduced to only the types of values that are
    // potentially "live" in the module which includes the types of all the
    // constructor invocations and the types of the constructors torn off
    // (potentially constructed) within the module. The current constructor
    // tearoff lowering does make this harder to know since all constructors
    // appeared to be invoked in the body of the method created by the
    // lowering. For now we over estimate and simply use all the interface
    // types introduced by all the classes defined in the module.
    for (var cls in library.classes) {
      var type = cls.getThisType(_coreTypes, Nullability.nonNullable);
      _typeRecipeGenerator.addLiveTypeAncestries(type);
    }
    var universeClass = _rtiLibrary.classes.firstWhere(
      (cls) => cls.name == '_Universe',
    );

    // Emits either an 'addRules', 'addOrUpdateRules', or 'deleteRules'
    // statement for a JSON-serializable [rules] made of RTI type rules.
    //
    // 'addRules' overrides existing state. Calling this function multiple
    // times is safe for types whose hierarchies can be exhaustively
    // discovered at compile-time, which is true for all types that aren't
    // 'LegacyJavaScriptObject'.
    //
    // TODO: The above assumption may not hold if a class's hierarchy
    // changes after a hot reload. Outdated 'addRules' invocations (during
    // linking) may clobber updated type rules.
    js_ast.Statement emitRulesStatement(
      Object? rules, {
      required String rulesFunction,
    }) {
      var template = '#._Universe.#(#, JSON.parse(#))';
      var rulesExpr = js.call(template, [
        _emitLibraryName(_rtiLibrary),
        _emitMemberName(rulesFunction, memberClass: universeClass),
        _runtimeCall('typeUniverse'),
        js.string(jsonEncode(rules), "'"),
      ]);
      return rulesExpr.toStatement();
    }

    // We must emit type rules for every interface type encountered by DDC,
    // with several caveats:
    // 1) 'LegacyJavaScriptObject' has special treatment. Its hierarchy
    //    accumulates across libraries and must always be emitted in 'append'
    //    mode ('addOrUpdateRules') to avoid clobbering its previous state.
    // 2) We manually add rules for mutual subtype relationships between
    //    'LegacyJavaScriptObject' and all JavaScript interop classes. There is
    //    special redirecting rule logic in the dart:_rti library for interop
    //    types because otherwise they would duplicate a lot of supertype
    //    information.
    // 3) The RTI treats an empty type hierarchy as implicitly containing
    //    'Object'. We explicitly emit 'deleteRules' instructions in case
    //    a type hierarchy was deleted or edited to extend 'Object' after hot
    //    reload.
    var legacyJavaScriptObjectRecipe = _typeRecipeGenerator.interfaceTypeRecipe(
      _coreTypes.index.getClass('dart:_interceptors', 'LegacyJavaScriptObject'),
    );
    var legacyJavaScriptObjectRules = _typeRecipeGenerator
        .liveInterfaceTypeRules[legacyJavaScriptObjectRecipe];
    var typeRulesExceptLegacyJavaScriptObject =
        _typeRecipeGenerator.liveInterfaceTypeRules
          ..remove(legacyJavaScriptObjectRecipe);
    var typesThatOnlyExtendObject =
        Set.from(_typeRecipeGenerator.visitedInterfaceTypeRecipes)
          ..removeAll(typeRulesExceptLegacyJavaScriptObject.keys)
          ..remove(legacyJavaScriptObjectRecipe);
    var legacyJavaScriptObjectMutualSubtypingRules =
        _typeRecipeGenerator.updateLegacyJavaScriptObjectRules;

    if (typeRulesExceptLegacyJavaScriptObject.isNotEmpty) {
      _typeRuleLinks.add(
        emitRulesStatement(
          typeRulesExceptLegacyJavaScriptObject,
          rulesFunction: 'addRules',
        ),
      );
    }
    if (_compileForHotReload && typesThatOnlyExtendObject.isNotEmpty) {
      _typeRuleLinks.add(
        emitRulesStatement(
          typesThatOnlyExtendObject.toList(),
          rulesFunction: 'deleteRules',
        ),
      );
    }
    if (legacyJavaScriptObjectRules != null) {
      _typeRuleLinks.add(
        emitRulesStatement({
          legacyJavaScriptObjectRecipe: legacyJavaScriptObjectRules,
        }, rulesFunction: 'addOrUpdateRules'),
      );
    }
    if (legacyJavaScriptObjectMutualSubtypingRules.isNotEmpty) {
      _typeRuleLinks.add(
        emitRulesStatement(
          legacyJavaScriptObjectMutualSubtypingRules,
          rulesFunction: 'addOrUpdateRules',
        ),
      );
    }

    var jsInteropTypeRecipes = _typeRecipeGenerator.visitedJsInteropTypeRecipes;
    if (jsInteropTypeRecipes.isNotEmpty) {
      // Update the `LegacyJavaScriptObject` class with the type tags for all
      // interop types in this module. This is the quick path for simple type
      // tests that matches the rules encoded above.
      var legacyJavaScriptObjectClass = _coreTypes.index.getClass(
        'dart:_interceptors',
        'LegacyJavaScriptObject',
      );
      var legacyJavaScriptObjectClassRef = _emitClassRef(
        legacyJavaScriptObjectClass.getThisType(
          _coreTypes,
          Nullability.nonNullable,
        ),
      );
      var interopRecipesArray = js_ast.stringArray([
        _typeRecipeGenerator.interfaceTypeRecipe(legacyJavaScriptObjectClass),
        ...jsInteropTypeRecipes,
      ]);
      var jsInteropRules = _runtimeStatement('addRtiResources(#, #)', [
        legacyJavaScriptObjectClassRef,
        interopRecipesArray,
      ]);
      _typeRuleLinks.add(jsInteropRules);
    }

    // Annotates the type parameter variances for each interface.
    var typeVariances = _typeRecipeGenerator.variances;
    if (typeVariances.isNotEmpty) {
      var addTypeParameterVariancesTemplate = '#._Universe.#(#, JSON.parse(#))';
      var addTypeParameterVariancesStatement =
          js.call(addTypeParameterVariancesTemplate, [
            _emitLibraryName(_rtiLibrary),
            _emitMemberName(
              'addTypeParameterVariances',
              memberClass: universeClass,
            ),
            _runtimeCall('typeUniverse'),
            js.string(jsonEncode(typeVariances), "'"),
          ]).toStatement();
      _typeRuleLinks.add(addTypeParameterVariancesStatement);
    }

    // Certain RTIs must be emitted during RTI normalization. We cache these
    // eagerly with 'findType' (without normalization) to avoid infinite loops.
    // See normalization functions in: sdk/lib/_internal/js_shared/lib/rti.dart
    if (_isSdkInternalRuntime(_currentLibrary!)) {
      var prerequisiteRtiTypes = [_coreTypes.objectNullableRawType];
      prerequisiteRtiTypes.forEach((type) {
        var recipe = _typeRecipeGenerator
            .recipeInEnvironment(type, EmptyTypeEnvironment())
            .recipe;
        _typeRuleLinks.add(
          js.call('#.findType("$recipe")', [
            _emitLibraryName(_rtiLibrary),
          ]).toStatement(),
        );
      });
    }

    // Additional method used by the module system to link class hierarchies.
    _moduleItems.add(_emitLibraryLinkMethod(_currentLibrary!));
    _ticker?.logMs('Emitted library link method');

    // Attach the import Uri to the library object for use in error messages
    // and debugging.
    _moduleItems.add(
      js.statement('#[#] = #', [
        _emitLibraryName(library),
        _runtimeCall('libraryImportUri'),
        js.string('${library.importUri}'),
      ]),
    );

    // Visit directives (for exports)
    _emitExports(library);
    _ticker?.logMs('Emitted exports');

    // Declare imports and extension symbols
    _emitImportsAndExtensionSymbols(
      items,
      forceExtensionSymbols: allowedNativeTest(library.importUri),
    );
    _ticker?.logMs('Emitted imports and extension symbols');

    // Emit the hoisted type table cache variables
    items.addAll(_typeTable.dischargeBoundTypes());
    _ticker?.logMs('Emitted type table');

    var compiledLibrary = _finishLibrary(
      items,
      '${library.importUri}',
      _emitLibraryName(library),
    );
    _ticker?.logMs('Finished emitting module');

    // Mark as finished for incremental mode, so it is safe to
    // switch to the incremental mode for expression compilation.
    _moduleEmitted = true;
    return compiledLibrary;
  }

  /// Returns a method that will perform all class hierarchy operations for the
  /// classes defined in this module.
  ///
  /// At a high level this method performs the prototype stitching for all
  /// `class A extends B` relationships but in practice will also include the
  /// operations that implicitly depend on those relationships to be established
  /// so they can walk the prototype chain.
  js_ast.Statement _emitLibraryLinkMethod(Library library) {
    var libraryName = _emitLibraryName(library);
    var nameExpr = js_ast.PropertyAccess(
      libraryName,
      js.call('dartDevEmbedder.linkSymbol'),
    );
    var functionName = _emitScopedId('link__${_jsLibraryName(library)}');

    var parameters = const <js_ast.Parameter>[];
    var body = js_ast.Block([
      ..._classExtendsLinks,
      // The ordering of extensions member definition and mixin applications
      // is fragile but important for the correct functionality of the html and
      // friends libraries. All mixins should have extension members defined
      // before being applied. Mixin classes are handled here, regular mixins
      // are handled inside the mixin application closure.
      ..._mixinClassDefineExtensionMemberLinks,
      ..._mixinApplicationLinks,
      // Extension members defined and mixed in above will be discovered during
      // the prototype walk during these extension member definitions.
      ..._defineExtensionMemberLinks,
      ..._nativeExtensionLinks,
      ..._typeRuleLinks,
      // Enum extensions must be emitted after type hierarchies have stabilized.
      ..._enumExtensions,
    ]);
    var function = js_ast.NamedFunction(
      functionName,
      js_ast.Fun(parameters, body),
    );
    return js.statement('# = #', [nameExpr, function]);
  }

  /// Choose a canonical name from the [library] element.
  String _jsLibraryName(Library library) {
    return libraryUriToJsIdentifier(library.importUri);
  }

  /// Choose a module-unique name from the [library] element.
  ///
  /// Returns null if no alias exists or there are multiple output paths
  /// (e.g., when compiling the Dart SDK).
  ///
  /// This never uses the library's name (the identifier in the `library`
  /// declaration) as it doesn't have any meaningful rules enforced.
  String? _jsLibraryAlias(Library library) {
    var uri = library.importUri.normalizePath();
    if (uri.isScheme('dart')) return null;

    Iterable<String> segments;
    if (uri.isScheme('package')) {
      // Strip the package name.
      segments = uri.pathSegments.skip(1);
    } else {
      segments = uri.pathSegments;
    }

    var qualifiedPath = js_ast.pathToJSIdentifier(
      p.withoutExtension(segments.join('/')),
    );
    return qualifiedPath == _jsLibraryName(library) ? null : qualifiedPath;
  }

  /// Debugger friendly name for a Dart [library].
  String _jsLibraryDebuggerName(Library library) => '${library.importUri}';

  /// True when [library] is the sdk internal library 'dart:_internal'.
  bool _isDartInternal(Library library) => _isDartLibrary(library, '_internal');

  /// True when [library] is the sdk internal library 'dart:_js_helper'.
  bool _isDartJsHelper(Library library) =>
      _isDartLibrary(library, '_js_helper');

  /// True when [library] is the sdk internal library 'dart:_internal'.
  bool _isDartForeignHelper(Library library) =>
      _isDartLibrary(library, '_foreign_helper');

  /// True when [library] is the sdk library 'dart:js_util'.
  bool _isDartJsUtil(Library library) => _isDartLibrary(library, 'js_util');

  /// Returns true if [library] is identified by [name].
  bool _isDartLibrary(Library library, String name) {
    var importUri = library.importUri;
    return importUri.isScheme('dart') && importUri.path == name;
  }

  /// Returns true if the library [l] is "dart:_runtime".
  bool _isSdkInternalRuntime(Library l) {
    return isSdkInternalRuntimeUri(l.importUri);
  }

  /// Gets the module import URI that contains [library].
  String _libraryToModule(Library library, {bool throwIfNotFound = true}) {
    if (library.importUri.isScheme('dart')) {
      // TODO(jmesserly): we need to split out HTML.
      return js_ast.dartSdkModule;
    }
    var summary = _importToSummary[library];
    if (summary == null) {
      if (throwIfNotFound) {
        throw StateError('Could not find summary for library "$library".');
      }
      return '';
    }
    var moduleName = _summaryToModule[summary];
    if (moduleName == null) {
      if (throwIfNotFound) {
        throw StateError(
          'Could not find module name for library "$library" '
          'from component "$summary".',
        );
      }
      return '';
    }
    return moduleName;
  }

  void _emitLibrary(Library library) {
    _staticTypeContext.enterLibrary(_currentLibrary!);

    if (_isBuildingSdk) {
      _containerizeSymbols = _isWebLibrary(library.importUri);
    }

    if (_isSdkInternalRuntime(library)) {
      // Add embedded globals.
      _moduleItems.add(
        _runtimeCall('typeUniverse = #', [
          js_ast.createRtiUniverse(),
        ]).toStatement(),
      );
      // `dart:_runtime` uses a different order for bootstrapping.
      //
      // Functions are first because we use them to associate type info
      // (such as `dart.fn`), then classes/typedefs, then fields
      // (which instantiate classes).
      //
      // For other libraries, we start with classes/types, because functions
      // often use classes/types from the library in their signature.
      //
      // TODO(jmesserly): we can merge these once we change signatures to be
      // lazily associated at the tear-off point for top-level functions.
      _emitLibraryMembers(library);
      library.classes.forEach(_emitClass);
    } else {
      library.classes.forEach(_emitClass);
      _emitLibraryMembers(library);
    }
    // Creating a function and setting the library object as the prototype
    // serves as a signal to V8 that the members of the library should get
    // optimized for fast lookup.
    // Do not remove without testing for performance regressions.
    _moduleItems.add(
      js.statement('(function() {}).prototype = #', [
        _libraries[_currentLibrary!],
      ]),
    );
    _staticTypeContext.leaveLibrary(_currentLibrary!);
  }

  void _emitExports(Library library) {
    library.additionalExports.forEach(_emitExport);
  }

  void _emitExport(Reference export) {
    var library = _currentLibrary!;

    // We only need to export main as it is the only method part of the
    // publicly exposed JS API for a library.

    var node = export.node;
    if (node is Procedure && node.name.text == 'main') {
      // Don't allow redefining names from this library.
      var name = _emitTopLevelName(node);
      _moduleItems.add(
        js.statement('#.# = #;', [
          _emitLibraryName(library),
          name.selector,
          name,
        ]),
      );
    }
  }

  /// Called to emit class declarations.
  ///
  /// Class hierarchy links are collected but not emitted as part of the
  /// declaration. Those operations will be contained in the link method for the
  /// library.
  void _emitClass(Class c) {
    // Avoid attempting to compile classes we reach through emitting class
    // extends supertypes when they are not members of the library being
    // compiled.
    // TODO(nshahan): Once `_declareBeforeUse` is removed this escape hatch will
    // no longer be necessary.
    if (c.enclosingLibrary != _currentLibrary) return;
    var savedClass = _currentClass;
    var savedLibrary = _currentLibrary;
    var savedUri = _currentUri;
    _currentClass = c;
    _currentLibrary = c.enclosingLibrary;
    _currentUri = c.fileUri;
    var savedTypeEnvironment = _currentTypeEnvironment;
    // When compiling the type heritage of the class we can't reference an rti
    // object attached to an instance. Instead we construct a type environment
    // manually when needed. Later we use the rti attached to an instance for
    // a simpler representation within instance members of the class.
    _currentTypeEnvironment = ClassTypeEnvironment(c.typeParameters);

    // Store identifiers for a mixin application's passed in superclass.
    // (see [_emitMixinStatement]).
    if (c.isMixinDeclaration && !c.isMixinClass) {
      _mixinSuperclassCache.putIfAbsent(
        c,
        () => _emitScopedId(getLocalClassName(c.superclass!)),
      );
    }

    // Mixins are unrolled in _defineClass.
    if (!c.isAnonymousMixin) {
      // If this class is annotated with `@JS`, then we only need to emit the
      // non-external factories and static members.
      if (!hasJSInteropAnnotation(c)) {
        _moduleItems.add(_emitClassDeclaration(c));
      } else {
        var interopClassDef = _emitJSInteropClassNonExternalMembers(c);
        if (interopClassDef != null) _moduleItems.add(interopClassDef);
      }
    }

    // The const table depends on dart.defineLazy, so emit it after the SDK.
    if (_isSdkInternalRuntime(_currentLibrary!)) {
      _constTableInsertionIndex = _moduleItems.length;
    }

    _currentClass = savedClass;
    _currentLibrary = savedLibrary;
    _currentUri = savedUri;
    _currentTypeEnvironment = savedTypeEnvironment;
  }

  static js_ast.Identifier _emitIdentifier(String name) =>
      js_ast.Identifier(js_ast.toJSIdentifier(name));

  static js_ast.ScopedId _emitScopedId(
    String name, {
    bool needsCapture = false,
  }) =>
      js_ast.ScopedId(js_ast.toJSIdentifier(name), needsCapture: needsCapture);

  js_ast.Statement _emitClassDeclaration(Class c) {
    var className = _emitTopLevelNameNoExternalInterop(c);
    var savedClassProperties = _classProperties;
    _classProperties = ClassPropertyModel.build(
      _types,
      _extensionTypes,
      _virtualFields,
      c,
    );

    var body = <js_ast.Statement>[];

    // ClassPropertyModel.build introduces symbols for virtual field accessors.
    _classProperties!.virtualFields.forEach((field, virtualField) {
      // TODO(vsm): Clean up this logic.
      //
      // Typically, [emitClassPrivateNameSymbol] creates a new symbol.  If it
      // is called multiple times, that symbol is cached.  If the former,
      // assign directly to [virtualField].  If the latter, copy the old
      // variable to [virtualField].
      var symbol = _emitClassPrivateNameSymbol(
        c.enclosingLibrary,
        getLocalClassName(c),
        field,
        virtualField,
      );
      if (symbol != virtualField) {
        _addSymbol(virtualField, _getSymbolValue(symbol));
        if (!_containerizeSymbols) {
          body.add(js.statement('const # = #;', [virtualField, symbol]));
        }
      }
    });

    var jsCtors = _defineConstructors(c, className);
    var jsProperties = _emitClassProperties(c);
    var jsStaticMethodTypeTags = <js_ast.Statement>[];
    for (var member in c.procedures) {
      // TODO(#57049): We tag all static members because we don't know if
      // they've been changed after a hot reload. This won't be necessary if we
      // can tag them during the delta diff phase.
      if (member.isStatic && _reifyTearoff(member) && !member.isExternal) {
        var propertyAccessor = _emitStaticTarget(member);
        var result = js.call('#.#', [
          propertyAccessor.receiver,
          propertyAccessor.selector,
        ]);
        // We only need to tag static functions that are torn off at
        // compile-time. We attach these at late so tearoffs have access to
        // their types.
        var reifiedType = member.function.computeThisFunctionType(
          Nullability.nonNullable,
        );
        jsStaticMethodTypeTags.add(
          _emitFunctionTagged(result, reifiedType, asLazy: true).toStatement(),
        );
      }
    }

    _emitSuperHelperSymbols(body);

    // Emit the class, e.g. `core.Object = class Object { ... }`
    _defineClass(c, className, jsProperties, body);
    body.addAll(jsCtors);
    body.addAll(jsStaticMethodTypeTags);

    // Emit things that come after the ES6 `class ... { ... }`.

    /// Collects all implemented types in the ancestry of [cls].
    Iterable<Supertype> transitiveImplementedTypes(Class cls) {
      var allImplementedTypes = <Supertype>{};
      var toVisit = ListQueue<Supertype>()..addAll(cls.implementedTypes);
      if (cls.isMixinApplication) {
        // Implemented types can come through the immediate mixin so we seed
        // the search with it as well.
        var mixedInType = cls.mixedInType;
        if (mixedInType != null) toVisit.add(mixedInType);
      }
      while (toVisit.isNotEmpty) {
        var supertype = toVisit.removeFirst();
        var superclass = supertype.classNode;
        if (allImplementedTypes.contains(supertype) ||
            superclass == _coreTypes.objectClass) {
          continue;
        }
        toVisit.addAll(superclass.supers);
        // Skip encoding the synthetic classes in the type rules because they
        // will never be instantiated or appear in type tests.
        if (superclass.isAnonymousMixin) continue;
        allImplementedTypes.add(supertype);
      }
      return allImplementedTypes;
    }

    // Tag all classes with the resources needed by the dart:_rti library.
    var name = _typeRecipeGenerator.interfaceTypeRecipe(c);
    var implementedRecipes = [
      name,
      for (var type in transitiveImplementedTypes(c))
        _typeRecipeGenerator.interfaceTypeRecipe(type.classNode),
    ];
    body.add(
      _runtimeStatement('addRtiResources(#, #)', [
        className,
        js_ast.stringArray(implementedRecipes),
      ]),
    );
    _emitClassSignature(c, className, body);
    _initExtensionSymbols(c);
    if (c.isMixinClass || c.isLegacyMixinEligible(_coreTypes)) {
      _defineExtensionMembers(className, _mixinClassDefineExtensionMemberLinks);
    } else if (!c.isMixinDeclaration) {
      _defineExtensionMembers(className, _defineExtensionMemberLinks);
    }

    var typeFormals = c.typeParameters;
    if (typeFormals.isNotEmpty) {
      var genericClassStmts = _defineGenericClass(
        typeFormals,
        js_ast.Statement.from(body),
      );
      body = [...genericClassStmts];
    }

    if (c == _coreTypes.objectClass) {
      // Avoid polluting the native JavaScript Object prototype with the members
      // of the Dart Core Object class.
      // Instead, just assign the identity equals method.
      _nativeExtensionLinks.add(_runtimeStatement('_installIdentityEquals()'));
    } else {
      for (var peer in _extensionTypes.getNativePeers(c)) {
        _registerExtensionType(c, peer, body);
      }
    }
    _classProperties = savedClassProperties;
    return js_ast.Statement.from(body);
  }

  /// Emits a class declaration for the JS interop class [c] for any
  /// non-external factories or static members.
  ///
  /// If [c] is not an interop class or does not contain non-external factories
  /// or static members, returns null.
  js_ast.Statement? _emitJSInteropClassNonExternalMembers(Class c) {
    if (!hasJSInteropAnnotation(c)) return null;
    var className = _emitTopLevelNameNoExternalInterop(c);

    // Non-external procedures and statics are still emitted
    var nonExternalProperties = <js_ast.Property>[];
    // Add factories and static methods.
    for (var procedure in c.procedures) {
      if (procedure.isExternal) continue;
      // Don't emit tear-offs for @staticInterop members as they're disallowed.
      if (_isStaticInteropTearOff(procedure)) continue;
      if (procedure.isFactory && !procedure.isRedirectingFactory) {
        // Skip redirecting factories (they've already been resolved).
        var factory = _emitFactoryConstructor(procedure);
        if (factory != null) nonExternalProperties.add(factory);
      } else if (procedure.isStatic) {
        var staticMethod = _emitMethodDeclaration(procedure);
        if (staticMethod != null) nonExternalProperties.add(staticMethod);
      }
    }

    // Add static fields and setters.
    var staticFields = c.fields
        .where((f) => f.isStatic && !f.isExternal)
        .toList();
    var staticFieldNames = Set.of(staticFields.map((f) => f.name));
    var staticSetters = c.procedures.where(
      (p) => p.isStatic && p.isAccessor && staticFieldNames.contains(p.name),
    );
    var members = [...staticFields, ...staticSetters];
    if (members.isNotEmpty) {
      nonExternalProperties.addAll(
        _emitLazyMembers(
          _emitTopLevelNameNoExternalInterop(c),
          members,
          (n) => _emitStaticMemberName(n.name.text),
        ),
      );
    }

    // Avoid unnecessary code emission if there are no members we care about.
    if (nonExternalProperties.isNotEmpty) {
      // Note that this class has no heritage. This class should never be used
      // as a type. It's merely a placeholder for static members.
      var body = _emitClassStatement(c, className, null, nonExternalProperties);
      var typeFormals = c.typeParameters;
      if (typeFormals.isNotEmpty) {
        var genericClassStmts = _defineGenericClass(
          typeFormals,
          js_ast.Statement.from(body),
        );
        body = genericClassStmts;
      }
      return js_ast.Statement.from(body);
    }
    return null;
  }

  /// Emits a generic class with additional initialization logic.
  List<js_ast.Statement> _defineGenericClass(
    List<TypeParameter> formals,
    js_ast.Statement body,
  ) {
    assert(formals.isNotEmpty);
    return [..._typeTable.dischargeFreeTypes(formals), body];
  }

  List<js_ast.Statement> _emitClassStatement(
    Class c,
    js_ast.Expression className,
    js_ast.Expression? heritage,
    List<js_ast.Property> properties,
  ) {
    var localClassName = getLocalClassName(c);
    var classIdentifier = _emitScopedId(localClassName);
    var classDefIdentifier = _emitScopedId('_$localClassName');
    // In order to ensure that 'super' binds to the correct target across hot
    // reloads, we rebind its pre-assigned class definition's prototype during
    // link phase (alongside the embedder-resolved class definition's).
    var referencesSuperKeyword = hasSuper(c);
    if (_options.emitDebugSymbols) classIdentifiers[c] = classIdentifier;
    if (heritage != null) {
      if (referencesSuperKeyword) {
        _classExtendsLinks.add(
          _runtimeStatement('classExtends(#, #)', [
            classDefIdentifier,
            heritage,
          ]),
        );
      }
      _classExtendsLinks.add(
        _runtimeStatement('classExtends(#, #)', [className, heritage]),
      );
    }
    var classExpr = js_ast.ClassExpression(classIdentifier, null, properties);
    var libraryExpr = (className as js_ast.PropertyAccess).receiver;
    var propertyExpr = className.selector;
    return referencesSuperKeyword
        ? [
            js.statement('let # = #;', [classDefIdentifier, classExpr]),
            _runtimeStatement('declareClass(#, #, #)', [
              libraryExpr,
              propertyExpr,
              classDefIdentifier,
            ]),
          ]
        : [
            _runtimeStatement('declareClass(#, #, #)', [
              libraryExpr,
              propertyExpr,
              classExpr,
            ]),
          ];
  }

  /// Like [_emitClassStatement] but emits a Dart 2.1 mixin represented by
  /// [c].
  ///
  /// Mixins work similar to normal classes, but their instance methods close
  /// over the actual superclass. Given a Dart class like:
  ///
  ///     mixin M on C {
  ///       foo() => super.foo() + 42;
  ///     }
  ///
  /// We generate a JS class like this:
  ///
  ///     lib.M = class M extends core.Object {}
  ///     lib.M[dart.mixinOn] = (C) => class M extends C {
  ///       foo() {
  ///         return super.foo() + 42;
  ///       }
  ///     };
  ///
  /// The special `dart.mixinOn` symbolized property is used by the runtime
  /// helper `dart.applyMixin`. The helper calls the function with the actual
  /// base class, and then copies the resulting members to the destination
  /// class.
  ///
  /// In the long run we may be able to improve this so we do not have the
  /// unnecessary class, but for now, this lets us get the right semantics with
  /// minimal compiler and runtime changes.
  void _emitMixinStatement(
    Class c,
    js_ast.Expression className,
    js_ast.Expression heritage,
    List<js_ast.Property> properties,
    List<js_ast.Statement> body,
  ) {
    var staticProperties = properties.where((m) => m.isStatic).toList();
    var instanceProperties = properties.where((m) => !m.isStatic).toList();

    body.addAll(_emitClassStatement(c, className, heritage, staticProperties));
    var superclassId = _mixinSuperclassCache[c]!;
    var classId = className is js_ast.Identifier
        ? className
        : _emitScopedId(getLocalClassName(c));

    var mixinMemberClass = js_ast.ClassExpression(
      classId,
      superclassId,
      instanceProperties,
    );

    js_ast.Node arrowFnBody = mixinMemberClass;
    var extensionInit = <js_ast.Statement>[];
    // The extension members need to be defined here when the class is created
    // inside the `mixinOn` closure. The prototype chain is connected in this
    // closure as well so it is safe to perform this operation here instead of
    // the link method.
    _defineExtensionMembers(classId, extensionInit);
    if (extensionInit.isNotEmpty) {
      extensionInit.insert(0, mixinMemberClass.toStatement());
      extensionInit.add(classId.toReturn());
      arrowFnBody = js_ast.Block(extensionInit);
    }

    body.add(
      js.statement('#[#] = #', [
        className,
        _runtimeCall('mixinOn'),
        js_ast.ArrowFun([superclassId], arrowFnBody),
      ]),
    );
  }

  /// Emits code required to represent [c] as a series of statements in [body].
  ///
  /// [properties] holds methods, fields, or properties in [c].
  void _defineClass(
    Class c,
    js_ast.Expression className,
    List<js_ast.Property> properties,
    List<js_ast.Statement> body,
  ) {
    if (c == _coreTypes.objectClass) {
      body.addAll(_emitClassStatement(c, className, null, properties));
      return;
    }

    js_ast.Expression emitClassRef(
      InterfaceType t, {
      bool resolvedFromEmbedder = false,
    }) {
      return _emitJSInterop(t.classNode) ??
          _emitClassRef(t, resolvedFromEmbedder: resolvedFromEmbedder);
    }

    // Find the real (user declared) superclass and the list of mixins.
    // We'll use this to unroll the intermediate classes.
    //
    // TODO(jmesserly): consider using Kernel's mixin unrolling.
    var superclass = _superClassAsWritten(c);
    var supertype = identical(c.superclass, superclass)
        ? c.supertype!.asInterfaceType
        : _hierarchy.getClassAsInstanceOf(c, superclass)!.asInterfaceType;
    // All mixins (real and anonymous) classes applied to c.
    var mixinApplications = [
      if (c.mixedInClass != null) c.mixedInClass,
      for (
        var sc = c.superclass!;
        sc.isAnonymousMixin && sc.mixedInClass != null;
        sc = sc.superclass!
      )
        sc,
    ].reversed.toList();

    var hasUnnamedSuper = _hasUnnamedInheritedConstructor(superclass);

    void emitMixinConstructors(
      js_ast.Expression className,
      Class mixinSuperclass,
      Class mixinClass,
      InterfaceType mixin,
    ) {
      for (var ctor in mixinSuperclass.constructors) {
        var savedUri = _currentUri;
        _currentUri = ctor.enclosingClass.fileUri;

        var sharedParams = _emitParameters(ctor.function, isForwarding: true);
        var mixinConstructorParams = [
          if (_requiresRtiForInstantiation(mixinSuperclass)) _rtiParam,
          ...sharedParams,
        ];
        var superConstructorArgs = [
          if (_requiresRtiForInstantiation(ctor.enclosingClass))
            js_ast.LiteralNull(),
          ...sharedParams,
        ];

        js_ast.Statement? mixinCtor;
        if (_hasUnnamedConstructor(mixin.classNode)) {
          var mixinRti = _requiresRtiForInstantiation(mixin.classNode)
              ? js_ast.LiteralNull()
              : null;
          mixinCtor = js.statement('#.#.call(this, #);', [
            emitClassRef(mixin),
            _usesMixinNew(mixin.classNode)
                ? _runtimeCall('mixinNew')
                : _constructorName(''),
            [if (mixinRti != null) mixinRti],
          ]);
        }

        var name = ctor.name.text;
        var ctorBody = [
          if (mixinCtor != null) mixinCtor,
          if (name != '' || hasUnnamedSuper)
            _emitSuperConstructorCall(
              ctor,
              className,
              name,
              superConstructorArgs,
            ),
        ];
        // TODO(nshahan) Record the name for this constructor in memberNames.
        body.add(
          _addConstructorToClass(
            c,
            className,
            _constructorName(name),
            js_ast.Fun(mixinConstructorParams, js_ast.Block(ctorBody)),
          ),
        );
        _currentUri = savedUri;
      }
    }

    var savedTopLevelClass = _classEmittingExtends;
    _classEmittingExtends = c;

    // Unroll mixins.
    var baseClass = emitClassRef(supertype);
    // The SDK is never hot reloaded, so we can avoid the overhead of
    // resolving their classes through the embedder.
    var embedderResolvedBaseClass = emitClassRef(
      supertype,
      resolvedFromEmbedder: !_isBuildingSdk,
    );

    // TODO(jmesserly): we need to unroll kernel mixins because the synthetic
    // classes lack required synthetic members, such as constructors.
    //
    // Also, we need to generate one extra level of nesting for alias classes.
    for (var i = 0; i < mixinApplications.length; i++) {
      var m = mixinApplications[i]!;
      var mixinClass = m.isAnonymousMixin ? m.mixedInClass! : m;
      var mixinType = _hierarchy
          .getClassAsInstanceOf(c, mixinClass)!
          .asInterfaceType;
      var mixinId = _emitMixinId(m, m.isAnonymousMixin ? m : c);
      // Collect all forwarding stub members from anonymous mixins classes.
      // These can contain covariant parameter checks that need to be applied.
      var savedClassProperties = _classProperties;
      _classProperties = ClassPropertyModel.build(
        _types,
        _extensionTypes,
        _virtualFields,
        m,
      );
      var forwardingMembers = {
        for (var procedure in m.procedures)
          if (procedure.isForwardingStub && !procedure.isAbstract)
            procedure.name.text: procedure,
      };
      // Mixin applications can introduce their own reference to the type
      // parameters from the class being mixed in and their use can appear in
      // the forwarding stubs.
      var savedTypeEnvironment = _currentTypeEnvironment;
      if (m.typeParameters.isNotEmpty) {
        assert(_currentTypeEnvironment is ClassTypeEnvironment);
        _currentTypeEnvironment = ClassTypeEnvironment(m.typeParameters);
      }
      var forwardingMethodStubs = <js_ast.Method>[];
      for (var s in forwardingMembers.values) {
        // Members are marked as "forwarding stubs" when they require a type
        // check of the arguments before calling super. It is assumed here that
        // no getters will be marked as a "forwarding stub".
        assert(!s.isGetter);
        var stub = _emitMethodDeclaration(s);
        if (stub != null) forwardingMethodStubs.add(stub);
        // If there are getters matching the setters somewhere above in the
        // class hierarchy we must also generate a forwarding getter due to the
        // representation used in the compiled JavaScript.
        if (s.isSetter) {
          var getterWrapper = _emitSuperAccessorWrapper(s, const {}, const {});
          if (getterWrapper != null) forwardingMethodStubs.add(getterWrapper);
        }
      }
      _currentTypeEnvironment = savedTypeEnvironment;
      _classProperties = savedClassProperties;

      // Mixins need to be exposed in this library in case they are
      // referenced in a super getter.
      // TODO(markzipan): We originally bound mixin classes to a temporary as a
      // workaround for a now-resolved Chrome issue. However, a side effect of
      // this operation is that mixin IDs are renamed by the local visitor. We
      // can remove this hoisting after we give mixins unique names.
      body.add(
        js.statement('let # = #', [
          mixinId,
          _runtimeCall('declareClass(#, #, #)', [
            _emitLibraryName(_currentLibrary!),
            js.string(mixinId.name),
            js_ast.ClassExpression(
              _emitScopedId('${mixinId.name}\$'),
              null,
              forwardingMethodStubs,
            ),
          ]),
        ]),
      );

      _classExtendsLinks.add(
        _runtimeStatement('classExtends(#, #)', [
          mixinId,
          embedderResolvedBaseClass,
        ]),
      );
      emitMixinConstructors(mixinId, superclass, mixinClass, mixinType);
      hasUnnamedSuper = hasUnnamedSuper || _hasUnnamedConstructor(mixinClass);
      var mixinTargetLabel = js.string(fullyResolvedMixinClassLabel(m));
      // The SDK is never hot reloaded, so we can avoid the overhead of
      // resolving their classes through the embedder.
      _mixinApplicationLinks.add(
        _runtimeStatement('applyMixin(#, #, #)', [
          mixinId,
          emitClassRef(mixinType, resolvedFromEmbedder: !_isBuildingSdk),
          mixinTargetLabel,
        ]),
      );
      baseClass = mixinId;
      embedderResolvedBaseClass = mixinId;
    }

    if (c.isMixinDeclaration && !c.isMixinClass) {
      _emitMixinStatement(c, className, baseClass, properties, body);
    } else {
      body.addAll(
        _emitClassStatement(
          c,
          className,
          embedderResolvedBaseClass,
          properties,
        ),
      );
    }

    _classEmittingExtends = savedTopLevelClass;
  }

  /// Defines all constructors for this class as ES5 constructors.
  List<js_ast.Statement> _defineConstructors(
    Class c,
    js_ast.Expression className,
  ) {
    var body = <js_ast.Statement>[];
    if (c.isAnonymousMixin) {
      // We already handled this when we defined the class.
      return body;
    }

    void addConstructor(js_ast.LiteralString name, js_ast.Expression jsCtor) {
      body.add(_addConstructorToClass(c, className, name, jsCtor));
    }

    var fields = c.fields;
    for (var ctor in c.constructors) {
      if (ctor.isExternal) continue;
      var constructorName = _constructorName(ctor.name.text);
      memberNames[ctor] = constructorName.valueWithoutQuotes;
      addConstructor(
        constructorName,
        _emitConstructor(ctor, fields, className),
      );
    }

    // If classElement has only factory constructors, and it can be mixed in,
    // then we need to emit a special hidden default constructor for use by
    // mixins.
    if (_usesMixinNew(c)) {
      body.add(
        js.statement('(#[#] = function() { # }).prototype = #.prototype;', [
          className,
          _runtimeCall('mixinNew'),
          [_initializeFields(fields)],
          className,
        ]),
      );
    }

    return body;
  }

  void _emitDartSymbols(
    Iterable<js_ast.ScopedId> vars,
    List<js_ast.ModuleItem> body,
  ) {
    for (var id in vars) {
      body.add(js.statement('const # = Symbol(#)', [id, js.string(id.name)]));
    }
  }

  void _emitSuperHelperSymbols(List<js_ast.Statement> body) {
    _emitDartSymbols(
      _superHelpers.values.map((m) => m.name as js_ast.ScopedId),
      body,
    );
    _superHelpers.clear();
  }

  /// Ensure `dartx.` symbols we will use are present.
  void _initExtensionSymbols(Class c) {
    if (_extensionTypes.hasNativeSubtype(c) || c == _coreTypes.objectClass) {
      for (var m in c.procedures) {
        if (!m.isAbstract && !m.isStatic && !m.name.isPrivate) {
          _declareMemberName(m, useExtension: true);
        }
      }
    }
  }

  /// If a concrete class implements one of our extensions, we might need to
  /// add forwarders.
  void _defineExtensionMembers(
    js_ast.Expression className,
    List<js_ast.Statement> body,
  ) {
    void emitExtensions(String helperName, Iterable<String> extensions) {
      if (extensions.isEmpty) return;
      var names = extensions
          .map((e) => _propertyName(js_ast.memberNameForDartMember(e)))
          .toList();
      body.add(
        _runtimeStatement('#(#, #)', [
          helperName,
          className,
          js_ast.ArrayInitializer(names, multiline: names.length > 4),
        ]),
      );
    }

    var props = _classProperties!;
    emitExtensions('defineExtensionMethods', props.extensionMethods);
    emitExtensions('defineExtensionAccessors', props.extensionAccessors);
  }

  /// Emit the signature on the class recording the runtime type information
  void _emitClassSignature(
    Class c,
    js_ast.Expression className,
    List<js_ast.Statement> body,
  ) {
    var savedTypeEnvironment = _currentTypeEnvironment;
    _currentTypeEnvironment = RtiTypeEnvironment(
      _currentTypeEnvironment.classTypeParameters,
    );
    var savedClass = _classEmittingSignatures;
    _classEmittingSignatures = c;

    void emitSignature(String name, List<js_ast.Property> elements) {
      if (elements.isEmpty) return;

      js_ast.Statement setSignature;
      if (!name.startsWith('Static')) {
        var proto = c == _coreTypes.objectClass
            ? js.call('Object.create(null)')
            : _runtimeCall('get${name}s(#)', [
                _emitJSObjectGetPrototypeOf(
                  className,
                  fullyQualifiedName: true,
                ),
              ]);

        setSignature = _runtimeStatement('set${name}Signature(#, () => #)', [
          className,
          _emitJSObjectSetPrototypeOf(
            js_ast.ObjectInitializer(elements, multiline: elements.length > 1),
            proto,
            fullyQualifiedName: true,
          ),
        ]);
      } else {
        // TODO(40273) Only tagging with the names of static members until the
        // debugger consumes signature information from symbol files.
        setSignature = _runtimeStatement('set${name}Signature(#, () => #)', [
          className,
          js_ast.ArrayInitializer(elements.map((e) => e.name).toList()),
        ]);
      }

      body.add(setSignature);
    }

    js_ast.Expression emitClassFieldSignature(Field field, Class fromClass) {
      var fieldType = _typeFromClass(
        field.type,
        field.enclosingClass!,
        fromClass,
      ).extensionTypeErasure;
      var uri = fieldType is InterfaceType
          ? _cacheUri(
              _jsLibraryDebuggerName(fieldType.classNode.enclosingLibrary),
            )
          : null;
      var isConst = js.boolean(field.isConst);
      var isFinal = js.boolean(field.isFinal);
      var type = _emitType(fieldType);
      var typeResolver = js_ast.ArrowFun([_rtiParam], type);
      return uri == null
          ? js('{type: #, isConst: #, isFinal: #}', [
              typeResolver,
              isConst,
              isFinal,
            ])
          : js('{type: #, isConst: #, isFinal: #, libraryUri: #}', [
              typeResolver,
              isConst,
              isFinal,
              uri,
            ]);
    }

    var extMethods = _classProperties!.extensionMethods;
    var extAccessors = _classProperties!.extensionAccessors;
    var staticMethods = <js_ast.Property>[];
    var instanceMethods = <js_ast.Property>[];
    var instanceMethodsDefaultTypeArgs = <js_ast.Property>[];
    var methodsImmediateTarget = <js_ast.Property>[];
    var staticGetters = <js_ast.Property>[];
    var instanceGetters = <js_ast.Property>[];
    var staticSetters = <js_ast.Property>[];
    var instanceSetters = <js_ast.Property>[];
    List<js_ast.Property> getSignatureList(Procedure p) {
      // TODO(40273) Skip for all statics when the debugger consumes signature
      // information from symbol files.
      if (p.isStatic) {
        if (p.isGetter) {
          return staticGetters;
        } else if (p.isSetter) {
          return staticSetters;
        } else {
          return staticMethods;
        }
      } else {
        if (p.isGetter) {
          return instanceGetters;
        } else if (p.isSetter) {
          return instanceSetters;
        } else {
          return instanceMethods;
        }
      }
    }

    var classProcedures = c.procedures.where((p) => !p.isAbstract).toList();
    for (var member in classProcedures) {
      // Static getters/setters cannot be called with dynamic dispatch or torn
      // off. Static methods can't be called with dynamic dispatch and are
      // tagged with a type when torn off. Most are implicitly const and
      // canonicalized. Static signatures are only used by the debugger and are
      // not needed for runtime correctness.
      // TODO(40273) Skip for all statics when the debugger consumes signature
      // information from symbol files.
      if (isTearOffLowering(member)) continue;

      var name = member.name.text;
      var reifiedType = _memberRuntimeType(member, c) as FunctionType;

      // Don't add redundant signatures for inherited methods whose signature
      // did not change.  If we are not overriding, or if the thing we are
      // overriding has a different reified type from ourselves, we must
      // emit a signature on this class.  Otherwise we will inherit the
      // signature from the superclass.
      var memberOverride = c.superclass != null
          ? _hierarchy.getDispatchTarget(
              c.superclass!,
              member.name,
              setter: member.isSetter,
            )
          : null;

      var needsSignature =
          memberOverride == null ||
          reifiedType != _memberRuntimeType(memberOverride, c);

      var memberName = _declareMemberName(
        member,
        useExtension: _isObjectMethodTearoff(member.name.text),
      );
      if (!member.isAccessor) {
        var immediateTarget = js.string(fullyResolvedTargetLabel(member));
        methodsImmediateTarget.add(
          js_ast.Property(memberName, immediateTarget),
        );
      }

      if (needsSignature) {
        js_ast.Expression type;
        if (member.isAccessor) {
          // These signatures are used for dynamic access and to inform the
          // debugger. The `arrayRti` accessor is only used by the dart:_rti
          // library internals and should not be included in the accessible
          // signatures.
          if (c == _jsArrayClass && name == 'arrayRti') continue;
          type = _emitType(
            member.isGetter
                ? reifiedType.returnType
                : reifiedType.positionalParameters[0],
          );
        } else {
          type = _emitType(reifiedType);
          if (!member.isStatic && reifiedType.typeParameters.isNotEmpty) {
            // Instance methods with generic type parameters require extra
            // information to support dynamic calls. The default values for the
            // type parameters are encoded into a separate storage object for
            // use at runtime.
            var defaultTypeArgs = js_ast.ArrayInitializer([
              for (var parameter in reifiedType.typeParameters)
                _emitType(parameter.defaultType),
            ]);
            var typeResolver = js_ast.ArrowFun([_rtiParam], defaultTypeArgs);
            var property = js_ast.Property(memberName, typeResolver);
            instanceMethodsDefaultTypeArgs.add(property);
            // As seen below, sometimes the member signatures are added again
            // using the extension symbol as the name. That logic is duplicated
            // here to ensure there are always default type arguments accessible
            // via the same name as the signature.
            // TODO(52867): Cleanup default type argument duplication.
            if (extMethods.contains(name) || extAccessors.contains(name)) {
              var property = js_ast.Property(
                _declareMemberName(member, useExtension: true),
                typeResolver,
              );
              instanceMethodsDefaultTypeArgs.add(property);
            }
          }
        }
        var typeResolver = js_ast.ArrowFun([_rtiParam], type);
        var property = js_ast.Property(memberName, typeResolver);
        var signatures = getSignatureList(member);
        signatures.add(property);
        if (!member.isStatic &&
            (extMethods.contains(name) || extAccessors.contains(name))) {
          // TODO(52867): Cleanup signature duplication.
          var typeResolver = js_ast.ArrowFun([_rtiParam], type);
          var property = js_ast.Property(
            _declareMemberName(member, useExtension: true),
            typeResolver,
          );
          signatures.add(property);
        }
      }
    }

    emitSignature('Method', instanceMethods);
    emitSignature('MethodsDefaultTypeArg', instanceMethodsDefaultTypeArgs);
    emitSignature('MethodsImmediateTarget', methodsImmediateTarget);
    // TODO(40273) Skip for all statics when the debugger consumes signature
    // information from symbol files.
    emitSignature('StaticMethod', staticMethods);
    emitSignature('Getter', instanceGetters);
    emitSignature('Setter', instanceSetters);
    emitSignature('StaticGetter', staticGetters);
    emitSignature('StaticSetter', staticSetters);
    body.add(
      _runtimeStatement('setLibraryUri(#, #)', [
        className,
        _cacheUri(_jsLibraryDebuggerName(c.enclosingLibrary)),
      ]),
    );

    var instanceFields = <js_ast.Property>[];
    var staticFields = <js_ast.Property>[];

    var classFields = c.fields.toList();
    for (var field in classFields) {
      // Static fields cannot be called with dynamic dispatch or torn off. The
      // signatures are only used by the debugger and are not needed for runtime
      // correctness.
      var memberName = _declareMemberName(field);
      var fieldSig = emitClassFieldSignature(field, c);
      var property = js_ast.Property(memberName, fieldSig);
      // TODO(40273) Skip static fields when the debugger consumes signature
      // information from symbol files.
      (field.isStatic ? staticFields : instanceFields).add(property);
    }
    emitSignature('Field', instanceFields);
    // TODO(40273) Skip for all statics when the debugger consumes signature
    // information from symbol files.
    emitSignature('StaticField', staticFields);
    _classEmittingSignatures = savedClass;
    _currentTypeEnvironment = savedTypeEnvironment;
  }

  DartType _memberRuntimeType(Member member, Class fromClass) {
    var f = member.function;
    if (f == null) {
      return (member as Field).type;
    }
    FunctionType result;
    if (!f.positionalParameters.any(isCovariantParameter) &&
        !f.namedParameters.any(isCovariantParameter)) {
      result = f.computeThisFunctionType(Nullability.nonNullable);
    } else {
      var fComputed = f.computeThisFunctionType(Nullability.nonNullable);
      var fComputedNamedByName = {
        for (NamedType namedParameter in fComputed.namedParameters)
          namedParameter.name: namedParameter,
      };
      DartType reifyParameter(
        VariableDeclaration parameter,
        DartType fComputedParameter,
      ) => isCovariantParameter(parameter)
          ? _coreTypes.objectNullableRawType
          : fComputedParameter;
      NamedType reifyNamedParameter(
        VariableDeclaration parameter,
        NamedType fComputedNamedParameter,
      ) {
        assert(parameter.name == fComputedNamedParameter.name);
        return NamedType(
          parameter.name!,
          reifyParameter(parameter, fComputedNamedParameter.type),
        );
      }

      // TODO(jmesserly): do covariant type parameter bounds also need to be
      // reified as `Object`?
      result = FunctionType(
        List<DartType>.generate(
          f.positionalParameters.length,
          (index) => reifyParameter(
            f.positionalParameters[index],
            fComputed.positionalParameters[index],
          ),
        ),
        f.returnType,
        Nullability.nonNullable,
        namedParameters: List<NamedType>.generate(
          f.namedParameters.length,
          (index) => reifyNamedParameter(
            f.namedParameters[index],
            fComputedNamedByName[f.namedParameters[index].name]!,
          ),
        )..sort(),
        typeParameters: fComputed.typeParameters,
        requiredParameterCount: f.requiredParameterCount,
      );
    }
    return _typeFromClass(result, member.enclosingClass!, fromClass)
        as FunctionType;
  }

  DartType _typeFromClass(DartType type, Class superclass, Class subclass) {
    if (identical(superclass, subclass)) return type;
    return Substitution.fromSupertype(
      _hierarchy.getClassAsInstanceOf(subclass, superclass)!,
    ).substituteType(type);
  }

  js_ast.Expression _emitConstructor(
    Constructor node,
    List<Field> fields,
    js_ast.Expression className,
  ) {
    var savedUri = _currentUri;
    _currentUri = node.fileUri;
    _staticTypeContext.enterMember(node);
    var savedTypeEnvironment = _currentTypeEnvironment;
    _currentTypeEnvironment = ClassTypeEnvironment(
      node.enclosingClass.typeParameters,
    );

    var params = <js_ast.Parameter>[];
    // Generic class constructors accept their RTI as their first argument.
    params.addAll(_emitParameters(node.function));
    var body = _withCurrentFunction(
      node.function,
      () =>
          _superDisallowed(() => _emitConstructorBody(node, fields, className)),
    );

    var end = _nodeEnd(node.fileEndOffset);
    _currentUri = savedUri;
    _staticTypeContext.leaveMember(node);
    end ??= _nodeEnd(node.enclosingClass.fileEndOffset);

    var constructor = js_ast.Fun([
      if (_requiresRtiForInstantiation(node.enclosingClass)) _rtiParam,
      ...params,
    ], js_ast.Block(body))..sourceInformation = end;

    _currentTypeEnvironment = savedTypeEnvironment;
    return constructor;
  }

  List<js_ast.Statement> _emitConstructorBody(
    Constructor node,
    List<Field> fields,
    js_ast.Expression className,
  ) {
    var cls = node.enclosingClass;

    // Generate optional/named argument value assignment. These can not have
    // side effects, and may be used by the constructor's initializers, so it's
    // nice to do them first.
    // Also for const constructors we need to ensure default values are
    // available for use by top-level constant initializers.
    var fn = node.function;
    var body = _emitArgumentInitializers(fn, node.name.text);

    // Class instances with type arguments are bound to their RTI on creation.
    // This must be bound early, as instantiated fields may reference this RTI.
    if (_requiresRtiForInstantiation(cls)) {
      // Only set the rti if there isn't one already. This avoids superclasses
      // overwriting the value already set by a subclass.
      var rtiProperty = _propertyName(js_ast.FixedNames.rtiName);
      body.add(
        js.statement('this.# = this.# || # || #', [
          rtiProperty,
          rtiProperty,
          _rtiParam,
          _runtimeCall('getReifiedType(this)'),
        ]),
      );
    }

    // Redirecting constructors are not allowed to have conventional
    // initializers but can have variable declarations in the form of
    // initializers to support named arguments appearing anywhere in the
    // arguments list.
    if (node.initializers.any((i) => i is RedirectingInitializer)) {
      body.add(_emitRedirectingConstructor(node.initializers, className));
      return body;
    }

    // Generate field initializers.
    // These are expanded into each non-redirecting constructor.
    // In the future we may want to create an initializer function if we have
    // multiple constructors, but it needs to be balanced against readability.
    body.add(_initializeFields(fields, node));

    // If no superinitializer is provided, an implicit superinitializer of the
    // form `super()` is added at the end of the initializer list, unless the
    // enclosing class is class Object.
    var superCall = node.initializers.whereType<SuperInitializer>().firstOrNull;
    var jsSuper = _emitSuperConstructorCallIfNeeded(cls, className, superCall);
    if (jsSuper != null) {
      // TODO(50465) Fix incorrect assumption there should always be a super
      // initializer here.
      if (superCall != null) jsSuper.sourceInformation = _nodeStart(superCall);
      body.add(jsSuper);
    }

    body.add(_emitFunctionScopedBody(fn));
    return body;
  }

  /// Returns the "actual" superclass of [c].
  ///
  /// Walks up the superclass chain looking for the first actual class
  /// skipping any synthetic classes inserted by the CFE.
  Class _superClassAsWritten(Class c) {
    var superclass = c.superclass!;
    while (superclass.isAnonymousMixin) {
      superclass = superclass.superclass!;
    }
    return superclass;
  }

  /// Returns `true` if [cls] requires/accepts an RTI during instantiation.
  ///
  /// We check [cls]'s transitive super classes for generic type parameters,
  /// but we do not consider anonymous mixins, implemented types or mixin on
  /// clauses - as their constructors are never invoked via super calls.
  /// Synthetic mixins are also skipped (despite sometimes having type
  /// parameters) since they can't be referenced during instantiation.
  ///
  /// Context: type arguments must be provided to a generic class during its
  /// instantiation. To avoid extraneous RTI evals, we pass the entire class's
  /// RTI instead of each type parameter's RTI individually. RTIs are attached
  /// to the instance on the hidden '$ti' field (see: FixedNames.rtiName). We
  /// attach RTIs eagerly (i.e., closer to the 'leaf' than the 'root') for
  /// simplicity. Setters on 'this' propagate up super calls since Dart super
  /// calls are synthetic. Ordinary JS super calls would require us to
  /// propagate the RTI all the way to the 'uppermost' generic class.
  bool _requiresRtiForInstantiation(Class? cls) {
    if (cls == null) return false;
    var cachedResult = _requiresRtiForInstantiationCache[cls];
    if (cachedResult != null) return cachedResult;
    // Skip synthetic mixins since their RTIs are never needed during
    // instantiation.
    if (cls.isAnonymousMixin) {
      cls = _superClassAsWritten(cls);
    }
    var hasTypeParameters =
        cls.typeParameters.isNotEmpty ||
        _requiresRtiForInstantiation(cls.superclass);
    _requiresRtiForInstantiationCache[cls] = hasTypeParameters;
    return hasTypeParameters;
  }

  js_ast.LiteralString _constructorName(String name) {
    if (name == '') {
      // Default constructors (factory or not) use `new` as their name.
      return _propertyName('new');
    }
    return _emitStaticMemberName(name);
  }

  js_ast.Statement _emitRedirectingConstructor(
    List<Initializer> initializers,
    js_ast.Expression className,
  ) {
    var jsInitializers = <js_ast.Statement>[];
    for (var init in initializers) {
      if (init is LocalInitializer) {
        // Temporary locals are created when named arguments don't appear at
        // the end of the arguments list.
        jsInitializers.add(visitVariableDeclaration(init.variable));
      } else if (init is RedirectingInitializer) {
        var rtiParam = _requiresRtiForInstantiation(init.target.enclosingClass)
            ? _rtiParam
            : null;
        // We can't dispatch to the constructor with `this.new` as that might
        // hit a derived class constructor with the same name.
        var initializer = js.statement('#.#.call(this, #);', [
          className,
          _constructorName(init.target.name.text),
          [
            if (rtiParam != null) rtiParam,
            ..._emitArgumentList(init.arguments, types: false),
          ],
        ]);
        jsInitializers.add(initializer);
      }
    }
    return js_ast.Block(jsInitializers);
  }

  js_ast.Statement? _emitSuperConstructorCallIfNeeded(
    Class c,
    js_ast.Expression className,
    SuperInitializer? superInit,
  ) {
    if (c == _coreTypes.objectClass) return null;

    Constructor ctor;
    List<js_ast.Expression> args;
    if (superInit == null) {
      ctor = unnamedConstructor(c.superclass!)!;
      args = [];
    } else {
      ctor = superInit.target;
      var savedTypeEnvironment = _currentTypeEnvironment;
      _currentTypeEnvironment = ClassTypeEnvironment(c.typeParameters);
      // An RTI will already have been set at the constructor call site, so
      // pass nothing if the superclass is expecting an RTI.
      var rti = _requiresRtiForInstantiation(ctor.enclosingClass)
          ? js_ast.LiteralNull()
          : null;
      args = [
        if (rti != null) rti,
        ..._emitArgumentList(superInit.arguments, types: true),
      ];

      _currentTypeEnvironment = savedTypeEnvironment;
    }
    // We can skip the super call if it's empty. Most commonly this happens for
    // things that extend Object, and don't have any field initializers or their
    // own default constructor.
    if (ctor.name.text == '' && !_hasUnnamedSuperConstructor(c)) {
      return null;
    }
    return _emitSuperConstructorCall(ctor, className, ctor.name.text, args);
  }

  js_ast.Statement _emitSuperConstructorCall(
    Constructor constructor,
    js_ast.Expression className,
    String name,
    List<js_ast.Expression> args,
  ) {
    return js.statement('#.#.call(this, #);', [
      _emitJSObjectGetPrototypeOf(className, fullyQualifiedName: true),
      _constructorName(name),
      args,
    ]);
  }

  bool _hasUnnamedInheritedConstructor(Class? c) {
    if (c == null) return false;
    return _hasUnnamedConstructor(c) || _hasUnnamedSuperConstructor(c);
  }

  bool _hasUnnamedSuperConstructor(Class c) {
    return _hasUnnamedConstructor(c.mixedInClass) ||
        _hasUnnamedInheritedConstructor(c.superclass);
  }

  bool _hasUnnamedConstructor(Class? c) {
    if (c == null || c == _coreTypes.objectClass) return false;
    var ctor = unnamedConstructor(c);
    if (ctor != null && !ctor.isSynthetic) return true;
    return c.fields.any((f) => !f.isStatic);
  }

  js_ast.Expression _emitFieldValueAccessor(Field f) {
    var virtualField = _classProperties!.virtualFields[f];
    // Avoid calling getSymbol on _declareMemberName since _declareMemberName
    // calls _emitMemberName downstream, which already invokes getSymbol.
    var access = virtualField == null
        ? _declareMemberName(f)
        : _getSymbol(virtualField);
    return access;
  }

  js_ast.Expression _emitFieldInit(
    Field f,
    Expression? initializer,
    TreeNode hoverInfo,
  ) {
    var access = _emitFieldValueAccessor(f);
    var jsInit = _visitInitializer(initializer, f.annotations);
    return jsInit.toAssignExpression(
      js.call('this.#', [access])..sourceInformation = _nodeStart(hoverInfo),
    );
  }

  /// Initialize fields. They follow the sequence:
  ///
  ///   1. field declaration initializer if non-const,
  ///   2. field initializing parameters,
  ///   3. constructor field initializers,
  ///   4. initialize fields not covered in 1-3
  js_ast.Statement _initializeFields(List<Field> fields, [Constructor? ctor]) {
    // Run field initializers if they can have side-effects.
    var ctorFields = ctor?.initializers
        .whereType<FieldInitializer>()
        .map((c) => c.field)
        .toSet();

    var body = <js_ast.Statement>[];
    for (var f in fields) {
      if (f.isStatic) continue;
      var init = f.initializer;
      if (ctorFields != null &&
          ctorFields.contains(f) &&
          (init == null || _constants.isConstant(init))) {
        continue;
      }
      _staticTypeContext.enterMember(f);
      body.add(_emitFieldInit(f, init, f).toStatement());
      _staticTypeContext.leaveMember(f);
    }

    // Run constructor field initializers such as `: foo = bar.baz`
    if (ctor != null) {
      for (var init in ctor.initializers) {
        if (init is FieldInitializer) {
          body.add(_emitFieldInit(init.field, init.value, init).toStatement());
        } else if (init is LocalInitializer) {
          body.add(visitVariableDeclaration(init.variable));
        } else if (init is AssertInitializer) {
          body.add(visitAssertStatement(init.statement));
        }
      }
    }

    return js_ast.Statement.from(body);
  }

  js_ast.Expression _visitInitializer(
    Expression? init,
    List<Expression> annotations,
  ) {
    // explicitly initialize to null, to avoid getting `undefined`.
    // TODO(jmesserly): do this only for vars that aren't definitely assigned.
    if (init == null) return js_ast.LiteralNull();
    return _annotatedNullCheck(annotations)
        ? _notNull(init)
        : _visitExpression(init);
  }

  js_ast.Expression _notNull(Expression expr) {
    var jsExpr = _visitExpression(expr);
    if (!_isNullable(expr)) return jsExpr;
    return _runtimeCall('notNull(#)', [jsExpr]);
  }

  /// If the class has only factory constructors, and it can be mixed in,
  /// then we need to emit a special hidden default constructor for use by
  /// mixins.
  bool _usesMixinNew(Class mixin) {
    // TODO(jmesserly): mixin declarations don't get implicit constructor nodes,
    // even if they have fields, so we need to ensure they're getting generated.
    return mixin.isMixinDeclaration && _hasUnnamedConstructor(mixin) ||
        mixin.superclass?.superclass == null &&
            mixin.constructors.every((c) => c.isExternal);
  }

  js_ast.Statement _addConstructorToClass(
    Class c,
    js_ast.Expression className,
    js_ast.LiteralString name,
    js_ast.Expression jsCtor,
  ) {
    jsCtor = _defineValueOnClass(c, className, name, jsCtor);
    return js.statement('#.prototype = #.prototype;', [jsCtor, className]);
  }

  /// Whether any superclass of [c] defines a static [name].
  bool _superclassHasStatic(Class c, String memberName) {
    // Note: because we're only considering statics, we can ignore mixins.
    // We're only trying to find conflicts due to JS inheriting statics.
    var superclass = c.superclass;
    var name = Name(memberName, c.enclosingLibrary);
    while (true) {
      if (superclass == null) return false;
      for (var m in superclass.members) {
        if (m.name == name &&
            (m is Procedure && m.isStatic || m is Field && m.isStatic)) {
          return true;
        }
      }
      superclass = superclass.superclass;
    }
  }

  /// Emits a value store and getter/setter pair for [member] that constitutes
  /// a static field.
  List<js_ast.Property> _emitStaticFieldAndAccessor(Member member) {
    return _emitLazyMember(
      _emitTopLevelNameNoExternalInterop(member.enclosingClass!),
      member,
      (m) => _emitStaticMemberName(m.name.text),
    );
  }

  /// Emits class methods and properties.
  List<js_ast.Property> _emitClassProperties(Class c) {
    var virtualFields = _classProperties!.virtualFields;

    var jsProperties = <js_ast.Property?>[];
    var hasJsPeer = _extensionTypes.isNativeClass(c);
    var hasIterator = false;

    if (c == _coreTypes.objectClass) {
      // Dart does not use ES6 constructors.
      // Add an error to catch any invalid usage.
      jsProperties.add(
        js_ast.Method(
          _propertyName('constructor'),
          js.fun(
            r'''function() {
                throw Error("use `new " + # +
                    ".new(...)` to create a Dart object");
              }''',
            [
              _runtimeCall('typeName(#)', [
                _runtimeCall('getReifiedType(this)'),
              ]),
            ],
          ),
        ),
      );
    } else if (c == _jsArrayClass) {
      // Provide access to the Array constructor property, so it works like
      // other native types (rather than calling the Dart Object "constructor"
      // above, which throws).
      //
      // This will become obsolete when
      // https://github.com/dart-lang/sdk/issues/31003 is addressed.
      jsProperties.add(
        js_ast.Method(
          _propertyName('constructor'),
          js.fun(r'function() { return []; }'),
        ),
      );
    }

    for (var m in c.fields) {
      if (m.isStatic) {
        jsProperties.addAll(_emitStaticFieldAndAccessor(m));
      } else if (_extensionTypes.isNativeClass(c)) {
        jsProperties.addAll(_emitNativeFieldAccessors(m));
      } else if (virtualFields.containsKey(m)) {
        jsProperties.addAll(_emitVirtualFieldAccessor(m));
      }
    }

    var getters = <String, Procedure>{};
    var setters = <String, Procedure>{};
    for (var m in c.procedures) {
      if (m.isAbstract) continue;
      if (m.isGetter) {
        getters[m.name.text] = m;
      } else if (m.isSetter) {
        setters[m.name.text] = m;
      }
    }

    var savedUri = _currentUri;
    for (var m in c.procedures) {
      _staticTypeContext.enterMember(m);
      // For the Dart SDK, we use the member URI because it may be different
      // from the class (because of patch files). User code does not need this.
      //
      // TODO(jmesserly): CFE has a bug(?) where nSM forwarders sometimes have a
      // bogus file URI, that is mismatched compared to the offsets. This causes
      // a crash when we look up the location. So for those forwarders, we just
      // suppress source spans.
      _currentUri = m.isNoSuchMethodForwarder ? null : m.fileUri;
      if (_isForwardingStub(m)) {
        // TODO(jmesserly): is there any other kind of forwarding stub?
        jsProperties.addAll(_emitCovarianceCheckStub(m));
      } else if (m.isFactory) {
        if (m.isRedirectingFactory) {
          // Skip redirecting factories (they've already been resolved).
        } else {
          jsProperties.add(_emitFactoryConstructor(m));
        }
      } else if (m.isAccessor) {
        jsProperties.add(_emitMethodDeclaration(m));
        jsProperties.add(_emitSuperAccessorWrapper(m, getters, setters));
        if (!hasJsPeer && m.isGetter && m.name.text == 'iterator') {
          hasIterator = true;
          jsProperties.add(_emitIterable(c));
        }
      } else {
        jsProperties.add(_emitMethodDeclaration(m));
      }
      _staticTypeContext.leaveMember(m);
    }
    _currentUri = savedUri;

    // If the type doesn't have an `iterator`, but claims to implement Iterable,
    // we inject the adaptor method here, as it's less code size to put the
    // helper on a parent class. This pattern is common in the core libraries
    // (e.g. IterableMixin<E> and IterableBase<E>).
    //
    // (We could do this same optimization for any interface with an `iterator`
    // method, but that's more expensive to check for, so it doesn't seem worth
    // it. The above case for an explicit `iterator` method will catch those.)
    if (!hasJsPeer && !hasIterator) {
      jsProperties.add(_emitIterable(c));
    }

    // Add all of the super helper methods
    jsProperties.addAll(_superHelpers.values);

    return jsProperties.nonNulls.toList();
  }

  bool _isForwardingStub(Procedure member) {
    if (member.isForwardingStub || member.isForwardingSemiStub) {
      if (!_currentLibrary!.importUri.isScheme('dart')) return true;
      // TODO(jmesserly): external methods in the SDK seem to get incorrectly
      // tagged as forwarding stubs even if they are patched. Perhaps there is
      // an ordering issue in CFE. So for now we pattern match to see if it
      // looks like an actual forwarding stub.
      //
      // We may be able to work around this in a cleaner way by simply emitting
      // the code, and letting the normal covariance check logic handle things.
      // But currently we use _emitCovarianceCheckStub to work around some
      // issues in the stubs.
      var body = member.function.body;
      if (body is ReturnStatement) {
        var expr = body.expression;
        return expr is SuperMethodInvocation || expr is SuperPropertySet;
      }
    }
    return false;
  }

  /// Emits a method, getter, or setter.
  js_ast.Method? _emitMethodDeclaration(Procedure member) {
    if (member.isAbstract) {
      return null;
    }

    js_ast.Fun fn;
    if (member.isExternal && !member.isNoSuchMethodForwarder) {
      if (member.isStatic) {
        // TODO(vsm): Do we need to handle this case?
        return null;
      }
      fn = _emitNativeFunctionBody(member);
    } else {
      fn = _withMethodDeclarationContext(
        member,
        () => _emitFunction(
          member.function,
          member.name.text,
          functionBody: _toSourceLocation(member.fileOffset),
          functionEnd: _toSourceLocation(member.fileEndOffset),
        ),
      );
    }

    var method = js_ast.Method(
      _declareMemberName(member),
      fn,
      isGetter: member.isGetter,
      isSetter: member.isSetter,
      isStatic: member.isStatic,
    );

    if (isTearOffLowering(member)) {
      // Remove all source information from static methods introduced by the
      // constructor tearoff CFE lowering.
      method.accept(js_ast.SourceInformationClearer());
    } else {
      method.sourceInformation = _nodeEnd(member.fileEndOffset);
    }
    return method;
  }

  js_ast.Fun _emitNativeFunctionBody(Procedure node) {
    var name = _annotationName(node, isJSAnnotation) ?? node.name.text;
    if (node.isGetter) {
      var returnValue = js('this.#', [name]);
      if (_isNullCheckableNative(node)) {
        // Add a potential null-check on native getter if type is non-nullable.
        returnValue = _runtimeCall('checkNativeNonNull(#)', [returnValue]);
      }
      return js_ast.Fun([], js.block('{ return #; }', [returnValue]));
    } else if (node.isSetter) {
      var params = _emitParameters(node.function);
      return js_ast.Fun(
        params,
        js.block('{ this.# = #; }', [name, params.last]),
      );
    } else {
      var returnValue = js('this.#.apply(this, args)', [name]);
      if (_isNullCheckableNative(node)) {
        // Add a potential null-check on return value if type is non-nullable.
        returnValue = _runtimeCall('checkNativeNonNull(#)', [returnValue]);
      }
      return js.fun('function (...args) { return #; }', [returnValue]);
    }
  }

  List<js_ast.Method> _emitCovarianceCheckStub(Procedure member) {
    // TODO(jmesserly): kernel stubs have a few problems:
    // - they're generated even when there is no concrete super member
    // - the stub parameter types don't match the types we need to check to
    //   ensure soundness of the super member, so we must lookup the super
    //   member and determine checks ourselves.
    // - it generates getter stubs, but these are not used
    if (member.isGetter) return const [];

    var enclosingClass = member.enclosingClass;
    var superMember =
        member.concreteForwardingStubTarget ??
        member.abstractForwardingStubTarget;

    if (superMember == null) return const [];

    DartType substituteType(DartType t) {
      return _typeFromClass(t, superMember.enclosingClass!, enclosingClass!);
    }

    var superMemberFunction = superMember.function;
    var name = _declareMemberName(member);
    if (member.isSetter) {
      if (superMember is Field && isCovariantField(superMember) ||
          superMember is Procedure &&
              isCovariantParameter(
                superMemberFunction!.positionalParameters[0],
              )) {
        return const [];
      }
      var setterType = substituteType(
        superMember.superSetterType,
      ).extensionTypeErasure;
      if (_types.isTop(setterType)) return const [];
      return [
        js_ast.Method(
          name,
          js.fun('function(x) { return super.# = #; }', [
            name,
            _emitCast(_emitIdentifier('x'), setterType),
          ]),
          isSetter: true,
        ),
        js_ast.Method(
          name,
          js.fun('function() { return super.#; }', [name]),
          isGetter: true,
        ),
      ];
    }
    assert(!member.isAccessor);

    var superMethodType =
        substituteType(
              superMemberFunction!.computeThisFunctionType(
                Nullability.nonNullable,
              ),
            )
            as FunctionType;
    var function = member.function;

    var body = <js_ast.Statement>[];
    var typeParameters = superMethodType.typeParameters;
    _emitCovarianceBoundsCheck(typeParameters, body);

    var typeFormals = _emitTypeFormals(typeParameters);
    var jsParams = List<js_ast.Parameter>.from(typeFormals);
    var positionalParameters = function.positionalParameters;
    for (var i = 0, n = positionalParameters.length; i < n; i++) {
      var param = positionalParameters[i];
      var jsParam = _emitIdentifier(param.name!);
      jsParams.add(jsParam);

      if (isCovariantParameter(param) &&
          !isCovariantParameter(superMemberFunction.positionalParameters[i])) {
        var check = _emitCast(jsParam, superMethodType.positionalParameters[i]);
        if (i >= function.requiredParameterCount) {
          body.add(js.statement('if (# !== void 0) #;', [jsParam, check]));
        } else {
          body.add(check.toStatement());
        }
      }
    }
    var namedParameters = function.namedParameters;
    for (var param in namedParameters) {
      if (isCovariantParameter(param) &&
          !isCovariantParameter(
            superMemberFunction.namedParameters.firstWhere(
              (n) => n.name == param.name,
            ),
          )) {
        var name = _propertyName(param.name!);
        var paramType = superMethodType.namedParameters.firstWhere(
          (n) => n.name == param.name,
        );
        body.add(
          js.statement('if (#) #;', [
            _namedArgumentProbe(name),
            _emitCast(
              js_ast.PropertyAccess(_namedArgumentTemp, name),
              paramType.type,
            ),
          ]),
        );
      }
    }

    if (body.isEmpty) return const []; // No checks were needed.

    if (namedParameters.isNotEmpty) jsParams.add(_namedArgumentTemp);
    body.add(js.statement('return super.#(#);', [name, jsParams]));
    return [js_ast.Method(name, js_ast.Fun(jsParams, js_ast.Block(body)))];
  }

  /// Emits a Dart factory constructor to a JS static method.
  js_ast.Method? _emitFactoryConstructor(Procedure node) {
    if (node.isExternal || isUnsupportedFactoryConstructor(node)) return null;
    var function = node.function;

    /// Note: factory constructors can't use `sync*`/`async*`/`async` bodies
    /// because it would return the wrong type, so we can assume `sync` here.
    ///
    /// We can also skip the logic in [_emitFunction] related to operator
    /// methods like ==, as well as generic method parameters.
    ///
    /// If a future Dart version allows factory constructors to take their
    /// own type parameters, this will need to be changed to call
    /// [_emitFunction] instead.
    var name = node.name.text;
    final savedTypeEnvironment = _currentTypeEnvironment;
    _currentTypeEnvironment = RtiTypeEnvironment([
      ...function.typeParameters,
      ..._currentTypeEnvironment.classTypeParameters,
    ]);

    var jsBody = js_ast.Block(
      _withCurrentFunction(function, () {
        var block = _emitArgumentInitializers(function, name);
        block.add(_emitFunctionScopedBody(function));
        return block;
      }),
    );
    var jsName = _constructorName(name);
    memberNames[node] = jsName.valueWithoutQuotes;

    // Generic class constructors accept their RTI as their first argument.
    var method = js_ast.Method(
      jsName,
      js_ast.Fun([
        if (_requiresRtiForInstantiation(node.enclosingClass)) _rtiParam,
        ..._emitParameters(function),
      ], jsBody),
      isStatic: true,
    )..sourceInformation = _nodeEnd(node.fileEndOffset);
    _currentTypeEnvironment = savedTypeEnvironment;
    return method;
  }

  /// Emits the expression necessary to access a constructor of [type];
  js_ast.Expression _emitConstructorAccess(InterfaceType type) =>
      _emitJSInterop(type.classNode) ?? _emitClassRef(type);

  /// This is called whenever a derived class needs to introduce a new field,
  /// shadowing a field or getter/setter pair on its parent.
  ///
  /// This is important because otherwise, trying to read or write the field
  /// would end up calling the getter or setter, and one of those might not even
  /// exist, resulting in a runtime error. Even if they did exist, that's the
  /// wrong behavior if a new field was declared.
  List<js_ast.Method> _emitVirtualFieldAccessor(Field field) {
    var virtualFieldSymbol = _emitFieldValueAccessor(field);
    var name = _declareMemberName(field);
    var initializer = _visitInitializer(field.initializer, field.annotations);
    var getter = _isNonHotReloadableResource(_currentLibrary!.importUri)
        ? js.fun('function() { return this[#]; }', [virtualFieldSymbol])
        : _emitLazyInitializingFunction(
            js.call('this.#', virtualFieldSymbol),
            initializer,
            field,
          );
    var jsGetter = js_ast.Method(name, getter, isGetter: true)
      ..sourceInformation = _nodeStart(field);

    var body = <js_ast.Statement>[];
    var value = _emitIdentifier('value');
    var args = field.isFinal
        ? [js_ast.Super(), name, value]
        : [
            js_ast.This(),
            virtualFieldSymbol,
            if (isCovariantField(field))
              _emitCast(value, field.type)
            else
              value,
          ];
    body.add(js.call('#[#] = #', args).toStatement());
    var jsSetter = js_ast.Method(
      name,
      js_ast.Fun([value], js_ast.Block(body)),
      isSetter: true,
    )..sourceInformation = _nodeStart(field);

    return [jsGetter, jsSetter];
  }

  /// Provide Dart getters and setters that forward to the underlying native
  /// field.  Note that the Dart names are always symbolized to avoid
  /// conflicts.  They will be installed as extension methods on the underlying
  /// native type.
  List<js_ast.Method> _emitNativeFieldAccessors(Field field) {
    // TODO(vsm): Can this by meta-programmed?
    // E.g., dart.nativeField(symbol, jsName)
    // Alternatively, perhaps it could be meta-programmed directly in
    // dart.registerExtensions?
    var jsMethods = <js_ast.Method>[];
    assert(!field.isStatic);

    var name = _annotationName(field, isJSName) ?? field.name.text;
    // Generate getter
    var fn = js_ast.Fun([], js.block('{ return this.#; }', [name]));
    var method = js_ast.Method(_declareMemberName(field), fn, isGetter: true);
    jsMethods.add(method);

    // Generate setter
    if (!field.isFinal) {
      var value = _emitScopedId('value');
      fn = js_ast.Fun([value], js.block('{ this.# = #; }', [name, value]));
      method = js_ast.Method(_declareMemberName(field), fn, isSetter: true);
      jsMethods.add(method);
    }

    return jsMethods;
  }

  /// Emit a getter (or setter) that simply forwards to the superclass getter
  /// (or setter).
  ///
  /// This is needed because in ES6, if you only override a getter
  /// (alternatively, a setter), then there is an implicit override of the
  /// setter (alternatively, the getter) that does nothing.
  js_ast.Method? _emitSuperAccessorWrapper(
    Procedure member,
    Map<String, Procedure> getters,
    Map<String, Procedure> setters,
  ) {
    if (member.isAbstract) return null;

    var name = member.name.text;
    var memberName = _declareMemberName(member);
    if (member.isGetter) {
      if (!setters.containsKey(name) &&
          _classProperties!.inheritedSetters.contains(name)) {
        // Generate a setter that forwards to super.
        var fn = js.fun('function(value) { super[#] = value; }', [memberName]);
        return js_ast.Method(memberName, fn, isSetter: true);
      }
    } else {
      assert(member.isSetter);
      if (!getters.containsKey(name) &&
          _classProperties!.inheritedGetters.contains(name)) {
        // Generate a getter that forwards to super.
        var fn = js.fun('function() { return super[#]; }', [memberName]);
        return js_ast.Method(memberName, fn, isGetter: true);
      }
    }
    return null;
  }

  /// Support for adapting dart:core Iterable to ES6 versions.
  ///
  /// This lets them use for-of loops transparently:
  /// <https://github.com/lukehoban/es6features#iterators--forof>
  ///
  /// This will return `null` if the adapter was already added on a super type,
  /// otherwise it returns the adapter code.
  // TODO(jmesserly): should we adapt `Iterator` too?
  js_ast.Method? _emitIterable(Class c) {
    var iterable = _hierarchy.getClassAsInstanceOf(c, _coreTypes.iterableClass);
    if (iterable == null) return null;
    var superclass = c.superclass!;
    // If a parent had an `iterator` (concrete or abstract) or implements
    // Iterable, we know the adapter is already there, so we can skip it as a
    // simple code size optimization.
    var parent = _hierarchy.getDispatchTarget(superclass, Name('iterator'));
    if (parent != null) return null;

    var parentIterable = _hierarchy.getClassAsInstanceOf(
      superclass,
      _coreTypes.iterableClass,
    );
    if (parentIterable != null) return null;

    if (c.enclosingLibrary.importUri.isScheme('dart') &&
        c.procedures.any((m) => _jsExportName(m) == 'Symbol.iterator')) {
      return null;
    }

    // Otherwise, emit the adapter method, which wraps the Dart iterator in
    // an ES6 iterator.
    return js_ast.Method(
      js.call('Symbol.iterator'),
      // TODO(nshahan) Don't access values in `runtimeModule` outside of
      // `runtimeCall`.
      js.call('function() { return new #.JsIterator(this.#); }', [
            _emitLibraryName(_runtimeLibrary),
            _emitMemberName('iterator', memberClass: _coreTypes.iterableClass),
          ])
          as js_ast.Fun,
    );
  }

  void _registerExtensionType(
    Class c,
    String jsPeerName,
    List<js_ast.Statement> body,
  ) {
    var className = _emitTopLevelName(c);
    // TODO(55547): Move these operations to the library link method.
    if (_typeRep.isPrimitive(_coreTypes.nonNullableRawType(c))) {
      body.add(
        _runtimeStatement('definePrimitiveHashCode(#.prototype)', [className]),
      );
    }
    _nativeExtensionLinks.add(
      _runtimeStatement('registerExtension(#, #)', [
        js.string(jsPeerName),
        className,
      ]),
    );
  }

  /// Generates an entrypoint function for [field] that returns the value in
  /// [valueCache] or initializes it to [initializer] on first access.
  ///
  /// [valueCache] is 'undefined' when uninitialized and holds a special
  /// sentinel value if [field] is final to detect multiple initializations.
  js_ast.Fun _emitLazyInitializingFunction(
    js_ast.Expression valueCache,
    js_ast.Expression initializer,
    Field field,
  ) {
    var initialFieldValueExpression = !_compileForHotReload
        ? valueCache
        : _emitCast(valueCache, field.type);
    // Lazy static fields require an additional type check around their value
    // cache if their type is updated after hot reload. To avoid a type check
    // on every access, the generated getter overrides itself with a direct
    // access on its underlying value cache on first access.
    // TODO(markzipan): The performance ramifications of a lookup vs
    // self-rewriting "smart" getter are unknown. We should revisit this if
    // property accesses become a bottleneck.
    if (field.isStatic) {
      var getterName = memberNames[field]!;
      // Final fields are generated with additional logic to detect
      // initialization cycles via a special sentinel.
      if (field.isFinal) {
        var finalLateInitDetectorSentinel = _getSymbol(
          _emitPrivateNameSymbol(field.enclosingLibrary, '_#initializing'),
        );
        // Emits code like:
        //
        // if ([valueCache] === _#initializing)
        //   dart.throwLateInitializationError(field);
        // if ([valueCache] === void 0) {
        //   [valueCache] = _#initializing;
        //   try {
        //     [valueCache] = initializer;
        //   } catch (e) {
        //     // Reset the sentinel on error so it can be reinitialized.
        //     if ([valueCache] === _#initializing) {
        //       [valueCache] = void 0;
        //     }
        //     throw e;
        //   }
        // }
        // _typeCheck([valueCache]);
        // Object.defineProperty(this, field, {
        //   get() {
        //     return [valueCache];
        //   }
        // });
        // return this.field;
        return js.fun(
          r'''
        function() {
          if (# === #) #;
          if (# === void 0) {
            # = #;
            try {
              # = #;
            } catch (e) {
              if (# === #) {
                # = void 0;
              }
              throw e;
            }
          }
          #;
          Object.defineProperty(this, #, {
            get() {
              return #;
            }
          });
          return this.#;
        }
      ''',
          [
            valueCache,
            finalLateInitDetectorSentinel,
            _runtimeCall('throwLateInitializationError(#)', [
              js.string(field.name.text),
            ]),
            valueCache,
            valueCache,
            finalLateInitDetectorSentinel,
            valueCache,
            initializer,
            valueCache,
            finalLateInitDetectorSentinel,
            valueCache,
            initialFieldValueExpression,
            js.string(getterName),
            valueCache,
            getterName,
          ],
        );
      } else {
        // Emits code like:
        //
        // if ([valueCache] === void 0) {
        //   [valueCache] = initializer;
        // }
        // _typeCheck([valueCache]);
        // Object.defineProperty(this, field, {
        //   get() {
        //     return [valueCache];
        //   }
        // });
        // return this.field;
        return js.fun(
          r'''
        function() {
          if (# === void 0) {
            # = #;
          }
          #;
          Object.defineProperty(this, #, {
            get() {
              return #;
            }
          });
          return this.#;
          }
      ''',
          [
            valueCache,
            valueCache,
            initializer,
            initialFieldValueExpression,
            js.string(getterName),
            valueCache,
            getterName,
          ],
        );
      }
    }
    // Final fields are generated with additional logic to detect
    // initialization cycles via a special sentinel.
    if (field.isFinal) {
      var finalLateInitDetectorSentinel = _getSymbol(
        _emitPrivateNameSymbol(field.enclosingLibrary, '_#initializing'),
      );
      // Emits code like:
      //
      // if ([valueCache] === _#initializing)
      //   dart.throwLateInitializationError(field);
      // if ([valueCache] === void 0) {
      //   [valueCache] = _#initializing;
      //   try {
      //     [valueCache] = initializer;
      //   } catch (e) {
      //     // Reset the sentinel on error so it can be reinitialized.
      //     if ([valueCache] === _#initializing) {
      //       [valueCache] = void 0;
      //     }
      //     throw e;
      //   }
      // }
      // return [valueCache];
      return js.fun(
        r'''
        function() {
          if (# === #) #;
          if (# === void 0) {
            # = #;
            try {
              # = #;
            } catch (e) {
              if (# === #) {
                # = void 0;
              }
              throw e;
            }
          }
          return #;
        }
      ''',
        [
          valueCache,
          finalLateInitDetectorSentinel,
          _runtimeCall('throwLateInitializationError(#)', [
            js.string(field.name.text),
          ]),
          valueCache,
          valueCache,
          finalLateInitDetectorSentinel,
          valueCache,
          initializer,
          valueCache,
          finalLateInitDetectorSentinel,
          valueCache,
          initialFieldValueExpression,
        ],
      );
    } else {
      return js.fun(
        r'''
        function() {
          if (# === void 0) {
            # = #;
          }
          return #;
        }
      ''',
        [valueCache, valueCache, initializer, initialFieldValueExpression],
      );
    }
  }

  /// Emit a lazy field (i.e., late or static).
  ///
  /// Lazy fields are represented as an inlined initializer and a value store.
  /// Value stores are JS symbols prefixed by [_fieldValueStorePrefix], are
  /// initialized on first access, and are not replaced after a hot reload.
  List<js_ast.Property> _emitLazyMember(
    js_ast.Expression objExpr,
    Member member,
    js_ast.LiteralString Function(Member) emitMemberName,
  ) {
    _currentUri = member.fileUri;
    _staticTypeContext.enterMember(member);
    var access = emitMemberName(member);
    memberNames[member] = access.valueWithoutQuotes;
    var properties = <js_ast.Property>[];

    if (member is Field) {
      // Add this field's value store. Lazy members must be prefixed by
      // [_fieldValueStorePrefix] to allow correct hot reload semantics.
      // TODO(markzipan): Const values are emitted along the lazy pathway, but
      // their hot reload semantics seem to permit their values to change after
      // initialization. Revisit this later as we work on consts.
      var fieldValueStoreName = member.isConst
          ? memberNames[member]!
          : '$_fieldValueStorePrefix${memberNames[member]!}';
      var memberValueStore = _getSymbol(
        _emitPrivateNameSymbol(_currentLibrary!, fieldValueStoreName),
      );
      properties.add(
        js_ast.Property(
          memberValueStore,
          js.call('void 0'),
          isStatic: member.isStatic && member.enclosingClass != null,
          isClassProperty: member.enclosingClass != null,
        ),
      );

      var initializer = _visitInitializer(
        member.initializer,
        member.annotations,
      );

      js_ast.Fun getter;
      if (_isNonHotReloadableResource(_currentLibrary!.importUri)) {
        getter = js.fun(
          'function() { return this[#] === void 0 ? this[#] = # : this[#]; }',
          [memberValueStore, memberValueStore, initializer, memberValueStore],
        );
      } else {
        getter = _emitLazyInitializingFunction(
          js.call('this.#', memberValueStore),
          initializer,
          member,
        );
      }
      properties.add(
        js_ast.Method(
            access,
            getter,
            isGetter: true,
            isStatic: member.isStatic && member.enclosingClass != null,
          )
          ..sourceInformation = _hoverComment(
            js_ast.PropertyAccess(objExpr, access),
            member.fileOffset,
            member.name.text.length,
          ),
      );
      if (!member.isFinal && !member.isConst) {
        var body = <js_ast.Statement>[];
        var param = _emitIdentifier('v');
        body.add(js.statement('this.# = #;', [memberValueStore, param]));
        // Even when no null check is present a dummy setter is still required
        // to indicate writeable.
        properties.add(
          js_ast.Method(
            access,
            js_ast.Fun([param], js_ast.Block(body)),
            isSetter: true,
            isStatic: member.isStatic && member.enclosingClass != null,
          ),
        );
      }
    } else if (member is Procedure) {
      properties.add(
        js_ast.Method(
            access,
            _emitFunction(member.function, member.name.text),
            isGetter: member.isGetter,
            isSetter: member.isSetter,
            isStatic: member.isStatic && member.enclosingClass != null,
          )
          ..sourceInformation = _hoverComment(
            js_ast.PropertyAccess(objExpr, access),
            member.fileOffset,
            member.name.text.length,
          ),
      );
    } else {
      throw UnsupportedError(
        'Unsupported lazy member type ${member.runtimeType}: $member',
      );
    }
    _staticTypeContext.leaveMember(member);
    return properties;
  }

  /// Emits [members] as lazy fields.
  List<js_ast.Property> _emitLazyMembers(
    js_ast.Expression objExpr,
    Iterable<Member> members,
    js_ast.LiteralString Function(Member) emitMemberName,
  ) {
    var properties = <js_ast.Property>[];
    var savedUri = _currentUri;

    for (var member in members) {
      properties.addAll(_emitLazyMember(objExpr, member, emitMemberName));
    }
    _currentUri = savedUri;
    return properties;
  }

  List<js_ast.Statement> _withLetScope(
    List<js_ast.Statement> Function() visitBody,
  ) {
    var savedLetVariables = _letVariables;
    _letVariables = [];

    var body = visitBody();
    var letVars = _initLetVariables();
    if (letVars != null) body.insert(0, letVars);

    _letVariables = savedLetVariables;
    return body;
  }

  js_ast.PropertyAccess _emitTopLevelName(NamedNode n, {String suffix = ''}) {
    return _emitJSInterop(n) ??
        _emitTopLevelNameNoExternalInterop(n, suffix: suffix);
  }

  /// Like [_emitMemberName], but for declaration sites.
  ///
  /// Unlike call sites, we always have an element available, so we can use it
  /// directly rather than computing the relevant options for [_emitMemberName].
  js_ast.Expression _declareMemberName(Member m, {bool useExtension = false}) {
    var c = m.enclosingClass;
    var name = m.name.text;
    var actualUseExtension =
        useExtension || (c != null && _extensionTypes.isNativeClass(c));
    return _emitMemberName(
      name,
      isStatic: m is Field ? m.isStatic : (m as Procedure).isStatic,
      useExtension: actualUseExtension,
      member: m,
    );
  }

  /// This handles member renaming for private names and operators.
  ///
  /// Private names are generated using ES6 symbols:
  ///
  ///     // At the top of the module:
  ///     let _x = Symbol('_x');
  ///     let _y = Symbol('_y');
  ///     ...
  ///
  ///     class Point {
  ///       Point(x, y) {
  ///         this[_x] = x;
  ///         this[_y] = y;
  ///       }
  ///       get x() { return this[_x]; }
  ///       get y() { return this[_y]; }
  ///     }
  ///
  /// For user-defined operators the following names are allowed:
  ///
  ///     <, >, <=, >=, ==, -, +, /, ~/, *, %, |, ^, &, <<, >>, >>>, []=, [], ~
  ///
  /// They generate code like:
  ///
  ///     x['+'](y)
  ///
  /// There are three exceptions: [], []= and unary -.
  /// The indexing operators we use `get` and `set` instead:
  ///
  ///     x.get('hi')
  ///     x.set('hi', 123)
  ///
  /// This follows the same pattern as ECMAScript 6 Map:
  /// <https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Map>
  ///
  /// Unary minus looks like: `x._negate()`.
  ///
  /// Equality is a bit special, it is generated via the Dart `equals` runtime
  /// helper, that checks for null. The user defined method is called '=='.
  ///
  js_ast.Expression _emitMemberName(
    String name, {
    bool isStatic = false,
    bool? useExtension,
    Member? member,
    Class? memberClass,
  }) {
    // Static members skip the rename steps and may require JS interop renames.
    if (isStatic) {
      var memberName = _emitStaticMemberName(name, member);
      if (member != null && !isTearOffLowering(member)) {
        // No need to track the names of methods that were created by the CFE
        // lowering and don't exist in the original source code.
        memberNames[member] = memberName.valueWithoutQuotes;
      }
      return memberName;
    }

    // We allow some (illegal in Dart) member names to be used in our private
    // SDK code. These renames need to be included at every declaration,
    // including overrides in subclasses.
    if (member != null) {
      var runtimeName = _jsExportName(member);
      if (runtimeName != null) {
        var parts = runtimeName.split('.');
        // TODO(nshahan) Record the name for this member in memberNames.
        if (parts.length < 2) return _propertyName(runtimeName);

        js_ast.Expression result = _emitIdentifier(parts[0]);
        for (var i = 1; i < parts.length; i++) {
          result = js_ast.PropertyAccess(result, _propertyName(parts[i]));
        }
        // TODO(nshahan) Record the name for this member in memberNames.
        return result;
      }
    }

    memberClass ??= member?.enclosingClass;
    if (name.startsWith('_')) {
      // Use the library that this private member's name is scoped to.
      var memberLibrary =
          member?.name.library ??
          memberClass?.enclosingLibrary ??
          _currentLibrary!;
      if (member != null) {
        // TODO(40273) Move this name collection to another location.
        // We really only want to collect member names when the member is
        // created, not called.
        // Wrap the name as a symbol here so it matches what you would find at
        // runtime when you get all properties and symbols from an instance.
        memberNames[member] = 'Symbol($name)';
      }
      return _getSymbol(_emitPrivateNameSymbol(memberLibrary, name));
    }

    useExtension ??= _isSymbolizedMember(memberClass, name);
    name = js_ast.memberNameForDartMember(name, _isExternal(member));
    if (useExtension) {
      // TODO(nshahan) Record the name for this member in memberNames.
      return _getSymbol(_getExtensionSymbolInternal(name));
    }
    var memberName = _propertyName(name);
    if (member != null) {
      // TODO(40273) Move this name collection to another location.
      // We really only want to collect member names when the member is created,
      // not called.
      memberNames[member] = memberName.valueWithoutQuotes;
    }
    return memberName;
  }

  /// Don't symbolize native members that just forward to the underlying
  /// native member.  We limit this to non-renamed members as the receiver
  /// may be a mock type.
  ///
  /// Note, this is an underlying assumption here that, if another native type
  /// subtypes this one, it also forwards this member to its underlying native
  /// one without renaming.
  bool _isSymbolizedMember(Class? c, String name) {
    if (c == null) {
      return _isObjectMember(name);
    }
    c = _typeRep.getImplementationClass(_coreTypes.nonNullableRawType(c)) ?? c;
    if (_extensionTypes.isNativeClass(c)) {
      var member = _lookupForwardedMember(c, name);

      // Fields on a native class are implicitly native.
      // Methods/getters/setters are marked external/native.
      if (member is Field || _isExternal(member)) {
        // If the native member needs to be null-checked and we're running in
        // sound null-safety, we require symbolizing it in order to access the
        // null-check at the member definition.
        if (_isNullCheckableNative(member!)) return true;
        var jsName = _annotationName(member, isJSName);
        return jsName != null && jsName != name;
      } else {
        // Non-external members must be symbolized.
        return true;
      }
    }
    // If the receiver *may* be a native type (i.e., an interface allowed to
    // be implemented by a native class), conservatively symbolize - we don't
    // know whether it'll be implemented via forwarding.
    // TODO(vsm): Consider CHA here to be less conservative.
    return _extensionTypes.isNativeInterface(c);
  }

  final _forwardingCache = HashMap<Class, Map<String, Member?>>();

  Member? _lookupForwardedMember(Class c, String name) {
    // We only care about public methods.
    if (name.startsWith('_')) return null;

    var map = _forwardingCache.putIfAbsent(c, () => {});

    return map.putIfAbsent(
      name,
      () =>
          _hierarchy.getDispatchTarget(c, Name(name)) ??
          _hierarchy.getDispatchTarget(c, Name(name), setter: true),
    );
  }

  js_ast.LiteralString _emitStaticMemberName(String name, [NamedNode? member]) {
    if (member != null) {
      var jsName = _emitJSInteropExternalStaticMemberName(member);
      if (jsName != null) return jsName;

      // Allow the Dart SDK to assign names to statics with the @JSExportName
      // annotation.
      var exportName = _jsExportName(member);
      if (exportName != null) return _propertyName(exportName);
    }
    if (member is Procedure && member.isFactory) {
      return _constructorName(member.name.text);
    }
    switch (name) {
      // Reserved for the compiler to do `x as T`.
      case 'as':
      // Reserved for the SDK to compute `Type.toString()`.
      case 'name':
      // Reserved by JS, not a valid static member name.
      case 'prototype':
        name += '_';
      default:
        // All trailing underscores static names are reserved for the compiler
        // or SDK libraries.
        //
        // If user code uses them, add an extra `_`.
        //
        // This also avoids collision with the renames above, e.g. `static as`
        // and `static as_` will become `as_` and `as__`.
        if (name.endsWith('_')) {
          name += '_';
        }
    }
    return _propertyName(name);
  }

  /// If [f] is a function passed to JS, make it throw at runtime when called if
  /// it isn't wrapped with `allowInterop`.
  ///
  /// Arguments which are _directly_ wrapped at the site they are passed are
  /// unmodified.
  Expression _assertInterop(Expression f) {
    // Erasing any extension types here for legacy JS interop support but if
    // using the new extension type interop the type system requires that
    // `.toJS` was called.
    var type = f.getStaticType(_staticTypeContext).extensionTypeErasure;
    if (type is FunctionType ||
        (type is InterfaceType && type.classNode == _coreTypes.functionClass)) {
      if (!isAllowInterop(f)) {
        return StaticInvocation(
          _assertInteropMethod,
          Arguments([f], types: [type]),
        );
      }
    }
    return f;
  }

  /// Emit the name associated with external static members of interop classes.
  js_ast.LiteralString? _emitJSInteropExternalStaticMemberName(NamedNode n) {
    if (!usesJSInterop(n)) return null;
    if (n is Member && !n.isExternal) return null;
    var name = _annotationName(n, isJSInteropAnnotation) ?? getTopLevelName(n);
    assert(
      !name.contains('.'),
      'JS interop checker rejects dotted names on static class members',
    );
    return js.escapedString(name, "'");
  }

  /// Emit the top-level name associated with [n], which should not be an
  /// external interop member.
  js_ast.PropertyAccess _emitTopLevelNameNoExternalInterop(
    NamedNode n, {
    String suffix = '',
    bool resolvedFromEmbedder = false,
  }) {
    // Some native tests use top-level native methods.
    var isTopLevelNative = n is Member && isNative(n);
    return js_ast.PropertyAccess(
      isTopLevelNative
          ? _runtimeCall('global.self')
          : (resolvedFromEmbedder
                ? _emitEmbedderResolvedLibrary(getLibrary(n))
                : _emitLibraryName(getLibrary(n))),
      _emitTopLevelMemberName(n, suffix: suffix),
    );
  }

  /// Emits [library] fully resolved via the Dart Dev Embedder.
  ///
  /// Used when the 'current' hot reload's generation of a library needs to be
  /// resolved.
  js_ast.Expression _emitEmbedderResolvedLibrary(Library library) {
    var libraryName = js.string('${library.importUri}');
    return js.call('dartDevEmbedder.importLibrary(#)', [libraryName]);
  }

  /// Emits the member name portion of a top-level member.
  ///
  /// NOTE: usually you should use [_emitTopLevelName] instead of this. This
  /// function does not handle JS interop.
  js_ast.LiteralString _emitTopLevelMemberName(
    NamedNode n, {
    String suffix = '',
  }) {
    var name = _jsExportName(n) ?? getTopLevelName(n);
    return _propertyName(name + suffix);
  }

  bool _isExternal(Member? m) {
    // Corresponds to the names in memberNameForDartMember in
    // compiler/js_names.dart.
    const renamedJsMembers = ['prototype', 'constructor'];
    if (m is Procedure) {
      if (m.isExternal) return true;
      if (m.isNoSuchMethodForwarder) {
        if (renamedJsMembers.contains(m.name.text)) {
          return _hasExternalProcedure(m.enclosingClass!, m.name.text);
        }
      }
    }
    return false;
  }

  /// Returns true if anything up the class hierarchy externally defines a
  /// procedure with name = [name].
  ///
  /// Used to determine when we should alias Dart-JS reserved members
  /// (e.g., 'prototype' and 'constructor').
  bool _hasExternalProcedure(Class c, String name) {
    var classes = Queue<Class>()..add(c);

    while (classes.isNotEmpty) {
      var c = classes.removeFirst();
      var classesToCheck = [
        if (c.supertype != null) c.supertype!.classNode,
        for (var t in c.implementedTypes) t.classNode,
      ];
      classes.addAll(classesToCheck);
      for (var procedure in c.procedures) {
        if (procedure.name.text == name && !procedure.isNoSuchMethodForwarder) {
          return procedure.isExternal;
        }
      }
    }

    return false;
  }

  String? _jsNameWithoutGlobal(NamedNode n) {
    if (!usesJSInterop(n)) return null;
    var libraryJSName = _annotationName(getLibrary(n), isJSInteropAnnotation);
    var jsName =
        _annotationName(n, isJSInteropAnnotation) ?? getTopLevelName(n);
    return libraryJSName != null ? '$libraryJSName.$jsName' : jsName;
  }

  String? _emitJsNameWithoutGlobal(NamedNode n) {
    if (!usesJSInterop(n)) return null;
    _setEmitIfIncrementalLibrary(getLibrary(n));
    return _jsNameWithoutGlobal(n);
  }

  js_ast.PropertyAccess? _emitJSInterop(NamedNode n) {
    var jsName = _emitJsNameWithoutGlobal(n);
    if (jsName == null) return null;
    return _emitJSInteropForGlobal(jsName);
  }

  js_ast.PropertyAccess _emitJSInteropForGlobal(String name) {
    var parts = name.split('.');
    if (parts.isEmpty) parts = [''];
    js_ast.PropertyAccess? access;
    for (var part in parts) {
      access = js_ast.PropertyAccess(
        access ?? _runtimeCall('global'),
        js.escapedString(part, "'"),
      );
    }
    return access!;
  }

  /// Emits top level library procedures and fields.
  ///
  /// Top level fields are represented as an initializer and a value store.
  /// The getter initializes the value on first access, and an accompanying
  /// setter (if not final) sets the underlying value store. Value stores
  /// prefixed by [_fieldValueStorePrefix] are not replaced after a hot reload.
  void _emitLibraryMembers(Library library) {
    var libraryProperties = <js_ast.Property>[];

    // Emit procedures
    var procedures = library.procedures
        .where(
          (p) => !p.isExternal && !p.isAbstract && !_isStaticInteropTearOff(p),
        )
        .toList();
    for (var p in procedures) {
      if (!p.isAccessor) {
        _moduleItems.add(_emitLibraryFunction(p));
      }
      // TODO(#57049): We tag all static members because we don't know if
      // they've been changed after a hot reload. This won't be necessary if we
      // can tag them during the delta diff phase.
      if (p.isStatic && _reifyTearoff(p) && !p.isExternal) {
        var nameExpr = _emitTopLevelName(p);
        _moduleItems.add(
          _emitFunctionTagged(
            nameExpr,
            p.function.computeThisFunctionType(Nullability.nonNullable),
            asLazy: true,
          ).toStatement(),
        );
      }
    }
    if (_hotReloadLibraryMetadata != null) {
      // Remove any top level procedures that were deleted in this hot reload
      // generation.
      for (var deletedProcedureName
          in _hotReloadLibraryMetadata.deletedStaticProcedureNames) {
        // The name used here must match the name used when creating top level
        // members. See [getTopLevelName].
        var methodName = _propertyName(deletedProcedureName);
        _moduleItems.add(
          js.statement('delete #', [
            js_ast.PropertyAccess(_emitLibraryName(library), methodName),
          ]),
        );
      }
    }
    var accessors = procedures
        .where((p) => p.isAccessor)
        .map(_emitLibraryAccessor);
    libraryProperties.addAll(accessors);

    // Emit fields
    var fields = library.fields;
    if (_isSdkInternalRuntime(_currentLibrary!)) {
      /// Treat dart:_runtime fields as safe to eagerly evaluate.
      // TODO(jmesserly): it'd be nice to avoid this special case.
      var lazyFields = <Field>[];
      var savedUri = _currentUri;

      // Helper functions to test if a constructor invocation is internal and
      // should be eagerly evaluated.
      bool isInternalConstructor(ConstructorInvocation node) {
        var type = node.getStaticType(_staticTypeContext) as InterfaceType;
        var library = type.classNode.enclosingLibrary;
        return _isSdkInternalRuntime(library);
      }

      for (var field in fields) {
        _staticTypeContext.enterMember(field);
        var init = field.initializer;
        if (init == null ||
            init is BasicLiteral ||
            init is ConstructorInvocation && isInternalConstructor(init) ||
            init is StaticInvocation && isInlineJS(init.target)) {
          _currentUri = field.fileUri;
          _moduleItems.add(
            js.statement('# = #;', [
              _emitTopLevelName(field),
              _visitInitializer(init, field.annotations),
            ]),
          );
        } else {
          lazyFields.add(field);
        }
        _staticTypeContext.leaveMember(field);
      }

      _currentUri = savedUri;
      fields = lazyFields;
    }

    var libraryExpr = _emitLibraryName(_currentLibrary!);
    if (fields.isNotEmpty) {
      libraryProperties.addAll(
        _emitLazyMembers(libraryExpr, fields, _emitTopLevelMemberName),
      );
    }

    if (libraryProperties.isNotEmpty) {
      var propertiesObject = js_ast.ObjectInitializer(libraryProperties);
      _moduleItems.add(
        _runtimeStatement('declareTopLevelProperties(#, #)', [
          libraryExpr,
          propertiesObject,
        ]),
      );
    }
  }

  /// Check whether [p] is a tear-off for an external or synthetic static
  /// interop member.
  ///
  /// Users are disallowed from using these tear-offs, so we should avoid
  /// emitting them.
  bool _isStaticInteropTearOff(Procedure p) {
    final extensionMember = _extensionIndex.getExtensionMemberForTearOff(p);
    if (extensionMember != null && extensionMember.asProcedure.isExternal) {
      return true;
    }
    final extensionTypeMember = _extensionIndex
        .getExtensionTypeMemberForTearOff(p);
    if (extensionTypeMember != null &&
        extensionTypeMember.asProcedure.isExternal) {
      return true;
    }
    final enclosingClass = p.enclosingClass;
    if (enclosingClass != null && isStaticInteropType(enclosingClass)) {
      // @staticInterop types can't use generative constructors, so we only
      // check for tear-offs of factories. The one exception is a tear-off of a
      // default constructor, which is disallowed on @staticInterop classes.
      final factoryName = extractConstructorNameFromTearOff(p.name);
      if (factoryName != null) {
        if (factoryName.isEmpty &&
            enclosingClass.constructors.any(
              (constructor) =>
                  constructor.isSynthetic && constructor.name.text.isEmpty,
            )) {
          return true;
        }
        if (enclosingClass.procedures.any(
          (procedure) =>
              procedure.isFactory &&
              procedure.isExternal &&
              procedure.name.text == factoryName,
        )) {
          return true;
        }
      }
    }
    return false;
  }

  js_ast.Method _emitLibraryAccessor(Procedure node) {
    var savedUri = _currentUri;
    _staticTypeContext.enterMember(node);
    _currentUri = node.fileUri;

    var name = node.name.text;
    memberNames[node] = name;
    var result = js_ast.Method(
      _propertyName(name),
      _emitFunction(node.function, name),
      isGetter: node.isGetter,
      isSetter: node.isSetter,
    )..sourceInformation = _nodeEnd(node.fileEndOffset);

    _currentUri = savedUri;
    _staticTypeContext.leaveMember(node);
    return result;
  }

  js_ast.Statement _emitLibraryFunction(Procedure p) {
    var savedUri = _currentUri;
    _staticTypeContext.enterMember(p);
    _currentUri = p.fileUri;

    var body = <js_ast.Statement>[];
    var fn = _emitFunction(
      p.function,
      p.name.text,
      functionBody: _toSourceLocation(p.fileOffset),
      functionEnd: _toSourceLocation(p.fileEndOffset),
    )..sourceInformation = _nodeEnd(p.fileEndOffset);

    if (_currentLibrary!.importUri.isScheme('dart') &&
        _isInlineJSFunction(p.function.body)) {
      fn = js_ast.simplifyPassThroughArrowFunCallBody(fn);
    }

    var nameExpr = _emitTopLevelName(p);
    var jsName = _safeFunctionNameForSafari(p.name.text, fn);
    var functionName = _emitScopedId(jsName);
    procedureIdentifiers[p] = functionName;
    body.add(
      js.statement('# = #', [nameExpr, js_ast.NamedFunction(functionName, fn)]),
    );

    _currentUri = savedUri;
    _staticTypeContext.leaveMember(p);

    if (_options.dynamicModule &&
        p.annotations.any((a) => _isEntrypointPragma(a, _coreTypes))) {
      if (_dynamicEntrypoint == null) {
        if (p.function.requiredParameterCount > 0) {
          // TODO(sigmund): this error should be caught by a kernel checker that
          // runs prior to DDC.
          throw StateError(
            'Entrypoint ${p.name.text} must accept being called '
            'with 0 arguments.',
          );
        } else {
          _dynamicEntrypoint = p;
        }
      } else {
        // TODO(sigmund): this error should be caught by a kernel checker that
        // runs prior to DDC.
        throw StateError('A module should define a single entrypoint.');
      }
    }

    return js_ast.Statement.from(body);
  }

  /// Choose a safe name for [fn].
  ///
  /// Most of the time we use [candidateName], except if the name collides
  /// with a parameter name and the function contains default parameter values.
  ///
  /// In ES6, functions containing default parameter values, which DDC
  /// generates when Dart uses positional optional parameters, cannot have
  /// two parameters with the same name. Because we have a similar restriction
  /// in Dart, this is not normally an issue we need to pay attention to.
  /// However, a bug in Safari makes it a syntax error to have the function
  /// name overlap with the parameter names as well. This rename works around
  /// such bug (dartbug.com/43520).
  static String _safeFunctionNameForSafari(
    String candidateName,
    js_ast.Fun fn,
  ) {
    if (fn.params.any((p) => p is js_ast.DestructuredVariable)) {
      while (fn.params.any((a) => a.parameterName == candidateName)) {
        candidateName = '$candidateName\$';
      }
    }
    return candidateName;
  }

  js_ast.Expression _emitFunctionTagged(
    js_ast.Expression fn,
    FunctionType type, {
    bool asLazy = false,
  }) {
    assert(type.nullability == Nullability.nonNullable);
    var typeRep = _emitType(type);
    if (type.typeParameters.isEmpty) {
      return asLazy
          ? _runtimeCall('lazyFn(#, () => #)', [fn, typeRep])
          : _runtimeCall('fn(#, #)', [fn, typeRep]);
    } else {
      var typeParameterDefaults = [
        for (var parameter in type.typeParameters)
          _emitType(parameter.defaultType),
      ];
      var defaultInstantiatedBounds = _emitConstList(
        const DynamicType(),
        typeParameterDefaults,
      );
      return asLazy
          ? _runtimeCall('lazyGFn(#, () => #, () => #)', [
              fn,
              typeRep,
              defaultInstantiatedBounds,
            ])
          : _runtimeCall('gFn(#, #, #)', [
              fn,
              typeRep,
              defaultInstantiatedBounds,
            ]);
    }
  }

  /// Returns an expression that evaluates to the rti object from the dart:_rti
  /// library that represents [type].
  ///
  /// [emitJSInteropGenericClassTypeParametersAsAny] indicates that we should
  /// emit the statically declared type as a JS interop generic class's type
  /// argument (rather than substituting Any). Any is required for correctness
  /// in most cases except for uses in non-external JS interop factories.
  /// Note: This only applies to the old style package:js interop and isn't
  /// necessary for any forms of static JS interop.
  js_ast.Expression _emitType(
    DartType type, {
    bool emitJSInteropGenericClassTypeParametersAsAny = true,
  }) {
    /// Returns an expression that evaluates a type [recipe] within the type
    /// [environment].
    ///
    /// At runtime the expression will evaluate to an rti object.
    js_ast.Expression emitRtiEval(
      js_ast.Expression environment,
      String recipe,
    ) => js.call('#.#("$recipe")', [
      environment,
      _emitMemberName('_eval', memberClass: _rtiClass),
    ]);

    /// Returns an expression that binds a type [parameter] within the type
    /// [environment].
    ///
    /// At runtime the expression will evaluate to an rti object that has been
    /// extended to include the provided [parameter].
    js_ast.Expression emitRtiBind(
      js_ast.Expression environment,
      TypeParameter parameter,
    ) {
      return js.call('#.#(#)', [
        environment,
        _emitMemberName('_bind', memberClass: _rtiClass),
        _emitTypeParameter(parameter),
      ]);
    }

    /// Returns an expression that evaluates a type [recipe] in a type
    /// [environment] resulting in an rti object.
    js_ast.Expression evalInEnvironment(
      DDCTypeEnvironment environment,
      String recipe,
    ) {
      switch (environment) {
        case EmptyTypeEnvironment():
          // Cache ground types in the type table for fast lookup. The table
          // will lazily lookup the RTI object on first access and then replace
          // the lazy getter with the initialized RTI object.
          return _typeTable.nameType(
            type,
            js.call('#._Universe.eval(#, "$recipe", true)', [
              _emitLibraryName(_rtiLibrary),
              _runtimeCall('typeUniverse'),
            ]),
          );
        case BindingTypeEnvironment():
          js_ast.Expression env;
          if (environment.isSingleTypeParameter) {
            // An environment with a single type parameter can be simplified to
            // just that parameter.
            env = _emitTypeParameter(environment.functionTypeParameters.single);
            // Skip a no-op evaluation and just return the parameter.
            if (recipe == '0') return env;
          } else {
            var environmentTypes = environment.functionTypeParameters;
            // Create a dummy interface type to "hold" type arguments.
            env = emitRtiEval(
              _emitTypeParameter(environmentTypes.first),
              '@<0>',
            );
            // Bind remaining type arguments.
            for (var i = 1; i < environmentTypes.length; i++) {
              env = emitRtiBind(env, environmentTypes[i]);
            }
          }
          return emitRtiEval(env, recipe);
        case RtiTypeEnvironment():
          // RTI type environments are already constructed and attached to the
          // provided RTI.
          var env = _rtiParam;
          return emitRtiEval(env, recipe);
        case ClassTypeEnvironment():
          // Class type environments are already constructed and attached to the
          // instance of a generic class.
          var env = js.call('#.instanceType(this)', [
            _emitLibraryName(_rtiLibrary),
          ]);
          return emitRtiEval(env, recipe);
        case ExtendedTypeEnvironment():
          // Class type environments are already constructed and attached to the
          // instance of a generic class, but function type parameters need to
          // be bound.
          var env = js.call('#.instanceType(this)', [
            _emitLibraryName(_rtiLibrary),
          ]);
          // Bind extra type parameters.
          for (var parameter in environment.functionTypeParameters) {
            env = emitRtiBind(env, parameter);
          }
          return emitRtiEval(env, recipe);
      }
      _typeCompilationError(
        type,
        'Unexpected DDCTypeEnvironment type (${environment.runtimeType}).',
      );
    }

    var normalizedType = _futureOrNormalizer.normalize(
      type.extensionTypeErasure,
    );
    try {
      var result = _typeRecipeGenerator.recipeInEnvironment(
        normalizedType,
        _currentTypeEnvironment,
        emitJSInteropGenericClassTypeParametersAsAny:
            emitJSInteropGenericClassTypeParametersAsAny,
      );
      var typeRep = evalInEnvironment(
        result.requiredEnvironment,
        result.recipe,
      );
      return typeRep;
    } on UnsupportedError catch (e) {
      _typeCompilationError(normalizedType, e.message ?? 'Unknown Error');
    }
  }

  js_ast.Expression _emitInvalidNode(Node node, [String message = '']) {
    if (message.isNotEmpty) message += ' ';
    return _runtimeCall('throwUnimplementedError(#)', [
      js.escapedString('node <${node.runtimeType}> $message`$node`'),
    ]);
  }

  /// Emits a reference to the class described by [type].
  ///
  /// The nullability of [type] is not considered because it is meaningless when
  /// describing a reference to the class itself.
  ///
  /// For generic classes, type arguments are not needed since they are
  /// resolved late via an RTI lookup.
  ///
  /// Note that for `package:js` types, this will emit the class we emitted
  /// using `_emitJSInteropClassNonExternalMembers`, and not the runtime type
  /// that we synthesize for `package:js` types.
  ///
  /// [resolvedFromEmbedder] looks up [type] via the embedder, which retrieves
  /// the correct library in the context of hot reload. This should not be set
  /// for external classes.
  js_ast.Expression _emitClassRef(
    InterfaceType type, {
    bool resolvedFromEmbedder = false,
  }) => _emitTopLevelNameNoExternalInterop(
    type.classNode,
    resolvedFromEmbedder: resolvedFromEmbedder,
  );

  Never _typeCompilationError(DartType type, String description) =>
      throw UnsupportedError(
        '$description Encountered while compiling '
        '${_currentLibrary!.fileUri}, which contains the type: $type.',
      );

  /// Emits an expression that lets you access statics on a [type] from code.
  js_ast.Expression _emitConstructorName(InterfaceType type, Member c) {
    var isSyntheticDefault =
        c is Constructor && c.isSynthetic && c.name.text.isEmpty;
    // If it's an external constructor or synthetic default, use the JS
    // constructor.
    var jsConstructor = _emitJSInterop(type.classNode);
    if (jsConstructor != null && (c.isExternal || isSyntheticDefault)) {
      return jsConstructor;
    }
    // If it's non-external but belongs to an interop class, we want the class
    // reference we defined in `_emitJSInteropClassNonExternalMembers`.
    return js_ast.PropertyAccess(
      _emitClassRef(type),
      _constructorName(c.name.text),
    );
  }

  /// Emits an expression that lets you access statics on [c] from code.
  ///
  /// If [isExternal] is false, emits the non-external name.
  js_ast.Expression _emitStaticClassName(Class c, bool isExternal) {
    return isExternal
        ? _emitTopLevelName(c)
        : _emitTopLevelNameNoExternalInterop(c);
  }

  js_ast.Identifier _emitTypeParameter(
    /* TypeParameter | StructuralParameter */ Object t,
  ) {
    assert(t is TypeParameter || t is StructuralParameter);
    return _emitIdentifier(getTypeParameterName(t));
  }

  /// Set incremental mode for expression compilation.
  ///
  /// Called for each expression compilation to set the incremental mode
  /// and clear referenced items.
  ///
  /// Sets all tables and internal structures to incremental mode so
  /// only referenced items will be emitted in a generated function.
  ///
  /// The compiler cannot revert to non-incremental mode, and requires the
  /// original module to be already emitted by the same compiler instance.
  void _setIncrementalMode() {
    if (!_moduleEmitted) {
      throw StateError(
        'Cannot run in incremental mode before module completion',
      );
    }
    _incrementalModules.clear();
    _privateNames.clear();
    _symbolContainer.setIncrementalMode();
    _incrementalMode = true;

    _constTableCache = ModuleItemContainer<String>.asArray('C');
    _constLazyAccessors.clear();
    _constAliasCache.clear();

    _uriContainer = ModuleItemContainer<String>.asArray('I');

    _typeTable.typeContainer.setIncrementalMode();
  }

  /// Emits function after initial compilation.
  ///
  /// Emits function from kernel [functionNode] with name [name] in the context
  /// of [library] and [cls], after the initial compilation of the module is
  /// finished. For example, this happens in expression compilation during
  /// expression evaluation initiated by the user from the IDE and coordinated
  /// by the debugger.
  /// Triggers incremental mode, which only emits symbols, types, constants,
  /// libraries, and uris referenced in the expression compilation result.
  js_ast.Fun _emitFunctionIncremental(
    List<ModuleItem> items,
    Library library,
    Class? cls,
    FunctionNode functionNode,
    String name,
  ) {
    // Setup context.
    _currentLibrary = library;
    _staticTypeContext.enterLibrary(_currentLibrary!);
    _currentClass = cls;
    // Generic parameters should be evaluated in a class environment if
    // provided. Otherwise we default to an empty type environment.
    if (cls != null) {
      _currentTypeEnvironment = ClassTypeEnvironment(cls.typeParameters);
    }

    // Keep all symbols in containers.
    _containerizeSymbols = true;

    // Set all tables to incremental mode, so we can only emit elements that
    // were referenced the compiled code for the expression.
    _setIncrementalMode();

    // Do not add formal parameter checks for the top-level synthetic function
    // generated for expression evaluation, as those parameters are a set of
    // variables from the current scope, and should already be checked in the
    // original code.
    _checkParameters = false;

    // Emit function while recoding elements accessed from tables.
    var fun = _emitFunction(functionNode, name);

    var extensionSymbols = <js_ast.Statement>[];
    _emitExtensionSymbols(extensionSymbols);

    // Add all elements from tables accessed in the function
    var body = js_ast.Block([
      ...extensionSymbols,
      ..._typeTable.dischargeBoundTypes(),
      ..._symbolContainer.emit(),
      ..._emitConstTable(),
      ..._uriContainer.emit(),
      ...fun.body.statements,
    ]);

    // Import all necessary libraries, including libraries accessed from the
    // current module and libraries accessed from the type table.
    for (var library in _typeTable.incrementalLibraries()) {
      _setEmitIfIncrementalLibrary(library);
    }
    _emitImports(items);
    _emitExportsAsImports(items, _currentLibrary!);

    return js_ast.Fun(fun.params, body);
  }

  List<js_ast.Statement> _emitConstTable() {
    var constTable = <js_ast.Statement>[];
    if (_constLazyAccessors.isNotEmpty) {
      constTable.add(
        js.statement('const # = Object.create(null);', [_constTable]),
      );

      constTable.add(
        _runtimeStatement('defineLazy(#, { # })', [
          _constTable,
          _constLazyAccessors,
        ]),
      );

      constTable.addAll(_constTableCache.emit());
    }
    return constTable;
  }

  js_ast.Fun _emitFunction(
    FunctionNode f,
    String? name, {
    SourceLocation? functionEnd,
    SourceLocation? functionBody,
  }) {
    var savedTypeEnvironment = _currentTypeEnvironment;
    if (f.typeParameters.isNotEmpty) {
      _currentTypeEnvironment = _currentTypeEnvironment.extend(
        f.typeParameters,
      );
    }
    var formals = _emitParameters(f);
    var typeFormals = _emitTypeFormals(f.typeParameters);

    var parent = f.parent;
    if (_reifyGenericFunction(parent is Member ? parent : null)) {
      formals.insertAll(0, typeFormals);
    }

    // TODO(jmesserly): need a way of determining if parameters are
    // potentially mutated in Kernel. For now we assume all parameters are.
    _enterFunction(name, formals, () => true);

    var block = js_ast.Block(
      _withCurrentFunction(f, () {
        final bodyPrefix = _emitArgumentInitializers(f, name);

        // Do the async transformation before adding parameter initialization
        // logic. Any parameter initialization should be performed synchronously
        // before the async body is evaluated.
        final bodyFn = js_ast.Fun(
          formals,
          js_ast.Block([_emitFunctionScopedBody(f)]),
        );
        final rewrittenFunction = _rewriteAsyncFunction(
          bodyFn,
          f.asyncMarker,
          name,
          f.emittedValueType,
          functionEnd: functionEnd,
          functionBody: functionBody,
          bodyPrefix: bodyPrefix,
        );
        formals = rewrittenFunction.params;
        return rewrittenFunction.body.statements;
      }),
    );

    block = _exitFunction(formals, block);
    var fn = js_ast.Fun(formals, block);

    _currentTypeEnvironment = savedTypeEnvironment;
    return fn;
  }

  /// Transforms [fun]'s body to support async execution if the function is
  /// async, sync*, or async*.
  ///
  /// [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 _rewriteAsyncFunction(
    js_ast.Fun fun,
    AsyncMarker asyncMarker,
    String? name,
    DartType? asyncType, {
    SourceLocation? functionEnd,
    SourceLocation? functionBody,
    List<js_ast.Statement>? bodyPrefix,
  }) {
    AsyncRewriterBase? asyncRewriter;
    final bodyName = _emitScopedId('t\$async${name ?? 'Body'}');
    switch (asyncMarker) {
      case AsyncMarker.Sync:
        break;
      case AsyncMarker.Async:
        asyncRewriter = AsyncRewriter(
          asyncStart: _emitTopLevelNameNoExternalInterop(_asyncStartMember),
          asyncAwait: _emitTopLevelNameNoExternalInterop(_asyncAwaitMember),
          asyncReturn: _emitTopLevelNameNoExternalInterop(_asyncReturnMember),
          asyncRethrow: _emitTopLevelNameNoExternalInterop(_asyncRethrowMember),
          completerFactory: _emitTopLevelNameNoExternalInterop(
            _asyncMakeCompleterMember,
          ),
          completerFactoryTypeArguments: [_emitType(asyncType!)],
          wrapBody: _emitTopLevelNameNoExternalInterop(
            _asyncWrapJsFunctionMember,
          ),
          bodyName: bodyName,
        );
      case AsyncMarker.SyncStar:
        asyncRewriter = SyncStarRewriter(
          makeSyncStarIterable: _emitTopLevelNameNoExternalInterop(
            _syncStarMakeIterableMember,
          ),
          syncStarIterableTypeArgument: _emitType(asyncType!),
          iteratorCurrentValueProperty: _emitMemberName(
            '_current',
            member: _syncStarIteratorCurrentMember,
          ),
          iteratorDatumProperty: _emitMemberName(
            '_datum',
            member: _syncStarIteratorDatumMember,
          ),
          yieldStarSelector: _emitMemberName(
            '_yieldStar',
            member: _syncStarIteratorYieldStarMember,
          ),
          bodyName: bodyName,
        );
      case AsyncMarker.AsyncStar:
        asyncRewriter = AsyncStarRewriter(
          asyncStarHelper: _emitTopLevelNameNoExternalInterop(
            _asyncStarHelperMember,
          ),
          streamOfController: _emitTopLevelNameNoExternalInterop(
            _asyncStreamOfControllerMember,
          ),
          newController: _emitTopLevelNameNoExternalInterop(
            _asyncMakeAsyncStarStreamControllerMember,
          ),
          newControllerTypeArguments: [_emitType(asyncType!)],
          yieldExpression: _emitStaticGet(
            _asyncIterationMarkerYieldSingleMember,
          ),
          yieldStarExpression: _emitStaticGet(
            _asyncIterationMarkerYieldStarMember,
          ),
          wrapBody: _emitTopLevelNameNoExternalInterop(
            _asyncWrapJsFunctionMember,
          ),
          bodyName: bodyName,
        );
    }
    if (asyncRewriter != null) {
      return asyncRewriter.rewrite(
        fun,
        functionBody,
        functionEnd,
        bodyPrefix: bodyPrefix,
      );
    } else if (bodyPrefix != null) {
      fun.body.statements.insertAll(0, bodyPrefix);
    }
    return fun;
  }

  js_ast.Parameter _emitParameter(
    VariableDeclaration node, {
    bool withoutInitializer = false,
  }) {
    var initializer = node.initializer;
    var id = _emitVariableDef(node);
    if (initializer == null || withoutInitializer) return id;
    return js_ast.DestructuredVariable(
      name: id,
      defaultValue: _visitExpression(initializer),
    );
  }

  List<js_ast.Parameter> _emitParameters(
    FunctionNode f, {
    bool isForwarding = false,
  }) {
    // Destructure optional positional parameters in place.
    // Given:
    //  - (arg1, arg2, [opt1, opt2 = def2])
    // Emit:
    //  - (arg1, arg2, opt1 = null, opt2 = def2)
    // Note, if [isForwarding] is set, omit initializers as this actually a
    // forwarded call not a parameter list. E.g., the second in:
    //  - foo(arg1, opt1 = def1) => super(arg1, opt1).
    var positional = f.positionalParameters;
    var result = List<js_ast.Parameter>.of(
      positional.map(
        (p) => _emitParameter(p, withoutInitializer: isForwarding),
      ),
    );
    if (positional.isNotEmpty &&
        f.requiredParameterCount == positional.length &&
        positional.last.annotations.any(isJsRestAnnotation)) {
      result.last = js_ast.RestParameter(result.last as js_ast.Identifier);
    }
    if (f.namedParameters.isNotEmpty) result.add(_namedArgumentTemp);
    return result;
  }

  List<js_ast.Identifier> _emitTypeFormals(
    List</*TypeParameter | StructuralParameter */ Object> typeFormals,
  ) {
    assert(
      typeFormals is List<TypeParameter> ||
          typeFormals is List<StructuralParameter>,
    );
    return typeFormals
        .map((t) => _emitIdentifier(getTypeParameterName(t)))
        .toList();
  }

  List<js_ast.Statement> _withCurrentFunction(
    FunctionNode fn,
    List<js_ast.Statement> Function() action,
  ) {
    var savedFunction = _currentFunction;
    _currentFunction = fn;
    _nullableInference.enterFunction(fn);
    var result = _withLetScope(action);
    _nullableInference.exitFunction(fn);
    _currentFunction = savedFunction;
    return result;
  }

  T _superDisallowed<T>(T Function() action) {
    var savedSuperAllowed = _superAllowed;
    _superAllowed = false;
    var result = action();
    _superAllowed = savedSuperAllowed;
    return result;
  }

  /// Executes [action] in context of the current [member].
  ///
  /// Saves and restores important context information about the member
  /// that can be used to generate code inside the body of the member.
  T _withMethodDeclarationContext<T>(Procedure member, T Function() action) {
    // Mixin applications require using 'super' in calls to members of
    // the super class. Store this information to disable non-virtual
    // super field access optimization when compiling the member body.
    var savedOptimizeNonVirtualFieldAccess = _optimizeNonVirtualFieldAccess;
    _optimizeNonVirtualFieldAccess =
        member.stubKind != ProcedureStubKind.ConcreteMixinStub;
    var result = action();
    _optimizeNonVirtualFieldAccess = savedOptimizeNonVirtualFieldAccess;
    return result;
  }

  /// Returns true if the underlying type does not accept a null value.
  bool _mustBeNonNullable(DartType type) =>
      type.nullability == Nullability.nonNullable;

  /// Emits argument initializers, which handles optional/named args, as well
  /// as generic type checks needed due to our covariance.
  List<js_ast.Statement> _emitArgumentInitializers(
    FunctionNode f,
    String? name,
  ) {
    var body = <js_ast.Statement>[];

    _emitCovarianceBoundsCheck(f.typeParameters, body);

    void initParameter(
      VariableDeclaration p,
      js_ast.Identifier jsParam,
      bool isOptional,
    ) {
      // When the parameter is covariant, insert the null check before the
      // covariant cast to avoid a TypeError when testing equality with null.
      if (name == '==') {
        // In Dart `operator ==` methods are not called with a null argument.
        // This is handled before calling them. For performance reasons, we push
        // this check inside the method, to simplify our `equals` helper.
        //
        // TODO(jmesserly): in most cases this check is not necessary, because
        // the Dart code already handles it (typically by an `is` check).
        // Eliminate it when possible.
        body.add(js.statement('if (# == null) return false;', [jsParam]));
      }
      if (isCovariantParameter(p) ||
          // TODO(52582): This should be unreachable once the CFE ensures that
          // redirecting factories parameter types match the target constructor.
          // Matches dart2js check semantics for redirecting factory tearoffs.
          // If a non-nullable optional argument with a null initializer is
          // detected, we add an additional covariant check at runtime.
          (f.parent is Procedure &&
              isOptional &&
              isConstructorTearOffLowering(f.parent as Procedure) &&
              !p.type.isPotentiallyNullable &&
              !p.initializer!
                  .getStaticType(_staticTypeContext)
                  .isPotentiallyNonNullable)) {
        var castExpr = _emitCast(jsParam, p.type);
        if (!identical(castExpr, jsParam)) body.add(castExpr.toStatement());
      }

      if (name == '==') return;

      if (_annotatedNullCheck(p.annotations)) {
        body.add(_nullParameterCheck(jsParam));
      }
    }

    var counter = 0;
    for (var p in f.positionalParameters) {
      var jsParam = _emitVariableRef(p);
      if (_checkParameters) {
        initParameter(p, jsParam, counter >= f.requiredParameterCount);
      }
      counter++;
    }
    for (var p in f.namedParameters) {
      // Parameters will be passed using their real names, not the (possibly
      // renamed) local variable.
      var jsParam = _emitVariableDef(p);
      var paramName = _propertyName(p.name!);
      var defaultValue = _defaultParamValue(p);
      body.add(
        js.statement('let # = # && # ? #.# : #;', [
          jsParam,
          _namedArgumentTemp,
          _namedArgumentProbe(paramName),
          _namedArgumentTemp,
          paramName,
          defaultValue,
        ]),
      );

      if (_checkParameters) {
        initParameter(p, jsParam, !p.isRequired);
      }
    }

    // '_checkParameters = false' is only needed once, while processing formal
    // parameters of the synthetic function from expression evaluation - it
    // will be called from emitFunctionIncremental, which is a top-level API
    // for expression compilation.
    // Here we either are done with processing those formals, or compiling
    // something else (in which case _checkParameters is already true).
    _checkParameters = true;
    return body;
  }

  bool _annotatedNullCheck(List<Expression> annotations) =>
      annotations.any(_nullableInference.isNullCheckAnnotation);

  bool _reifyGenericFunction(Member? m) =>
      m == null ||
      // JS interop members should not pass type arguments.
      !isJsMember(m) &&
          !(m.enclosingLibrary.importUri.isScheme('dart') &&
              m.annotations.any(
                (a) => isBuiltinAnnotation(a, '_js_helper', 'NoReifyGeneric'),
              ));

  js_ast.Statement _nullParameterCheck(js_ast.Expression param) {
    var call = _runtimeCall('argumentError((#))', [param]);
    return js.statement('if (# == null) #;', [param, call]);
  }

  js_ast.Expression _defaultParamValue(VariableDeclaration p) {
    if (p.initializer != null) {
      return _visitExpression(p.initializer!);
    } else {
      return js_ast.LiteralNull();
    }
  }

  /// Returns a test for the existence of [propertyName] in the named argument
  /// package.
  js_ast.Expression _namedArgumentProbe(js_ast.LiteralString propertyName) =>
      // If the name collides with the names in the native JavaScript object
      // prototype then use a slower but more direct test to avoid
      // accidentally finding a value up the prototype chain.
      js_ast.objectProperties.contains(propertyName.valueWithoutQuotes)
      ? _runtimeCall('hOP.call(#, #)', [_namedArgumentTemp, propertyName])
      : js.call('# in #', [propertyName, _namedArgumentTemp]);

  void _emitCovarianceBoundsCheck(
    List</* TypeParameter | StructuralParameter */ Object> typeFormals,
    List<js_ast.Statement> body,
  ) {
    assert(
      typeFormals is List<TypeParameter> ||
          typeFormals is List<StructuralParameter>,
    );
    for (var t in typeFormals) {
      bool? isCovariantByClass;
      DartType bound;
      String name;
      DartType typeParameterType;
      if (t is TypeParameter) {
        isCovariantByClass = t.isCovariantByClass;
        bound = t.bound.extensionTypeErasure;
        name = t.name!;
        typeParameterType = TypeParameterType(t, Nullability.undetermined);
      } else {
        t as StructuralParameter;
        bound = t.bound.extensionTypeErasure;
        name = t.name!;
        typeParameterType = StructuralParameterType(
          t,
          Nullability.undetermined,
        );
      }

      if (isCovariantByClass != null &&
          isCovariantByClass &&
          !_types.isTop(bound)) {
        body.add(
          _runtimeStatement('checkTypeBound(#, #, #)', [
            _emitType(typeParameterType),
            _emitType(bound),
            _propertyName(name),
          ]),
        );
      }
    }
  }

  js_ast.Statement _visitStatement(Statement s) {
    var result = s.accept(this);

    // In most cases, a Dart expression statement with a child expression
    // compile to a JS expression statement with a child expression.
    //
    //   ExpressionStatement                         js_ast.ExpressionStatement
    //            |           --> compiles to -->                 |
    //        Expression                                  js_ast.Expression
    //
    // Both the expression statement and child expression nodes contain their
    // own source location information.
    //
    // In the case of a debugger() call, the code compiles to a single node.
    //
    //   ExpressionStatement                         js_ast.DebuggerStatement
    //            |           --> compiles to -->
    //        Expression
    //
    // The js_ast.DebuggerStatement already has the correct source information
    // attached so we avoid overwriting with the incorrect source location from
    // [s].
    // TODO(jmesserly): is the `is! Block` still necessary?
    if (!(s is Block || result is js_ast.DebuggerStatement)) {
      result.sourceInformation ??= _nodeStart(s);
    }

    // The statement might be the target of a break or continue with a label.
    var name = _labelNames[s];
    if (name != null) result = js_ast.LabeledStatement(name, result);
    return result;
  }

  js_ast.Statement _emitFunctionScopedBody(FunctionNode f) {
    var jsBody = _visitStatement(f.body!);
    return _emitScopedBody(f, jsBody);
  }

  js_ast.Statement _emitScopedBody(FunctionNode f, js_ast.Statement body) {
    if (f.positionalParameters.isNotEmpty || f.namedParameters.isNotEmpty) {
      // Handle shadowing of parameters by local variables, which is allowed in
      // Dart but not in JS.
      //
      // We need this for all function types, including generator-based ones
      // (sync*/async/async*). Our code generator assumes it can emit names for
      // named argument initialization, and sync* functions also emit locally
      // modified parameters into the function's scope.
      var parameterNames = {
        for (var p in f.positionalParameters) p.name!,
        for (var p in f.namedParameters) p.name!,
      };

      return body.toScopedBlock(parameterNames);
    }
    return body;
  }

  /// Visits [nodes] with [_visitExpression].
  List<js_ast.Expression> _visitExpressionList(Iterable<Expression> nodes) {
    return nodes.map(_visitExpression).toList();
  }

  /// Generates an expression for a boolean conversion context (if, while, &&,
  /// etc.), where conversions and null checks are implemented via `dart.test`
  /// to give a more helpful message.
  // TODO(sra): When nullablility is available earlier, it would be cleaner to
  // build an input AST where the boolean conversion is a single AST node.
  js_ast.Expression _visitTest(Expression node) {
    if (node is Not) {
      return visitNot(node);
    }
    if (node is LogicalExpression) {
      js_ast.Expression shortCircuit(String code) {
        return js.call(code, [_visitTest(node.left), _visitTest(node.right)]);
      }

      var op = node.operatorEnum;
      if (op == LogicalExpressionOperator.AND) return shortCircuit('# && #');
      if (op == LogicalExpressionOperator.OR) return shortCircuit('# || #');
    }

    if (node is AsExpression && node.isTypeError) {
      assert(
        node.getStaticType(_staticTypeContext) ==
            _types.coreTypes.boolNonNullableRawType,
      );
      return _runtimeCall('dtest(#)', [_visitExpression(node.operand)]);
    }

    var result = _visitExpression(node);
    if (_isNullable(node)) result = _runtimeCall('test(#)', [result]);
    return result;
  }

  js_ast.Expression _visitExpression(Expression e) {
    if (e is ConstantExpression) {
      return visitConstant(e.constant);
    }
    var result = e.accept(this);
    result.sourceInformation ??= _nodeStart(e);
    return result;
  }

  /// Gets the start position of [node] for use in source mapping.
  ///
  /// This is the most common kind of marking, and is used for most expressions
  /// and statements.
  SourceLocation? _nodeStart(TreeNode node) => node is StringConcatenation
      // Manually selecting the location of the first element to work around the
      // location on the StringConcatenation node that points to the end of
      // String. See https://github.com/dart-lang/sdk/issues/55690.
      ? _toSourceLocation(node.expressions.first.fileOffset)
      : _toSourceLocation(node.fileOffset);

  /// Gets the end position of [node] for use in source mapping.
  ///
  /// This is mainly used for things that compile to JS functions. JS wants a
  /// marking on the end of all functions for stepping purposes.
  ///
  /// This can be used to complete a hover span, when we know the start position
  /// has already been emitted. For example, `foo.bar` we only need to mark the
  /// end of `.bar` to ensure `foo.bar` has a hover tooltip.
  NodeEnd? _nodeEnd(int endOffset) {
    var loc = _toSourceLocation(endOffset);
    return loc != null ? NodeEnd(loc) : null;
  }

  /// Combines [_nodeStart] with the variable name length to produce a hoverable
  /// span for the variable.
  //
  // TODO(jmesserly): we need a lot more nodes to support hover.
  NodeSpan? _variableSpan(int offset, int nameLength) {
    var start = _toSourceLocation(offset);
    var end = _toSourceLocation(offset + nameLength);
    return start != null && end != null ? NodeSpan(start, end) : null;
  }

  SourceLocation? _toSourceLocation(int offset) {
    if (offset == -1) return null;
    var fileUri = _currentUri;
    if (fileUri == null) return null;
    try {
      var loc = _component.getLocation(fileUri, offset);
      if (loc == null || loc.line < 0) return null;
      return SourceLocation(
        offset,
        sourceUrl: fileUri,
        line: loc.line - 1,
        column: loc.column - 1,
      );
    } on StateError catch (_) {
      // TODO(jmesserly): figure out why this is throwing. Perhaps the file URI
      // and offset are mismatched and don't correspond to the same source?
      return null;
    } on RangeError catch (_) {
      return null;
    }
  }

  /// Adds a hover comment for Dart node using JS expression [expr], where
  /// that expression would not otherwise not be generated into source code.
  ///
  /// For example, top-level and static fields are defined as lazy properties,
  /// on the library/class, so their access expressions do not appear in the
  /// source code.
  HoverComment? _hoverComment(
    js_ast.Expression expr,
    int offset,
    int nameLength,
  ) {
    var start = _toSourceLocation(offset);
    var end = _toSourceLocation(offset + nameLength);
    return start != null && end != null ? HoverComment(expr, start, end) : null;
  }

  @override
  js_ast.Statement visitExpressionStatement(ExpressionStatement node) {
    var expr = node.expression;
    if (expr is StaticInvocation) {
      if (isInlineJS(expr.target)) {
        return _emitInlineJSCode(expr).toStatement();
      }
      if (_isDebuggerCall(expr.target)) {
        return _emitDebuggerCall(expr).toStatement();
      }
    }
    var jsExpression = _visitExpression(expr);
    if (jsExpression is js_ast.InvocationWithHotReloadChecks) {
      // When the static invocation expression has been rewritten to include
      // hot reload correctness checks the entire resulting node shouldn't
      // get source-mapped to the original call. Instead the call sites in
      // the sub-expressions will have the correct mapping applied.
      return jsExpression.toStatement()..sourceInformation = continueSourceMap;
    }
    return _visitExpression(expr).toStatement();
  }

  @override
  js_ast.Statement visitBlock(Block node) {
    // If this is the block body of a function, don't mark it as a separate
    // scope, because the function is the scope. This avoids generating an
    // unnecessary nested block.
    //
    // NOTE: we do sometimes need to handle this because Dart and JS rules are
    // slightly different (in Dart, there is a nested scope), but that's handled
    // by _emitSyncFunctionBody.
    var isScope = !identical(node.parent, _currentFunction);
    return js_ast.Block(
      node.statements.map(_visitStatement).toList(),
      isScope: isScope,
    );
  }

  @override
  js_ast.Statement visitEmptyStatement(EmptyStatement node) =>
      js_ast.EmptyStatement();

  @override
  js_ast.Statement visitAssertBlock(AssertBlock node) {
    // AssertBlocks are introduced by the VM-specific async elimination
    // transformation.  We do not expect them to arise here.
    throw UnsupportedError('compilation of an assert block');
  }

  // Replace a string `uri` literal with a cached top-level variable containing
  // the value to reduce overall code size.
  js_ast.Expression _cacheUri(String uri) {
    if (!_uriContainer.contains(uri)) {
      _uriContainer[uri] = js_ast.LiteralString('"$uri"');
    }
    _uriContainer.setEmitIfIncremental(uri);
    return _uriContainer.access(uri);
  }

  @override
  js_ast.Statement visitAssertStatement(AssertStatement node) {
    if (!_options.enableAsserts) return js_ast.EmptyStatement();
    var condition = node.condition;
    var conditionType = condition
        .getStaticType(_staticTypeContext)
        .extensionTypeErasure;
    var jsCondition = _visitExpression(condition);

    if (conditionType != _coreTypes.boolNullableRawType &&
        conditionType != _coreTypes.boolNonNullableRawType) {
      jsCondition = _runtimeCall('dtest(#)', [jsCondition]);
    } else if (_isNullable(condition)) {
      // TODO(nshahan): Is this branch even reachable in null safe code?
      jsCondition = _runtimeCall('test(#)', [jsCondition]);
    }

    SourceLocation? location;
    late String conditionSource;
    var assertLocation = node.location;
    if (assertLocation != null) {
      var fileUri = assertLocation.file;
      var source = node.enclosingComponent!.uriToSource[fileUri]!.text;
      conditionSource = source.substring(
        node.conditionStartOffset,
        node.conditionEndOffset,
      );
      // Assertions that appear in debugger expressions have a synthetic Uri
      // that is different than the current library where the expression will
      // be evaluated.
      var savedUri = _currentUri;
      _currentUri = fileUri;
      location = _toSourceLocation(node.conditionStartOffset)!;
      _currentUri = savedUri;
    } else {
      // If the location is ever null, only show the error with the condition
      // AST instead of the source.
      conditionSource = node.condition.toString();
    }
    return js.statement(' if (!#) #;', [
      jsCondition,
      _runtimeCall('assertFailed(#, #, #, #, #)', [
        if (node.message == null)
          js_ast.LiteralNull()
        else
          _visitExpression(node.message!),
        if (location == null)
          _cacheUri('<unknown source>')
        else
          _cacheUri(location.sourceUrl.toString()),
        // Lines and columns are typically printed with 1 based indexing.
        js.number(location == null ? -1 : location.line + 1),
        js.number(location == null ? -1 : location.column + 1),
        js.escapedString(conditionSource),
      ]),
    ]);
  }

  bool _isBreakable(Statement stmt) {
    // These are conservatively the things that compile to things that can be
    // the target of a break without a label.
    return stmt is ForStatement ||
        stmt is WhileStatement ||
        stmt is DoStatement ||
        stmt is ForInStatement ||
        stmt is SwitchStatement;
  }

  @override
  js_ast.Statement visitLabeledStatement(LabeledStatement node) {
    List<LabeledStatement>? saved;
    // If the effective target is known then this statement is either contained
    // in a labeled statement or a loop.  It has already been processed when
    // the enclosing statement was visited.
    if (!_effectiveTargets.containsKey(node)) {
      // Find the effective target by bypassing and collecting labeled
      // statements.
      var statements = [node];
      var target = node.body;
      while (target is LabeledStatement) {
        var labeled = target;
        statements.add(labeled);
        target = labeled.body;
      }
      for (var statement in statements) {
        _effectiveTargets[statement] = target;
      }

      // If the effective target will compile to something that can have a
      // break from it without a label (e.g., a loop but not a block), then any
      // of the labeled statements can have a break from them by breaking from
      // the effective target.  Otherwise breaks will need a label and a break
      // without a label can still target an outer breakable so the list of
      // current break targets does not change.
      if (_isBreakable(target)) {
        saved = _currentBreakTargets;
        _currentBreakTargets = statements;
      }
    }

    var result = _visitStatement(node.body);
    if (saved != null) _currentBreakTargets = saved;
    return result;
  }

  @override
  js_ast.Statement visitBreakStatement(BreakStatement node) {
    // Switch statements with continue labels must explicitly break to their
    // implicit label due to their being wrapped in a loop.
    if (_inLabeledContinueSwitch &&
        _switchLabelStates.containsKey(node.target.body)) {
      return js_ast.Break(_switchLabelStates[node.target.body]!.label);
    }
    // Can it be compiled to a break without a label?
    if (_currentBreakTargets.contains(node.target)) {
      return js_ast.Break(null);
    }
    // Can it be compiled to a continue without a label?
    if (_currentContinueTargets.contains(node.target)) {
      return js_ast.Continue(null);
    }

    // Ensure the effective target is labeled.  Labels are named globally per
    // Kernel binary.
    //
    // TODO(markzipan): Retrieve the real label name with source offsets
    var target = _effectiveTargets[node.target];
    var name = _labelNames[target!];
    if (name == null) _labelNames[target] = name = 'L${_labelNames.length}';

    // It is a break if the target labeled statement encloses the effective
    // target.
    Statement current = node.target;
    while (current is LabeledStatement) {
      current = current.body;
    }
    if (identical(current, target)) {
      return js_ast.Break(name);
    }
    // Otherwise it is a continue.
    return js_ast.Continue(name);
  }

  // Labeled loop bodies can be the target of a continue without a label
  // (targeting the loop).  Find the outermost non-labeled statement starting
  // from body and record all the intermediate labeled statements as continue
  // targets.
  Statement _effectiveBodyOf(Statement loop, Statement body) {
    // In a loop whose body is not labeled, this list should be empty because
    // it is not possible to continue to an outer loop without a label.
    _currentContinueTargets = <LabeledStatement>[];
    while (body is LabeledStatement) {
      var labeled = body;
      _currentContinueTargets.add(labeled);
      _effectiveTargets[labeled] = loop;
      body = labeled.body;
    }
    return body;
  }

  T _translateLoop<T extends js_ast.Statement>(
    Statement node,
    T Function() action,
  ) {
    List<LabeledStatement>? savedBreakTargets;
    if (_currentBreakTargets.isNotEmpty &&
        _effectiveTargets[_currentBreakTargets.first] != node) {
      // If breaking without a label targets some other (outer) loop, then
      // this loop prevents breaking to that loop without a label.  This loop
      // was not labeled for a break in Kernel, otherwise it would be the
      // effective target of the current break targets, so it is not itself the
      // target of a break.
      savedBreakTargets = _currentBreakTargets;
      _currentBreakTargets = <LabeledStatement>[];
    }
    var savedContinueTargets = _currentContinueTargets;
    var result = action();
    if (savedBreakTargets != null) _currentBreakTargets = savedBreakTargets;
    _currentContinueTargets = savedContinueTargets;
    return result;
  }

  @override
  js_ast.While visitWhileStatement(WhileStatement node) {
    return _translateLoop(node, () {
      var condition = _visitTest(node.condition);
      var body = _visitScope(_effectiveBodyOf(node, node.body));
      return js_ast.While(condition, body);
    });
  }

  @override
  js_ast.Do visitDoStatement(DoStatement node) {
    return _translateLoop(node, () {
      var body = _visitScope(_effectiveBodyOf(node, node.body));
      var condition = _visitTest(node.condition);
      return js_ast.Do(body, condition);
    });
  }

  @override
  js_ast.Statement visitForStatement(ForStatement node) {
    return _translateLoop(node, () {
      js_ast.VariableInitialization emitForInitializer(VariableDeclaration v) =>
          js_ast.VariableInitialization(
            _emitVariableDef(v),
            _visitInitializer(v.initializer, v.annotations),
          );

      if (node.variables.any(containsFunctionExpression)) {
        return _rewriteAsWhile(node);
      }
      var init = node.variables.map(emitForInitializer).toList();
      var initList = init.isEmpty
          ? null
          : js_ast.VariableDeclarationList('let', init);
      var updates = node.updates;
      js_ast.Expression? update;
      if (updates.isNotEmpty) {
        update = js_ast.Expression.binary(
          updates.map(_visitExpression).toList(),
          ',',
        ).toVoidExpression();
      }
      var condition = node.condition != null
          ? _visitTest(node.condition!)
          : null;
      var body = _visitScope(_effectiveBodyOf(node, node.body));

      return js_ast.For(initList, condition, update, body);
    });
  }

  /// Rewrites a `for(;;)` style loop as a while loop to produce the correct
  /// semantics when loop variable initializers contain function expressions
  /// that close over other loop variables.
  ///
  /// The Dart semantics expect that every loop iteration gets fresh loop
  /// variables that can be closed over. The initialization is only executed
  /// for the first iteration. In later iterations, the fresh loop variables are
  /// initialized to the values from the end of the previous iteration.
  ///
  /// These semantics differ from JavaScript when there are closures capturing
  /// loop variables so the simple lowering doesn't work as expected.
  ///
  /// A for loop like:
  ///
  /// ```
  /// for(var v1 = init1, v2 = init2; condition; updates) { body }
  /// ```
  ///
  /// Produces a rewrite like:
  ///
  /// ```
  /// var initFlag = true;
  /// var prev_v1, prev_v2;
  /// while (true) {
  ///   var v1, v2;
  ///   if (initFlag) {
  ///     initFlag = false;
  ///     v1 = inti1;
  ///     v2 = init2;
  ///   } else {
  ///     v1 = prev_v1;
  ///     v2 = prev_v2;
  ///     updates;
  ///   }
  ///   if (!condition) break;
  ///   body;
  ///   prev_v1 = v1;
  ///   prev_v2 = v2;
  /// }
  /// ```
  js_ast.Statement _rewriteAsWhile(ForStatement node) {
    var initFlagTempId = _emitScopedId('t#_init');
    var loopVariableIds = {
      for (var variable in node.variables) variable: _emitVariableDef(variable),
    };
    var prevVariableTempIds = {
      for (var variable in node.variables)
        variable: _emitScopedId('t#_prev_${variable.name!}'),
    };
    var inits = js_ast.Block([
      // Set init flag to false so the initialization only happens on the first
      // iteration of the while loop.
      js.statement('# = false;', [initFlagTempId]),
      // Initialize fresh loop variables to initial values.
      for (var variable in node.variables)
        js.statement('# = #;', [
          loopVariableIds[variable]!,
          _visitInitializer(variable.initializer, variable.annotations),
        ]),
    ]);
    var prevInits = js_ast.Block([
      // Intialize fresh loop variables with the value from the previous
      // iteration.
      for (var variable in node.variables)
        js.statement('# = #;', [
          loopVariableIds[variable],
          prevVariableTempIds[variable],
        ]),
      // Original update expressions.
      for (var update in node.updates) _visitExpression(update).toStatement(),
    ]);
    return js_ast.Block([
        // Create temporary variables for the initialization flag and previous
        // loop variables.
        js_ast.VariableDeclarationList('let', [
          js_ast.VariableInitialization(
            initFlagTempId,
            js_ast.LiteralBool(true),
          ),
          for (var variable in node.variables)
            js_ast.VariableInitialization(prevVariableTempIds[variable]!, null),
        ]).toStatement(),
        // The for loop transformed into a while loop.
        js_ast.While(
            js_ast.LiteralBool(true),
            js_ast.Block([
              // Create fresh loop variables every iteration.
              if (node.variables.isNotEmpty)
                js_ast.VariableDeclarationList('let', [
                  for (var variable in node.variables)
                    js_ast.VariableInitialization(
                      loopVariableIds[variable]!,
                      null,
                    ),
                ]).toStatement(),
              // Initialize loop variables.
              js_ast.If(initFlagTempId, inits, prevInits),
              // Loop condition guard.
              if (node.condition != null)
                js.statement('if (!#) break;', [_visitTest(node.condition!)])
                  ..sourceInformation = _nodeStart(node.condition!),
              // Original loop body.
              _visitScope(_effectiveBodyOf(node, node.body)),
              // Save previous loop variables
              for (var variable in node.variables)
                js.statement('# = #;', [
                    prevVariableTempIds[variable]!,
                    _emitVariableRef(variable),
                  ])
                  // Map these locations to the variable declaration so stepping
                  // in the Dart debugger doesn't jump to the previous line when
                  // stepping.
                  ..sourceInformation = _nodeStart(variable),
            ]),
          )
          // The while loop gets mapped to the original for loop location.
          ..sourceInformation = _nodeStart(node),
      ])
      // Clear the source mapping on the outer block so it doesn't automatically
      // get mapped to the for loop node in _visitStatement.
      ..sourceInformation = continueSourceMap;
  }

  @override
  js_ast.Statement visitForInStatement(ForInStatement node) {
    return _translateLoop(node, () {
      if (node.isAsync) {
        return _emitAwaitFor(node);
      }
      var iterable = _visitExpression(node.iterable);
      var body = _visitScope(_effectiveBodyOf(node, node.body));

      var init = js.call('let #', _emitVariableDef(node.variable));
      if (_annotatedNullCheck(node.variable.annotations)) {
        body = js_ast.Block([
          _nullParameterCheck(_emitVariableRef(node.variable)),
          body,
        ]);
      }

      if (node.variable.name != null &&
          js_ast.variableIsReferenced(node.variable.name!, iterable)) {
        var temp = _emitScopedId('iter');
        return js_ast.Block([
          iterable.toVariableDeclaration(temp),
          js_ast.ForOf(init, temp, body),
        ]);
      }
      return js_ast.ForOf(init, iterable, body);
    });
  }

  js_ast.Statement _emitAwaitFor(ForInStatement node) {
    // Emits `await for (var value in stream) ...`, which desugars as:
    //
    // var iter = new StreamIterator(stream);
    // try {
    //   while (await iter.moveNext()) {
    //     var value = iter.current;
    //     ...
    //   }
    // } finally {
    //   await iter.cancel();
    // }
    //
    // Like the Dart VM, we call cancel() always, as it's safe to call if the
    // stream has already been cancelled.
    //
    // TODO(jmesserly): we may want a helper if these become common. For now the
    // full desugaring seems okay.
    var streamIterator = _coreTypes.nonNullableRawType(
      _asyncStreamIteratorClass,
    );
    var streamIteratorRti = _emitType(streamIterator);
    var createStreamIter = js_ast.Call(
      _emitConstructorName(
        streamIterator,
        _asyncStreamIteratorClass.procedures.firstWhere(
          (p) => p.isFactory && p.name.text == '',
        ),
      ),
      [streamIteratorRti, _visitExpression(node.iterable)],
    );

    var iter = _emitScopedId('iter');

    var savedContinueTargets = _currentContinueTargets;
    var savedBreakTargets = _currentBreakTargets;
    _currentContinueTargets = <LabeledStatement>[];
    _currentBreakTargets = <LabeledStatement>[];
    var loopStmt = js.statement('while (#) { let # = #.current; #; }', [
      js_ast.Await(js.call('#.moveNext()', iter))
        ..sourceInformation = _nodeStart(node.variable),
      _emitVariableDef(node.variable),
      iter,
      _visitStatement(node.body),
    ]);

    // Any label on the Dart loop statement should target the inner loop rather
    // than the try-block we will wrap it in.
    final loopLabelName = _labelNames.remove(node);
    if (loopLabelName != null) {
      loopStmt = js_ast.LabeledStatement(loopLabelName, loopStmt);
    }

    var awaitForStmt = js_ast.Block([
      js_ast.ExpressionStatement(
        js_ast.VariableDeclarationList('let', [
          js_ast.VariableInitialization(iter, createStreamIter),
        ])..sourceInformation = _nodeStart(node.iterable),
      ),
      js.statement('try { # } finally { #; }', [
        loopStmt,
        js_ast.Await(js.call('#.cancel()', iter))
          ..sourceInformation = _nodeStart(node.variable),
      ]),
    ], isScope: true);

    _currentContinueTargets = savedContinueTargets;
    _currentBreakTargets = savedBreakTargets;
    return awaitForStmt;
  }

  @override
  js_ast.Statement visitSwitchStatement(SwitchStatement node) {
    // Switches with labeled continues are generated as an infinite loop with
    // an explicit variable for holding the switch's next case state and an
    // explicit label. Any implicit breaks are made explicit (e.g., when break
    // is omitted for the final case statement).
    var previous = _inLabeledContinueSwitch;
    _inLabeledContinueSwitch = hasLabeledContinue(node);

    var cases = <js_ast.SwitchClause>[];

    if (_inLabeledContinueSwitch) {
      var labelState = _emitScopedId('labelState');
      // TODO(markzipan): Retrieve the real label name with source offsets
      var labelName = 'SL${_switchLabelStates.length}';
      _switchLabelStates[node] = _SwitchLabelState(labelName, labelState);

      // Since we wrap the switch in a 'while (true)' loop the continue targets
      // within the switch will no longer target the correct loop so we need
      // explicit breaks.
      final savedCurrentContinueTargets = _currentContinueTargets;
      _currentContinueTargets = [];

      for (var c in node.cases) {
        var subcases = _visitSwitchCase(
          c,
          lastSwitchCase: c == node.cases.last,
        );
        if (subcases.isNotEmpty) cases.addAll(subcases);
      }
      _currentContinueTargets = savedCurrentContinueTargets;

      var switchExpr = _visitExpression(node.expression);
      var switchStmt = js_ast.Switch(labelState, cases);
      var loopBody = js_ast.Block([switchStmt, js_ast.Break(null)]);
      var loopStmt = js_ast.While(js.boolean(true), loopBody);
      // Note: Cannot use _labelNames, as the label must be on the loop.
      // not the block surrounding the switch statement.
      var labeledStmt = js_ast.LabeledStatement(labelName, loopStmt);
      var block = js_ast.Block([
        js.statement('let # = #', [labelState, switchExpr]),
        labeledStmt,
      ]);
      _inLabeledContinueSwitch = previous;
      return block;
    }

    for (var c in node.cases) {
      var subcases = _visitSwitchCase(c);
      if (subcases.isNotEmpty) cases.addAll(subcases);
    }

    var stmt = js_ast.Switch(_visitExpression(node.expression), cases);
    _inLabeledContinueSwitch = previous;
    return stmt;
  }

  /// Helper for visiting a SwitchCase statement.
  ///
  /// [lastSwitchCase] is only used when the current switch statement contains
  /// labeled continues. Dart permits the final case to implicitly break, but
  /// switch statements with labeled continues must explicitly break/continue
  /// to escape the surrounding infinite loop.
  List<js_ast.SwitchClause> _visitSwitchCase(
    SwitchCase node, {
    bool lastSwitchCase = false,
  }) {
    var cases = <js_ast.SwitchClause>[];
    var emptyBlock = js_ast.Block.empty();
    // TODO(jmesserly): make sure we are statically checking fall through
    var body = _visitStatement(node.body).toBlock();
    var expressions = node.expressions;
    var lastExpr = expressions.isNotEmpty && !node.isDefault
        ? expressions.last
        : null;
    for (var e in expressions) {
      var jsExpr = _visitExpression(e);
      if (e is ConstantExpression && e.constant is NullConstant) {
        // Coerce null and undefined by adding an extra case.
        cases.add(js_ast.Case(js_ast.Prefix('void', js.number(0)), emptyBlock));
      }
      cases.add(js_ast.Case(jsExpr, e == lastExpr ? body : emptyBlock));
    }
    if (node.isDefault) {
      cases.add(js_ast.Default(body));
    }
    // Switch statements with continue labels must explicitly break from their
    // last case to escape the additional loop around the switch.
    if (lastSwitchCase && _inLabeledContinueSwitch && cases.isNotEmpty) {
      // TODO(markzipan): avoid generating unreachable breaks
      var switchStmt = node.parent as SwitchStatement;
      assert(_switchLabelStates.containsKey(node.parent));
      var breakStmt = js_ast.Break(_switchLabelStates[switchStmt]!.label);
      var switchBody = js_ast.Block(cases.last.body.statements..add(breakStmt));
      var lastCase = cases.last;
      var updatedSwitch = lastCase is js_ast.Case
          ? js_ast.Case(lastCase.expression, switchBody)
          : js_ast.Default(switchBody);
      cases.removeLast();
      cases.add(updatedSwitch);
    }
    return cases;
  }

  @override
  js_ast.Statement visitContinueSwitchStatement(ContinueSwitchStatement node) {
    var switchStmt = node.target.parent as SwitchStatement;
    if (_inLabeledContinueSwitch &&
        _switchLabelStates.containsKey(switchStmt)) {
      var switchState = _switchLabelStates[switchStmt]!;
      // Use the first constant expression that can match the collated switch
      // case. Use an unused symbol otherwise to force the default case.
      var jsExpr = node.target.expressions.isEmpty
          ? js.call("Symbol('_default')", [])
          : _visitExpression(node.target.expressions[0]);
      var setStateStmt = js.statement('# = #', [switchState.variable, jsExpr]);
      var continueStmt = js_ast.Continue(switchState.label);
      return js_ast.Block([setStateStmt, continueStmt]);
    }
    return _emitInvalidNode(
      node,
      'see https://github.com/dart-lang/sdk/issues/29352',
    ).toStatement();
  }

  @override
  js_ast.Statement visitIfStatement(IfStatement node) {
    bool isTriviallyTrue(condition) =>
        condition is js_ast.LiteralBool && condition.value;

    bool isTriviallyFalse(condition) =>
        condition is js_ast.LiteralBool && !condition.value;

    var condition = _visitTest(node.condition);
    if (isTriviallyTrue(condition)) return _visitScope(node.then);
    var otherwise = node.otherwise;
    var hasElse = otherwise != null;
    if (isTriviallyFalse(condition)) {
      return hasElse ? _visitScope(otherwise) : js_ast.EmptyStatement();
    }
    return hasElse
        ? js_ast.If(condition, _visitScope(node.then), _visitScope(otherwise))
        : js_ast.If.noElse(condition, _visitScope(node.then));
  }

  /// Visits a statement, and ensures the resulting AST handles block scope
  /// correctly. Essentially, we need to promote a variable declaration
  /// statement into a block in some cases, e.g.
  ///
  ///     do var x = 5; while (false); // Dart
  ///     do { let x = 5; } while (false); // JS
  js_ast.Statement _visitScope(Statement stmt) {
    var result = _visitStatement(stmt);
    if (result is js_ast.ExpressionStatement &&
        result.expression is js_ast.VariableDeclarationList) {
      return js_ast.Block([result]);
    }
    return result;
  }

  @override
  js_ast.Statement visitReturnStatement(ReturnStatement node) {
    var expression = node.expression;
    var value = expression == null ? null : _visitExpression(expression);
    return _emitReturnStatement(value);
  }

  @override
  js_ast.Statement visitTryCatch(TryCatch node) {
    return js_ast.Try(
      _visitStatement(node.body).toBlock(),
      _visitCatch(node.catches),
      null,
    );
  }

  js_ast.Catch? _visitCatch(List<Catch> clauses) {
    if (clauses.isEmpty) return null;

    var caughtError = VariableDeclaration('#e', isSynthesized: true);
    var savedRethrow = _rethrowParameter;
    _rethrowParameter = caughtError;

    // If we have more than one catch clause, always create a temporary so we
    // don't shadow any names.
    var exceptionParameter =
        (clauses.length == 1 ? clauses[0].exception : null) ??
        VariableDeclaration('#ex', isSynthesized: true);

    var stackTraceParameter =
        (clauses.length == 1 ? clauses[0].stackTrace : null) ??
        (clauses.any((c) => c.stackTrace != null)
            ? VariableDeclaration('#st', isSynthesized: true)
            : null);

    js_ast.Statement catchBody = js_ast.Throw(_emitVariableRef(caughtError));
    for (var clause in clauses.reversed) {
      catchBody = _catchClauseGuard(
        clause,
        catchBody,
        exceptionParameter,
        stackTraceParameter,
      );
    }
    var catchStatements = [
      js.statement('let # = #', [
        _emitVariableDef(exceptionParameter),
        _runtimeCall('getThrown(#)', [_emitVariableRef(caughtError)]),
      ]),
      if (stackTraceParameter != null)
        js.statement('let # = #', [
          _emitVariableDef(stackTraceParameter),
          _runtimeCall('stackTrace(#)', [_emitVariableRef(caughtError)]),
        ]),
      catchBody,
    ];
    _rethrowParameter = savedRethrow;
    return js_ast.Catch(
      _emitVariableDef(caughtError),
      js_ast.Block(catchStatements, isScope: true),
    );
  }

  js_ast.Statement _catchClauseGuard(
    Catch node,
    js_ast.Statement otherwise,
    VariableDeclaration exceptionParameter,
    VariableDeclaration? stackTraceParameter,
  ) {
    var body = <js_ast.Statement>[];
    var vars = HashSet<String>();

    void declareVariable(
      VariableDeclaration? variable,
      VariableDeclaration? value,
    ) {
      if (variable == null || value == null) return;
      vars.add(variable.name!);
      if (variable.name != value.name) {
        body.add(
          js.statement('let # = #', [
            _emitVariableDef(variable),
            _emitVariableRef(value),
          ]),
        );
      }
    }

    declareVariable(node.exception, exceptionParameter);
    declareVariable(node.stackTrace, stackTraceParameter);

    body.add(_visitStatement(node.body).toScopedBlock(vars));
    // Each catch clause defines its own scope.
    var then = js_ast.Block(body, isScope: true);
    var guardType = node.guard.extensionTypeErasure;
    // Discard following clauses, if any, as they are unreachable.
    if (_types.isTop(guardType)) return then;

    var condition = _emitIsExpression(
      VariableGet(exceptionParameter),
      guardType,
    );
    return js_ast.If(condition, then, otherwise)
      ..sourceInformation = _nodeStart(node);
  }

  @override
  js_ast.Statement visitTryFinally(TryFinally node) {
    var body = _visitStatement(node.body);
    var finallyBlock = _superDisallowed(
      () => _visitStatement(node.finalizer).toBlock(),
    );

    if (body is js_ast.Try && body.finallyPart == null) {
      // Kernel represents Dart try/catch/finally as try/catch nested inside of
      // try/finally.  Flatten that pattern in the output into JS try/catch/
      // finally.
      return js_ast.Try(body.body, body.catchPart, finallyBlock);
    }
    return js_ast.Try(body.toBlock(), null, finallyBlock);
  }

  @override
  js_ast.Statement visitYieldStatement(YieldStatement node) {
    return js_ast.DartYield(
      _visitExpression(node.expression),
      node.isYieldStar,
    );
  }

  @override
  js_ast.Statement visitVariableDeclaration(VariableDeclaration node) {
    // TODO(jmesserly): casts are sometimes required here.
    // Kernel does not represent these explicitly.
    var v = _emitVariableDef(node);
    return js.statement('let # = #;', [
      v,
      _visitInitializer(node.initializer, node.annotations),
    ]);
  }

  @override
  js_ast.Statement visitFunctionDeclaration(FunctionDeclaration node) {
    var func = node.function;
    var fn = _emitFunction(func, node.variable.name);

    var name = _emitVariableDef(node.variable);
    js_ast.Statement declareFn;
    declareFn = js_ast.toBoundFunctionStatement(fn, name);
    if (_reifyFunctionType(func)) {
      declareFn = js_ast.Block([
        declareFn,
        _emitFunctionTagged(
          _emitVariableRef(node.variable),
          func.computeThisFunctionType(Nullability.nonNullable),
        ).toStatement(),
      ]);
    }
    return declareFn;
  }

  @override
  js_ast.Expression visitInvalidExpression(InvalidExpression node) =>
      _emitInvalidNode(node);

  @override
  js_ast.Expression visitConstantExpression(ConstantExpression node) =>
      visitConstant(node.constant);

  @override
  js_ast.Expression visitVariableGet(VariableGet node) {
    var v = node.variable;
    var id = _emitVariableRef(v);
    if (id.name == v.name) {
      id = id.withSourceInformation(
        _variableSpan(node.fileOffset, v.name!.length),
      );
    }
    return id;
  }

  /// Detects temporary variables so we can avoid displaying
  /// them in the debugger if needed.
  bool _isTemporaryVariable(VariableDeclaration v) {
    // Late local variables are be exposed to the debugger for inspection and
    // evaluation by treating the backing store local variable as a regular
    // non-temporary variable.
    // See https://github.com/dart-lang/sdk/issues/55918
    if (isLateLoweredLocal(v)) return false;
    return v.isLowered ||
        v.isSynthesized ||
        v.name == null ||
        v.name!.startsWith('#');
  }

  /// Creates a temporary name recognized by the debugger.
  /// Assumes `_isTemporaryVariable(v)`  is true.
  String? _debuggerFriendlyTemporaryVariableName(VariableDeclaration v) {
    assert(_isTemporaryVariable(v));

    // Show extension 'this' in the debugger.
    // Do not show the rest of temporary variables.
    if (isExtensionThis(v)) {
      return extractLocalNameFromVariable(v);
    } else if (v.name != null) {
      return 't\$${v.name}';
    }
    return null;
  }

  js_ast.ScopedId _emitVariableRef(VariableDeclaration v) {
    if (_isTemporaryVariable(v)) {
      var name = _debuggerFriendlyTemporaryVariableName(v);
      name ??= 't\$${_tempVariables.length}';
      return _tempVariables.putIfAbsent(
        v,
        () => _emitScopedId(name!, needsCapture: true),
      );
    }
    var name = v.name!;
    if (isLateLoweredLocal(v)) {
      // Late local variables are be exposed to the debugger for inspection and
      // evaluation by treating the backing store local variable as a regular
      // non-temporary variable.
      // See https://github.com/dart-lang/sdk/issues/55918
      name = extractLocalNameFromLateLoweredLocal(name);
    }
    return js_ast.ScopedId.from(
      _variableTempIds[v] ??= _emitScopedId(name, needsCapture: true),
    );
  }

  /// Emits the declaration of a variable.
  ///
  /// This is similar to [_emitVariableRef] but it also attaches source
  /// location information, so hover will work as expected.
  js_ast.Identifier _emitVariableDef(VariableDeclaration v) {
    var identifier = _emitVariableRef(v)..sourceInformation = _nodeStart(v);
    variableIdentifiers[v] = identifier;
    return identifier;
  }

  js_ast.Statement? _initLetVariables() {
    var letVars = _letVariables!;
    if (letVars.isEmpty) return null;
    var result = js_ast.VariableDeclarationList(
      'let',
      letVars.map((v) => js_ast.VariableInitialization(v, null)).toList(),
    ).toStatement();
    letVars.clear();
    return result;
  }

  // TODO(jmesserly): resugar operators for kernel, such as ++x, x++, x+=.
  @override
  js_ast.Expression visitVariableSet(VariableSet node) {
    // Make the source information of the assignment use the start of the right
    // hand side, to help normalize the inconsistent locations of the CFE
    // lowerings for ++x, x++, x+=, etc.
    // See https://github.com/dart-lang/sdk/issues/55691.
    return _visitExpression(node.value).toAssignExpression(
      _emitVariableRef(node.variable),
    )..sourceInformation = _nodeStart(node.value);
  }

  @override
  js_ast.Expression visitDynamicGet(DynamicGet node) {
    var jsReceiver = _visitExpression(node.receiver);
    var jsMemberName = _emitMemberName(node.name.text);
    return _emitDynamicGet(jsReceiver, jsMemberName);
  }

  js_ast.Expression _emitDynamicGet(
    js_ast.Expression receiver,
    js_ast.Expression memberName,
  ) => _runtimeCall('dload$_replSuffix(#, #)', [receiver, memberName]);

  @override
  js_ast.Expression visitInstanceGet(InstanceGet node) {
    // TODO(nshahan): Marking an end span for property accessors would improve
    // source maps and hovering in the debugger. Unfortunately this is not
    // possible as Kernel does not store this data.
    var member = node.interfaceTarget;
    var receiver = node.receiver;
    var jsReceiver = _visitExpression(receiver);
    if (_isNonStaticJsInteropCallMember(member)) {
      // Historically DDC has treated this as a "callable class" and the access
      // of `.call` as a no-op.
      //
      // This is here to preserve the existing behavior for the non-static
      // JavaScript interop (including some failing cases) but could potentially
      // be cleaned up as a breaking change.
      return jsReceiver;
    }
    var memberName = node.name.text;
    if (_isObjectGetter(memberName) &&
        _shouldCallObjectMemberHelper(receiver)) {
      // The names of the static helper methods in the runtime must match the
      // names of the Object instance getters.
      return _runtimeCall('#(#)', [memberName, jsReceiver]);
    }
    // Otherwise generate this as a normal typed property get.
    var jsMemberName = _emitMemberName(
      memberName,
      member: node.interfaceTarget,
    );
    var instanceGet = js_ast.PropertyAccess(jsReceiver, jsMemberName);
    if (_shouldRewriteInvocationWithHotReloadChecks(node.interfaceTarget)) {
      instanceGet.sourceInformation = _nodeStart(node);
      // Since there are no arguments (unlike methods) the dynamic get path can
      // be reused for the hot reload checks on a getter.
      var checkedGet = _emitCast(
        _emitDynamicGet(
          _visitExpression(receiver),
          _emitMemberName(memberName),
        ),
        node.resultType,
      )..sourceInformation = _nodeStart(node);
      return _emitHotReloadSafeInvocation(instanceGet, checkedGet);
    }
    return _isNullCheckableJsInterop(node.interfaceTarget)
        ? _wrapWithJsInteropNullCheck(instanceGet)
        : instanceGet;
  }

  @override
  js_ast.Expression visitRecordIndexGet(RecordIndexGet node) =>
      _emitRecordElementGet(node.receiver, '\$${node.index + 1}');

  @override
  js_ast.Expression visitRecordNameGet(RecordNameGet node) =>
      _emitRecordElementGet(node.receiver, node.name);

  js_ast.Expression _emitRecordElementGet(
    Expression receiver,
    String elementName,
  ) => js_ast.PropertyAccess(
    _visitExpression(receiver),
    _emitMemberName(elementName),
  );

  @override
  js_ast.Expression visitInstanceTearOff(InstanceTearOff node) {
    var member = node.interfaceTarget;
    var receiver = node.receiver;
    var jsReceiver = _visitExpression(receiver);
    if (_isNonStaticJsInteropCallMember(member)) {
      // Historically DDC has treated this as a "callable class" and the tearoff
      // of `.call` as a no-op.
      //
      // This is here to preserve the existing behavior for the non-static
      // JavaScript interop (including some failing cases) but could potentially
      // be cleaned up as a breaking change.
      return jsReceiver;
    }
    var memberName = node.name.text;
    if (_isObjectMethodTearoff(memberName) &&
        _shouldCallObjectMemberHelper(receiver)) {
      // The names of the static helper methods in the runtime must start with
      // the names of the Object instance methods.
      var tearOffName = '${memberName}Tearoff';
      return _runtimeCall('#(#)', [tearOffName, jsReceiver]);
    }
    var jsMemberName = _emitMemberName(memberName, member: member);
    if (_reifyTearoff(member)) {
      return _runtimeCall('tearoff(#, null, #)', [jsReceiver, jsMemberName]);
    }
    var jsPropertyAccess = js_ast.PropertyAccess(jsReceiver, jsMemberName);
    return isJsMember(member)
        ? _runtimeCall('tearoffInterop(#, #)', [
            jsPropertyAccess,
            js.boolean(_isNullCheckableJsInterop(member)),
          ])
        : jsPropertyAccess;
  }

  /// Returns `true` when [member] is a `.call` member (field, getter or method)
  /// of a non-static JavaScript interop class.
  bool _isNonStaticJsInteropCallMember(Member member) =>
      member.name.text == 'call' && isNonStaticJsInterop(member);

  @override
  js_ast.Expression visitDynamicSet(DynamicSet node) {
    return _runtimeCall('dput$_replSuffix(#, #, #)', [
      _visitExpression(node.receiver),
      _emitMemberName(node.name.text),
      _visitExpression(node.value),
    ]);
  }

  @override
  js_ast.Expression visitInstanceSet(InstanceSet node) {
    var target = node.interfaceTarget;
    var value = isJsMember(target) ? _assertInterop(node.value) : node.value;
    return js.call('#.# = #', [
      _visitExpression(node.receiver),
      _emitMemberName(node.name.text, member: target),
      _visitExpression(value),
    ]);
  }

  /// True when the result of evaluating [e] is not known to have the Object
  /// members installed so a helper method should be called instead of a direct
  /// instance invocation.
  ///
  /// This is a best effort approach determined by the static type information
  /// and may return `true` when the evaluation result does in fact have the
  /// members at runtime.
  bool _shouldCallObjectMemberHelper(Expression e) {
    if (_isNullable(e)) return true;
    var type = e.getStaticType(_staticTypeContext).extensionTypeErasure;
    if (type is RecordType || type is FunctionType) return false;
    if (type is InterfaceType) {
      // TODO(nshahan): This could be expanded to any classes where we know all
      // implementations at compile time and none of them are JS interop.
      var cls = type.classNode;
      // NOTE: This is not guaranteed to always be true. Currently in the SDK
      // none of the final classes or their subtypes use JavaScript interop.
      // If that was to ever change, this check will need to be updated.
      // For now, this is a shortcut since all subclasses of a class are not
      // immediately accessible.
      if (cls.isFinal && cls.enclosingLibrary.importUri.isScheme('dart')) {
        return false;
      }
    }
    // Constants have a static type known at compile time that will not be a
    // subtype at runtime.
    return !_triviallyConstNoInterop(e);
  }

  /// True when [e] is known to evaluate to a constant that has an interface
  /// type that is not a JavaScript interop type.
  ///
  /// This is a simple approach and not an exhaustive search.
  bool _triviallyConstNoInterop(Expression? e) {
    if (e is ConstantExpression) {
      var type = e.constant.getType(_staticTypeContext).extensionTypeErasure;
      if (type is InterfaceType) return !usesJSInterop(type.classNode);
    } else if (e is StaticGet && e.target.isConst) {
      var target = e.target;
      if (target is Field) {
        return _triviallyConstNoInterop(target.initializer);
      }
    } else if (e is VariableGet && e.variable.isConst) {
      return _triviallyConstNoInterop(e.variable.initializer);
    }
    return false;
  }

  /// Returns [expression] wrapped in an optional null check.
  ///
  /// The null check is enabled by setting a flag during the application
  /// bootstrap via `jsInteropNonNullAsserts(true)` in the SDK runtime library.
  js_ast.Expression _wrapWithJsInteropNullCheck(js_ast.Expression expression) =>
      _runtimeCall('jsInteropNullCheck(#)', [expression]);

  /// Returns `true` when [member] is a JavaScript interop API that should be
  /// checked to be not null when the runtime flag `--interop-null-assertions`
  /// is enabled.
  ///
  /// These APIs are defined using the non-static package:js interop library and
  /// are typed to be non-nullable.
  bool _isNullCheckableJsInterop(Member member) {
    var type = member is Procedure
        ? member.function.returnType
        : member.getterType;
    return type.nullability == Nullability.nonNullable &&
        isNonStaticJsInterop(member);
  }

  /// Return whether [member] returns a native object whose type needs to be
  /// null-checked in sound null-safety.
  ///
  /// This is true for non-nullable native return types.
  bool _isNullCheckableNative(Member member) {
    var c = member.enclosingClass;
    return member.isExternal &&
        c != null &&
        _extensionTypes.isNativeClass(c) &&
        member is Procedure &&
        member.function.returnType.isPotentiallyNonNullable &&
        _isWebLibrary(member.enclosingLibrary.importUri);
  }

  // TODO(jmesserly): can we encapsulate REPL name lookups and remove this?
  // _emitMemberName would be a nice place to handle it, but we don't have
  // access to the target expression there (needed for `dart.replNameLookup`).
  String get _replSuffix => _options.replCompile ? 'Repl' : '';

  @override
  js_ast.Expression visitAbstractSuperPropertyGet(
    AbstractSuperPropertyGet node,
  ) {
    return _emitSuperPropertyGet(node.interfaceTarget);
  }

  @override
  js_ast.Expression visitSuperPropertyGet(SuperPropertyGet node) {
    return _emitSuperPropertyGet(node.interfaceTarget);
  }

  /// Emits a reference to a distinct mixin application, represented by
  /// a [mixedInClass] being mixed into [baseClass].
  ///
  /// Anonymous mixins should pass themselves as [baseClass] since they are
  /// already uniquely generated per distinct mixin application
  js_ast.Identifier _emitMixinId(Class mixedInClass, Class baseClass) {
    var mixinName = mixedInClass.name;
    if (!mixedInClass.isAnonymousMixin) {
      mixinName += '#${baseClass.name}';
    }
    return _mixinCache.putIfAbsent((
      mixedInClass,
      baseClass,
    ), () => _emitScopedId(mixinName));
  }

  js_ast.Expression _emitSuperPropertyGet(Member target) {
    if (_reifyTearoff(target)) {
      if (_superAllowed) {
        var jsName = _declareMemberName(target);
        var enclosingClass = target.enclosingClass!;
        js_ast.Expression? supertypeReference =
            _mixinSuperclassCache[_currentClass!];
        if (supertypeReference == null) {
          if (enclosingClass.isAnonymousMixin) {
            var mixinId = _emitMixinId(enclosingClass, enclosingClass);
            var enclosingLibrary = _emitLibraryName(getLibrary(enclosingClass));
            supertypeReference = js_ast.PropertyAccess(
              enclosingLibrary,
              js.string(mixinId.name),
            );
          } else {
            supertypeReference = _emitTopLevelNameNoExternalInterop(
              enclosingClass,
            );
          }
        }
        return _runtimeCall('superTearoff(this, #, #)', [
          supertypeReference,
          jsName,
        ]);
      } else {
        return _emitSuperTearoffFromDisallowedContext(target);
      }
    }
    return _emitSuperTarget(target);
  }

  @override
  js_ast.Expression visitAbstractSuperPropertySet(
    AbstractSuperPropertySet node,
  ) {
    return _emitSuperPropertySet(node.interfaceTarget, node.value);
  }

  @override
  js_ast.Expression visitSuperPropertySet(SuperPropertySet node) {
    return _emitSuperPropertySet(node.interfaceTarget, node.value);
  }

  js_ast.Expression _emitSuperPropertySet(Member target, Expression value) {
    var jsTarget = _emitSuperTarget(target, setter: true);
    return _visitExpression(value).toAssignExpression(jsTarget);
  }

  @override
  js_ast.Expression visitStaticGet(StaticGet node) {
    final target = node.target;
    if (_isDartJsHelper(target.enclosingLibrary)) {
      final name = target.name.text;
      if (name == 'staticInteropGlobalContext') {
        return _runtimeCall('global');
      }
    }
    var staticGet = _emitStaticGet(target);
    return _isNullCheckableJsInterop(target)
        ? _wrapWithJsInteropNullCheck(staticGet)
        : staticGet;
  }

  @override
  js_ast.Expression visitStaticTearOff(StaticTearOff node) =>
      _emitStaticGet(node.target);

  js_ast.Expression _emitStaticGet(Member target) {
    var propertyAccessor = _emitStaticTarget(target);
    var context = propertyAccessor.receiver;
    var property = propertyAccessor.selector;
    var result = js.call('#.#', [context, property]);
    if (_reifyTearoff(target)) {
      var targetLabel = js.string(fullyResolvedTargetLabel(target));
      return _runtimeCall('staticTearoff(#, #, #)', [
        context,
        targetLabel,
        property,
      ]);
    }
    return result;
  }

  @override
  js_ast.Expression visitStaticSet(StaticSet node) {
    var target = node.target;
    var result = _emitStaticTarget(target);
    var value = isJsMember(target) ? _assertInterop(node.value) : node.value;
    return _visitExpression(value).toAssignExpression(result);
  }

  @override
  js_ast.Expression visitDynamicInvocation(DynamicInvocation node) {
    return _emitDynamicInvocation(
      node.receiver,
      node.name.text,
      node.arguments,
    );
  }

  @override
  js_ast.Expression visitFunctionInvocation(FunctionInvocation node) {
    var name = node.name.text;
    assert(name == 'call');
    if (node.functionType == null) {
      // A `null` here implies the receiver is typed as `Function`. There isn't
      // any more type information available at compile time to know this
      // invocation is sound so a dynamic call will handle the checks at
      // runtime.
      return _emitDynamicInvocation(node.receiver, name, node.arguments);
    }
    return js_ast.Call(
      _visitExpression(node.receiver),
      _emitArgumentList(node.arguments),
    );
  }

  @override
  js_ast.Expression visitInstanceInvocation(InstanceInvocation node) {
    var invocation = _emitInstanceInvocation(node);
    return _isNullCheckableJsInterop(node.interfaceTarget)
        ? _wrapWithJsInteropNullCheck(invocation)
        : invocation;
  }

  @override
  js_ast.Expression visitInstanceGetterInvocation(
    InstanceGetterInvocation node,
  ) {
    if (node.functionType == null) {
      // A `null` here implies the receiver must be typed as `dynamic` or
      // `Function`. There isn't any more type information available at compile
      // time to know this invocation is sound so a dynamic call will handle the
      // checks at runtime.
      return _emitDynamicInvocation(
        node.receiver,
        node.name.text,
        node.arguments,
      );
    }
    var getterInvocation = _emitInstanceGetterInvocation(node);
    return _isNullCheckableJsInterop(node.interfaceTarget)
        ? _wrapWithJsInteropNullCheck(getterInvocation)
        : getterInvocation;
  }

  js_ast.Expression _emitInstanceGetterInvocation(
    InstanceGetterInvocation node,
  ) {
    var receiver = _visitExpression(node.receiver);
    var arguments = _emitArgumentList(
      node.arguments,
      target: node.interfaceTarget,
    );
    if (node.name.text == 'call') {
      // Erasing the extension types here to support existing callable behavior
      // on the old style JS interop types that are callable. This should be
      // safe as it is a compile time error to try to dynamically invoke a call
      // method that is inherited from an extension type.
      var receiverType = node.receiver
          .getStaticType(_staticTypeContext)
          .extensionTypeErasure;
      if (_isDirectCallable(receiverType)) {
        // Call methods on function types should be handled as function calls.
        return js_ast.Call(receiver, arguments);
      }
    }
    var memberName = _emitMemberName(
      node.name.text,
      member: node.interfaceTarget,
    );
    // We must erase the extension type to potentially find the `call` method.
    // If the extension type has a runtime representation with a `call`:
    //
    // ```
    // extension type Ext(C c) implements C {...}
    // class C {
    //   call() {...}
    // }
    // ```
    //
    // We can always erase eagerly because:
    //  - Extension types that do not implement an interface that exposes a
    //    `call` method will result in a static error at the call site.
    //  - Calls to extension types that implement their own call method are
    //    lowered by the CFE to top level static method calls.
    var erasedGetterType = node.interfaceTarget.getterType.extensionTypeErasure;
    if (erasedGetterType is InterfaceType) {
      var callName = _implicitCallTarget(erasedGetterType);
      if (callName != null) {
        return js.call('#.#.#(#)', [receiver, memberName, callName, arguments]);
      }
    }
    return js.call('#.#(#)', [receiver, memberName, arguments]);
  }

  @override
  js_ast.Expression visitLocalFunctionInvocation(LocalFunctionInvocation node) {
    assert(node.name.text == 'call');
    final localName = VariableGet(node.variable)..fileOffset = node.fileOffset;
    return js_ast.Call(
      _visitExpression(localName),
      _emitArgumentList(node.arguments),
    );
  }

  @override
  js_ast.Expression visitEqualsCall(EqualsCall node) {
    return _emitEqualityOperator(
      node.left,
      node.interfaceTarget,
      node.right,
      negated: false,
    );
  }

  @override
  js_ast.Expression visitEqualsNull(EqualsNull node) {
    return _emitCoreIdenticalCall([
      node.expression,
      NullLiteral(),
    ], negated: false);
  }

  js_ast.Expression _emitInstanceInvocation(InstanceInvocation node) {
    /// Returns `true` when [node] represents an invocation of `List.add()` that
    /// can be optimized.
    ///
    /// The optimized add operation can skip checks for a growable or modifiable
    /// list and the element type is known to be invariant so it can skip the
    /// type check.
    bool isNativeListInvariantAdd(InstanceInvocation node) {
      if (node.isInvariant && node.name.text == 'add') {
        // The call to add is marked as invariant, so the type check on the
        // parameter to add is not needed.
        var receiver = node.receiver;
        if (receiver is VariableGet &&
            receiver.variable.isFinal &&
            !receiver.variable.isLate) {
          // The receiver is a final variable, so it only contains the
          // initializer value. Also, avoid late variables in case the CFE
          // lowering of late variables is changed in the future.
          var initializer = receiver.variable.initializer;
          if (initializer is ListLiteral) {
            // The initializer is a list literal, so we know the list can be
            // grown, modified, and is represented by a JavaScript Array.
            return true;
          }
          if (initializer is StaticInvocation &&
              initializer.target.enclosingClass == _coreTypes.listClass &&
              initializer.target.name.text == 'of' &&
              initializer.arguments.named.isEmpty) {
            // The initializer is a `List.of()` call from the dart:core library
            // and the growable named argument has not been passed (it defaults
            // to true).
            return true;
          }
        }
      }
      return false;
    }

    var name = node.name.text;
    var receiver = node.receiver;
    var arguments = node.arguments;
    var target = node.interfaceTarget;
    if (isOperatorMethodName(name) && arguments.named.isEmpty) {
      var argLength = arguments.positional.length;
      if (argLength == 0) {
        return _emitUnaryOperator(receiver, target, node);
      } else if (argLength == 1) {
        return _emitBinaryOperator(
          receiver,
          target,
          arguments.positional[0],
          node,
        );
      }
    }
    var jsReceiver = _visitExpression(receiver);
    var args = _emitArgumentList(arguments, target: target);
    if (isNativeListInvariantAdd(node)) {
      return js.call('#.push(#)', [jsReceiver, args]);
    }
    if (name == 'call') {
      // Erasing the extension types here to support existing callable behavior
      // on the old style JS interop types that are callable. This should be
      // safe as it is a compile time error to try to dynamically invoke a call
      // method that is inherited from an extension type.
      var receiverType = receiver
          .getStaticType(_staticTypeContext)
          .extensionTypeErasure;
      if (_isDirectCallable(receiverType)) {
        // Handle call methods on function types as function calls.
        return js_ast.Call(jsReceiver, args);
      }
    }
    if (_isObjectMethodCall(name, arguments) &&
        _shouldCallObjectMemberHelper(receiver)) {
      // Handle Object methods when the receiver could potentially be `null` or
      // JavaScript interop values with static helper methods.
      // The names of the static helper methods in the runtime must match the
      // names of the Object instance members.
      return _runtimeCall('#(#, #)', [name, jsReceiver, args]);
    }
    // Otherwise generate this as a normal typed method call.
    var jsName = _emitMemberName(name, member: target);
    return js.call('#.#(#)', [jsReceiver, jsName, args]);
  }

  /// Returns an invocation of the runtime helpers `dcall`, `dgcall`, `dsend`,
  /// or `dgsend` to perform dynamic checks before invoking [memberName] on
  /// [receiver] and passing [arguments].
  js_ast.Expression _emitDynamicInvocation(
    Expression receiver,
    String memberName,
    Arguments arguments,
  ) {
    var jsArgs = [_visitExpression(receiver)];
    String jsCode;
    var (:typeArguments, :positionalArguments, :namedArguments) =
        _emitArgumentGroups(arguments, isJSInterop: false);
    if (memberName == 'call') {
      if (typeArguments != null) {
        jsCode = 'dgcall(#, #';
        jsArgs.add(js_ast.ArrayInitializer(typeArguments));
      } else {
        jsCode = 'dcall(#';
      }
    } else {
      if (typeArguments != null) {
        jsCode = 'dgsend$_replSuffix(#, #, #';
        jsArgs.add(js_ast.ArrayInitializer(typeArguments));
      } else {
        jsCode = 'dsend$_replSuffix(#, #';
      }
      jsArgs.add(_emitMemberName(memberName));
    }
    if (positionalArguments != null) {
      jsCode += ', #';
      jsArgs.add(js_ast.ArrayInitializer(positionalArguments));
    } else {
      jsCode += ', []';
    }
    if (namedArguments != null) {
      jsCode += ', #';
      jsArgs.add(js_ast.ObjectInitializer(namedArguments));
    }
    jsCode += ')';
    return _runtimeCall(jsCode, jsArgs);
  }

  bool _isDirectCallable(DartType t) =>
      t is FunctionType || (t is InterfaceType && usesJSInterop(t.classNode));

  js_ast.Expression? _implicitCallTarget(InterfaceType from) {
    var c = from.classNode;
    var member = _hierarchy.getInterfaceMember(c, Name('call'));
    if (member is Procedure && !member.isAccessor && !usesJSInterop(c)) {
      return _emitMemberName('call', member: member);
    }
    return null;
  }

  js_ast.Expression _emitUnaryOperator(
    Expression expr,
    Member? target,
    InvocationExpression node,
  ) {
    var op = node.name.text;
    if (target != null) {
      var dispatchType = _coreTypes.nonNullableRawType(target.enclosingClass!);
      if (_typeRep.unaryOperationIsPrimitive(dispatchType)) {
        if (op == '~') {
          if (_typeRep.isNumber(dispatchType)) {
            return _coerceBitOperationResultToUnsigned(
              node,
              js.call('~#', _notNull(expr)),
            );
          }
          return _emitOperatorCall(expr, target, op, []);
        }
        if (op == 'unary-') op = '-';
        return js.call('$op#', _notNull(expr));
      }
    }
    return _emitOperatorCall(expr, target, op, []);
  }

  /// Bit operations are coerced to values on [0, 2^32). The coercion changes
  /// the interpretation of the 32-bit value from signed to unsigned.  Most
  /// JavaScript operations interpret their operands as signed and generate
  /// signed results.
  js_ast.Expression _coerceBitOperationResultToUnsigned(
    Expression node,
    js_ast.Expression uncoerced,
  ) {
    // Don't coerce if the parent will coerce.
    var parent = node.parent;
    if (parent is InvocationExpression && _nodeIsBitwiseOperation(parent)) {
      return uncoerced;
    }

    // Don't do a no-op coerce if the most significant bit is zero.
    if (_is31BitUnsigned(node)) return uncoerced;

    // If the consumer of the expression is '==' or '!=' with a constant that
    // fits in 31 bits, adding a coercion does not change the result of the
    // comparison, e.g.  `a & ~b == 0`.
    Expression? left;
    late Expression right;
    late String op;
    if (parent is InvocationExpression &&
        parent.arguments.positional.length == 1) {
      op = parent.name.text;
      left = getInvocationReceiver(parent);
      right = parent.arguments.positional[0];
    } else if (parent is EqualsCall) {
      left = parent.left;
      right = parent.right;
      op = '==';
    } else if (parent is EqualsNull) {
      left = parent.expression;
      right = NullLiteral();
      op = '==';
    }
    if (left != null) {
      if (op == '==') {
        const MAX = 0x7fffffff;
        if (_asIntInRange(right, 0, MAX) != null) return uncoerced;
        if (_asIntInRange(left, 0, MAX) != null) return uncoerced;
      } else if (op == '>>') {
        if (_isDefinitelyNonNegative(left) &&
            _asIntInRange(right, 0, 31) != null) {
          // Parent will generate `# >>> n`.
          return uncoerced;
        }
      }
    }
    return js.call('# >>> 0', uncoerced);
  }

  bool _nodeIsBitwiseOperation(InvocationExpression node) {
    switch (node.name.text) {
      case '&':
      case '|':
      case '^':
      case '~':
        return true;
    }
    return false;
  }

  int? _asIntInRange(Expression expr, int low, int high) {
    if (expr is IntLiteral) {
      if (expr.value >= low && expr.value <= high) return expr.value;
      return null;
    }
    if (_constants.isConstant(expr)) {
      var c = _constants.evaluate(expr);
      if (c is IntConstant && c.value >= low && c.value <= high) return c.value;
    }
    return null;
  }

  bool _isDefinitelyNonNegative(Expression expr) {
    if (expr is IntLiteral) return expr.value >= 0;

    // TODO(sra): Lengths of known list types etc.
    return expr is InvocationExpression && _nodeIsBitwiseOperation(expr);
  }

  /// Does the parent of [node] mask the result to [width] bits or fewer?
  bool _parentMasksToWidth(Expression node, int width) {
    var parent = node.parent;
    if (parent == null) return false;
    if (parent is InvocationExpression && _nodeIsBitwiseOperation(parent)) {
      if (parent.name.text == '&' && parent.arguments.positional.length == 1) {
        var left = getInvocationReceiver(parent);
        var right = parent.arguments.positional[0];
        final max = (1 << width) - 1;
        if (left != null) {
          if (_asIntInRange(right, 0, max) != null) return true;
          if (_asIntInRange(left, 0, max) != null) return true;
        }
      }
      return _parentMasksToWidth(parent, width);
    }
    return false;
  }

  /// Determines if the result of evaluating [expr] will be an non-negative
  /// value that fits in 31 bits.
  bool _is31BitUnsigned(Expression expr) {
    const MAX = 32; // Includes larger and negative values.
    /// Determines how many bits are required to hold result of evaluation
    /// [expr].  [depth] is used to bound exploration of huge expressions.
    int bitWidth(Expression expr, int depth) {
      if (expr is IntLiteral) {
        return expr.value >= 0 ? expr.value.bitLength : MAX;
      }
      if (++depth > 5) return MAX;
      if (expr is InvocationExpression &&
          expr.arguments.positional.length == 1) {
        var left = getInvocationReceiver(expr);
        var right = expr.arguments.positional[0];
        if (left != null) {
          switch (expr.name.text) {
            case '&':
              return min(bitWidth(left, depth), bitWidth(right, depth));

            case '|':
            case '^':
              return max(bitWidth(left, depth), bitWidth(right, depth));

            case '>>':
              var shiftValue = _asIntInRange(right, 0, 31);
              if (shiftValue != null) {
                var leftWidth = bitWidth(left, depth);
                return leftWidth == MAX ? MAX : max(0, leftWidth - shiftValue);
              }
              return MAX;

            case '<<':
              var leftWidth = bitWidth(left, depth);
              var shiftValue = _asIntInRange(right, 0, 31);
              if (shiftValue != null) {
                return min(MAX, leftWidth + shiftValue);
              }
              var rightWidth = bitWidth(right, depth);
              if (rightWidth <= 5) {
                // e.g.  `1 << (x & 7)` has a rightWidth of 3, so shifts by up
                // to (1 << 3) - 1 == 7 bits.
                return min(MAX, leftWidth + ((1 << rightWidth) - 1));
              }
              return MAX;
            default:
              return MAX;
          }
        }
      }
      var value = _asIntInRange(expr, 0, 0x7fffffff);
      if (value != null) return value.bitLength;
      return MAX;
    }

    return bitWidth(expr, 0) < 32;
  }

  js_ast.Expression _emitBinaryOperator(
    Expression left,
    Member? target,
    Expression right,
    InvocationExpression node,
  ) {
    var op = node.name.text;
    if (op == '==') return _emitEqualityOperator(left, target, right);

    // TODO(jmesserly): using the target type here to work around:
    // https://github.com/dart-lang/sdk/issues/33293
    if (target != null) {
      var targetClass = target.enclosingClass!;
      var leftType = _coreTypes.nonNullableRawType(targetClass);
      var rightType = right.getStaticType(_staticTypeContext);

      if (_typeRep.binaryOperationIsPrimitive(leftType, rightType) ||
          targetClass == _coreTypes.stringClass && op == '+') {
        // Inline operations on primitive types where possible.
        // TODO(jmesserly): inline these from dart:core instead of hardcoding
        // the implementation details here.

        /// Emits an inlined binary operation using the JS [code], adding null
        /// checks if needed to ensure we throw the appropriate error.
        js_ast.Expression binary(String code) {
          return js.call(code, [_notNull(left), _notNull(right)])
            ..sourceInformation = continueSourceMap;
        }

        js_ast.Expression bitwise(String code) {
          return _coerceBitOperationResultToUnsigned(node, binary(code));
        }

        /// Similar to [binary] but applies a boolean conversion to the right
        /// operand, to match the boolean bitwise operators in dart:core.
        ///
        /// Short circuiting operators should not be used in [code], because the
        /// null checks for both operands must happen unconditionally.
        js_ast.Expression bitwiseBool(String code) {
          return js.call(code, [_notNull(left), _visitTest(right)]);
        }

        switch (op) {
          case '~/':
            // `a ~/ b` is equivalent to `(a / b).truncate()`
            return js.call('(# / #).#()', [
              _notNull(left),
              _notNull(right),
              _emitMemberName('truncate', memberClass: targetClass),
            ]);

          case '%':
            // TODO(sra): We can generate `a % b + 0` if both are non-negative
            // (the `+ 0` is to coerce -0.0 to 0).
            return _emitOperatorCall(left, target, op, [right]);

          case '&':
            return _typeRep.isBoolean(leftType)
                ? bitwiseBool('!!(# & #)')
                : bitwise('# & #');

          case '|':
            return _typeRep.isBoolean(leftType)
                ? bitwiseBool('!!(# | #)')
                : bitwise('# | #');

          case '^':
            return _typeRep.isBoolean(leftType)
                ? bitwiseBool('# !== #')
                : bitwise('# ^ #');

          case '>>':
            var shiftCount = _asIntInRange(right, 0, 31);
            if (_is31BitUnsigned(left) && shiftCount != null) {
              return binary('# >> #');
            }
            if (_isDefinitelyNonNegative(left) && shiftCount != null) {
              return binary('# >>> #');
            }
            // If the context selects out only bits that can't be affected by
            // the sign position we can use any JavaScript shift,
            // `(x >> 6) & 3`.
            if (shiftCount != null &&
                _parentMasksToWidth(node, 31 - shiftCount)) {
              return binary('# >> #');
            }
            return _emitOperatorCall(left, target, op, [right]);

          case '<<':
            if (_is31BitUnsigned(node)) {
              // Result is 31 bit unsigned which implies the shift count was
              // small enough not to pollute the sign bit.
              return binary('# << #');
            }
            if (_asIntInRange(right, 0, 31) != null) {
              return _coerceBitOperationResultToUnsigned(
                node,
                binary('# << #'),
              );
            }
            return _emitOperatorCall(left, target, op, [right]);

          case '>>>':
            if (_asIntInRange(right, 0, 31) != null) {
              return binary('# >>> #');
            }
            return _emitOperatorCall(left, target, op, [right]);

          default:
            // TODO(vsm): When do Dart ops not map to JS?
            return binary('# $op #');
        }
      }
    }

    return _emitOperatorCall(left, target, op, [right]);
  }

  js_ast.Expression _emitEqualityOperator(
    Expression left,
    Member? target,
    Expression right, {
    bool negated = false,
  }) {
    var targetClass = target?.enclosingClass;
    var leftType = left.getStaticType(_staticTypeContext).extensionTypeErasure;

    // Conceptually `x == y` in Dart is defined as:
    //
    // If either x or y is null, then they are equal iff they are both null.
    // Otherwise, equality is the result of calling `x.==(y)`.
    //
    // In practice, `x.==(y)` is equivalent to `identical(x, y)` in many cases:
    // - when either side is known to be `null` (literal or Null type)
    // - left side is an enum
    // - left side is a primitive type
    //
    // We also compile `operator ==` methods to ensure they check the right side
    // for null`. This allows us to skip the check at call sites.
    //
    // TODO(leafp,jmesserly): we could use class hierarchy analysis to check
    // if `operator ==` was overridden, similar to how we devirtualize private
    // fields.
    //
    // If we know that the left type uses identity for equality, we can
    // sometimes emit better code, either `===` or `==`.
    var isEnum = leftType is InterfaceType && leftType.classNode.isEnum;

    var usesIdentity =
        _typeRep.isPrimitive(leftType) ||
        isEnum ||
        _isNull(left) ||
        _isNull(right);

    if (usesIdentity) {
      return _emitCoreIdenticalCall([left, right], negated: negated);
    }

    if (_shouldCallObjectMemberHelper(left)) {
      // The LHS isn't guaranteed to have an equals method we need to use a
      // runtime helper.
      return js.call(negated ? '!#' : '#', [
        _runtimeCall('equals(#, #)', [
          _visitExpression(left),
          _visitExpression(right),
        ]),
      ]);
    }
    // Otherwise it is safe to call the equals method on the LHS directly.
    return js.call(negated ? '!#[#](#)' : '#[#](#)', [
      _visitExpression(left),
      _emitMemberName('==', memberClass: targetClass),
      _visitExpression(right),
    ]);
  }

  /// Emits a generic send, like an operator method.
  ///
  /// **Please note** this function does not support method invocation syntax
  /// `obj.name(args)` because that could be a getter followed by a call.
  /// See [visitMethodInvocation].
  js_ast.Expression _emitOperatorCall(
    Expression receiver,
    Member? target,
    String name,
    List<Expression> args,
  ) {
    // TODO(jmesserly): calls that don't pass `element` are probably broken for
    // `super` calls from disallowed super locations.
    var memberName = _emitMemberName(name, member: target);
    if (target == null) {
      // dynamic dispatch
      var dynamicHelper = const {'[]': 'dindex', '[]=': 'dsetindex'}[name];
      if (dynamicHelper != null) {
        return _runtimeCall('$dynamicHelper(#, #)', [
          _visitExpression(receiver),
          _visitExpressionList(args),
        ]);
      } else {
        return _runtimeCall('dsend(#, #, [#])', [
          _visitExpression(receiver),
          memberName,
          _visitExpressionList(args),
        ]);
      }
    }

    // Generic dispatch to a statically known method.
    return js.call('#.#(#)', [
      _visitExpression(receiver),
      memberName,
      _visitExpressionList(args),
    ]);
  }

  // TODO(jmesserly): optimize super operators for kernel
  @override
  js_ast.Expression visitAbstractSuperMethodInvocation(
    AbstractSuperMethodInvocation node,
  ) {
    return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments);
  }

  @override
  js_ast.Expression visitSuperMethodInvocation(SuperMethodInvocation node) {
    return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments);
  }

  js_ast.Expression _emitSuperMethodInvocation(
    Member target,
    Arguments arguments,
  ) {
    return js_ast.Call(
      _emitSuperTarget(target),
      _emitArgumentList(arguments, target: target),
    );
  }

  /// Emits the [js_ast.PropertyAccess] for accessors or method calls to
  /// [jsTarget].[jsName], replacing `super` if it is not allowed in scope.
  js_ast.PropertyAccess _emitSuperTarget(Member member, {bool setter = false}) {
    var jsName = _declareMemberName(member);
    if (_optimizeNonVirtualFieldAccess &&
        member is Field &&
        !_virtualFields.isVirtual(member)) {
      return js_ast.PropertyAccess(js_ast.This(), jsName);
    }
    if (_superAllowed) return js_ast.PropertyAccess(js_ast.Super(), jsName);

    // If we can't emit `super` in this context, generate a helper that does it
    // for us, and call the helper.
    //
    // NOTE: This is intended to help in the cases of calling a `super` getter,
    // setter, or method. For the case of tearing off a `super` method in
    // contexts where `super` isn't allowed, see
    // [_emitSuperTearoffFromDisallowedContext].
    var name = member.name.text;
    var getter =
        (member is Field && !setter) ||
        (member is Procedure && member.isGetter);
    // Prefix applied to the name only used in the compiler for a map key. This
    // name does not make its way into the compiled program.
    var lookupPrefix = setter
        ? r'set$'
        : getter
        ? r'get$'
        : '';
    var jsMethod = _superHelpers.putIfAbsent('$lookupPrefix$name', () {
      var isAccessor = member is Procedure ? member.isAccessor : true;
      if (isAccessor) {
        assert(
          member is Procedure
              ? member.isSetter == setter
              : !setter || !(member as Field).isFinal,
        );
        var fn = js.fun(
          setter
              ? 'function(x) { super[#] = x; }'
              : 'function() { return super[#]; }',
          [jsName],
        );

        return js_ast.Method(
          _emitScopedId(name),
          fn,
          isGetter: !setter,
          isSetter: setter,
        );
      } else {
        var function = member.function;
        var params = [
          ..._emitTypeFormals(function.typeParameters),
          for (var param in function.positionalParameters)
            _emitIdentifier(param.name!),
          if (function.namedParameters.isNotEmpty) _namedArgumentTemp,
        ];

        var fn = js.fun('function(#) { return super[#](#); }', [
          params,
          jsName,
          params,
        ]);
        name = js_ast.friendlyNameForDartOperator[name] ?? name;
        return js_ast.Method(_emitScopedId(name), fn);
      }
    });
    return js_ast.PropertyAccess(js_ast.This(), jsMethod.name);
  }

  /// Generates a special string used for identifying a torn off member [m].
  ///
  /// This tag is used for determining tearoff equality. We attach these tags
  /// at tearoff time for static tearoffs and in the method signature for
  /// dynamic tearoffs.
  String fullyResolvedTargetLabel(Member m) {
    return '${m.enclosingLibrary.importUri}:${m.enclosingClass?.name ?? ""}';
  }

  /// Generates a special string used for identifying class [c]'s applied mixed
  /// in members.
  ///
  /// This tag is used for determining tearoff equality. We attach these tags
  /// at tearoff time for static tearoffs and in the method signature for
  /// dynamic tearoffs.
  String fullyResolvedMixinClassLabel(Class c) {
    return '${c.enclosingLibrary.importUri}:${c.name}';
  }

  /// Generates a helper method that is inserted into the class that binds a
  /// tearoff of [member] from `super` and returns a call to the helper.
  ///
  /// This method assumes `super` is not allowed in the current context.
  // TODO(nshahan) Replace with a kernel transform and synthetic method filters
  // for devtools.
  js_ast.Expression _emitSuperTearoffFromDisallowedContext(Member member) {
    var jsName = _declareMemberName(member);
    var name = '_#super#tearOff#${member.name.text}';
    var jsMethod = _superHelpers.putIfAbsent(name, () {
      var superclass = member.enclosingClass!;
      var supertypeReference =
          _mixinSuperclassCache[superclass] ??
          _emitTopLevelNameNoExternalInterop(superclass);
      var jsReturnValue = _runtimeCall('superTearoff(this, #, #)', [
        supertypeReference,
        jsName,
      ]);
      var fn = js.fun('function() { return #; }', [jsReturnValue]);
      name = js_ast.friendlyNameForDartOperator[name] ?? name;
      return js_ast.Method(_emitScopedId(name), fn);
    });
    return js_ast.Call(js_ast.PropertyAccess(js_ast.This(), jsMethod.name), []);
  }

  /// If [e] is a [TypeLiteral] or a [TypeLiteralConstant] expression, return
  /// the underlying [DartType], otherwise returns null.
  // TODO(sigmund,nshahan): remove all uses of type literals in the runtime
  // libraries, so that this pattern can be deleted.
  DartType? _getTypeLiteralType(Expression e) {
    if (e is TypeLiteral) return e.type;
    if (e is ConstantExpression) {
      var constant = e.constant;
      if (constant is TypeLiteralConstant) {
        return constant.type.withDeclaredNullability(Nullability.nonNullable);
      }
    }
    return null;
  }

  @override
  js_ast.Expression visitStaticInvocation(StaticInvocation node) {
    var target = node.target;
    if (isInlineJS(target)) return _emitInlineJSCode(node) as js_ast.Expression;
    if (target.isFactory) return _emitFactoryInvocation(node);

    var enclosingLibrary = target.enclosingLibrary;
    if (_isDartLibrary(enclosingLibrary, '_rti') &&
        _inlineTester.canInline(target.function)) {
      // Transform code that would otherwise appear as a static invocation:
      // ```
      // if (_rti._isString(object)) {...}
      // ```
      //
      // to be avoid cost of extra function calls:
      //
      // ```
      // if (typeof object == "string") {...}
      // ```
      var body = node.target.function.body;
      Expression? bodyToInline;
      // Extract the body.
      if (body is ReturnStatement) {
        // Ex: foo() => <body>;
        bodyToInline = body.expression;
      } else if (body is Block) {
        // Ex: foo() { <body> }
        var singleStatement = body.statements.single;
        if (singleStatement is ReturnStatement) {
          bodyToInline = singleStatement.expression;
        }
      }
      if (bodyToInline != null) {
        // Clone the function parameters and create the mappings from the clone
        // to the argument passed.
        var cloner = CloneVisitorNotMembers();
        var originalParameters = target.function.positionalParameters;
        var replacementArguments = node.arguments.positional;
        var replacements = {
          for (var i = 0; i < originalParameters.length; i++)
            originalParameters[i].accept(cloner) as VariableDeclaration:
                replacementArguments[i],
        };
        // Clone the body using the same cloner to ensure the cloned parameters
        // are correctly linked to their accesses.
        var cloneToInline = bodyToInline.accept(cloner);
        // Substitute the use of the parameters with the values passed.
        var replacer = VariableGetReplacer(replacements);
        var replaced = cloneToInline.accept(replacer) as Expression;
        // Compile the result normally and wrap in parenthesis.
        return js.call('(#)', [replaced.accept(this)]);
      }
    }

    if (_isDartInternal(enclosingLibrary)) {
      var args = node.arguments;
      if (args.positional.length == 1 &&
          args.types.length == 1 &&
          args.named.isEmpty &&
          target.name.text == 'unsafeCast') {
        // Optimize some internal SDK calls by avoiding the insertion of a
        // runtime cast.
        return args.positional.single.accept(this);
      } else if (node.arguments.positional.length == 2 &&
          node.arguments.types.length == 1 &&
          node.arguments.named.isEmpty &&
          target.name.text == 'extractTypeArguments') {
        // Inline the extraction and method call at compile time because we
        // don't preserve the original type argument names into the runtime.
        // Those names are needed in the evaluation string used to extract the
        // types from the provided instance.
        // At this time the only two uses of this method are extracting from
        // `Iterable` and `Map`. There are no extension type uses so no need for
        // erasure here.
        var extractionType = node.arguments.types.single;
        if (extractionType is! InterfaceType) {
          throw UnsupportedError(
            'Type arguments can only be extracted from interface types: '
            'found $extractionType (${extractionType.runtimeType}) at '
            '${node.location}',
          );
        }
        var extractionTypeParameters = extractionType.classNode.typeParameters;
        if (extractionTypeParameters.isEmpty) {
          throw UnsupportedError(
            'The extraction type must have type arguments to be extracted: '
            'found $extractionType (${extractionType.runtimeType}) at '
            '${node.location}',
          );
        }
        var extractionTypeParameterNames = extractionTypeParameters.map(
          (p) => '${extractionType.classNode.name}.${p.name!}',
        );
        var instance = node.arguments.positional.first.accept(this);
        var function = node.arguments.positional.last.accept(this);
        var extractedTypeArgs = js_ast.ArrayInitializer([
          for (var recipe in extractionTypeParameterNames)
            js.call('#.#(#, "$recipe")', [
              _emitLibraryName(_rtiLibrary),
              _emitMemberName('evalInInstance', memberClass: _rtiClass),
              instance,
            ]),
        ]);
        return _runtimeCall('dgcall(#, #, [])', [function, extractedTypeArgs]);
      }
    }

    if (_isDartForeignHelper(enclosingLibrary)) {
      var args = node.arguments.positional;
      var typeArgs = node.arguments.types;
      var name = target.name.text;

      if (args.isEmpty) {
        if (typeArgs.isEmpty && name == 'DART_RUNTIME_LIBRARY') {
          return _emitLibraryName(_runtimeLibrary);
        }
        if (typeArgs.length == 1) {
          if (name == 'TYPE_REF') {
            return _emitType(typeArgs.single);
          }
        }
      }
      if (args.length == 1) {
        if (name == 'getInterceptor') {
          var argExpression = args.single.accept(this);
          return _runtimeCall('getInterceptorForRti(#)', [argExpression]);
        }
        if (name == 'JS_GET_NAME') {
          var staticGet = args.single as StaticGet;
          var enumField = staticGet.target as Field;
          return _emitExpressionForJsGetName(_asJsGetName(enumField));
        }
        if (name == 'JS_CLASS_REF') {
          var constNode = args.single as ConstantExpression;
          var typeConstant = constNode.constant as TypeLiteralConstant;
          var type = typeConstant.type;
          if (type is NullType) {
            return _emitTopLevelName(_coreTypes.deprecatedNullClass);
          }
          if (type is! InterfaceType) {
            throw UnsupportedError(
              'JS_CLASS_REF only supports interface types: found $type '
              '(${type.runtimeType}) at ${node.location}',
            );
          }
          return _emitTopLevelName(type.classNode);
        }
        if (name == 'RAW_DART_FUNCTION_REF') {
          var expression = args.single as ConstantExpression;
          var fn = expression.constant as StaticTearOffConstant;
          return _emitStaticTarget(fn.target);
        }
        if (name == 'JS_GET_FLAG') {
          var flag = args.single as StringLiteral;
          var value = flag.value;
          return switch (value) {
            'DEV_COMPILER' => js.boolean(true),
            'MINIFIED' => js.boolean(false),
            'VARIANCE' =>
              // Variance is turned on by default, but only interfaces that have
              // at least one type parameter with non-legacy variance will have
              // extra information recorded.
              js.boolean(true),
            _ => throw UnsupportedError(
              'Unknown JS_GET_FLAG "$value" at ${node.location}',
            ),
          };
        }
      } else if (args.length == 2) {
        if (name == 'JS_EMBEDDED_GLOBAL') return _emitEmbeddedGlobal(node);
        if (name == 'JS_STRING_CONCAT') {
          var left = _visitExpression(args.first);
          var right = _visitExpression(args.last);
          return js.call('# + #', [left, right]);
        }
      }
      if (name == 'JS_BUILTIN') {
        var staticGet = args[1] as StaticGet;
        var enumField = staticGet.target as Field;
        return _emitOperationForJsBuiltIn(_asJsBuiltin(enumField));
      }
      if (name == 'JS_RAW_EXCEPTION') {
        // Serves as a way to access the wrapped JS exception.
        return _emitVariableRef(_rethrowParameter!);
      }
      if (name == 'JS_RTI_PARAMETER') {
        return _rtiParam;
      }
    }

    if (_isSdkInternalRuntime(enclosingLibrary)) {
      var name = target.name.text;
      if (node.arguments.positional.isEmpty) {
        if (name == 'hotRestartGeneration') {
          return js.call('dartDevEmbedder.hotRestartGeneration');
        }
      } else if (node.arguments.positional.length == 1) {
        var firstArg = node.arguments.positional.single;
        if (name == 'extensionSymbol' && firstArg is StringLiteral) {
          return _getSymbol(_getExtensionSymbolInternal(firstArg.value));
        }
      } else if (node.arguments.positional.length == 2) {
        var firstArg = node.arguments.positional[0];
        var secondArg = node.arguments.positional[1];
        var type = _getTypeLiteralType(secondArg);
        if (name == '_jsInstanceOf' &&
            type is InterfaceType &&
            type.typeArguments.isEmpty) {
          return js.call('# instanceof #', [
            _visitExpression(firstArg),
            _emitTopLevelName(type.classNode),
          ]);
        }
      }
    }
    if (_isDartJsHelper(enclosingLibrary)) {
      var name = target.name.text;
      if (name == 'jsObjectGetPrototypeOf') {
        var obj = node.arguments.positional.single;
        return _emitJSObjectGetPrototypeOf(
          _visitExpression(obj),
          fullyQualifiedName: false,
        );
      }
      if (name == 'jsObjectSetPrototypeOf') {
        var obj = node.arguments.positional.first;
        var prototype = node.arguments.positional.last;
        return _emitJSObjectSetPrototypeOf(
          _visitExpression(obj),
          _visitExpression(prototype),
          fullyQualifiedName: false,
        );
      }
    }
    if (target.isExternal &&
        target.isExtensionTypeMember &&
        target.function.namedParameters.isNotEmpty) {
      // JS interop checks assert that only external extension type constructors
      // and factories have named parameters.
      assert(target.function.positionalParameters.isEmpty);
      return _emitObjectLiteral(
        Arguments(
          node.arguments.positional,
          types: node.arguments.types,
          named: node.arguments.named,
        ),
        target,
      );
    }
    if (target == _coreTypes.identicalProcedure) {
      return _emitCoreIdenticalCall(node.arguments.positional);
    }
    if (_isDebuggerCall(target)) {
      return _emitDebuggerCall(node) as js_ast.Expression;
    }
    if (_isDartJsUtil(enclosingLibrary)) {
      // We try and do further inlining here for the unchecked/trusted-type
      // variants of js_util methods. Note that we only lower the methods that
      // are used in transformations and are private. Also note that this
      // inlining ignores `sdk/lib/_internal/js_shared/lib/js_util_patch.dart`'s
      // implementations for the lowered methods.
      //
      // If you update the code there, you should update the code here.
      // Long-term, we'll need a better IR to lower interop methods to, or a DDC
      // inliner to do the inlining for us.
      var name = target.name.text;
      if (name == '_getPropertyTrustType') {
        return js_ast.PropertyAccess(
          _visitExpression(node.arguments.positional[0]),
          _visitExpression(node.arguments.positional[1]),
        );
      } else if (name == '_setPropertyUnchecked') {
        return _visitExpression(
          node.arguments.positional[2],
        ).toAssignExpression(
          js_ast.PropertyAccess(
            _visitExpression(node.arguments.positional[0]),
            _visitExpression(node.arguments.positional[1]),
          ),
        );
      } else if (_callMethodUncheckedRegex.hasMatch(name)) {
        // Note that we don't lower `_callMethodTrustType`. This is because it
        // uses `assertInterop` checks.
        var trustType = name.contains('TrustType');
        var args = <js_ast.Expression>[];
        assert(node.arguments.named.isEmpty);
        // Ignore the receiver and name of the method.
        for (var i = 2; i < node.arguments.positional.length; i++) {
          args.add(_visitExpression(node.arguments.positional[i]));
        }
        js_ast.Expression call = js_ast.Call(
          js_ast.PropertyAccess(
            _visitExpression(node.arguments.positional[0]),
            _visitExpression(node.arguments.positional[1]),
          ),
          args,
        );
        if (!trustType) {
          call = _emitCast(call, node.arguments.types[0]);
        }
        return call;
      } else if (_callConstructorUncheckedRegex.hasMatch(name)) {
        var args = <js_ast.Expression>[];
        assert(node.arguments.named.isEmpty);
        // Ignore the constructor.
        for (var i = 1; i < node.arguments.positional.length; i++) {
          args.add(_visitExpression(node.arguments.positional[i]));
        }
        return _emitCast(
          js_ast.New(_visitExpression(node.arguments.positional[0]), args),
          node.arguments.types[0],
        );
      }
    }

    var fn = _emitStaticTarget(target);
    var args = _emitArgumentList(node.arguments, target: target);
    var staticCall = js_ast.Call(fn, args)
      ..sourceInformation = _nodeStart(node);
    if (_shouldRewriteInvocationWithHotReloadChecks(target)) {
      var checkedCall = _rewriteInvocationWithHotReloadChecks(
        target,
        node.arguments,
        node.getStaticType(_staticTypeContext),
        _nodeStart(node),
      );
      // As an optimization, avoid extra checks when the invocation code was
      // compiled in the same generation that it is running.
      return _emitHotReloadSafeInvocation(staticCall, checkedCall);
    }
    return _isNullCheckableJsInterop(target)
        ? _wrapWithJsInteropNullCheck(staticCall)
        : staticCall;
  }

  /// Returns `true` when an invocation of [target] should be rewritten to
  /// include checks to preserve soundness in the presence of hot reloads at
  /// runtime.
  bool _shouldRewriteInvocationWithHotReloadChecks(Member target) =>
      _inFunctionExpression &&
      !_isBuildingSdk &&
      !usesJSInterop(target) &&
      target != _assertInteropMethod;

  js_ast.Expression _emitHotReloadSafeInvocation(
    js_ast.Expression uncheckedCall,
    js_ast.Expression checkedCall,
  ) {
    var generationCheck = js.call('# === #', [
      js.number(_hotReloadGeneration),
      _runtimeCall('global.dartDevEmbedder.hotReloadGeneration'),
    ]);
    return js_ast.InvocationWithHotReloadChecks(
      generationCheck,
      uncheckedCall,
      checkedCall,
    )..sourceInformation = continueSourceMap;
  }

  /// Rewrites an invocation of [target] that is statically sound at compile
  /// time to include checks to preserve soundness in the presence of hot
  /// reloads at runtime.
  ///
  /// The checks are similar to the those performed when making a dynamic call.
  /// The [arguments] are checked for the correct shape and runtime types.
  /// Additionally after the invocation, the returned value is checked against
  /// the [expectedReturnType].
  ///
  /// Invokes `noSuchMethod` if the check fails. If that also returns a value,
  /// it's cast to the [expectedReturnType].
  ///
  /// The resulting expression for the validated call site will receive the
  /// [originalCallSiteSourceLocation].
  js_ast.Expression _rewriteInvocationWithHotReloadChecks(
    Member target,
    Arguments arguments,
    DartType expectedReturnType,
    SourceLocation? originalCallSiteSourceLocation,
  ) {
    var hoistedPositionalVariables = <js_ast.Expression>[];
    var hoistedNamedVariables = <String, js_ast.Expression>{};
    js_ast.Expression? letAssignments;
    for (var i = 0; i < arguments.positional.length; i++) {
      var argument = arguments.positional[i];
      var argumentExpression = _visitExpression(argument);
      if (argument is VariableGet || argument is BasicLiteral) {
        // No need to create new let variables, it is safe to repeat these
        // expressions.
        hoistedPositionalVariables.add(argumentExpression);
        continue;
      }
      // Hoist the passed positional argument expressions into let variables.
      var hoistedVariable = _emitScopedId('\$p$i');
      _letVariables!.add(hoistedVariable);
      var assignment = js.call('# = #', [hoistedVariable, argumentExpression]);
      hoistedPositionalVariables.add(hoistedVariable);
      letAssignments = letAssignments == null
          ? assignment
          : js_ast.Binary(',', letAssignments, assignment);
    }
    for (var i = 0; i < arguments.named.length; i++) {
      var argument = arguments.named[i];
      var argumentName = argument.name;
      var argumentValue = _visitExpression(argument.value);
      if (argument is VariableGet || argument is BasicLiteral) {
        // No need to create new let variables, it is safe to repeat these
        // expressions.
        hoistedNamedVariables[argumentName] = argumentValue;
        continue;
      }
      // Hoist the passed named argument expressions into let variables.
      var hoistedVariable = _emitScopedId('\$n$i');
      _letVariables!.add(hoistedVariable);
      var assignment = js.call('# = #', [hoistedVariable, argumentValue]);
      hoistedNamedVariables[argumentName] = hoistedVariable;
      letAssignments = letAssignments == null
          ? assignment
          : js_ast.Binary(',', letAssignments, assignment);
    }
    // Create an invocation of the correctness checks to verify the call is
    // still valid.
    var checkResult = _emitScopedId('\$result');
    _letVariables!.add(checkResult);
    var jsTarget = _emitStaticTarget(target);
    var jsTypeArguments = [
      // TODO(nshahan): Remove this check if we stop rewriting calls to SDK
      // functions.
      if (_reifyGenericFunction(target))
        for (var typeArgument in arguments.types) _emitType(typeArgument),
    ];
    var correctnessCheck = _runtimeCall(
      'hotReloadCorrectnessChecks(#, #, #, #, #)',
      [
        jsTarget.receiver,
        jsTarget.selector,
        js_ast.ArrayInitializer(jsTypeArguments),
        js_ast.ArrayInitializer(hoistedPositionalVariables),
        hoistedNamedVariables.isEmpty
            ? js_ast.LiteralNull()
            : js_ast.ObjectInitializer([
                for (var e in hoistedNamedVariables.entries)
                  js_ast.Property(js.string(e.key), e.value),
              ]),
      ],
    );
    var checkAssignment = js.call('# = #', [checkResult, correctnessCheck]);
    letAssignments = letAssignments == null
        ? checkAssignment
        : js_ast.Binary(',', letAssignments, checkAssignment);
    // Create a new invocation of the original target but passing all the
    // arguments via their let variables.
    var validatedCallSite = js_ast.Call(jsTarget, [
      ...jsTypeArguments,
      ...hoistedPositionalVariables,
      if (hoistedNamedVariables.isNotEmpty)
        js_ast.ObjectInitializer([
          for (var e in hoistedNamedVariables.entries)
            js_ast.Property(js.string(e.key), e.value),
        ]),
    ])..sourceInformation = originalCallSiteSourceLocation;
    // Cast the result of the checked call or the value returned from a
    // `NoSuchMethod` invocation.
    return js_ast.Binary(
      ',',
      letAssignments,
      js.call('# == # ? # : #', [
        checkResult,
        _runtimeCall('validArgumentsSentinel'),
        _emitCast(validatedCallSite, expectedReturnType),
        _emitCast(checkResult, expectedReturnType),
      ]),
    );
  }

  js_ast.Expression _emitJSObjectGetPrototypeOf(
    js_ast.Expression obj, {
    required bool fullyQualifiedName,
  }) => fullyQualifiedName
      ? _runtimeCall('global.Object.getPrototypeOf(#)', [obj])
      : js.call('Object.getPrototypeOf(#)', obj);

  js_ast.Expression _emitJSObjectSetPrototypeOf(
    js_ast.Expression obj,
    js_ast.Expression prototype, {
    required bool fullyQualifiedName,
  }) => fullyQualifiedName
      ? _runtimeCall('global.Object.setPrototypeOf(#, #)', [obj, prototype])
      : js.call('Object.setPrototypeOf(#, #)', [obj, prototype]);

  bool _isDebuggerCall(Procedure target) {
    return target.name.text == 'debugger' &&
        target.enclosingLibrary.importUri.toString() == 'dart:developer';
  }

  js_ast.Node _emitDebuggerCall(StaticInvocation node) {
    var args = node.arguments.named;
    var isStatement = node.parent is ExpressionStatement;
    var debuggerStatement = js_ast.DebuggerStatement().withSourceInformation(
      _nodeStart(node),
    );
    if (args.isEmpty) {
      // Inline `debugger()` with no arguments, as a statement if possible,
      // otherwise as an immediately invoked function.
      return isStatement
          ? debuggerStatement
          : js.call('(() => { #; return true})()', [debuggerStatement]);
    }

    // The signature of `debugger()` is:
    //
    //     bool debugger({bool when: true, String message})
    //
    // This code path handles the named arguments `when` and/or `message`.
    // Both must be evaluated in the supplied order, and then `when` is used
    // to decide whether to break or not.
    //
    // We also need to return the value of `when`.
    var jsArgs = args.map(_emitNamedExpression).toList();
    var when = args.length == 1
        // For a single `when` argument, use it.
        //
        // For a single `message` argument, use `{message: ...}`, which
        // coerces to true (the default value of `when`).
        ? (args[0].name == 'when'
              ? jsArgs[0].value
              : js_ast.ObjectInitializer(jsArgs))
        // If we have both `message` and `when` arguments, evaluate them in
        // order, then extract the `when` argument.
        : js.call('#.when', js_ast.ObjectInitializer(jsArgs));
    return isStatement
        ? js.statement('if (#) #;', [when, debuggerStatement])
        : js.call('# && (() => { #; return true })()', [
            when,
            debuggerStatement,
          ]);
  }

  /// Emits the target of a [StaticInvocation], [StaticGet], or [StaticSet].
  js_ast.PropertyAccess _emitStaticTarget(Member target) {
    var c = target.enclosingClass;
    if (c != null) {
      // A static native element should just forward directly to the JS type's
      // member, for example `Css.supports(...)` in dart:html should be replaced
      // by a direct call to the DOM API: `global.CSS.supports`.
      var isExternal = _isExternal(target);
      if (isExternal && (target as Procedure).isStatic) {
        var nativeName = _extensionTypes.getNativePeers(c);
        if (nativeName.isNotEmpty) {
          var annotationName = _annotationName(target, isJSName);
          var memberName = annotationName == null
              ? _emitStaticMemberName(target.name.text, target)
              : js.string(annotationName);
          return js_ast.PropertyAccess(
            _runtimeCall('global.#', [nativeName[0]]),
            memberName,
          );
        }
      }
      return js_ast.PropertyAccess(
        _emitStaticClassName(c, isExternal),
        _emitStaticMemberName(target.name.text, target),
      );
    }
    return _emitTopLevelName(target);
  }

  /// Returns all parts of [arguments] flattened into a list so they can be
  /// passed in the calling convention for calls with no runtime checks.
  ///
  /// When [types] is `false` any type arguments present in [arguments] will be
  /// omitted.
  ///
  /// Passing [target] when applicable allows for detection of an annotation to
  /// omit passing type parameters and to detect if positional arguments should
  /// be packaged to be passed to a JavaScript using an interop call.
  List<js_ast.Expression> _emitArgumentList(
    Arguments node, {
    bool types = true,
    Member? target,
  }) {
    types = types && _reifyGenericFunction(target);
    var (
      :typeArguments,
      :positionalArguments,
      :namedArguments,
    ) = _emitArgumentGroups(
      node,
      isJSInterop: target != null && isJsMember(target),
    );
    return [
      if (types && typeArguments != null) ...typeArguments,
      if (positionalArguments != null) ...positionalArguments,
      if (namedArguments != null) js_ast.ObjectInitializer([...namedArguments]),
    ];
  }

  /// Returns all [arguments] but kept in separate packets so they can be
  /// further processed.
  ///
  /// Facilitates passing arguments in the calling convention used by runtime
  /// helpers that check arguments.
  ///
  /// When [isJSInterop] is `true` the positional arguments are packaged to
  /// be passed to JavaScript via an interop call.
  _ArgumentGroups _emitArgumentGroups(
    Arguments node, {
    required bool isJSInterop,
  }) {
    var typeArguments = node.types.isEmpty
        ? null
        : [for (var typeArgument in node.types) _emitType(typeArgument)];
    var positionalArguments = node.positional.isEmpty
        ? null
        : [
            for (var arg in node.positional)
              if (arg is StaticInvocation &&
                  isJSSpreadInvocation(arg.target) &&
                  arg.arguments.positional.length == 1)
                js_ast.Spread(_visitExpression(arg.arguments.positional[0]))
              else if (isJSInterop)
                _visitExpression(_assertInterop(arg))
              else
                _visitExpression(arg),
          ];
    var namedArguments = node.named.isEmpty
        ? null
        : [for (var arg in node.named) _emitNamedExpression(arg, isJSInterop)];

    return (
      typeArguments: typeArguments,
      positionalArguments: positionalArguments,
      namedArguments: namedArguments,
    );
  }

  js_ast.Property _emitNamedExpression(
    NamedExpression arg, [
    bool isJsInterop = false,
  ]) {
    var value = isJsInterop ? _assertInterop(arg.value) : arg.value;
    return js_ast.Property(_propertyName(arg.name), _visitExpression(value));
  }

  /// Emits code for the `JS(...)` macro.
  js_ast.Node _emitInlineJSCode(StaticInvocation node) {
    var args = node.arguments.positional;
    // arg[0] is static return type, used in `RestrictedStaticTypeAnalyzer`
    var code = args[1];
    List<Expression> templateArgs;
    String source;
    if (code is ConstantExpression) {
      templateArgs = args.skip(2).toList();
      source = (code.constant as StringConstant).value;
    } else if (code is StringConcatenation) {
      if (code.expressions.every((e) => e is StringLiteral)) {
        templateArgs = args.skip(2).toList();
        source = code.expressions.map((e) => (e as StringLiteral).value).join();
      } else {
        if (args.length > 2) {
          throw ArgumentError(
            "Can't mix template args and string interpolation in JS calls: "
            '`$node`',
          );
        }
        templateArgs = <Expression>[];
        source = code.expressions.map((expression) {
          if (expression is StringLiteral) {
            return expression.value;
          } else {
            templateArgs.add(expression);
            return '#';
          }
        }).join();
      }
    } else {
      templateArgs = args.skip(2).toList();
      source = (code as StringLiteral).value;
    }

    // TODO(jmesserly): arguments to JS() that contain type literals evaluate to
    // the raw runtime type instead of the wrapped Type object.
    // We can clean this up by switching to `unwrapType(<type literal>)`, which
    // the compiler will then optimize.
    var wasInForeignJS = _isInForeignJS;
    _isInForeignJS = true;
    var jsArgs = templateArgs.map(_visitExpression).toList();
    _isInForeignJS = wasInForeignJS;

    var result = js.parseForeignJS(source).instantiate(jsArgs);

    // Add a check to make sure any JS() values from a native type are typed
    // properly in sound null-safety.
    if (_isWebLibrary(_currentLibrary!.importUri)) {
      var type = node.getStaticType(_staticTypeContext);
      if (type.isPotentiallyNonNullable) {
        result = _runtimeCall('checkNativeNonNull(#)', [result]);
      }
    }

    assert(
      result is js_ast.Expression ||
          result is js_ast.Statement && node.parent is ExpressionStatement,
    );
    return result.withSourceInformation(_nodeStart(node));
  }

  js_ast.Expression _emitEmbeddedGlobal(StaticInvocation node) {
    var constantExpression = node.arguments.positional[1] as ConstantExpression;
    var name = constantExpression.constant as StringConstant;
    var value = name.value;
    if (value == 'arrayRti') {
      // Special case for the rti on a JSArray. These are defined via the dartx
      // extension functionality.
      return _emitMemberName('arrayRti', memberClass: _jsArrayClass);
    }
    return _runtimeCall('#', [name.value]);
  }

  /// Returns the string literal that is to be used as the result of a call to
  /// [JS_GET_NAME] for [name].
  js_ast.Expression _emitExpressionForJsGetName(JsGetName name) {
    switch (name) {
      case JsGetName.OPERATOR_IS_PREFIX:
        return js.string(js_ast.FixedNames.operatorIsPrefix);
      case JsGetName.SIGNATURE_NAME:
        return _runtimeCall('#', [
          js.string(js_ast.FixedNames.operatorSignature),
        ]);
      case JsGetName.RTI_NAME:
        return js.string(js_ast.FixedNames.rtiName);
      case JsGetName.FUTURE_CLASS_TYPE_NAME:
        return js.string(
          _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.futureClass),
        );
      case JsGetName.LIST_CLASS_TYPE_NAME:
        return js.string(
          _typeRecipeGenerator.interfaceTypeRecipe(_coreTypes.listClass),
        );
      case JsGetName.RTI_FIELD_AS:
        return _emitMemberName(
          js_ast.FixedNames.rtiAsField,
          memberClass: _rtiClass,
        );
      case JsGetName.RTI_FIELD_IS:
        return _emitMemberName(
          js_ast.FixedNames.rtiIsField,
          memberClass: _rtiClass,
        );
      default:
        throw UnsupportedError('JsGetName has no name for "$name".');
    }
  }

  /// Returns the expression that is to be used as the result of a call to
  /// [JS_BUILTIN] for [builtin].
  js_ast.Expression _emitOperationForJsBuiltIn(JsBuiltin builtin) {
    switch (builtin) {
      case JsBuiltin.dartClosureConstructor:
        // TODO(48585) Is this safe or will it conflict with functions that
        // enter the program through JS Interop?
        return js.call('Function');
      case JsBuiltin.dartObjectConstructor:
        return _emitTopLevelName(_coreTypes.objectClass);
      default:
        throw UnsupportedError('JsBuiltin has no operation for "$builtin".');
    }
  }

  String _enumValueName(Field field) {
    var enumName = field.enclosingClass!.name;
    var valueName = field.name.text;
    return '$enumName.$valueName';
  }

  JsGetName _asJsGetName(Field field) => JsGetName.values.firstWhere(
    (val) => val.toString() == _enumValueName(field),
  );

  JsBuiltin _asJsBuiltin(Field field) => JsBuiltin.values.firstWhere(
    (val) => val.toString() == _enumValueName(field),
  );

  bool _isWebLibrary(Uri importUri) =>
      importUri.isScheme('dart') &&
      (importUri.path == 'html' ||
          importUri.path == 'svg' ||
          importUri.path == 'indexed_db' ||
          importUri.path == 'web_audio' ||
          importUri.path == 'web_gl' ||
          importUri.path == 'web_sql' ||
          importUri.path == 'html_common');

  bool _isNull(Expression expr) =>
      expr is NullLiteral ||
      expr.getStaticType(_staticTypeContext).extensionTypeErasure is NullType;

  bool _doubleEqIsIdentity(Expression left, Expression right) {
    // If we statically know LHS or RHS is null we can use ==.
    if (_isNull(left) || _isNull(right)) return true;
    // If the representation of the  two types will not induce conversion in
    // JS then we can use == .
    return !_typeRep.equalityMayConvert(
      left.getStaticType(_staticTypeContext),
      right.getStaticType(_staticTypeContext),
    );
  }

  bool _tripleEqIsIdentity(Expression left, Expression right) {
    // If either is non-nullable, then we don't need to worry about
    // equating null and undefined, and so we can use triple equals.
    return !_isNullable(left) || !_isNullable(right);
  }

  /// Returns true if [expr] can be null.
  bool _isNullable(Expression expr) => _nullableInference.isNullable(expr);

  js_ast.Expression _emitJSDoubleEq(
    List<js_ast.Expression> args, {
    bool negated = false,
  }) {
    var op = negated ? '# != #' : '# == #';
    return js.call(op, args);
  }

  js_ast.Expression _emitJSTripleEq(
    List<js_ast.Expression> args, {
    bool negated = false,
  }) {
    var op = negated ? '# !== #' : '# === #';
    return js.call(op, args);
  }

  js_ast.Expression _emitCoreIdenticalCall(
    List<Expression> args, {
    bool negated = false,
  }) {
    if (args.length != 2) {
      // Shouldn't happen in typechecked code
      return _runtimeCall(
        'throw(Error("compile error: calls to `identical` require 2 args")',
      );
    }
    var left = args[0];
    var right = args[1];
    var jsArgs = [_visitExpression(left), _visitExpression(right)];
    if (_tripleEqIsIdentity(left, right)) {
      return _emitJSTripleEq(jsArgs, negated: negated);
    }
    if (_doubleEqIsIdentity(left, right)) {
      return _emitJSDoubleEq(jsArgs, negated: negated);
    }
    var code = negated ? '!#' : '#';
    return js.call(
      code,
      js_ast.Call(_emitTopLevelName(_coreTypes.identicalProcedure), jsArgs),
    );
  }

  /// Returns true if this [member] is a JS interop member.
  bool isJSInteropMember(Member member) =>
      member.isExternal && hasJSInteropAnnotation(member.enclosingClass!);

  @override
  js_ast.Expression visitConstructorInvocation(ConstructorInvocation node) {
    var ctor = node.target;
    var ctorClass = ctor.enclosingClass;
    var args = node.arguments;
    if (isJSAnonymousType(ctorClass)) return _emitObjectLiteral(args, ctor);
    // JS interop constructor calls do not provide an RTI at the call site.
    var shouldProvideRti =
        !isJSInteropMember(ctor) && _requiresRtiForInstantiation(ctorClass);
    var rti = shouldProvideRti
        ? _emitType(
            node.constructedType,
            emitJSInteropGenericClassTypeParametersAsAny: false,
          )
        : null;
    var result = js_ast.New(_emitConstructorName(node.constructedType, ctor), [
      if (rti != null) rti,
      ..._emitArgumentList(args, types: false, target: ctor),
    ]);
    return node.isConst ? _canonicalizeConstObject(result) : result;
  }

  js_ast.Expression _emitFactoryInvocation(StaticInvocation node) {
    var args = node.arguments;
    var ctor = node.target;
    var ctorClass = ctor.enclosingClass!;
    // JS interop constructor calls do not require an RTI at the call site.
    if (isJSInteropMember(ctor)) {
      return _emitJSInteropNew(ctor, args);
    }

    var type = ctorClass.typeParameters.isEmpty
        ? _coreTypes.nonNullableRawType(ctorClass)
        : InterfaceType(ctorClass, Nullability.nonNullable, args.types);

    if (isFromEnvironmentInvocation(_coreTypes, node)) {
      var value = _constants.evaluate(node);
      if (value is PrimitiveConstant) {
        return visitConstant(value);
      }
    }

    if (args.positional.isEmpty &&
        args.named.isEmpty &&
        ctorClass.enclosingLibrary.importUri.isScheme('dart')) {
      // Skip the slow SDK factory constructors when possible.
      switch (ctorClass.name) {
        case 'Map':
        case 'HashMap':
        case 'LinkedHashMap':
          if (ctor.name.text == '') {
            var mapType = _createMapImplType(type);
            var mapClass = _emitClassRef(mapType);
            var rti = _emitType(mapType);
            return js.call('new #.new(#)', [mapClass, rti]);
          } else if (ctor.name.text == 'identity') {
            var mapType = _createMapImplType(type, identity: true);
            var mapClass = _emitClassRef(mapType);
            var rti = _emitType(mapType);
            return js.call('new #.new(#)', [mapClass, rti]);
          }
        case 'Set':
        case 'HashSet':
        case 'LinkedHashSet':
          if (ctor.name.text == '') {
            var setType = _createSetImplType(type);
            var setClass = _emitClassRef(setType);
            var rti = _emitType(setType);
            return js.call('new #.new(#)', [setClass, rti]);
          } else if (ctor.name.text == 'identity') {
            var setType = _createSetImplType(type, identity: true);
            var setClass = _emitClassRef(setType);
            var rti = _emitType(setType);
            return js.call('new #.new(#)', [setClass, rti]);
          }
        case 'List':
          if (ctor.name.text == '') {
            return _emitList(type.typeArguments[0], []);
          }
      }
    }
    var rti = _requiresRtiForInstantiation(ctorClass)
        ? _emitType(type, emitJSInteropGenericClassTypeParametersAsAny: false)
        : null;
    var result = js_ast.Call(_emitConstructorName(type, ctor), [
      if (rti != null) rti,
      ..._emitArgumentList(args, types: false),
    ]);
    return node.isConst ? _canonicalizeConstObject(result) : result;
  }

  js_ast.Expression _emitJSInteropNew(Member ctor, Arguments args) {
    var ctorClass = ctor.enclosingClass!;
    if (isJSAnonymousType(ctorClass)) return _emitObjectLiteral(args, ctor);
    // JS interop constructor calls do not require an RTI at the call site.
    return js_ast.New(
      _emitConstructorName(_coreTypes.nonNullableRawType(ctorClass), ctor),
      _emitArgumentList(args, types: false, target: ctor),
    );
  }

  InterfaceType _createMapImplType(InterfaceType type, {bool? identity}) {
    var typeArgs = type.typeArguments;
    if (typeArgs.isEmpty) {
      return type.withDeclaredNullability(Nullability.nonNullable);
    }
    identity ??= _typeRep.isPrimitive(typeArgs[0]);
    var c = identity ? _identityHashMapImplClass : _linkedHashMapImplClass;
    return InterfaceType(c, Nullability.nonNullable, typeArgs);
  }

  InterfaceType _createSetImplType(InterfaceType type, {bool? identity}) {
    var typeArgs = type.typeArguments;
    if (typeArgs.isEmpty) {
      return type.withDeclaredNullability(Nullability.nonNullable);
    }
    identity ??= _typeRep.isPrimitive(typeArgs[0]);
    var c = identity ? _identityHashSetImplClass : _linkedHashSetImplClass;
    return InterfaceType(c, Nullability.nonNullable, typeArgs);
  }

  js_ast.Expression _emitObjectLiteral(Arguments node, Member ctor) {
    var args = _emitArgumentList(node, types: false, target: ctor);
    if (args.isEmpty) return js.call('{}');
    assert(args.single is js_ast.ObjectInitializer);
    return args.single;
  }

  @override
  js_ast.Expression visitNot(Not node) {
    var operand = node.operand;
    if (operand is EqualsCall) {
      return _emitEqualityOperator(
        operand.left,
        operand.interfaceTarget,
        operand.right,
        negated: true,
      );
    } else if (operand is EqualsNull) {
      return _emitCoreIdenticalCall([
        operand.expression,
        NullLiteral(),
      ], negated: true);
    } else if (operand is StaticInvocation &&
        operand.target == _coreTypes.identicalProcedure) {
      return _emitCoreIdenticalCall(
        operand.arguments.positional,
        negated: true,
      );
    }

    var jsOperand = _visitTest(operand);
    if (jsOperand is js_ast.LiteralBool) {
      // Flipping the value here for `!true` or `!false` allows for simpler
      // `if (true)` or `if (false)` detection and optimization.
      return js_ast.LiteralBool(
            !jsOperand.value,
          ).withSourceInformation(jsOperand.sourceInformation)
          as js_ast.LiteralBool;
    }

    // Logical negation, `!e`, is a boolean conversion context since it is
    // defined as `e ? false : true`.
    return js.call('!#', jsOperand).withSourceInformation(continueSourceMap);
  }

  @override
  js_ast.Expression visitNullCheck(NullCheck node) {
    var expr = node.operand;
    var jsExpr = _visitExpression(expr);
    // If the expression is non-nullable already, this is a no-op.
    return _isNullable(expr) ? _runtimeCall('nullCheck(#)', [jsExpr]) : jsExpr;
  }

  @override
  js_ast.Expression visitLogicalExpression(LogicalExpression node) {
    // The operands of logical boolean operators are subject to boolean
    // conversion.
    return _visitTest(node);
  }

  @override
  js_ast.Expression visitConditionalExpression(ConditionalExpression node) {
    var condition = _visitTest(node.condition);
    if (condition is js_ast.LiteralBool) {
      if (condition.value) {
        // Avoid emitting conditional when one branch is effectively dead code.
        // ex: `true ? foo : bar` -> `foo`
        return _visitExpression(node.then);
      } else {
        // ex: `false ? foo : bar` -> `bar`
        return _visitExpression(node.otherwise);
      }
    }
    var then = _visitExpression(node.then);
    var otherwise = _visitExpression(node.otherwise);
    return js.call('# ? # : #', [condition, then, otherwise])
      ..sourceInformation =
          condition.sourceInformation ?? _nodeStart(node.condition);
  }

  @override
  js_ast.Expression visitStringConcatenation(StringConcatenation node) {
    var parts = <js_ast.Expression>[];
    for (var e in node.expressions) {
      var jsExpr = _visitExpression(e);
      if (jsExpr is js_ast.LiteralString && jsExpr.valueWithoutQuotes.isEmpty) {
        continue;
      }
      var type = e.getStaticType(_staticTypeContext).extensionTypeErasure;
      if (DartTypeEquivalence(
            _coreTypes,
            ignoreTopLevelNullability: true,
          ).areEqual(type, _coreTypes.stringNonNullableRawType) &&
          !_isNullable(e)) {
        parts.add(jsExpr);
      } else if (_shouldCallObjectMemberHelper(e)) {
        parts.add(_runtimeCall('str(#)', [jsExpr]));
      } else {
        // It is safe to call a version of `str()` that does not probe for the
        // toString method before calling it.
        parts.add(_runtimeCall('strSafe(#)', [jsExpr]));
      }
    }
    if (parts.isEmpty) return js.string('');
    return js_ast.Expression.binary(parts, '+');
  }

  @override
  js_ast.Expression visitListConcatenation(ListConcatenation node) {
    // Only occurs inside unevaluated constants.
    throw UnsupportedError('List concatenation');
  }

  @override
  js_ast.Expression visitSetConcatenation(SetConcatenation node) {
    // Only occurs inside unevaluated constants.
    throw UnsupportedError('Set concatenation');
  }

  @override
  js_ast.Expression visitMapConcatenation(MapConcatenation node) {
    // Only occurs inside unevaluated constants.
    throw UnsupportedError('Map concatenation');
  }

  @override
  js_ast.Expression visitInstanceCreation(InstanceCreation node) {
    // Only occurs inside unevaluated constants.
    throw UnsupportedError('Instance creation');
  }

  @override
  js_ast.Expression visitFileUriExpression(FileUriExpression node) {
    // Only occurs inside unevaluated constants.
    throw UnsupportedError('File URI expression');
  }

  @override
  js_ast.Expression visitConstructorTearOff(ConstructorTearOff node) {
    throw UnsupportedError('Constructor tear off');
  }

  @override
  js_ast.Expression visitRedirectingFactoryTearOff(
    RedirectingFactoryTearOff node,
  ) {
    throw UnsupportedError('RedirectingFactory tear off');
  }

  @override
  js_ast.Expression visitTypedefTearOff(TypedefTearOff node) {
    throw UnsupportedError('Typedef instantiation');
  }

  @override
  js_ast.Expression visitIsExpression(IsExpression node) {
    return _emitIsExpression(node.operand, node.type.extensionTypeErasure);
  }

  js_ast.Expression _emitIsExpression(Expression operand, DartType type) {
    // Generate `is` as `dart.is` or `typeof` depending on the RHS type.
    var lhs = _visitExpression(operand);
    // It is invalid to use a simplified check for a native type in place of
    // a type test for a `TypeParameterType`. This is because at runtime type
    // parameters can be instantiated as the bottom type `Never` and
    // `val is Never` should always evaluate to false.
    var typeofName =
        type is TypeParameterType || type is StructuralParameterType
        ? null
        : _typeRep.typeFor(type).primitiveTypeOf;
    // Inline non-nullable primitive types other than int (which requires a
    // Math.floor check).
    if (typeofName != null &&
        type.nullability == Nullability.nonNullable &&
        type != _types.coreTypes.intNonNullableRawType) {
      return js.call('typeof # == #', [lhs, js.string(typeofName, "'")]);
    }

    return js.call('#.#(#)', [
      _emitType(type),
      _emitMemberName(js_ast.FixedNames.rtiIsField, memberClass: _rtiClass),
      lhs,
    ]);
  }

  @override
  js_ast.Expression visitAsExpression(AsExpression node) {
    var fromExpr = node.operand;
    var jsFrom = _visitExpression(fromExpr);
    if (node.isUnchecked) return jsFrom;
    return _emitCast(
      jsFrom,
      node.type,
      fromStaticType: fromExpr.getStaticType(_staticTypeContext),
      isTypeError: node.isTypeError,
    );
  }

  js_ast.Expression _emitCast(
    js_ast.Expression value,
    DartType toType, {
    DartType? fromStaticType,
    bool isTypeError = false,
  }) {
    toType = toType.extensionTypeErasure;
    if (_types.isTop(toType)) return value;
    if (fromStaticType != null) {
      fromStaticType = fromStaticType.extensionTypeErasure;
      // If the check was put here by static analysis to ensure soundness, we
      // can't skip it. For example, one could implement covariant generic
      // caller side checks like this:
      //
      //      typedef F<T>(T t);
      //      class C<T> {
      //        F<T> f;
      //        add(T t) {
      //          // required check `t as T`
      //        }
      //      }
      //      main() {
      //        C<Object> c = new C<int>()..f = (int x) => x.isEven;
      //        c.f('hi'); // required check `c.f as F<Object>`
      //        c.add('hi);
      //      }
      //
      if (!isTypeError &&
          _types.isSubtypeOf(
            fromStaticType,
            toType,
            SubtypeCheckMode.withNullabilities,
          )) {
        return value;
      }
      if (!isTypeError &&
          _mustBeNonNullable(toType) &&
          DartTypeEquivalence(
            _coreTypes,
            ignoreTopLevelNullability: true,
          ).areEqual(fromStaticType, toType)) {
        // If the underlying type is the same, we only need a null check.
        return _runtimeCall('nullCast(#, #)', [value, _emitType(toType)]);
      }
      // All Dart number types map to a JavaScript Number. We can specialize
      // these cases.
      if (_typeRep.isNumber(fromStaticType) && _typeRep.isNumber(toType)) {
        // If `toType` is some form of `num`, it should have been filtered
        // above.
        if (toType == _coreTypes.doubleNullableRawType) {
          // Any number/nullability -> double? : no-op
          return value;
        }
        if (toType == _coreTypes.doubleNonNullableRawType) {
          if (fromStaticType.nullability == Nullability.nonNullable) {
            // Any non-nullable number -> double : no-op
            return value;
          }
          // Any number/nullability -> double : null check
          return _runtimeCall('nullCast(#, #)', [value, _emitType(toType)]);
        }
      }
    }
    var directMethod = _directCastMethod(toType);
    if (directMethod != null) {
      return js.call('#(#)', [_emitTopLevelName(directMethod), value]);
    }

    return js.call('#.#(#)', [
      _emitType(toType),
      _emitMemberName(js_ast.FixedNames.rtiAsField, memberClass: _rtiClass),
      value,
    ]);
  }

  /// Returns the direct `_as` method when [type] is a primitive type otherwise,
  /// `null`.
  Member? _directCastMethod(DartType type) {
    if (type is InterfaceType && type.typeArguments.isEmpty) {
      if (type.nullability == Nullability.nonNullable) {
        if (type == _types.coreTypes.boolNonNullableRawType) return _asBool;
        if (type == _types.coreTypes.doubleNonNullableRawType) return _asDouble;
        if (type == _types.coreTypes.intNonNullableRawType) return _asInt;
        if (type == _types.coreTypes.numNonNullableRawType) return _asNum;
        if (type == _types.coreTypes.objectNonNullableRawType) return _asObject;
        if (type == _types.coreTypes.stringNonNullableRawType) return _asString;
      } else if (type.nullability == Nullability.nullable) {
        if (type == _types.coreTypes.boolNullableRawType) return _asBoolQ;
        if (type == _types.coreTypes.doubleNullableRawType) return _asDoubleQ;
        if (type == _types.coreTypes.intNullableRawType) return _asIntQ;
        if (type == _types.coreTypes.numNullableRawType) return _asNumQ;
        if (type == _types.coreTypes.stringNullableRawType) return _asStringQ;
      }
    }
    return null;
  }

  @override
  js_ast.Expression visitSymbolLiteral(SymbolLiteral node) =>
      _emitDartSymbol(node.value);

  @override
  js_ast.Expression visitTypeLiteral(TypeLiteral node) =>
      _emitTypeLiteral(node.type);

  js_ast.Expression _emitTypeLiteral(DartType type) {
    var typeRep = _emitType(type);

    // TODO(46002) All `JS()` calls in the SDK should be explicit when using the
    // internal rti object by calling the `TYPE_REF` helper.
    if (_isInForeignJS) return typeRep;

    // If the type is a type literal expression in Dart code, wrap the raw
    // runtime type in a "Type" instance.
    return js.call('#.createRuntimeType(#)', [
      _emitLibraryName(_rtiLibrary),
      typeRep,
    ]);
  }

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

  @override
  js_ast.Expression visitRethrow(Rethrow node) {
    return _runtimeCall('rethrow(#)', [_emitVariableRef(_rethrowParameter!)]);
  }

  @override
  js_ast.Expression visitThrow(Throw node) =>
      _runtimeCall('throw(#)', [_visitExpression(node.expression)]);

  @override
  js_ast.Expression visitListLiteral(ListLiteral node) {
    var elementType = node.typeArgument;
    var elements = _visitExpressionList(node.expressions);
    return _emitList(elementType, elements);
  }

  js_ast.Expression _emitList(
    DartType itemType,
    List<js_ast.Expression> items,
  ) {
    var list = js_ast.ArrayInitializer(items);

    // List's type parameter is default-initialized to dynamic in our runtime.
    if (itemType == const DynamicType()) return list;

    // Call `new JSArray<E>.of(list)`
    var type = InterfaceType(_jsArrayClass, Nullability.nonNullable, [
      itemType,
    ]);
    var arrayClass = _emitClassRef(type);
    var arrayRti = _emitType(type);
    return js.call('#.of(#, #)', [arrayClass, arrayRti, list]);
  }

  js_ast.Expression _emitConstList(
    DartType elementType,
    List<js_ast.Expression> elements,
  ) {
    return _runtimeCall('constList(#, [#])', [
      _emitType(elementType),
      elements,
    ]);
  }

  @override
  js_ast.Expression visitSetLiteral(SetLiteral node) {
    // TODO(markzipan): remove const check when we use front-end const eval
    if (!node.isConst) {
      var type = InterfaceType(_linkedHashSetClass, Nullability.nonNullable, [
        node.typeArgument,
      ]);
      var setClass = _emitClassRef(type);
      var rti = _emitType(type);
      if (node.expressions.isEmpty) {
        return js.call('#.new(#)', [setClass, rti]);
      }
      return js.call('#.from(#, [#])', [
        setClass,
        rti,
        _visitExpressionList(node.expressions),
      ]);
    }
    return _emitConstSet(
      node.typeArgument,
      _visitExpressionList(node.expressions),
    );
  }

  js_ast.Expression _emitConstSet(
    DartType elementType,
    List<js_ast.Expression> elements,
  ) {
    return _runtimeCall('constSet(#, [#])', [_emitType(elementType), elements]);
  }

  @override
  js_ast.Expression visitMapLiteral(MapLiteral node) {
    var entries = [
      for (var e in node.entries) ...[
        _visitExpression(e.key),
        _visitExpression(e.value),
      ],
    ];

    // TODO(markzipan): remove const check when we use front-end const eval
    if (!node.isConst) {
      var type = node.getStaticType(_staticTypeContext) as InterfaceType;
      var mapType = _createMapImplType(type);
      var mapClass = _emitClassRef(mapType);
      var rti = _emitType(mapType);
      if (node.entries.isEmpty) {
        return js.call('new #.new(#)', [mapClass, rti]);
      }
      return js.call('new #.from(#, [#])', [mapClass, rti, entries]);
    }
    return _emitConstMap(node.keyType, node.valueType, entries);
  }

  js_ast.Expression _emitConstMap(
    DartType keyType,
    DartType valueType,
    List<js_ast.Expression> entries,
  ) {
    return _runtimeCall('constMap(#, #, [#])', [
      _emitType(keyType),
      _emitType(valueType),
      entries,
    ]);
  }

  /// Returns the key used for shape lookup at runtime.
  ///
  /// See `shapes` in dart:_runtime (records.dart) for a description.
  String _recordShapeKey(
    int positionalElementCount,
    Iterable<String> namedElementNames,
  ) {
    var elementCount = positionalElementCount + namedElementNames.length;
    return '$elementCount;${namedElementNames.join(',')}';
  }

  @override
  js_ast.Expression visitRecordLiteral(RecordLiteral node) {
    var names = node.named.map((element) => element.name);
    var positionalElementCount = node.positional.length;
    var shapeKey = _recordShapeKey(positionalElementCount, names);
    var shapeExpr = _runtimeCall('recordLiteral(#, #, #, [#])', [
      js.string(shapeKey),
      js.number(positionalElementCount),
      names.isEmpty ? js.call('void 0') : js.stringArray(names),
      [
        for (var positional in node.positional) _visitExpression(positional),
        for (var named in node.named) _visitExpression(named.value),
      ],
    ]);
    return shapeExpr;
  }

  @override
  js_ast.Expression visitAwaitExpression(AwaitExpression node) {
    var expression = _visitExpression(node.operand);
    var type = node.runtimeCheckType;
    if (type != null) {
      // When an expected runtime type is present there is a possible soundness
      // issue with the static types. The type of the await expression must be
      // checked at runtime to ensure soundness.
      var expectedType = _emitType(type);
      var asyncLibrary = _emitLibraryName(_coreTypes.asyncLibrary);
      expression = js.call('#.awaitWithTypeCheck(#, #)', [
        asyncLibrary,
        expectedType,
        expression,
      ]);
    }
    return js_ast.Await(expression);
  }

  @override
  js_ast.Expression visitFunctionExpression(FunctionExpression node) {
    var savedInFunctionExpression = _inFunctionExpression;
    _inFunctionExpression = true;
    var fn = _emitArrowFunction(node);
    _inFunctionExpression = savedInFunctionExpression;
    if (!_reifyFunctionType(node.function)) return fn;
    return _emitFunctionTagged(
      fn,
      node.getStaticType(_staticTypeContext) as FunctionType,
    );
  }

  js_ast.ArrowFun _emitArrowFunction(FunctionExpression node) {
    var f = _emitFunction(node.function, null);
    js_ast.Node body = f.body;

    // Simplify `=> { return e; }` to `=> e`
    if (body is js_ast.Block) {
      var block = body;
      if (block.statements.length == 1) {
        var s = block.statements.single;
        if (s is js_ast.Block) {
          block = s;
          if (block.statements.length == 1) s = block.statements.single;
        }
        if (s is js_ast.Return && s.value != null) body = s.value!;
      }
    }

    // Convert `function(...) { ... }` to `(...) => ...`
    // This is for readability, but it also ensures correct `this` binding.
    return js_ast.ArrowFun(f.params, body);
  }

  @override
  js_ast.Expression visitStringLiteral(StringLiteral node) =>
      js.escapedString(node.value, '"');

  @override
  js_ast.Expression visitIntLiteral(IntLiteral node) => js.uint64(node.value);

  @override
  js_ast.Expression visitDoubleLiteral(DoubleLiteral node) =>
      js.number(node.value);

  @override
  js_ast.Expression visitBoolLiteral(BoolLiteral node) =>
      js_ast.LiteralBool(node.value);

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

  @override
  js_ast.Expression visitLet(Let node) {
    var v = node.variable;
    var init = _visitExpression(v.initializer!);
    var body = _visitExpression(node.body);
    var temp = _tempVariables.remove(v);
    if (temp != null) {
      if (_letVariables != null) {
        init = js_ast.Assignment(temp, init);
        _letVariables!.add(temp);
      } else {
        // TODO(jmesserly): make sure this doesn't happen on any performance
        // critical call path.
        //
        // Annotations on a top-level, non-lazy function type should be the only
        // remaining use.
        var arrowFunction = js_ast.ArrowFun([temp], body);
        final asyncAnalysis = PreTranslationAnalysis((node) {
          throw UnsupportedError('Unknown node in block expression: $node');
        }, arrowFunction)..analyze();
        final isAsyncIife = asyncAnalysis.hasAwaitOrYield.contains(body);
        if (isAsyncIife) {
          final transformedFunction = _rewriteAsyncFunction(
            js_ast.Fun([temp], js_ast.Block([js_ast.Return(body)])),
            AsyncMarker.Async,
            null,
            node.getStaticType(_staticTypeContext),
            functionBody: _toSourceLocation(node.fileOffset),
            functionEnd: _toSourceLocation(node.fileOffset),
          );
          arrowFunction = js_ast.ArrowFun([temp], transformedFunction.body);
        }
        final call = js_ast.Call(arrowFunction, [init]);
        return isAsyncIife ? js_ast.Await(call) : call;
      }
    }
    return js_ast.Binary(',', init, body);
  }

  @override
  js_ast.Expression visitBlockExpression(BlockExpression node) {
    var jsExpr = _visitExpression(node.value);
    var jsStmts = [
      for (var s in node.body.statements) _visitStatement(s),
      js_ast.Return(jsExpr),
    ];
    final statementBlock = js_ast.Block(jsStmts);
    var arrowFunction = js_ast.ArrowFun(const [], statementBlock);
    final asyncAnalysis = PreTranslationAnalysis((node) {
      throw UnsupportedError(
        'Unknown node in block expression: $node (${node.runtimeType}, '
        '${node.sourceInformation})',
      );
    }, arrowFunction)..analyze();
    final isAsyncIife = asyncAnalysis.hasAwaitOrYield.contains(statementBlock);
    if (isAsyncIife) {
      final transformedFunction = _rewriteAsyncFunction(
        js_ast.Fun(const [], statementBlock),
        AsyncMarker.Async,
        null,
        node.getStaticType(_staticTypeContext),
        functionBody: _toSourceLocation(node.fileOffset),
        functionEnd: _toSourceLocation(node.fileOffset),
      );
      arrowFunction = js_ast.ArrowFun(const [], transformedFunction.body);
    }
    final call = js_ast.Call(arrowFunction, const []);
    return isAsyncIife ? js_ast.Await(call) : call;
  }

  @override
  js_ast.Expression visitInstantiation(Instantiation node) {
    return _runtimeCall('gbind(#, #)', [
      _visitExpression(node.expression),
      node.typeArguments.map(_emitType).toList(),
    ]);
  }

  @override
  js_ast.Expression visitLoadLibrary(LoadLibrary node) =>
      _runtimeCall('loadLibrary(#, #, #)', [
        js.string(node.import.enclosingLibrary.importUri.toString()),
        js.string(node.import.name!),
        js.string(
          _libraryToModule(node.import.targetLibrary, throwIfNotFound: false),
        ),
      ]);

  // TODO(jmesserly): DDC loads all libraries eagerly.
  // See
  // https://github.com/dart-lang/sdk/issues/27776
  // https://github.com/dart-lang/sdk/issues/27777
  @override
  js_ast.Expression visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) =>
      _runtimeCall('checkDeferredIsLoaded(#, #)', [
        js.string(node.import.enclosingLibrary.importUri.toString()),
        js.string(node.import.name!),
      ]);

  bool _reifyFunctionType(FunctionNode f) {
    var parent = f.parent;
    if (parent is FunctionDeclaration &&
        (isLateLoweredLocalGetter(parent.variable) ||
            isLateLoweredLocalSetter(parent.variable))) {
      // Late local variables are lowered to local get and set functions.
      // These functions should never need to be tagged with their types.
      return false;
    }
    if (!_currentLibrary!.importUri.isScheme('dart')) return true;

    // SDK libraries can skip reification if they request it.
    bool reifyFunctionTypes(Expression a) =>
        isBuiltinAnnotation(a, '_js_helper', 'ReifyFunctionTypes');
    while (parent != null) {
      var a = findAnnotation(parent, reifyFunctionTypes);
      if (a != null) {
        var value = _constants.getFieldValueFromAnnotation(a, 'value');
        if (value is bool) return value;
      }
      parent = parent.parent;
    }
    return true;
  }

  bool _reifyTearoff(Member member) {
    return member is Procedure &&
        !member.isAccessor &&
        !member.isFactory &&
        !(_isInForeignJS && _isBuildingSdk) &&
        !usesJSInterop(member) &&
        _reifyFunctionType(member.function);
  }

  /// Returns the name value of the `JSExportName` annotation (when compiling
  /// the SDK), or `null` if there's none. This is used to control the name
  /// under which functions are compiled and exported.
  String? _jsExportName(NamedNode n) {
    var library = getLibrary(n);
    if (!library.importUri.isScheme('dart')) return null;

    return _annotationName(n, isJSExportNameAnnotation);
  }

  /// If [node] has annotation matching [test] and the first argument is a
  /// string, this returns the string value.
  ///
  /// Calls [findAnnotation] followed by [getNameFromAnnotation].
  String? _annotationName(NamedNode node, bool Function(Expression) test) {
    var annotation = findAnnotation(node, test);
    return annotation != null
        ? _constants.getFieldValueFromAnnotation(annotation, 'name') as String?
        : null;
  }

  @override
  js_ast.Expression visitConstant(Constant node) {
    if (node is StaticTearOffConstant) {
      // JS() or external JS consts should not be lazily loaded.
      var isSdk = node.target.enclosingLibrary.importUri.isScheme('dart');
      if (_isInForeignJS) {
        return _emitStaticTarget(node.target);
      }
      if (node.target.isExternal && !isSdk) {
        return _runtimeCall('tearoffInterop(#, #)', [
          _emitStaticTarget(node.target),
          js.boolean(_isNullCheckableJsInterop(node.target)),
        ]);
      }
    }
    if (node is TypeLiteralConstant) {
      // We bypass the use of constants, since types are already canonicalized
      // in the DDC output.
      return _emitTypeLiteral(node.type);
    }
    if (node is PrimitiveConstant) {
      return super.visitConstant(node);
    }

    // Avoid caching constants during evaluation while scoping issues remain.
    // See: #44713
    if (_constTableCache.incrementalMode) {
      return super.visitConstant(node);
    }

    var constAlias = _constAliasCache[node];
    if (constAlias != null) {
      return constAlias;
    }
    var constAliasString = 'C${_constAliasCache.length}';
    var constAliasProperty = _propertyName(constAliasString);

    _constTableCache[constAliasString] = js.call('void 0');
    var constAliasAccessor = _constTableCache.access(constAliasString);

    var constAccessor = js.call('# || #.#', [
      constAliasAccessor,
      _constTable,
      constAliasProperty,
    ]);
    _constAliasCache[node] = constAccessor;
    var constJs = super.visitConstant(node);

    var func = js_ast.Fun(
      [],
      js_ast.Block([
        js.statement('return # = #;', [constAliasAccessor, constJs]),
      ]),
    );
    var accessor = js_ast.Method(constAliasProperty, func, isGetter: true);
    _constLazyAccessors.add(accessor);
    return constAccessor;
  }

  @override
  js_ast.Expression visitNullConstant(NullConstant node) =>
      js_ast.LiteralNull();
  @override
  js_ast.Expression visitBoolConstant(BoolConstant node) =>
      js.boolean(node.value);
  @override
  js_ast.Expression visitIntConstant(IntConstant node) => js.number(node.value);
  @override
  js_ast.Expression visitDoubleConstant(DoubleConstant node) {
    var value = node.value;

    // Emit the constant as an integer, if possible.
    if (value.isFinite) {
      var intValue = value.toInt();
      const minInt32 = -0x80000000;
      const maxInt32 = 0x7FFFFFFF;
      if (intValue.toDouble() == value &&
          intValue >= minInt32 &&
          intValue <= maxInt32) {
        return js.number(intValue);
      }
    }
    if (value.isInfinite) {
      if (value.isNegative) {
        return js.call('-1 / 0');
      }
      return js.call('1 / 0');
    }
    if (value.isNaN) {
      return js.call('0 / 0');
    }
    return js.number(value);
  }

  @override
  js_ast.Expression visitStringConstant(StringConstant node) =>
      js.escapedString(node.value, '"');

  // DDC does not currently use the non-primitive constant nodes; rather these
  // are emitted via their normal expression nodes.
  @override
  js_ast.Expression defaultConstant(Constant node) => _emitInvalidNode(node);

  @override
  js_ast.Expression visitSymbolConstant(SymbolConstant node) =>
      _emitDartSymbol(node.name);

  @override
  js_ast.Expression visitMapConstant(MapConstant node) {
    var entries = [
      for (var e in node.entries) ...[
        visitConstant(e.key),
        visitConstant(e.value),
      ],
    ];
    return _emitConstMap(node.keyType, node.valueType, entries);
  }

  @override
  js_ast.Expression visitListConstant(ListConstant node) => _emitConstList(
    node.typeArgument,
    node.entries.map(visitConstant).toList(),
  );

  @override
  js_ast.Expression visitSetConstant(SetConstant node) => _emitConstSet(
    node.typeArgument,
    node.entries.map(visitConstant).toList(),
  );

  @override
  js_ast.Expression visitRecordConstant(RecordConstant node) {
    // RecordConstant names are already sorted alphabetically in kernel.
    var names = node.named.keys;
    var positionalElementCount = node.positional.length;
    var shapeKey = _recordShapeKey(positionalElementCount, names);
    return _runtimeCall('recordLiteral(#, #, #, [#])', [
      js.string(shapeKey),
      js.number(positionalElementCount),
      names.isEmpty ? js.call('void 0') : js.stringArray(names),
      [
        ...node.positional.map(visitConstant),
        ...node.named.values.map(visitConstant),
      ],
    ]);
  }

  js_ast.Expression visitEnum(InstanceConstant node) {
    var type = node.getType(_staticTypeContext);
    assert(
      type.nullability == Nullability.nonNullable,
      'An instance constant should only ever have a non-nullable type.',
    );
    var classRef = _emitClassRef(type as InterfaceType);
    var prototype = js.call('#.prototype', [classRef]);
    var enumAccessor = _emitTopLevelName(node.classNode);

    // Enums are canonicalized based on their 'name' member alone. We
    // append other members (such as 'index' and those introduced via enhanced
    // enums) after canonicalization so they can be updated across hot reloads.
    var constantProperties = <js_ast.Property>[];
    var additionalProperties = <js_ast.Property>[];
    if (type.typeArguments.isNotEmpty) {
      // Generic interface type instances require a type information tag.
      var property = js_ast.Property(
        _propertyName(js_ast.FixedNames.rtiName),
        _emitType(type),
      );
      constantProperties.add(property);
    }
    node.fieldValues.forEach((k, v) {
      var constant = visitConstant(v);
      var member = k.asField;
      var memberClass = member.enclosingClass!;
      if (!memberClass.isEnum) {
        if (member.name.text == 'index') {
          // We transform the 'index' field of Enum fields into a special
          // getter so that their indices are consistent across hot reloads.
          var value = js.call('#.values.indexOf(this)', enumAccessor);
          var jsMember = _getSymbol(
            _emitClassPrivateNameSymbol(
              memberClass.enclosingLibrary,
              getLocalClassName(memberClass),
              member,
            ),
          );
          additionalProperties.add(
            js_ast.Method(
              jsMember,
              js.fun('function() { return #; }', [value]),
              isGetter: true,
            ),
          );
        } else {
          var jsMember = _getSymbol(
            _emitClassPrivateNameSymbol(
              memberClass.enclosingLibrary,
              getLocalClassName(memberClass),
              member,
            ),
          );
          constantProperties.add(js_ast.Property(jsMember, constant));
        }
      } else {
        additionalProperties.add(
          js_ast.Property(
            _emitMemberName(member.name.text, member: member),
            constant,
          ),
        );
      }
    });

    var canonicalizedEnum = _canonicalizeConstObject(
      _emitJSObjectSetPrototypeOf(
        js_ast.ObjectInitializer(constantProperties, multiline: true),
        prototype,
        fullyQualifiedName: false,
      ),
    );

    var enumExtension = _runtimeStatement('extendEnum(#, #)', [
      canonicalizedEnum,
      js_ast.ObjectInitializer(additionalProperties, multiline: true),
    ]);
    _enumExtensions.add(enumExtension);

    return canonicalizedEnum;
  }

  @override
  js_ast.Expression visitInstanceConstant(InstanceConstant node) {
    var savedTypeEnvironment = _currentTypeEnvironment;
    if (node.classNode.typeParameters.isNotEmpty) {
      _currentTypeEnvironment = ClassTypeEnvironment(
        node.classNode.typeParameters,
      );
    }

    if (node.classNode.isEnum) {
      var constant = visitEnum(node);
      _currentTypeEnvironment = savedTypeEnvironment;
      return constant;
    }

    js_ast.Property entryToProperty(MapEntry<Reference, Constant> entry) {
      var constant = visitConstant(entry.value);
      var member = entry.key.asField;
      var cls = member.enclosingClass!;
      var symbol = _getSymbol(
        _emitClassPrivateNameSymbol(
          cls.enclosingLibrary,
          getLocalClassName(cls),
          member,
        ),
      );
      return js_ast.Property(symbol, constant);
    }

    var type = node.getType(_staticTypeContext);
    assert(
      type.nullability == Nullability.nonNullable,
      'An instance constant should only ever have a non-nullable type.',
    );
    var classRef = _emitClassRef(type as InterfaceType);
    var prototype = js.call('#.prototype', [classRef]);
    var properties = [
      if (type.typeArguments.isNotEmpty)
        // Generic interface type instances require a type information tag.
        js_ast.Property(
          _propertyName(js_ast.FixedNames.rtiName),
          _emitType(type),
        ),
      for (var e in node.fieldValues.entries.toList().reversed)
        entryToProperty(e),
    ];
    var constant = _canonicalizeConstObject(
      _emitJSObjectSetPrototypeOf(
        js_ast.ObjectInitializer(properties, multiline: true),
        prototype,
        fullyQualifiedName: false,
      ),
    );
    _currentTypeEnvironment = savedTypeEnvironment;
    return constant;
  }

  /// Emits a private name JS Symbol for [member] unique to a Dart class
  /// [className].
  ///
  /// This is now required for fields of constant objects that may be overridden
  /// within the same library.
  js_ast.ScopedId _emitClassPrivateNameSymbol(
    Library library,
    String className,
    Member member, [
    js_ast.ScopedId? id,
  ]) {
    var name = '$className.${member.name.text}';
    // Wrap the name as a symbol here so it matches what you would find at
    // runtime when you get all properties and symbols from an instance.
    memberNames[member] = 'Symbol($name)';
    return _emitPrivateNameSymbol(library, name, id);
  }

  @override
  js_ast.Expression visitStaticTearOffConstant(StaticTearOffConstant node) {
    return _emitStaticGet(node.target);
  }

  @override
  js_ast.Expression visitTypeLiteralConstant(TypeLiteralConstant node) =>
      _emitTypeLiteral(node.type);

  @override
  js_ast.Expression visitInstantiationConstant(InstantiationConstant node) =>
      _canonicalizeConstObject(
        _runtimeCall('gbind(#, #)', [
          visitConstant(node.tearOffConstant),
          node.types.map(_emitType).toList(),
        ]),
      );

  @override
  js_ast.Expression visitUnevaluatedConstant(UnevaluatedConstant node) =>
      throw UnsupportedError('Encountered an unevaluated constant: $node');

  @override
  js_ast.Expression visitFunctionTearOff(FunctionTearOff node) {
    var receiver = node.receiver;
    var receiverType = receiver.getStaticType(_staticTypeContext);
    var jsReceiver = _visitExpression(receiver);
    if (receiverType is InterfaceType &&
        receiverType.classNode == _coreTypes.functionClass) {
      // Historically DDC has treated this case as a dynamic get and allowed it
      // to evaluate at runtime.
      //
      // This is here to preserve the existing behavior for the non-static
      // JavaScript interop (including some failing cases) but could potentially
      // be cleaned up as a breaking change.
      return _runtimeCall('dload$_replSuffix(#, #)', [
        jsReceiver,
        js.string('call'),
      ]);
    }
    // Otherwise, tearoff of `call` on a function type is a no-op.
    return jsReceiver;
  }

  @override
  js_ast.Statement visitIfCaseStatement(IfCaseStatement node) {
    // This node is internal to the front end and removed by the constant
    // evaluator.
    throw UnsupportedError('ProgramCompiler.visitIfCaseStatement');
  }

  @override
  js_ast.Expression visitPatternAssignment(PatternAssignment node) {
    // This node is internal to the front end and removed by the constant
    // evaluator.
    throw UnsupportedError('ProgramCompiler.visitPatternAssignment');
  }

  @override
  js_ast.Statement visitPatternSwitchStatement(PatternSwitchStatement node) {
    // This node is internal to the front end and removed by the constant
    // evaluator.
    throw UnsupportedError('ProgramCompiler.visitPatternSwitchStatement');
  }

  @override
  js_ast.Statement visitPatternVariableDeclaration(
    PatternVariableDeclaration node,
  ) {
    // This node is internal to the front end and removed by the constant
    // evaluator.
    throw UnsupportedError('ProgramCompiler.visitPatternVariableDeclaration');
  }

  @override
  js_ast.Expression visitSwitchExpression(SwitchExpression node) {
    // This node is internal to the front end and removed by the constant
    // evaluator.
    throw UnsupportedError('ProgramCompiler.visitSwitchExpression');
  }

  @override
  js_ast.Expression visitAuxiliaryExpression(AuxiliaryExpression node) {
    throw UnsupportedError(
      'Unsupported auxiliary expression $node (${node.runtimeType}).',
    );
  }

  @override
  js_ast.Statement visitAuxiliaryStatement(AuxiliaryStatement node) {
    throw UnsupportedError(
      'Unsupported auxiliary statement $node (${node.runtimeType}).',
    );
  }

  void _setEmitIfIncrementalLibrary(Library library) {
    if (_incrementalMode) {
      _setEmitIfIncremental(_libraryToModule(library), _jsLibraryName(library));
    }
  }

  void _setEmitIfIncremental(String module, String library) {
    if (_incrementalMode) {
      _incrementalModules.putIfAbsent(module, () => {}).add(library);
    }
  }

  /// When compiling the body of a `operator []=` method, this will be non-null
  /// and will indicate the value that should be returned from any `return;`
  /// statements.
  js_ast.Identifier? get _operatorSetResult {
    var stack = _operatorSetResultStack;
    return stack.isEmpty ? null : stack.last;
  }

  /// Called when starting to emit methods/functions, in particular so we can
  /// implement special handling of the user-defined `[]=` and `==` methods.
  ///
  /// See also [_exitFunction] and [_emitReturnStatement].
  void _enterFunction(
    String? name,
    List<js_ast.Parameter> formals,
    bool Function() isLastParamMutated,
  ) {
    if (name == '[]=') {
      _operatorSetResultStack.add(
        isLastParamMutated()
            ? js_ast.ScopedId((formals.last as js_ast.Identifier).name)
            : formals.last as js_ast.Identifier,
      );
    } else {
      _operatorSetResultStack.add(null);
    }
  }

  /// Called when finished emitting methods/functions, and must correspond to a
  /// previous [_enterFunction] call.
  js_ast.Block _exitFunction(
    List<js_ast.Parameter> formals,
    js_ast.Block code,
  ) {
    var setOperatorResult = _operatorSetResultStack.removeLast();
    if (setOperatorResult != null) {
      // []= methods need to return the value. We could also address this at
      // call sites, but it's less code size to handle inside the operator.
      var valueParam = formals.last;
      var statements = code.statements;
      if (statements.isEmpty || !statements.last.alwaysReturns) {
        statements.add(js_ast.Return(setOperatorResult));
      }
      if (!identical(setOperatorResult, valueParam)) {
        // If the value parameter was mutated, then we use a temporary
        // variable to track the initial value
        formals.last = setOperatorResult;
        code = js.block('{ let # = #; #; }', [
          valueParam,
          setOperatorResult,
          code,
        ]);
      }
    }
    return code;
  }

  /// Emits a return statement `return <value>;`, handling special rules for
  /// the `operator []=` method.
  js_ast.Statement _emitReturnStatement(js_ast.Expression? value) {
    if (_operatorSetResult != null) {
      var result = js_ast.Return(_operatorSetResult);
      return value != null
          ? js_ast.Block([value.toStatement(), result])
          : result;
    }
    return value != null ? value.toReturn() : js_ast.Return();
  }

  /// Prepends the `dart.` and then uses [js.call] to parse the specified JS
  /// [code] template, passing [args].
  ///
  /// For example:
  ///
  ///     _runtimeCall('asInt(#)', [<expr>])
  ///
  /// Generates a JS AST representing:
  ///
  ///     dart.asInt(<expr>)
  ///
  js_ast.Expression _runtimeCall(String code, [List<Object>? args]) {
    return js.call('#.$code', <Object>[
      _emitLibraryName(_runtimeLibrary),
      ...?args,
    ]);
  }

  /// Calls [_runtimeCall] and uses `toStatement()` to convert the resulting
  /// expression into a statement.
  js_ast.Statement _runtimeStatement(String code, [List<Object>? args]) =>
      _runtimeCall(code, args).toStatement();

  /// Emits a private name JS Symbol for [name] scoped to the Dart [library].
  ///
  /// If the same name is used in multiple libraries in the same module,
  /// distinct symbols will be used, so each library will have distinct private
  /// member names, that won't collide at runtime, as required by the Dart
  /// language spec.
  ///
  /// If an [id] is provided, try to use that.
  ///
  /// TODO(vsm): Clean up id generation logic.  This method is used to both
  /// define new symbols and to reference existing ones.  If it's called
  /// multiple times with same [library] and [name], we'll allocate redundant
  /// top-level variables (see callers to this method).
  js_ast.ScopedId _emitPrivateNameSymbol(
    Library library,
    String name, [
    js_ast.ScopedId? id,
  ]) {
    /// Initializes the JS `Symbol` for the private member [name] in [library].
    ///
    /// If the library is in the current JS module ([_libraries] contains it),
    /// the private name will be created and exported. The exported symbol is
    /// used for a few things:
    ///
    /// - private fields of constant objects
    /// - stateful hot reload (not yet implemented)
    /// - correct library scope in REPL (not yet implemented)
    ///
    /// If the library is imported, then the existing private name will be
    /// retrieved from it. In both cases, we use the same `dart.privateName`
    /// runtime call.
    js_ast.ScopedId initPrivateNameSymbol() {
      var idName = name.endsWith('=') ? name.replaceAll('=', '_') : name;
      idName = idName.replaceAll(js_ast.invalidCharInIdentifier, '_');
      var identifier = id ?? js_ast.ScopedId(idName);
      _addSymbol(
        identifier,
        _runtimeCall('privateName(#, #)', [
          js.string('${library.importUri}'),
          js.string(name),
        ]),
      );
      if (!_containerizeSymbols) {
        // TODO(vsm): Change back to `const`.
        // See https://github.com/dart-lang/sdk/issues/40380.
        _moduleItems.add(
          js.statement('var # = #', [
            identifier,
            _runtimeCall('privateName(#, #)', [
              js.string('${library.importUri}'),
              js.string(name),
            ]),
          ]),
        );
      }
      return identifier;
    }

    var privateNames = _privateNames.putIfAbsent(library, () => HashMap());
    var symbolId = privateNames.putIfAbsent(name, initPrivateNameSymbol);

    _setEmitIfIncrementalLibrary(library);
    _setEmitIfIncremental(
      _libraryToModule(_coreLibrary),
      _runtimeLibraryId.name,
    );
    _symbolContainer.setEmitIfIncremental(symbolId);

    return symbolId;
  }

  /// Emits an expression to set the property [nameExpr] on the class
  /// [className], with [value].
  ///
  /// This will use `className.name = value` if possible, otherwise it will use
  /// `dart.defineValue(className, name, value)`. This is required when
  /// `FunctionNode.prototype` already defines a getters with the same name.
  js_ast.Expression _defineValueOnClass(
    Class c,
    js_ast.Expression className,
    js_ast.Expression nameExpr,
    js_ast.Expression value,
  ) {
    var args = [className, nameExpr, value];
    if (nameExpr is js_ast.LiteralString) {
      var name = nameExpr.valueWithoutQuotes;
      if (js_ast.isFunctionPrototypeGetter(name) ||
          _superclassHasStatic(c, name)) {
        return _runtimeCall('defineValue(#, #, #)', args);
      }
    }
    return js.call('#.# = #', args);
  }

  /// Emits a Dart Symbol with the given member [symbolName].
  ///
  /// If the symbol refers to a private name, its library will be set to the
  /// [currentLibrary], so the Symbol is scoped properly.
  js_ast.Expression _emitDartSymbol(String symbolName) {
    // TODO(vsm): Handle qualified symbols correctly.
    var last = symbolName.split('.').last;
    var name = js.escapedString(symbolName, "'");
    js_ast.Expression result;
    if (last.startsWith('_')) {
      var nativeSymbolAccessor = _getSymbol(
        _emitPrivateNameSymbol(_currentLibrary!, last),
      );
      result = js.call('new #.new(#, #)', [
        _emitConstructorAccess(_privateSymbolType),
        name,
        nativeSymbolAccessor,
      ]);
    } else {
      result = js.call('new #.new(#)', [
        _emitConstructorAccess(_internalSymbolType),
        name,
      ]);
    }
    return _canonicalizeConstObject(result);
  }

  /// Calls the `dart.const` function in "dart:_runtime" to canonicalize a
  /// constant instance of a user-defined class stored in [expr].
  js_ast.Expression _canonicalizeConstObject(js_ast.Expression expr) =>
      _runtimeCall('const(#)', [expr]);

  /// Emits preamble for the module containing [libraries], and returns the
  /// list of module items for further items to be added.
  ///
  /// The preamble consists of initializing the identifiers for each library,
  /// that will be used to store their members. It also generates the
  /// appropriate ES6 `export` declaration to export them from this module.
  ///
  /// After the code for all of the library members is emitted,
  /// [_emitImportsAndExtensionSymbols] should be used to emit imports/extension
  /// symbols into the list returned by this method. Finally, [_finishLibrary]
  /// can be called to complete the module and return the resulting JS AST.
  ///
  /// This also initializes several fields: [_runtimeLibraryId],
  /// [_extensionSymbolsLibraryId], and the [_libraries] map needed by
  /// [_emitLibraryName].
  List<js_ast.ModuleItem> _startLibrary(Library library) {
    if (_isSdkInternalRuntime(library)) {
      // Don't allow these to be renamed when we're building the SDK.
      // There is JS code in dart:* that depends on their names.
      _runtimeLibraryId = js_ast.Identifier('dart');
      _extensionSymbolsLibraryId = js_ast.Identifier(
        _extensionSymbolHolderName,
      );
    } else {
      // Otherwise allow these to be renamed so users can write them.
      _runtimeLibraryId = js_ast.ScopedId('dart');
      _extensionSymbolsLibraryId = js_ast.ScopedId(_extensionSymbolHolderName);
    }

    // Initialize our library variables.
    var items = <js_ast.ModuleItem>[];
    var exports = <js_ast.NameSpecifier>[];
    if (_isSdkInternalRuntime(library)) {
      _libraries[library] = _runtimeLibraryId;
    } else {
      var libraryId = _isBuildingSdk && _isDartLibrary(library, '_rti')
          ? _rtiLibraryId
          : js_ast.ScopedId(_jsLibraryName(library));

      _libraries[library] = libraryId;
      var alias = _jsLibraryAlias(library);
      var aliasId = alias == null ? null : js_ast.ScopedId(alias);
      exports.add(js_ast.NameSpecifier(libraryId, asName: aliasId));
    }
    items.add(js_ast.ExportDeclaration(js_ast.ExportClause(exports)));

    if (_isSdkInternalRuntime(library)) {
      // Initialize the private name function.
      // To bootstrap the SDK, this needs to be emitted before other code.
      var privateNamesId = _emitScopedId('privateNames');
      items.add(js.statement('const # = new Map()', privateNamesId));
      items.add(
        _runtimeStatement(
          r'''
        privateName = function privateName(libraryUri, name) {
          let names = #.get(libraryUri);
          if (names == null) #.set(libraryUri, names = new Map());
          let symbol = names.get(name);
          if (symbol == null) names.set(name, symbol = Symbol(name));
          return symbol;
        }
      ''',
          [privateNamesId, privateNamesId],
        ),
      );
    }

    return items;
  }

  /// Returns the canonical name to refer to the Dart library.
  js_ast.Identifier _emitLibraryName(Library library) {
    _setEmitIfIncrementalLibrary(library);

    // It's either one of the libraries in this module, or it's an import.
    return _libraries[library] ??
        _imports.putIfAbsent(library, () {
          if (_isSdkInternalRuntime(library)) return _runtimeLibraryId;
          if (_isDartLibrary(library, '_rti')) return _rtiLibraryId;
          return js_ast.ScopedId(_jsLibraryName(library));
        });
  }

  /// Emits imports into [items].
  void _emitImports(List<js_ast.ModuleItem> items) {
    var modules = <String, List<Library>>{};
    for (var import in _imports.keys) {
      modules.putIfAbsent(_libraryToModule(import), () => []).add(import);
    }
    // TODO(nshahan): Update this code and the representation of
    // `ImportDeclaration`s when other module formats are no longer supported.
    modules.forEach((module, libraries) {
      if (!_incrementalMode || _incrementalModules.containsKey(module)) {
        var usedLibraries = _incrementalModules[module];

        // Generate import directives.
        //
        // Our import variables are temps and can get renamed. Since our
        // renaming is integrated into js_ast, it is aware of this possibility
        // and will generate an "as" if needed. For example:
        //
        //     import {foo} from 'foo';         // if no rename needed
        //     import {foo as foo$} from 'foo'; // if rename was needed
        //
        for (var library in libraries) {
          if (!_incrementalMode ||
              usedLibraries!.contains(_jsLibraryName(library))) {
            var alias = _jsLibraryAlias(library);
            if (alias != null) {
              var aliasId = js_ast.ScopedId(alias);
              items.add(
                js_ast.ImportDeclaration(
                  from: js.string('${library.importUri}'),
                  namedImports: [
                    js_ast.NameSpecifier(aliasId, asName: _imports[library]),
                  ],
                ),
              );
            } else {
              items.add(
                js_ast.ImportDeclaration(
                  from: js.string('${library.importUri}'),
                  namedImports: [js_ast.NameSpecifier(_imports[library])],
                ),
              );
            }
          }
        }
      }
    });
    items.add(
      js_ast.ImportDeclaration(
        from: js.string(_extensionSymbolHolderName),
        namedImports: [js_ast.NameSpecifier(_extensionSymbolsLibraryId)],
      ),
    );
  }

  /// Emits extension methods into [items].
  void _emitExtensionSymbols(
    List<js_ast.ModuleItem> items, {
    bool forceExtensionSymbols = false,
  }) {
    // Initialize extension symbols
    _extensionSymbols.forEach((name, id) {
      js_ast.Expression value = js_ast.PropertyAccess(
        _extensionSymbolsLibraryId,
        _propertyName(name),
      );
      if (forceExtensionSymbols) {
        value = js.call('# || (# = Symbol(#))', [
          value,
          value,
          js.string('$_extensionSymbolHolderName.$name'),
        ]);
      }
      // Emit hoisted extension symbols that are marked as noEmit in regular as
      // well as incremental mode (if needed) since they are going to be
      // referenced as such in the generated expression.
      if (!_incrementalMode ||
          _symbolContainer.incrementalModuleItems.contains(id)) {
        if (!_symbolContainer.canEmit(id)) {
          // Extension symbols marked with noEmit are managed manually.
          // TODO(vsm): Change back to `const`.
          // See https://github.com/dart-lang/sdk/issues/40380.
          items.add(js.statement('var # = #;', [id, value]));
        }
      }
      if (_symbolContainer.incrementalModuleItems.contains(id)) {
        _setEmitIfIncremental(
          _libraryToModule(_coreLibrary),
          _extensionSymbolsLibraryId.name,
        );
      }
      _symbolContainer[id] = value;
    });
  }

  /// Emits exports as imports into [items].
  ///
  /// Use information from exports to re-define library variables referenced
  /// inside compiled expressions in incremental mode. That matches importing
  /// a current module into the symbol used to represent the library during
  /// original compilation in [emitLibrary].
  ///
  /// Example of exports emitted to JavaScript during emitModule:
  ///
  /// ```
  /// // Exports:
  /// return {
  ///  web__main: main
  /// };
  /// ```
  ///
  /// The transformation to imports during expression compilation converts the
  /// exports above to:
  ///
  /// ```
  /// const web__main = require('web/main');
  /// const main = web__main.web__main;
  /// ```
  ///
  /// Where the compiled expression references `main`.
  void _emitExportsAsImports(List<js_ast.ModuleItem> items, Library current) {
    var exports = <js_ast.NameSpecifier>[];
    assert(_incrementalMode);
    assert(!_isBuildingSdk);

    var module = _libraryToModule(current);
    var usedLibraries = _incrementalModules[module] ?? {};

    if (usedLibraries.isNotEmpty) {
      _libraries.forEach((library, libraryId) {
        if (usedLibraries.contains(_jsLibraryName(library))) {
          var alias = _jsLibraryAlias(library);
          var aliasId = alias == null ? libraryId : js_ast.ScopedId(alias);
          var asName = alias == null ? null : libraryId;
          exports.add(js_ast.NameSpecifier(aliasId, asName: asName));
        }
      });

      items.add(
        js_ast.ImportDeclaration(
          namedImports: exports,
          from: js.string(current.importUri.toString(), "'"),
        ),
      );
    }
  }

  /// Emits imports and extension methods into [items].
  void _emitImportsAndExtensionSymbols(
    List<js_ast.ModuleItem> items, {
    bool forceExtensionSymbols = false,
  }) {
    _emitImports(items);
    _emitExtensionSymbols(items, forceExtensionSymbols: forceExtensionSymbols);
  }

  /// Returns an accessor for [id] via the symbol container.
  /// E.g., transforms $sym to S$5.$sym.
  ///
  /// A symbol lookup on an id marked no emit omits the symbol accessor.
  js_ast.Expression _getSymbol(js_ast.Identifier id) {
    _symbolContainer.setEmitIfIncremental(id);
    return _symbolContainer.canEmit(id) ? _symbolContainer.access(id) : id;
  }

  /// Returns the raw JS value associated with [id].
  js_ast.Expression _getSymbolValue(js_ast.Identifier id) {
    _symbolContainer.setEmitIfIncremental(id);
    return _symbolContainer[id]!;
  }

  /// Inserts a symbol into the symbol table.
  js_ast.Expression _addSymbol(js_ast.Identifier id, js_ast.Expression symbol) {
    _symbolContainer[id] = symbol;
    _symbolContainer.setEmitIfIncremental(id);
    if (!_containerizeSymbols) {
      _symbolContainer.setNoEmit(id);
    }
    return _symbolContainer[id]!;
  }

  /// Finishes the library created by [_startLibrary], by combining the preamble
  /// [items] with the [_moduleItems] that have been emitted.
  ///
  /// The [libraryName] should specify the library's name, and the items should
  /// be the list resulting from [_startLibrary], with additional items added,
  /// but not including the contents of [_moduleItems] (which will be handled
  /// by this method itself).
  ///
  /// Note, this function mutates the items list and returns it as the `body`
  /// field of the result.
  js_ast.Program _finishLibrary(
    List<js_ast.ModuleItem> items,
    String libraryName,
    js_ast.Identifier libraryId,
  ) {
    // TODO(jmesserly): there's probably further consolidation we can do
    // between DDC's two backends, by moving more code into this method, as the
    // code between `_startLibrary` and `_finishLibrary` is very similar in
    // both.

    // Emit all top-level JS symbol containers.
    items.addAll(_symbolContainer.emit());

    if (_dynamicEntrypoint != null) {
      // Expose the entrypoint of the dynamic module under a reserved name.
      // TODO(sigmund): this could use a reserved symbol from dartx.
      var name = _emitTopLevelName(_dynamicEntrypoint!);
      _moduleItems.add(
        js_ast.ExportDeclaration(
          js('var __dynamic_module_entrypoint__ = #', [name]),
        ),
      );
    }

    // Add the library's code (produced by visiting compilation units, above)
    _copyAndFlattenBlocks(items, _moduleItems);
    _moduleItems.clear();

    // Build the library.
    return js_ast.Program(items, name: libraryName, librarySelfVar: libraryId);
  }

  /// Flattens blocks in [items] to a single list.
  ///
  /// This will not flatten blocks that are marked as being scopes.
  void _copyAndFlattenBlocks(
    List<js_ast.ModuleItem> result,
    Iterable<js_ast.ModuleItem> items,
  ) {
    for (var item in items) {
      if (item is js_ast.Block && !item.isScope) {
        _copyAndFlattenBlocks(result, item.statements);
      } else {
        result.add(item);
      }
    }
  }

  /// This is an internal method used by [_emitMemberName] and the
  /// optimized `dart:_runtime extensionSymbol` builtin to get the symbol
  /// for `dartx.<name>`.
  ///
  /// Do not call this directly; you want [_emitMemberName], which knows how to
  /// handle the many details involved in naming.
  js_ast.ScopedId _getExtensionSymbolInternal(String name) {
    if (!_extensionSymbols.containsKey(name)) {
      var id = js_ast.ScopedId(
        '\$${js_ast.friendlyNameForDartOperator[name] ?? name}',
      );
      _extensionSymbols[name] = id;
      _addSymbol(id, id);
    }
    var symbolId = _extensionSymbols[name]!;
    _symbolContainer.setEmitIfIncremental(symbolId);
    return symbolId;
  }

  /// Shorthand for identifier-like property names.
  /// For now, we emit them as strings and the printer restores them to
  /// identifiers if it can.
  // TODO(jmesserly): avoid the round tripping through quoted form.
  js_ast.LiteralString _propertyName(String name) => js.string(name, "'");

  /// Unique identifiers indicating the locations to inline the corresponding
  /// information.
  ///
  /// We cannot generate the source map before the script it is for is
  /// generated so we have generate the script including this identifier in the
  /// JS AST, and then replace it once the source map is generated.  Similarly,
  /// metrics include the size of the source map.
  static const String sourceMapLocationID =
      'SourceMap3G5a8h6JVhHfdGuDxZr1EF9GQC8y0e6u';
  static const String metricsLocationID =
      'MetricsJ7xFWBfSv6ZjrW9yLb21GNzisZr3anSf5h';

  /// Matches against the `dart:js_util` `_callMethodUnchecked` and
  /// `_callMethodUncheckedTrustType` variants with 0 to 4 arguments.
  static final RegExp _callMethodUncheckedRegex = RegExp(
    r'^\_callMethodUnchecked(TrustType)?[0-4]',
  );

  /// Matches against the `dart:js_util` `_callConstructorUnchecked` and
  /// `_callConstructorUncheckedTrustType` variants with 0 to 4 arguments.
  static final RegExp _callConstructorUncheckedRegex = RegExp(
    r'^\_callConstructorUnchecked[0-4]',
  );
}

bool _isInlineJSFunction(Statement? body) {
  var block = body;
  if (block is Block) {
    var statements = block.statements;
    if (statements.length != 1) return false;
    body = statements[0];
  }
  if (body is ReturnStatement) {
    var expr = body.expression;
    return expr is StaticInvocation && isInlineJS(expr.target);
  }
  return false;
}

/// Return true if this is one of the methods/properties on all Dart Objects
/// (toString, hashCode, noSuchMethod, runtimeType).
///
/// Operator == is excluded, as it is handled as part of the equality binary
/// operator.
bool _isObjectMember(String name) {
  // We could look these up on Object, but we have hard coded runtime helpers
  // so it's not really providing any benefit.
  switch (name) {
    case 'hashCode':
    case 'toString':
    case 'noSuchMethod':
    case 'runtimeType':
    case '==':
      return true;
  }
  return false;
}

bool _isObjectGetter(String name) =>
    name == 'hashCode' || name == 'runtimeType';

bool _isObjectMethodTearoff(String name) =>
    // "==" isn't in here because there is no syntax to tear it off.
    name == 'toString' || name == 'noSuchMethod';

bool _isObjectMethodCall(String name, Arguments args) {
  if (name == 'toString') {
    return args.positional.isEmpty && args.named.isEmpty && args.types.isEmpty;
  } else if (name == 'noSuchMethod') {
    return args.positional.length == 1 &&
        args.named.isEmpty &&
        args.types.isEmpty;
  }
  return false;
}

class _SwitchLabelState {
  String label;
  js_ast.Identifier variable;

  _SwitchLabelState(this.label, this.variable);
}

/// Whether [expression] is a constant of the form
/// `const pragma('dyn-module:entry-point')`.
///
/// Used to denote the entrypoint method of a dynamic module.
bool _isEntrypointPragma(Expression expression, CoreTypes coreTypes) {
  if (expression is! ConstantExpression) return false;
  final value = expression.constant;
  if (value is! InstanceConstant) return false;
  if (value.classReference != coreTypes.pragmaClass.reference) return false;
  final name = value.fieldValues[coreTypes.pragmaName.fieldReference];
  if (name is! StringConstant) return false;
  return name.value == 'dyn-module:entry-point';
}
