diff --git a/pkg/dev_compiler/analysis_options.yaml b/pkg/dev_compiler/analysis_options.yaml
index 13ed31a..249dc5d 100644
--- a/pkg/dev_compiler/analysis_options.yaml
+++ b/pkg/dev_compiler/analysis_options.yaml
@@ -24,6 +24,7 @@
     - empty_catches
     - empty_constructor_bodies
     - library_names
+    - library_prefixes
     - no_duplicate_case_values
     - null_closures
     - prefer_contains
diff --git a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
index 3ff97b0..1dc1e73 100644
--- a/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/code_generator.dart
@@ -29,12 +29,12 @@
 import 'package:path/path.dart' as path;
 import 'package:source_span/source_span.dart' show SourceLocation;
 
-import '../compiler/js_metalet.dart' as JS;
-import '../compiler/js_names.dart' as JS;
-import '../compiler/js_utils.dart' as JS;
+import '../compiler/js_metalet.dart' as js_ast;
+import '../compiler/js_names.dart' as js_ast;
+import '../compiler/js_utils.dart' as js_ast;
 import '../compiler/module_builder.dart' show pathToJSIdentifier;
 import '../compiler/shared_compiler.dart';
-import '../js_ast/js_ast.dart' as JS;
+import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 import '../js_ast/source_map_printer.dart' show NodeEnd, NodeSpan, HoverComment;
 import 'ast_builder.dart';
@@ -68,12 +68,12 @@
 // (which result in (JS.Statement).
 class CodeGenerator extends Object
     with
-        UIAsCodeVisitorMixin<JS.Node>,
+        UIAsCodeVisitorMixin<js_ast.Node>,
         NullableTypeInference,
         SharedCompiler<LibraryElement, ClassElement, InterfaceType,
             FunctionBody>
     implements
-        AstVisitor<JS.Node> {
+        AstVisitor<js_ast.Node> {
   final SummaryDataStore summaryData;
 
   final CompilerOptions options;
@@ -87,7 +87,7 @@
 
   /// The list of dart:_runtime SDK functions; these are assumed by other code
   /// in the SDK to be generated before anything else.
-  final _internalSdkFunctions = <JS.ModuleItem>[];
+  final _internalSdkFunctions = <js_ast.ModuleItem>[];
 
   /// Table of named and possibly hoisted types.
   TypeTable _typeTable;
@@ -105,9 +105,10 @@
   SimpleIdentifier _rethrowParameter;
 
   /// In an async* function, this represents the stream controller parameter.
-  JS.TemporaryId _asyncStarController;
+  js_ast.TemporaryId _asyncStarController;
 
-  final _initializingFormalTemps = HashMap<ParameterElement, JS.TemporaryId>();
+  final _initializingFormalTemps =
+      HashMap<ParameterElement, js_ast.TemporaryId>();
 
   /// The  type provider from the current Analysis [context].
   final TypeProvider types;
@@ -167,13 +168,13 @@
   /// mappings.
   Element _currentElement;
 
-  final _deferredProperties = HashMap<PropertyAccessorElement, JS.Method>();
+  final _deferredProperties = HashMap<PropertyAccessorElement, js_ast.Method>();
 
   String _libraryRoot;
 
   bool _superAllowed = true;
 
-  final _superHelpers = Map<String, JS.Method>();
+  final _superHelpers = Map<String, js_ast.Method>();
 
   /// Whether we are currently generating code for the body of a `JS()` call.
   bool _isInForeignJS = false;
@@ -194,7 +195,7 @@
   /// Tracks the temporary variable used to build collections containing
   /// control flow [IfElement] and [ForElement] nodes. Should be saved when
   /// visiting a new control flow tree and restored after.
-  JS.Expression _currentCollectionVariable;
+  js_ast.Expression _currentCollectionVariable;
 
   CodeGenerator(LinkedAnalysisDriver driver, this.types, this.summaryData,
       this.options, this._extensionTypes, this.errors)
@@ -261,7 +262,7 @@
   ///
   /// Takes the metadata for the build unit, as well as resolved trees and
   /// errors, and computes the output module code and optionally the source map.
-  JS.Program compile(List<CompilationUnit> compilationUnits) {
+  js_ast.Program compile(List<CompilationUnit> compilationUnits) {
     _libraryRoot = options.libraryRoot;
     if (!_libraryRoot.endsWith(path.separator)) {
       _libraryRoot += path.separator;
@@ -373,18 +374,18 @@
     return libraryJSName != null ? '$libraryJSName.$jsName' : jsName;
   }
 
-  JS.PropertyAccess _emitJSInterop(Element e) {
+  js_ast.PropertyAccess _emitJSInterop(Element e) {
     var jsName = _getJSNameWithoutGlobal(e);
     if (jsName == null) return null;
     return _emitJSInteropForGlobal(jsName);
   }
 
-  JS.PropertyAccess _emitJSInteropForGlobal(String name) {
+  js_ast.PropertyAccess _emitJSInteropForGlobal(String name) {
     var parts = name.split('.');
     if (parts.isEmpty) parts = [''];
-    JS.PropertyAccess access;
+    js_ast.PropertyAccess access;
     for (var part in parts) {
-      access = JS.PropertyAccess(
+      access = js_ast.PropertyAccess(
           access ?? runtimeCall('global'), js.escapedString(part, "'"));
     }
     return access;
@@ -474,7 +475,7 @@
     var source = library.source;
     // TODO(jmesserly): we need to split out HTML.
     if (source.uri.scheme == 'dart') {
-      return JS.dartSdkModule;
+      return js_ast.dartSdkModule;
     }
     var summaryPath = (source as InSummarySource).summaryPath;
     var moduleName = options.summaryModules[summaryPath];
@@ -507,7 +508,7 @@
     // only run this on the outermost function, and not any closures.
     inferNullableTypes(node);
 
-    moduleItems.add(node.accept(this) as JS.ModuleItem);
+    moduleItems.add(node.accept(this) as js_ast.ModuleItem);
 
     _currentElement = savedElement;
   }
@@ -566,7 +567,7 @@
       }
 
       inferNullableTypes(declaration);
-      var item = declaration.accept(this) as JS.ModuleItem;
+      var item = declaration.accept(this) as js_ast.ModuleItem;
       if (isInternalSdk && element is FunctionElement) {
         _internalSdkFunctions.add(item);
       } else {
@@ -709,7 +710,7 @@
     return _emitCast(to, jsFrom, implicit: isImplicit);
   }
 
-  JS.Expression _emitCast(DartType type, JS.Expression expr,
+  js_ast.Expression _emitCast(DartType type, js_ast.Expression expr,
       {bool implicit = true}) {
     // If [type] is a top type we can omit the cast.
     if (rules.isSubtypeOf(types.objectType, type)) {
@@ -720,15 +721,15 @@
   }
 
   @override
-  JS.Expression visitIsExpression(IsExpression node) {
+  js_ast.Expression visitIsExpression(IsExpression node) {
     return _emitIsExpression(
         node.expression, node.type.type, node.notOperator != null);
   }
 
-  JS.Expression _emitIsExpression(Expression operand, DartType type,
+  js_ast.Expression _emitIsExpression(Expression operand, DartType type,
       [bool negated = false]) {
     // Generate `is` as `dart.is` or `typeof` depending on the RHS type.
-    JS.Expression result;
+    js_ast.Expression result;
     var lhs = _visitExpression(operand);
     var typeofName = jsTypeRep.typeFor(type).primitiveTypeOf;
     // Inline primitives other than int (which requires a Math.floor check).
@@ -750,12 +751,12 @@
   visitGenericTypeAlias(GenericTypeAlias node) => null;
 
   @override
-  JS.Expression visitTypeName(node) => _emitTypeAnnotation(node);
+  js_ast.Expression visitTypeName(node) => _emitTypeAnnotation(node);
 
   @override
-  JS.Expression visitGenericFunctionType(node) => _emitTypeAnnotation(node);
+  js_ast.Expression visitGenericFunctionType(node) => _emitTypeAnnotation(node);
 
-  JS.Expression _emitTypeAnnotation(TypeAnnotation node) {
+  js_ast.Expression _emitTypeAnnotation(TypeAnnotation node) {
     var type = node.type;
     if (type == null) {
       // TODO(jmesserly): if the type fails to resolve, should we generate code
@@ -767,17 +768,17 @@
   }
 
   @override
-  JS.Statement visitClassTypeAlias(ClassTypeAlias node) {
+  js_ast.Statement visitClassTypeAlias(ClassTypeAlias node) {
     return _emitClassDeclaration(
         node, node.declaredElement as ClassElement, []);
   }
 
   @override
-  JS.Statement visitClassDeclaration(ClassDeclaration node) {
+  js_ast.Statement visitClassDeclaration(ClassDeclaration node) {
     return _emitClassDeclaration(node, node.declaredElement, node.members);
   }
 
-  JS.Statement _emitClassDeclaration(Declaration classNode,
+  js_ast.Statement _emitClassDeclaration(Declaration classNode,
       ClassElement classElem, List<ClassMember> members) {
     // If this class is annotated with `@JS`, then there is nothing to emit.
     if (_hasJSInteropAnnotation(classElem)) return null;
@@ -790,8 +791,8 @@
     // https://github.com/dart-lang/sdk/issues/31003
     var className = classElem.typeParameters.isNotEmpty
         ? (classElem == _jsArray
-            ? JS.Identifier(classElem.name)
-            : JS.TemporaryId(classElem.name))
+            ? js_ast.Identifier(classElem.name)
+            : js_ast.TemporaryId(classElem.name))
         : _emitTopLevelName(classElem);
 
     var savedClassProperties = _classProperties;
@@ -818,9 +819,9 @@
     var jsMethods = _emitClassMethods(classElem, members);
     _emitSuperclassCovarianceChecks(classNode, jsMethods);
 
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     _emitSuperHelperSymbols(body);
-    var deferredSupertypes = <JS.Statement>[];
+    var deferredSupertypes = <js_ast.Statement>[];
 
     // Emit the class, e.g. `core.Object = class Object { ... }`
     _defineClass(classElem, className, jsMethods, body, deferredSupertypes);
@@ -844,7 +845,7 @@
     }
     _emitClassMetadata(classNode.metadata, className, body);
 
-    var classDef = JS.Statement.from(body);
+    var classDef = js_ast.Statement.from(body);
     var typeFormals = classElem.typeParameters;
     if (typeFormals.isNotEmpty) {
       classDef = _defineClassTypeArguments(
@@ -861,12 +862,12 @@
     }
 
     _classProperties = savedClassProperties;
-    return JS.Statement.from(body);
+    return js_ast.Statement.from(body);
   }
 
-  JS.Statement _emitClassTypeTests(ClassElement classElem,
-      JS.Expression className, List<JS.Statement> body) {
-    JS.Expression getInterfaceSymbol(ClassElement c) {
+  js_ast.Statement _emitClassTypeTests(ClassElement classElem,
+      js_ast.Expression className, List<js_ast.Statement> body) {
+    js_ast.Expression getInterfaceSymbol(ClassElement c) {
       var library = c.library;
       if (library.isDartCore || library.isDartAsync) {
         switch (c.name) {
@@ -882,7 +883,7 @@
       return null;
     }
 
-    void markSubtypeOf(JS.Expression testSymbol) {
+    void markSubtypeOf(js_ast.Expression testSymbol) {
       body.add(js.statement('#.prototype[#] = true', [className, testSymbol]));
     }
 
@@ -1052,7 +1053,7 @@
     if (isClassSymbol == null) {
       // TODO(jmesserly): we could export these symbols, if we want to mark
       // implemented interfaces for user-defined classes.
-      var id = JS.TemporaryId("_is_${classElem.name}_default");
+      var id = js_ast.TemporaryId("_is_${classElem.name}_default");
       moduleItems.add(
           js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
       isClassSymbol = id;
@@ -1070,53 +1071,55 @@
     return runtimeStatement('addTypeTests(#, #)', [defaultInst, isClassSymbol]);
   }
 
-  void _emitSymbols(Iterable<JS.TemporaryId> vars, List<JS.ModuleItem> body) {
+  void _emitSymbols(
+      Iterable<js_ast.TemporaryId> 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.Statement> body) {
+  void _emitSuperHelperSymbols(List<js_ast.Statement> body) {
     _emitSymbols(
-        _superHelpers.values.map((m) => m.name as JS.TemporaryId), body);
+        _superHelpers.values.map((m) => m.name as js_ast.TemporaryId), body);
     _superHelpers.clear();
   }
 
   void _emitVirtualFieldSymbols(
-      ClassElement classElement, List<JS.Statement> body) {
+      ClassElement classElement, List<js_ast.Statement> body) {
     _classProperties.virtualFields.forEach((field, virtualField) {
       body.add(js.statement('const # = Symbol(#);',
           [virtualField, js.string('${classElement.name}.${field.name}')]));
     });
   }
 
-  List<JS.Identifier> _emitTypeFormals(List<TypeParameterElement> typeFormals) {
+  List<js_ast.Identifier> _emitTypeFormals(
+      List<TypeParameterElement> typeFormals) {
     return typeFormals
-        .map((t) => JS.Identifier(t.name))
+        .map((t) => js_ast.Identifier(t.name))
         .toList(growable: false);
   }
 
   @override
-  JS.Statement visitEnumDeclaration(EnumDeclaration node) {
+  js_ast.Statement visitEnumDeclaration(EnumDeclaration node) {
     return _emitClassDeclaration(node, node.declaredElement, []);
   }
 
   @override
-  JS.Statement visitMixinDeclaration(MixinDeclaration node) {
+  js_ast.Statement visitMixinDeclaration(MixinDeclaration node) {
     return _emitClassDeclaration(node, node.declaredElement, node.members);
   }
 
   /// Wraps a possibly generic class in its type arguments.
-  JS.Statement _defineClassTypeArguments(TypeDefiningElement element,
-      List<TypeParameterElement> formals, JS.Statement body,
-      [JS.Expression className, List<JS.Statement> deferredBaseClass]) {
+  js_ast.Statement _defineClassTypeArguments(TypeDefiningElement element,
+      List<TypeParameterElement> formals, js_ast.Statement body,
+      [js_ast.Expression className, List<js_ast.Statement> deferredBaseClass]) {
     assert(formals.isNotEmpty);
     var jsFormals = _emitTypeFormals(formals);
     var typeConstructor = js.call('(#) => { #; #; return #; }', [
       jsFormals,
       _typeTable.discharge(formals),
       body,
-      className ?? JS.Identifier(element.name)
+      className ?? js_ast.Identifier(element.name)
     ]);
 
     var genericArgs = [typeConstructor];
@@ -1131,17 +1134,18 @@
         [genericName, genericCall, _emitTopLevelName(element), genericName]);
   }
 
-  JS.Statement _emitClassStatement(
+  js_ast.Statement _emitClassStatement(
       ClassElement classElem,
-      JS.Expression className,
-      JS.Expression heritage,
-      List<JS.Method> methods) {
+      js_ast.Expression className,
+      js_ast.Expression heritage,
+      List<js_ast.Method> methods) {
     if (classElem.typeParameters.isNotEmpty) {
-      return JS.ClassExpression(className as JS.Identifier, heritage, methods)
+      return js_ast.ClassExpression(
+              className as js_ast.Identifier, heritage, methods)
           .toStatement();
     }
-    var classExpr =
-        JS.ClassExpression(JS.TemporaryId(classElem.name), heritage, methods);
+    var classExpr = js_ast.ClassExpression(
+        js_ast.TemporaryId(classElem.name), heritage, methods);
     return js.statement('# = #;', [className, classExpr]);
   }
 
@@ -1174,10 +1178,10 @@
   /// minimal compiler and runtime changes.
   void _emitMixinStatement(
       ClassElement classElem,
-      JS.Expression className,
-      JS.Expression heritage,
-      List<JS.Method> methods,
-      List<JS.Statement> body) {
+      js_ast.Expression className,
+      js_ast.Expression heritage,
+      List<js_ast.Method> methods,
+      List<js_ast.Statement> body) {
     assert(classElem.isMixin);
 
     var staticMethods = methods.where((m) => m.isStatic).toList();
@@ -1185,42 +1189,43 @@
     body.add(
         _emitClassStatement(classElem, className, heritage, staticMethods));
 
-    var superclassId = JS.TemporaryId(
+    var superclassId = js_ast.TemporaryId(
         classElem.superclassConstraints.map((t) => t.name).join('_'));
-    var classId =
-        className is JS.Identifier ? className : JS.TemporaryId(classElem.name);
+    var classId = className is js_ast.Identifier
+        ? className
+        : js_ast.TemporaryId(classElem.name);
 
     var mixinMemberClass =
-        JS.ClassExpression(classId, superclassId, instanceMethods);
+        js_ast.ClassExpression(classId, superclassId, instanceMethods);
 
-    JS.Node arrowFnBody = mixinMemberClass;
-    var extensionInit = <JS.Statement>[];
+    js_ast.Node arrowFnBody = mixinMemberClass;
+    var extensionInit = <js_ast.Statement>[];
     _defineExtensionMembers(classId, extensionInit);
     if (extensionInit.isNotEmpty) {
       extensionInit.insert(0, mixinMemberClass.toStatement());
       extensionInit.add(classId.toReturn());
-      arrowFnBody = JS.Block(extensionInit);
+      arrowFnBody = js_ast.Block(extensionInit);
     }
 
     body.add(js.statement('#[#.mixinOn] = #', [
       className,
       runtimeModule,
-      JS.ArrowFun([superclassId], arrowFnBody)
+      js_ast.ArrowFun([superclassId], arrowFnBody)
     ]));
   }
 
   void _defineClass(
       ClassElement classElem,
-      JS.Expression className,
-      List<JS.Method> methods,
-      List<JS.Statement> body,
-      List<JS.Statement> deferredSupertypes) {
+      js_ast.Expression className,
+      List<js_ast.Method> methods,
+      List<js_ast.Statement> body,
+      List<js_ast.Statement> deferredSupertypes) {
     if (classElem.type.isObject) {
       body.add(_emitClassStatement(classElem, className, null, methods));
       return;
     }
 
-    JS.Expression emitDeferredType(DartType t) {
+    js_ast.Expression emitDeferredType(DartType t) {
       if (t is InterfaceType && t.typeArguments.isNotEmpty) {
         _declareBeforeUse(t.element);
         return _emitGenericClassType(
@@ -1267,9 +1272,10 @@
     var supertype = classElem.isMixin ? types.objectType : classElem.supertype;
     var hasUnnamedSuper = _hasUnnamedInheritedConstructor(supertype.element);
 
-    void emitMixinConstructors(JS.Expression className, [InterfaceType mixin]) {
+    void emitMixinConstructors(js_ast.Expression className,
+        [InterfaceType mixin]) {
       var supertype = classElem.supertype;
-      JS.Statement mixinCtor;
+      js_ast.Statement mixinCtor;
       if (mixin != null && _hasUnnamedConstructor(mixin.element)) {
         mixinCtor = js.statement('#.#.call(this);', [
           emitClassRef(mixin),
@@ -1281,14 +1287,14 @@
 
       for (var ctor in supertype.constructors) {
         var jsParams = _emitParametersForElement(ctor);
-        var ctorBody = <JS.Statement>[];
+        var ctorBody = <js_ast.Statement>[];
         if (mixinCtor != null) ctorBody.add(mixinCtor);
         if (ctor.name != '' || hasUnnamedSuper) {
           ctorBody
               .add(_emitSuperConstructorCall(className, ctor.name, jsParams));
         }
         body.add(_addConstructorToClass(classElem, className, ctor.name,
-            JS.Fun(jsParams, JS.Block(ctorBody))));
+            js_ast.Fun(jsParams, js_ast.Block(ctorBody))));
       }
     }
 
@@ -1334,8 +1340,8 @@
         //     applyMixin(C, class C$ extends M { <methods>  });
         mixinBody.add(runtimeStatement('applyMixin(#, #)', [
           classExpr,
-          JS.ClassExpression(
-              JS.TemporaryId(classElem.name), mixinClass, methods)
+          js_ast.ClassExpression(
+              js_ast.TemporaryId(classElem.name), mixinClass, methods)
         ]));
       }
 
@@ -1347,10 +1353,10 @@
       var m = classElem.mixins[i];
 
       var mixinString = classElem.supertype.name + '_' + m.name;
-      var mixinClassName = JS.TemporaryId(mixinString);
-      var mixinId = JS.TemporaryId(mixinString + '\$');
+      var mixinClassName = js_ast.TemporaryId(mixinString);
+      var mixinId = js_ast.TemporaryId(mixinString + '\$');
       var mixinClassExpression =
-          JS.ClassExpression(mixinClassName, baseClass, []);
+          js_ast.ClassExpression(mixinClassName, baseClass, []);
       // Bind the mixin class to a name to workaround a V8 bug with es6 classes
       // and anonymous function names.
       // TODO(leafp:) Eliminate this once the bug is fixed:
@@ -1392,28 +1398,28 @@
   /// 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.Method> _emitNativeFieldAccessors(FieldDeclaration node) {
+  List<js_ast.Method> _emitNativeFieldAccessors(FieldDeclaration node) {
     // 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.Method>[];
+    var jsMethods = <js_ast.Method>[];
     if (!node.isStatic) {
       for (var decl in node.fields.variables) {
         var field = decl.declaredElement as FieldElement;
         var name = getAnnotationName(field, isJSName) ?? field.name;
         // Generate getter
-        var fn = JS.Fun([], js.block('{ return this.#; }', [name]));
+        var fn = js_ast.Fun([], js.block('{ return this.#; }', [name]));
         var method =
-            JS.Method(_declareMemberName(field.getter), fn, isGetter: true);
+            js_ast.Method(_declareMemberName(field.getter), fn, isGetter: true);
         jsMethods.add(method);
 
         // Generate setter
         if (!decl.isFinal) {
-          var value = JS.TemporaryId('value');
-          fn = JS.Fun([value], js.block('{ this.# = #; }', [name, value]));
-          method =
-              JS.Method(_declareMemberName(field.setter), fn, isSetter: true);
+          var value = js_ast.TemporaryId('value');
+          fn = js_ast.Fun([value], js.block('{ this.# = #; }', [name, value]));
+          method = js_ast.Method(_declareMemberName(field.setter), fn,
+              isSetter: true);
           jsMethods.add(method);
         }
       }
@@ -1421,20 +1427,20 @@
     return jsMethods;
   }
 
-  List<JS.Method> _emitClassMethods(
+  List<js_ast.Method> _emitClassMethods(
       ClassElement classElem, List<ClassMember> memberNodes) {
     var type = classElem.type;
     var virtualFields = _classProperties.virtualFields;
 
-    var jsMethods = <JS.Method>[];
+    var jsMethods = <js_ast.Method>[];
     bool hasJsPeer = _extensionTypes.isNativeClass(classElem);
     bool hasIterator = false;
 
     if (type.isObject) {
       // Dart does not use ES6 constructors.
       // Add an error to catch any invalid usage.
-      jsMethods
-          .add(JS.Method(propertyName('constructor'), js.fun(r'''function() {
+      jsMethods.add(
+          js_ast.Method(propertyName('constructor'), js.fun(r'''function() {
                   throw Error("use `new " + #.typeName(#.getReifiedType(this)) +
                       ".new(...)` to create a Dart object");
               }''', [runtimeModule, runtimeModule])));
@@ -1445,20 +1451,20 @@
       //
       // This will become obsolete when
       // https://github.com/dart-lang/sdk/issues/31003 is addressed.
-      jsMethods.add(JS.Method(
+      jsMethods.add(js_ast.Method(
           propertyName('constructor'), js.fun(r'function() { return []; }')));
     } else if (classElem.isEnum) {
       // Generate Enum.toString()
       var fields = classElem.fields.where((f) => f.type == type).toList();
-      var mapMap = List<JS.Property>(fields.length);
+      var mapMap = List<js_ast.Property>(fields.length);
       for (var i = 0; i < fields.length; ++i) {
-        mapMap[i] = JS.Property(
+        mapMap[i] = js_ast.Property(
             js.number(i), js.string('${type.name}.${fields[i].name}'));
       }
-      jsMethods.add(JS.Method(
+      jsMethods.add(js_ast.Method(
           _declareMemberName(types.objectType.getMethod('toString')),
           js.fun('function() { return #[this.index]; }',
-              JS.ObjectInitializer(mapMap, multiline: true))));
+              js_ast.ObjectInitializer(mapMap, multiline: true))));
     }
 
     for (var m in memberNodes) {
@@ -1515,7 +1521,7 @@
   }
 
   void _emitSuperclassCovarianceChecks(
-      Declaration node, List<JS.Method> methods) {
+      Declaration node, List<js_ast.Method> methods) {
     var covariantParams = getSuperclassCovariantParameters(node);
     if (covariantParams == null) return;
 
@@ -1526,22 +1532,22 @@
       if (member is PropertyAccessorElement) {
         var param =
             covariantParams.lookup(member.parameters[0]) as ParameterElement;
-        methods.add(JS.Method(
+        methods.add(js_ast.Method(
             name,
             js.fun('function(x) { return super.# = #; }',
-                [name, _emitCast(param.type, JS.Identifier('x'))]),
+                [name, _emitCast(param.type, js_ast.Identifier('x'))]),
             isSetter: true));
-        methods.add(JS.Method(
+        methods.add(js_ast.Method(
             name, js.fun('function() { return super.#; }', [name]),
             isGetter: true));
       } else if (member is MethodElement) {
         var type = member.type;
 
-        var body = <JS.Statement>[];
+        var body = <js_ast.Statement>[];
         _emitCovarianceBoundsCheck(type.typeFormals, covariantParams, body);
 
         var typeFormals = _emitTypeFormals(type.typeFormals);
-        var jsParams = List<JS.Parameter>.from(typeFormals);
+        var jsParams = List<js_ast.Parameter>.from(typeFormals);
         bool foundNamedParams = false;
         for (var param in member.parameters) {
           param = covariantParams.lookup(param) as ParameterElement;
@@ -1554,7 +1560,8 @@
             body.add(js.statement('if (# in #) #;', [
               name,
               namedArgumentTemp,
-              _emitCast(param.type, JS.PropertyAccess(namedArgumentTemp, name))
+              _emitCast(
+                  param.type, js_ast.PropertyAccess(namedArgumentTemp, name))
             ]));
           } else {
             var jsParam = _emitParameter(param);
@@ -1579,8 +1586,8 @@
           body.add(js.statement(
               'return super.#(#)(#);', [name, typeFormals, jsParams]));
         }
-        var fn = JS.Fun(jsParams, JS.Block(body));
-        methods.add(JS.Method(name, fn));
+        var fn = js_ast.Fun(jsParams, js_ast.Block(body));
+        methods.add(js_ast.Method(name, fn));
       } else {
         throw StateError(
             'unable to generate a covariant check for element: `$member` '
@@ -1590,12 +1597,12 @@
   }
 
   /// Emits a Dart factory constructor to a JS static method.
-  JS.Method _emitFactoryConstructor(ConstructorDeclaration node) {
+  js_ast.Method _emitFactoryConstructor(ConstructorDeclaration node) {
     if (isUnsupportedFactoryConstructor(node)) return null;
 
     var element = node.declaredElement;
     var name = _constructorName(element.name);
-    JS.Fun fun;
+    js_ast.Fun fun;
 
     var savedFunction = _currentFunction;
     _currentFunction = node.body;
@@ -1610,27 +1617,27 @@
       // rest/spread support, but this should work for now.
       var params = _emitParameters(node.parameters?.parameters);
 
-      fun = JS.Fun(
+      fun = js_ast.Fun(
           params,
-          JS.Block([
+          js_ast.Block([
             js.statement('return $newKeyword #(#)',
                 [visitConstructorName(redirect), params])
               ..sourceInformation = _nodeStart(redirect)
           ]));
     } else {
       // Normal factory constructor
-      var body = <JS.Statement>[];
+      var body = <js_ast.Statement>[];
       var init = _emitArgumentInitializers(element, node.parameters);
       if (init != null) body.add(init);
       body.add(_visitStatement(node.body));
 
       var params = _emitParameters(node.parameters?.parameters);
-      fun = JS.Fun(params, JS.Block(body));
+      fun = js_ast.Fun(params, js_ast.Block(body));
     }
 
     _currentFunction = savedFunction;
 
-    return JS.Method(name, fun, isStatic: true)
+    return js_ast.Method(name, fun, isStatic: true)
       ..sourceInformation = _functionEnd(node);
   }
 
@@ -1653,14 +1660,15 @@
   ///       return core.bool.as(this.noSuchMethod(
   ///           new dart.InvocationImpl.new('eatFood', [food])));
   ///     }
-  JS.Method _implementMockMember(ExecutableElement method, InterfaceType type) {
-    var invocationProps = <JS.Property>[];
-    addProperty(String name, JS.Expression value) {
-      invocationProps.add(JS.Property(js.string(name), value));
+  js_ast.Method _implementMockMember(
+      ExecutableElement method, InterfaceType type) {
+    var invocationProps = <js_ast.Property>[];
+    addProperty(String name, js_ast.Expression value) {
+      invocationProps.add(js_ast.Property(js.string(name), value));
     }
 
     var typeParams = _emitTypeFormals(method.type.typeFormals);
-    var fnArgs = List<JS.Parameter>.from(typeParams);
+    var fnArgs = List<js_ast.Parameter>.from(typeParams);
     var args = _emitParametersForElement(method);
     fnArgs.addAll(args);
     var argInit = _emitArgumentInitializers(method);
@@ -1682,12 +1690,12 @@
       // Sort the names to match dart2js order.
       var sortedNames = (namedParameterTypes.keys.toList())..sort();
       var named = sortedNames
-          .map((n) => JS.Property(propertyName(n), JS.Identifier(n)));
-      addProperty('namedArguments', JS.ObjectInitializer(named.toList()));
+          .map((n) => js_ast.Property(propertyName(n), js_ast.Identifier(n)));
+      addProperty('namedArguments', js_ast.ObjectInitializer(named.toList()));
       positionalArgs.removeLast();
     }
     if (typeParams.isNotEmpty) {
-      addProperty('typeArguments', JS.ArrayInitializer(typeParams));
+      addProperty('typeArguments', js_ast.ArrayInitializer(typeParams));
     }
 
     var fnBody =
@@ -1695,19 +1703,19 @@
       runtimeModule,
       _declareMemberName(method),
       args,
-      JS.ObjectInitializer(invocationProps)
+      js_ast.ObjectInitializer(invocationProps)
     ]);
 
     fnBody = _emitCast(method.returnType, fnBody);
 
     var fnBlock = argInit != null
-        ? JS.Block([argInit, fnBody.toReturn()])
+        ? js_ast.Block([argInit, fnBody.toReturn()])
         : fnBody.toReturn().toBlock();
 
-    return JS.Method(
+    return js_ast.Method(
         _declareMemberName(method,
             useExtension: _extensionTypes.isNativeClass(type.element)),
-        JS.Fun(fnArgs, fnBlock),
+        js_ast.Fun(fnArgs, fnBlock),
         isGetter: method is PropertyAccessorElement && method.isGetter,
         isSetter: method is PropertyAccessorElement && method.isSetter,
         isStatic: false);
@@ -1720,23 +1728,25 @@
   /// 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.Method> _emitVirtualFieldAccessor(VariableDeclaration field) {
+  List<js_ast.Method> _emitVirtualFieldAccessor(VariableDeclaration field) {
     var element = field.declaredElement as FieldElement;
     var virtualField = _classProperties.virtualFields[element];
-    var result = <JS.Method>[];
+    var result = <js_ast.Method>[];
     var name = _declareMemberName(element.getter);
 
     var mocks = _classProperties.mockMembers;
     if (!mocks.containsKey(element.name)) {
       var getter = js.fun('function() { return this[#]; }', [virtualField]);
-      result.add(JS.Method(name, getter, isGetter: true)
+      result.add(js_ast.Method(name, getter, isGetter: true)
         ..sourceInformation = _functionSpan(field.name));
     }
 
     if (!mocks.containsKey(element.name + '=')) {
-      var args = field.isFinal ? [JS.Super(), name] : [JS.This(), virtualField];
+      var args = field.isFinal
+          ? [js_ast.Super(), name]
+          : [js_ast.This(), virtualField];
 
-      JS.Expression value = JS.Identifier('value');
+      js_ast.Expression value = js_ast.Identifier('value');
 
       var setter = element.setter;
       if (setter != null) {
@@ -1749,7 +1759,8 @@
       }
       args.add(value);
 
-      result.add(JS.Method(name, js.fun('function(value) { #[#] = #; }', args),
+      result.add(js_ast.Method(
+          name, js.fun('function(value) { #[#] = #; }', args),
           isSetter: true)
         ..sourceInformation = _functionSpan(field.name));
     }
@@ -1761,7 +1772,7 @@
   /// 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.Method _emitSuperAccessorWrapper(
+  js_ast.Method _emitSuperAccessorWrapper(
       MethodDeclaration member, InterfaceType type) {
     var accessorElement = member.declaredElement as PropertyAccessorElement;
     var field = accessorElement.variable;
@@ -1775,7 +1786,7 @@
           _classProperties.inheritedSetters.contains(field.name)) {
         // Generate a setter that forwards to super.
         var fn = js.fun('function(value) { super[#] = value; }', [name]);
-        return JS.Method(name, fn, isSetter: true);
+        return js_ast.Method(name, fn, isSetter: true);
       }
     } else {
       var getter = field.getter;
@@ -1783,7 +1794,7 @@
           _classProperties.inheritedGetters.contains(field.name)) {
         // Generate a getter that forwards to super.
         var fn = js.fun('function() { return super[#]; }', [name]);
-        return JS.Method(name, fn, isGetter: true);
+        return js_ast.Method(name, fn, isGetter: true);
       }
     }
     return null;
@@ -1800,7 +1811,7 @@
   /// 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.Method _emitIterable(InterfaceType t) {
+  js_ast.Method _emitIterable(InterfaceType t) {
     // 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.
@@ -1816,13 +1827,15 @@
 
     // Otherwise, emit the adapter method, which wraps the Dart iterator in
     // an ES6 iterator.
-    return JS.Method(
+    return js_ast.Method(
         js.call('Symbol.iterator'),
-        js.call('function() { return new #.JsIterator(this.#); }',
-            [runtimeModule, _emitMemberName('iterator', type: t)]) as JS.Fun);
+        js.call('function() { return new #.JsIterator(this.#); }', [
+          runtimeModule,
+          _emitMemberName('iterator', type: t)
+        ]) as js_ast.Fun);
   }
 
-  JS.Expression _instantiateAnnotation(Annotation node) {
+  js_ast.Expression _instantiateAnnotation(Annotation node) {
     var element = node.element;
     if (element is ConstructorElement) {
       return _emitInstanceCreationExpression(
@@ -1836,7 +1849,7 @@
   }
 
   void _registerExtensionType(
-      ClassElement classElem, String jsPeerName, List<JS.Statement> body) {
+      ClassElement classElem, String jsPeerName, List<js_ast.Statement> body) {
     var className = _emitTopLevelName(classElem);
     if (jsTypeRep.isPrimitive(classElem.type)) {
       body.add(runtimeStatement(
@@ -1847,18 +1860,18 @@
   }
 
   /// Defines all constructors for this class as ES5 constructors.
-  List<JS.Statement> _defineConstructors(
+  List<js_ast.Statement> _defineConstructors(
       ClassElement classElem,
-      JS.Expression className,
+      js_ast.Expression className,
       Map<Element, Declaration> memberMap,
       Declaration classNode) {
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     if (classElem.isMixinApplication) {
       // We already handled this when we defined the class.
       return body;
     }
 
-    addConstructor(String name, JS.Expression jsCtor) {
+    addConstructor(String name, js_ast.Expression jsCtor) {
       body.add(_addConstructorToClass(classElem, className, name, jsCtor));
     }
 
@@ -1878,12 +1891,12 @@
       assert(classElem.constructors.length == 1,
           'default constructor only if no other constructors');
       var superCall = _emitSuperConstructorCallIfNeeded(classElem, className);
-      var ctorBody = <JS.Statement>[_initializeFields(fields)];
+      var ctorBody = <js_ast.Statement>[_initializeFields(fields)];
       if (superCall != null) ctorBody.add(superCall);
 
       addConstructor(
           '',
-          JS.Fun([], JS.Block(ctorBody))
+          js_ast.Fun([], js_ast.Block(ctorBody))
             ..sourceInformation = _functionEnd(classNode));
       return body;
     }
@@ -1923,8 +1936,8 @@
             c.isSynthetic && c.name != '' || c.isFactory || c.isExternal);
   }
 
-  JS.Statement _addConstructorToClass(ClassElement c, JS.Expression className,
-      String name, JS.Expression jsCtor) {
+  js_ast.Statement _addConstructorToClass(ClassElement c,
+      js_ast.Expression className, String name, js_ast.Expression jsCtor) {
     jsCtor = defineValueOnClass(c, className, _constructorName(name), jsCtor);
     return js.statement('#.prototype = #.prototype;', [jsCtor, className]);
   }
@@ -1951,22 +1964,22 @@
   /// Emits static fields for a class, and initialize them eagerly if possible,
   /// otherwise define them as lazy properties.
   void _emitStaticFields(ClassElement classElem,
-      Map<Element, Declaration> members, List<JS.Statement> body) {
+      Map<Element, Declaration> members, List<js_ast.Statement> body) {
     if (classElem.isEnum) {
       // Emit enum static fields
       var type = classElem.type;
-      void addField(FieldElement e, JS.Expression value) {
+      void addField(FieldElement e, js_ast.Expression value) {
         body.add(defineValueOnClass(classElem, _emitStaticClassName(e),
                 _declareMemberName(e.getter), value)
             .toStatement());
       }
 
       int index = 0;
-      var values = <JS.Expression>[];
+      var values = <js_ast.Expression>[];
       for (var f in classElem.fields) {
         if (f.type != type) continue;
         // static const E id_i = const E(i);
-        values.add(JS.PropertyAccess(
+        values.add(js_ast.PropertyAccess(
             _emitStaticClassName(f), _declareMemberName(f.getter)));
         var enumValue = runtimeCall('const(new (#.#)(#))', [
           emitConstructorAccess(type),
@@ -1993,8 +2006,8 @@
     }
   }
 
-  void _emitClassMetadata(List<Annotation> metadata, JS.Expression className,
-      List<JS.Statement> body) {
+  void _emitClassMetadata(List<Annotation> metadata,
+      js_ast.Expression className, List<js_ast.Statement> body) {
     // Metadata
     if (options.emitMetadata && metadata.isNotEmpty) {
       body.add(js.statement('#[#.metadata] = () => [#];',
@@ -2019,18 +2032,18 @@
   /// If a concrete class implements one of our extensions, we might need to
   /// add forwarders.
   void _defineExtensionMembers(
-      JS.Expression className, List<JS.Statement> body) {
+      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.memberNameForDartMember(e)))
+          .map((e) => propertyName(js_ast.memberNameForDartMember(e)))
           .toList();
       body.add(js.statement('#.#(#, #);', [
         runtimeModule,
         helperName,
         className,
-        JS.ArrayInitializer(names, multiline: names.length > 4)
+        js_ast.ArrayInitializer(names, multiline: names.length > 4)
       ]));
     }
 
@@ -2040,8 +2053,8 @@
   }
 
   /// Emit the signature on the class recording the runtime type information
-  void _emitClassSignature(ClassElement classElem, JS.Expression className,
-      Map<Element, Declaration> annotatedMembers, List<JS.Statement> body) {
+  void _emitClassSignature(ClassElement classElem, js_ast.Expression className,
+      Map<Element, Declaration> annotatedMembers, List<js_ast.Statement> body) {
     if (classElem.interfaces.isNotEmpty ||
         classElem.superclassConstraints.isNotEmpty) {
       var interfaces = classElem.interfaces.toList()
@@ -2051,18 +2064,18 @@
           [className, runtimeModule, interfaces.map(_emitType)]));
     }
 
-    void emitSignature(String name, List<JS.Property> elements) {
+    void emitSignature(String name, List<js_ast.Property> elements) {
       if (elements.isEmpty) return;
 
       if (!name.startsWith('Static')) {
         var proto = classElem.type.isObject
             ? js.call('Object.create(null)')
             : runtimeCall('get${name}s(#.__proto__)', [className]);
-        elements.insert(0, JS.Property(propertyName('__proto__'), proto));
+        elements.insert(0, js_ast.Property(propertyName('__proto__'), proto));
       }
       body.add(runtimeStatement('set${name}Signature(#, () => #)', [
         className,
-        JS.ObjectInitializer(elements, multiline: elements.length > 1)
+        js_ast.ObjectInitializer(elements, multiline: elements.length > 1)
       ]));
     }
 
@@ -2070,8 +2083,8 @@
 
     {
       var extMembers = _classProperties.extensionMethods;
-      var staticMethods = <JS.Property>[];
-      var instanceMethods = <JS.Property>[];
+      var staticMethods = <js_ast.Property>[];
+      var instanceMethods = <js_ast.Property>[];
       var classMethods = List.of(classElem.methods.where((m) => !m.isAbstract));
       for (var m in mockMembers.values) {
         if (m is MethodElement) classMethods.add(m);
@@ -2100,13 +2113,13 @@
           var type = _emitAnnotatedFunctionType(
               reifiedType, annotationNode?.metadata,
               parameters: annotationNode?.parameters?.parameters);
-          var property = JS.Property(_declareMemberName(method), type);
+          var property = js_ast.Property(_declareMemberName(method), type);
           if (isStatic) {
             staticMethods.add(property);
           } else {
             instanceMethods.add(property);
             if (extMembers.contains(name)) {
-              instanceMethods.add(JS.Property(
+              instanceMethods.add(js_ast.Property(
                   _declareMemberName(method, useExtension: true), type));
             }
           }
@@ -2119,10 +2132,10 @@
 
     {
       var extMembers = _classProperties.extensionAccessors;
-      var staticGetters = <JS.Property>[];
-      var instanceGetters = <JS.Property>[];
-      var staticSetters = <JS.Property>[];
-      var instanceSetters = <JS.Property>[];
+      var staticGetters = <js_ast.Property>[];
+      var instanceGetters = <js_ast.Property>[];
+      var staticSetters = <js_ast.Property>[];
+      var instanceSetters = <js_ast.Property>[];
 
       var classAccessors = classElem.accessors
           .where((m) => !m.isAbstract && !m.isSynthetic)
@@ -2163,14 +2176,14 @@
                   cacheType: false),
               annotationNode?.metadata);
 
-          var property = JS.Property(_declareMemberName(accessor), type);
+          var property = js_ast.Property(_declareMemberName(accessor), type);
           if (isStatic) {
             (isGetter ? staticGetters : staticSetters).add(property);
           } else {
             var accessors = isGetter ? instanceGetters : instanceSetters;
             accessors.add(property);
             if (extMembers.contains(accessor.variable.name)) {
-              accessors.add(JS.Property(
+              accessors.add(js_ast.Property(
                   _declareMemberName(accessor, useExtension: true), type));
             }
           }
@@ -2187,8 +2200,8 @@
     }
 
     {
-      var instanceFields = <JS.Property>[];
-      var staticFields = <JS.Property>[];
+      var instanceFields = <js_ast.Property>[];
+      var staticFields = <js_ast.Property>[];
 
       for (var field in classElem.fields) {
         if (field.isSynthetic && !classElem.isEnum) continue;
@@ -2205,21 +2218,21 @@
         var fieldSig = _emitFieldSignature(field.type,
             metadata: metadata, isFinal: field.isFinal);
         (isStatic ? staticFields : instanceFields)
-            .add(JS.Property(memberName, fieldSig));
+            .add(js_ast.Property(memberName, fieldSig));
       }
       emitSignature('Field', instanceFields);
       emitSignature('StaticField', staticFields);
     }
 
     if (options.emitMetadata) {
-      var constructors = <JS.Property>[];
+      var constructors = <js_ast.Property>[];
       for (var ctor in classElem.constructors) {
         var annotationNode = annotatedMembers[ctor] as ConstructorDeclaration;
         var memberName = _constructorName(ctor.name);
         var type = _emitAnnotatedFunctionType(
             ctor.type, annotationNode?.metadata,
             parameters: annotationNode?.parameters?.parameters);
-        constructors.add(JS.Property(memberName, type));
+        constructors.add(js_ast.Property(memberName, type));
       }
 
       emitSignature('Constructor', constructors);
@@ -2234,8 +2247,8 @@
     }
   }
 
-  JS.Expression _emitConstructor(ConstructorDeclaration node,
-      List<VariableDeclaration> fields, JS.Expression className) {
+  js_ast.Expression _emitConstructor(ConstructorDeclaration node,
+      List<VariableDeclaration> fields, js_ast.Expression className) {
     var params = _emitParameters(node.parameters?.parameters);
 
     var savedFunction = _currentFunction;
@@ -2247,7 +2260,7 @@
     _superAllowed = savedSuperAllowed;
     _currentFunction = savedFunction;
 
-    return JS.Fun(params, body)..sourceInformation = _functionEnd(node);
+    return js_ast.Fun(params, body)..sourceInformation = _functionEnd(node);
   }
 
   FunctionType _getMemberRuntimeType(ExecutableElement element) {
@@ -2273,7 +2286,7 @@
     return function.type = FunctionTypeImpl(function);
   }
 
-  JS.Expression _constructorName(String name) {
+  js_ast.Expression _constructorName(String name) {
     if (name == '') {
       // Default constructors (factory or not) use `new` as their name.
       return propertyName('new');
@@ -2281,9 +2294,9 @@
     return _emitStaticMemberName(name);
   }
 
-  JS.Block _emitConstructorBody(ConstructorDeclaration node,
-      List<VariableDeclaration> fields, JS.Expression className) {
-    var body = <JS.Statement>[];
+  js_ast.Block _emitConstructorBody(ConstructorDeclaration node,
+      List<VariableDeclaration> fields, js_ast.Expression className) {
+    var body = <js_ast.Statement>[];
     var cls = node.parent as ClassDeclaration;
 
     // Generate optional/named argument value assignment. These can not have
@@ -2299,7 +2312,7 @@
     for (var init in node.initializers) {
       if (init is RedirectingConstructorInvocation) {
         body.add(_emitRedirectingConstructor(init, className));
-        return JS.Block(body);
+        return js_ast.Block(body);
       }
     }
 
@@ -2326,11 +2339,11 @@
     }
 
     body.add(_emitFunctionScopedBody(node.body, node.declaredElement));
-    return JS.Block(body);
+    return js_ast.Block(body);
   }
 
-  JS.Statement _emitRedirectingConstructor(
-      RedirectingConstructorInvocation node, JS.Expression className) {
+  js_ast.Statement _emitRedirectingConstructor(
+      RedirectingConstructorInvocation node, js_ast.Expression className) {
     var ctor = node.staticElement;
     // We can't dispatch to the constructor with `this.new` as that might hit a
     // derived class constructor with the same name.
@@ -2341,9 +2354,9 @@
     ]);
   }
 
-  JS.Statement _emitSuperConstructorCallIfNeeded(
-      ClassElement element, JS.Expression className,
-      [ConstructorElement superCtor, List<JS.Expression> args]) {
+  js_ast.Statement _emitSuperConstructorCallIfNeeded(
+      ClassElement element, js_ast.Expression className,
+      [ConstructorElement superCtor, List<js_ast.Expression> args]) {
     // Get the supertype's unnamed constructor.
     superCtor ??= element.supertype?.element?.unnamedConstructor;
     if (superCtor == null) {
@@ -2362,8 +2375,8 @@
     return _emitSuperConstructorCall(className, superCtor.name, args);
   }
 
-  JS.Statement _emitSuperConstructorCall(
-      JS.Expression className, String name, List<JS.Expression> args) {
+  js_ast.Statement _emitSuperConstructorCall(
+      js_ast.Expression className, String name, List<js_ast.Expression> args) {
     return js.statement('#.__proto__.#.call(this, #);',
         [className, _constructorName(name), args ?? []]);
   }
@@ -2393,7 +2406,7 @@
   ///   2. field initializing parameters,
   ///   3. constructor field initializers,
   ///   4. initialize fields not covered in 1-3
-  JS.Statement _initializeFields(List<VariableDeclaration> fieldDecls,
+  js_ast.Statement _initializeFields(List<VariableDeclaration> fieldDecls,
       [ConstructorDeclaration ctor]) {
     Set<FieldElement> ctorFields;
     emitFieldInit(FieldElement f, Expression initializer, AstNode hoverInfo) {
@@ -2407,7 +2420,7 @@
           .toStatement();
     }
 
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     if (ctor != null) {
       ctorFields = HashSet<FieldElement>();
 
@@ -2437,7 +2450,7 @@
     // (for example, it's a literal value such as implicit `null`) and where
     // there's another explicit initialization (either in the initializer list
     // like `field = value`, or via a `this.field` parameter).
-    var fieldInit = <JS.Statement>[];
+    var fieldInit = <js_ast.Statement>[];
     for (var field in fieldDecls) {
       var f = field.declaredElement as FieldElement;
       if (f.isStatic) continue;
@@ -2450,14 +2463,14 @@
     }
     // Run field initializers before the other ones.
     fieldInit.addAll(body);
-    return JS.Statement.from(fieldInit);
+    return js_ast.Statement.from(fieldInit);
   }
 
   /// Emits argument initializers, which handles optional/named args, as well
   /// as generic type checks needed due to our covariance.
-  JS.Statement _emitArgumentInitializers(ExecutableElement element,
+  js_ast.Statement _emitArgumentInitializers(ExecutableElement element,
       [FormalParameterList parameterNodes]) {
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
 
     _emitCovarianceBoundsCheck(
         element.typeParameters, _classProperties?.covariantParameters, body);
@@ -2471,13 +2484,13 @@
       }
 
       if (param.isOptional) {
-        JS.Expression defaultValue;
+        js_ast.Expression defaultValue;
         if (findAnnotation(param, isUndefinedAnnotation) != null) {
           defaultValue = null;
         } else if (paramNode != null) {
           var paramDefault = (paramNode as DefaultFormalParameter).defaultValue;
           if (paramDefault == null) {
-            defaultValue = JS.LiteralNull();
+            defaultValue = js_ast.LiteralNull();
           } else {
             defaultValue = _visitExpression(paramDefault);
           }
@@ -2528,7 +2541,7 @@
         body.add(_nullParameterCheck(jsParam));
       }
     }
-    return body.isEmpty ? null : JS.Statement.from(body);
+    return body.isEmpty ? null : js_ast.Statement.from(body);
   }
 
   bool _isCovariant(ParameterElement p) {
@@ -2536,26 +2549,27 @@
         (_classProperties?.covariantParameters?.contains(p) ?? false);
   }
 
-  JS.Fun _emitNativeFunctionBody(MethodDeclaration node) {
+  js_ast.Fun _emitNativeFunctionBody(MethodDeclaration node) {
     String name = getAnnotationName(node.declaredElement, isJSAnnotation) ??
         node.name.name;
     if (node.isGetter) {
-      return JS.Fun([], js.block('{ return this.#; }', [name]));
+      return js_ast.Fun([], js.block('{ return this.#; }', [name]));
     } else if (node.isSetter) {
       var params = _emitParameters(node.parameters?.parameters);
-      return JS.Fun(params, js.block('{ this.# = #; }', [name, params.last]));
+      return js_ast.Fun(
+          params, js.block('{ this.# = #; }', [name, params.last]));
     } else {
       return js.fun(
           'function (...args) { return this.#.apply(this, args); }', name);
     }
   }
 
-  JS.Method _emitMethodDeclaration(MethodDeclaration node) {
+  js_ast.Method _emitMethodDeclaration(MethodDeclaration node) {
     if (node.isAbstract) {
       return null;
     }
 
-    JS.Fun fn;
+    js_ast.Fun fn;
     if (node.externalKeyword != null || node.body is NativeFunctionBody) {
       if (node.isStatic) {
         // TODO(vsm): Do we need to handle this case?
@@ -2566,7 +2580,7 @@
       fn = _emitFunction(node.declaredElement, node.parameters, node.body);
     }
 
-    return JS.Method(_declareMemberName(node.declaredElement), fn,
+    return js_ast.Method(_declareMemberName(node.declaredElement), fn,
         isGetter: node.isGetter,
         isSetter: node.isSetter,
         isStatic: node.isStatic)
@@ -2574,7 +2588,7 @@
   }
 
   @override
-  JS.Statement visitFunctionDeclaration(FunctionDeclaration node) {
+  js_ast.Statement visitFunctionDeclaration(FunctionDeclaration node) {
     assert(node.parent is CompilationUnit);
 
     if (node.externalKeyword != null ||
@@ -2589,7 +2603,7 @@
           : element.correspondingGetter;
 
       var jsCode = _emitTopLevelProperty(node);
-      var props = <JS.Method>[jsCode];
+      var props = <js_ast.Method>[jsCode];
       if (pairAccessor != null) {
         // If we have a getter/setter pair, they need to be defined together.
         // If this is the first one, save the generated code for later.
@@ -2605,12 +2619,12 @@
           'copyProperties(#, { # })', [emitLibraryName(currentLibrary), props]);
     }
 
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     var fn = _emitFunctionExpression(node.functionExpression);
 
     if (currentLibrary.source.isInSystemLibrary &&
         _isInlineJSFunction(node.functionExpression)) {
-      fn = JS.simplifyPassThroughArrowFunCallBody(fn);
+      fn = js_ast.simplifyPassThroughArrowFunCallBody(fn);
     }
     fn.sourceInformation = _functionEnd(node);
 
@@ -2626,7 +2640,7 @@
           .toStatement());
     }
 
-    return JS.Statement.from(body);
+    return js_ast.Statement.from(body);
   }
 
   bool _isInlineJSFunction(FunctionExpression functionExpression) {
@@ -2648,9 +2662,9 @@
   bool _isJSInvocation(Expression expr) =>
       expr is MethodInvocation && isInlineJS(expr.methodName.staticElement);
 
-  JS.Method _emitTopLevelProperty(FunctionDeclaration node) {
+  js_ast.Method _emitTopLevelProperty(FunctionDeclaration node) {
     var name = node.name.name;
-    return JS.Method(
+    return js_ast.Method(
         propertyName(name), _emitFunctionExpression(node.functionExpression),
         isGetter: node.isGetter, isSetter: node.isSetter)
       ..sourceInformation = _functionEnd(node);
@@ -2697,7 +2711,7 @@
     return !_declarationNodes.containsKey(type.element);
   }
 
-  JS.Expression _emitFunctionTagged(JS.Expression fn, FunctionType type,
+  js_ast.Expression _emitFunctionTagged(js_ast.Expression fn, FunctionType type,
       {bool topLevel = false}) {
     var lazy = topLevel && !_canEmitTypeAtTopLevel(type);
     var typeRep = _emitFunctionType(type, lazy: lazy);
@@ -2712,7 +2726,7 @@
   ///
   /// Contrast with [_emitFunctionExpression].
   @override
-  JS.Expression visitFunctionExpression(FunctionExpression node) {
+  js_ast.Expression visitFunctionExpression(FunctionExpression node) {
     assert(node.parent is! FunctionDeclaration &&
         node.parent is! MethodDeclaration);
     var fn = _emitArrowFunction(node);
@@ -2721,22 +2735,22 @@
         topLevel: _executesAtTopLevel(node));
   }
 
-  JS.ArrowFun _emitArrowFunction(FunctionExpression node) {
+  js_ast.ArrowFun _emitArrowFunction(FunctionExpression node) {
     var f = _emitFunction(node.declaredElement, node.parameters, node.body);
-    JS.Node body = f.body;
+    js_ast.Node body = f.body;
 
     // Simplify `=> { return e; }` to `=> e`
-    if (body is JS.Block) {
-      var block = body as JS.Block;
+    if (body is js_ast.Block) {
+      var block = body as js_ast.Block;
       if (block.statements.length == 1) {
-        JS.Statement s = block.statements[0];
-        if (s is JS.Return && s.value != null) body = s.value;
+        js_ast.Statement s = block.statements[0];
+        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.ArrowFun(f.params, body);
+    return js_ast.ArrowFun(f.params, body);
   }
 
   /// Emits a non-arrow FunctionExpression node.
@@ -2746,11 +2760,11 @@
   /// as methods, properties, and top-level functions.
   ///
   /// Contrast with [visitFunctionExpression].
-  JS.Fun _emitFunctionExpression(FunctionExpression node) {
+  js_ast.Fun _emitFunctionExpression(FunctionExpression node) {
     return _emitFunction(node.declaredElement, node.parameters, node.body);
   }
 
-  JS.Fun _emitFunction(ExecutableElement element,
+  js_ast.Fun _emitFunction(ExecutableElement element,
       FormalParameterList parameters, FunctionBody body) {
     FunctionType type = element.type;
 
@@ -2766,19 +2780,19 @@
         () => isPotentiallyMutated(
             body, parameters.parameters.last.declaredElement));
 
-    JS.Block code = isSync
+    js_ast.Block code = isSync
         ? _emitSyncFunctionBody(element, parameters, body)
         : _emitGeneratorFunctionBody(element, parameters, body);
 
     code = super.exitFunction(element.name, formals, code);
-    return JS.Fun(formals, code);
+    return js_ast.Fun(formals, code);
   }
 
   /// Emits a `sync` function body (the default in Dart)
   ///
   /// To emit an `async`, `sync*`, or `async*` function body, use
   /// [_emitGeneratorFunctionBody] instead.
-  JS.Block _emitSyncFunctionBody(ExecutableElement element,
+  js_ast.Block _emitSyncFunctionBody(ExecutableElement element,
       FormalParameterList parameters, FunctionBody body) {
     var savedFunction = _currentFunction;
     _currentFunction = body;
@@ -2786,7 +2800,7 @@
     var initArgs = _emitArgumentInitializers(element, parameters);
     var block = _emitFunctionScopedBody(body, element);
 
-    if (initArgs != null) block = JS.Block([initArgs, block]);
+    if (initArgs != null) block = js_ast.Block([initArgs, block]);
 
     _currentFunction = savedFunction;
 
@@ -2794,7 +2808,7 @@
       // TODO(jmesserly: JS AST printer does not understand the need to emit a
       // nested scoped block in a JS function. So we need to add a non-scoped
       // wrapper to ensure it gets printed.
-      block = JS.Block([block]);
+      block = js_ast.Block([block]);
     }
     return block;
   }
@@ -2810,17 +2824,17 @@
   ///
   /// To emit a `sync` function body (the default in Dart), use
   /// [_emitSyncFunctionBody] instead.
-  JS.Block _emitGeneratorFunctionBody(ExecutableElement element,
+  js_ast.Block _emitGeneratorFunctionBody(ExecutableElement element,
       FormalParameterList parameters, FunctionBody body) {
     var savedFunction = _currentFunction;
     _currentFunction = body;
 
     var initArgs = _emitArgumentInitializers(element, parameters);
-    var block = JS.Block([
+    var block = js_ast.Block([
       _emitGeneratorFunction(element, parameters, body).toReturn()
         ..sourceInformation = _nodeStart(body)
     ]);
-    if (initArgs != null) block = JS.Block([initArgs, block]);
+    if (initArgs != null) block = js_ast.Block([initArgs, block]);
 
     _currentFunction = savedFunction;
 
@@ -2828,14 +2842,14 @@
       // TODO(jmesserly: JS AST printer does not understand the need to emit a
       // nested scoped block in a JS function. So we need to add a non-scoped
       // wrapper to ensure it gets printed.
-      block = JS.Block([block]);
+      block = js_ast.Block([block]);
     }
     return block;
   }
 
-  JS.Block _emitFunctionScopedBody(
+  js_ast.Block _emitFunctionScopedBody(
       FunctionBody body, ExecutableElement element) {
-    var block = body.accept(this) as JS.Block;
+    var block = body.accept(this) as js_ast.Block;
     if (element.parameters.isNotEmpty) {
       // Handle shadowing of parameters by local variables, which is allowed in
       // Dart but not in JS.
@@ -2852,7 +2866,7 @@
   }
 
   void _emitCovarianceBoundsCheck(List<TypeParameterElement> typeFormals,
-      Set<Element> covariantParams, List<JS.Statement> body) {
+      Set<Element> covariantParams, List<js_ast.Statement> body) {
     if (covariantParams == null) return;
     for (var t in typeFormals) {
       t = covariantParams.lookup(t) as TypeParameterElement;
@@ -2863,14 +2877,15 @@
     }
   }
 
-  JS.Expression _emitGeneratorFunction(ExecutableElement element,
+  js_ast.Expression _emitGeneratorFunction(ExecutableElement element,
       FormalParameterList parameters, FunctionBody body) {
     // Transforms `sync*` `async` and `async*` function bodies
     // using ES6 generators.
 
     var returnType = _getExpectedReturnType(element);
 
-    emitGeneratorFn(List<JS.Parameter> jsParams, [JS.TemporaryId asyncStar]) {
+    emitGeneratorFn(List<js_ast.Parameter> jsParams,
+        [js_ast.TemporaryId asyncStar]) {
       var savedSuperAllowed = _superAllowed;
       var savedController = _asyncStarController;
       _superAllowed = false;
@@ -2885,14 +2900,15 @@
       var jsBody = _emitFunctionScopedBody(body, element);
       _currentFunction = savedFunction;
 
-      var genFn = JS.Fun(jsParams, jsBody, isGenerator: true);
+      var genFn = js_ast.Fun(jsParams, jsBody, isGenerator: true);
 
       // Name the function if possible, to get better stack traces.
       var name = element.name;
-      JS.Expression gen = genFn;
+      js_ast.Expression gen = genFn;
       if (name.isNotEmpty) {
-        gen = JS.NamedFunction(
-            JS.TemporaryId(JS.friendlyNameForDartOperator[name] ?? name),
+        gen = js_ast.NamedFunction(
+            js_ast.TemporaryId(
+                js_ast.friendlyNameForDartOperator[name] ?? name),
             genFn);
       }
       gen.sourceInformation = _functionEnd(body);
@@ -2943,7 +2959,7 @@
       // `await` is generated as `yield`.
       //
       // _AsyncStarImpl has an example of the generated code.
-      var asyncStarParam = JS.TemporaryId('stream');
+      var asyncStarParam = js_ast.TemporaryId('stream');
       var gen = emitGeneratorFn([asyncStarParam], asyncStarParam);
 
       var asyncStarImpl = asyncStarImplType.instantiate([returnType]);
@@ -2966,7 +2982,7 @@
   }
 
   @override
-  JS.Statement visitFunctionDeclarationStatement(
+  js_ast.Statement visitFunctionDeclarationStatement(
       FunctionDeclarationStatement node) {
     var func = node.functionDeclaration;
     if (func.isGetter || func.isSetter) {
@@ -2975,11 +2991,11 @@
 
     var fn = _emitFunctionExpression(func.functionExpression);
     var name = _emitVariableDef(func.name);
-    JS.Statement declareFn;
+    js_ast.Statement declareFn;
     declareFn = toBoundFunctionStatement(fn, name);
     var element = func.declaredElement;
     if (_reifyFunctionType(element)) {
-      declareFn = JS.Block(
+      declareFn = js_ast.Block(
           [declareFn, _emitFunctionTagged(name, element.type).toStatement()]);
     }
     return declareFn;
@@ -2988,15 +3004,15 @@
   /// Emits a simple identifier, including handling an inferred generic
   /// function instantiation.
   @override
-  JS.Expression visitSimpleIdentifier(SimpleIdentifier node,
+  js_ast.Expression visitSimpleIdentifier(SimpleIdentifier node,
       [PrefixedIdentifier prefix]) {
     var typeArgs = _getTypeArgs(node.staticElement, node.staticType);
     var simpleId = _emitSimpleIdentifier(node, prefix)
       ..sourceInformation = _nodeSpan(node);
     if (prefix != null &&
         // Check that the JS AST is for a Dart property and not JS interop.
-        simpleId is JS.PropertyAccess &&
-        simpleId.receiver is JS.Identifier) {
+        simpleId is js_ast.PropertyAccess &&
+        simpleId.receiver is js_ast.Identifier) {
       // Attach the span to the library prefix.
       simpleId.receiver.sourceInformation = _nodeSpan(prefix.prefix);
     }
@@ -3007,7 +3023,7 @@
   /// Emits a simple identifier, handling implicit `this` as well as
   /// going through the qualified library name if necessary, but *not* handling
   /// inferred generic function instantiation.
-  JS.Expression _emitSimpleIdentifier(SimpleIdentifier node,
+  js_ast.Expression _emitSimpleIdentifier(SimpleIdentifier node,
       [PrefixedIdentifier prefix]) {
     var accessor = resolutionMap.staticElementForIdentifier(node);
     if (accessor == null) {
@@ -3074,10 +3090,11 @@
       return _emitParameter(element);
     }
 
-    return JS.Identifier(element.name);
+    return js_ast.Identifier(element.name);
   }
 
-  JS.Expression _emitLibraryMemberElement(Element element, Expression node) {
+  js_ast.Expression _emitLibraryMemberElement(
+      Element element, Expression node) {
     var result = _emitTopLevelName(element);
     if (element is FunctionElement && _reifyTearoff(element, node)) {
       return _emitFunctionTagged(result, element.type);
@@ -3085,7 +3102,7 @@
     return result;
   }
 
-  JS.Expression _emitClassMemberElement(
+  js_ast.Expression _emitClassMemberElement(
       ClassMemberElement element, Element accessor, Expression node) {
     bool isStatic = element.isStatic;
     var classElem = element.enclosingElement;
@@ -3095,22 +3112,22 @@
 
     // For instance members, we add implicit-this.
     // For method tear-offs, we ensure it's a bound method.
-    var target = isStatic ? _emitStaticClassName(element) : JS.This();
+    var target = isStatic ? _emitStaticClassName(element) : js_ast.This();
     if (element is MethodElement && _reifyTearoff(element, node)) {
       if (isStatic) {
         // TODO(jmesserly): we could tag static/top-level function types once
         // in the module initialization, rather than at the point where they
         // escape.
         return _emitFunctionTagged(
-            JS.PropertyAccess(target, member), element.type);
+            js_ast.PropertyAccess(target, member), element.type);
       }
       return runtimeCall('bind(#, #)', [target, member]);
     }
-    return JS.PropertyAccess(target, member);
+    return js_ast.PropertyAccess(target, member);
   }
 
-  JS.Identifier _emitVariableDef(SimpleIdentifier id) {
-    return JS.Identifier(id.name)..sourceInformation = _nodeStart(id);
+  js_ast.Identifier _emitVariableDef(SimpleIdentifier id) {
+    return js_ast.Identifier(id.name)..sourceInformation = _nodeStart(id);
   }
 
   /// Returns `true` if the type name referred to by [node] is used in a
@@ -3139,7 +3156,7 @@
     return true;
   }
 
-  JS.Identifier _emitParameter(ParameterElement element,
+  js_ast.Identifier _emitParameter(ParameterElement element,
       {bool declaration = false}) {
     // initializing formal parameter, e.g. `Point(this._x)`
     // TODO(jmesserly): type ref is not attached in this case.
@@ -3148,10 +3165,10 @@
       /// The renamer would handle this, but it would prefer to rename the
       /// temporary used for the private symbol. Instead rename the parameter.
       return _initializingFormalTemps.putIfAbsent(
-          element, () => JS.TemporaryId(element.name.substring(1)));
+          element, () => js_ast.TemporaryId(element.name.substring(1)));
     }
 
-    return JS.Identifier(element.name);
+    return js_ast.Identifier(element.name);
   }
 
   List<Annotation> _parameterMetadata(FormalParameter p) =>
@@ -3161,52 +3178,52 @@
 
   // Wrap a result - usually a type - with its metadata.  The runtime is
   // responsible for unpacking this.
-  JS.Expression _emitAnnotatedResult(
-      JS.Expression result, List<Annotation> metadata) {
+  js_ast.Expression _emitAnnotatedResult(
+      js_ast.Expression result, List<Annotation> metadata) {
     if (options.emitMetadata && metadata != null && metadata.isNotEmpty) {
-      result = JS.ArrayInitializer(
+      result = js_ast.ArrayInitializer(
           [result]..addAll(metadata.map(_instantiateAnnotation)));
     }
     return result;
   }
 
-  JS.Expression _emitFieldSignature(DartType type,
+  js_ast.Expression _emitFieldSignature(DartType type,
       {List<Annotation> metadata, bool isFinal = true}) {
     var args = [_emitType(type)];
     if (options.emitMetadata && metadata != null && metadata.isNotEmpty) {
-      args.add(
-          JS.ArrayInitializer(metadata.map(_instantiateAnnotation).toList()));
+      args.add(js_ast.ArrayInitializer(
+          metadata.map(_instantiateAnnotation).toList()));
     }
     return runtimeCall(isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
   }
 
-  JS.ArrayInitializer _emitTypeNames(
+  js_ast.ArrayInitializer _emitTypeNames(
       List<DartType> types, List<FormalParameter> parameters,
       {bool cacheType = true}) {
-    var result = <JS.Expression>[];
+    var result = <js_ast.Expression>[];
     for (int i = 0; i < types.length; ++i) {
       var metadata =
           parameters != null ? _parameterMetadata(parameters[i]) : null;
       var typeName = _emitType(types[i], cacheType: cacheType);
       result.add(_emitAnnotatedResult(typeName, metadata));
     }
-    return JS.ArrayInitializer(result);
+    return js_ast.ArrayInitializer(result);
   }
 
-  JS.ObjectInitializer _emitTypeProperties(Map<String, DartType> types,
+  js_ast.ObjectInitializer _emitTypeProperties(Map<String, DartType> types,
       {bool cacheType = true}) {
-    var properties = <JS.Property>[];
+    var properties = <js_ast.Property>[];
     types.forEach((name, type) {
       var key = propertyName(name);
       var value = _emitType(type, cacheType: cacheType);
-      properties.add(JS.Property(key, value));
+      properties.add(js_ast.Property(key, value));
     });
-    return JS.ObjectInitializer(properties);
+    return js_ast.ObjectInitializer(properties);
   }
 
   /// Emit the pieces of a function type, as an array of return type,
   /// regular args, and optional/named args.
-  JS.Expression _emitFunctionType(FunctionType type,
+  js_ast.Expression _emitFunctionType(FunctionType type,
       {List<FormalParameter> parameters,
       bool cacheType = true,
       bool lazy = false}) {
@@ -3217,7 +3234,7 @@
 
     var ra = _emitTypeNames(parameterTypes, parameters, cacheType: cacheType);
 
-    List<JS.Expression> typeParts;
+    List<js_ast.Expression> typeParts;
     if (namedTypes.isNotEmpty) {
       assert(optionalTypes.isEmpty);
       // TODO(vsm): Pass in annotations here as well.
@@ -3233,13 +3250,13 @@
       typeParts = [rt, ra];
     }
 
-    JS.Expression fullType;
+    js_ast.Expression fullType;
     String helperCall;
     var typeFormals = type.typeFormals;
     if (typeFormals.isNotEmpty) {
       var tf = _emitTypeFormals(typeFormals);
 
-      addTypeFormalsAsParameters(List<JS.Expression> elements) {
+      addTypeFormalsAsParameters(List<js_ast.Expression> elements) {
         var names = _typeTable.discharge(typeFormals);
         return names.isEmpty
             ? js.call('(#) => [#]', [tf, elements])
@@ -3264,7 +3281,7 @@
     return _typeTable.nameFunctionType(type, fullType, lazy: lazy);
   }
 
-  JS.Expression _emitAnnotatedFunctionType(
+  js_ast.Expression _emitAnnotatedFunctionType(
       FunctionType type, List<Annotation> metadata,
       {List<FormalParameter> parameters}) {
     var result =
@@ -3273,7 +3290,7 @@
   }
 
   @override
-  JS.Expression emitConstructorAccess(DartType type) {
+  js_ast.Expression emitConstructorAccess(DartType type) {
     return _emitJSInterop(type.element) ?? _emitType(type);
   }
 
@@ -3282,7 +3299,7 @@
   /// Typically this is equivalent to [_declareBeforeUse] followed by
   /// [_emitTopLevelName] on the class, but if the member is external, then the
   /// native class name will be used, for direct access to the native member.
-  JS.Expression _emitStaticClassName(ClassMemberElement member) {
+  js_ast.Expression _emitStaticClassName(ClassMemberElement member) {
     var c = member.enclosingElement;
     _declareBeforeUse(c);
 
@@ -3301,7 +3318,7 @@
   /// Emits a Dart [type] into code.
   ///
   /// If [cacheType] is true, then the type will be cached for the module.
-  JS.Expression _emitType(DartType type, {bool cacheType = true}) {
+  js_ast.Expression _emitType(DartType type, {bool cacheType = true}) {
     // The void and dynamic types are not defined in core.
     if (type.isVoid) {
       return runtimeCall('void');
@@ -3341,7 +3358,7 @@
 
     var name = type.name;
     if (type is TypeParameterType) {
-      return JS.Identifier(name);
+      return js_ast.Identifier(name);
     }
 
     if (type is ParameterizedType) {
@@ -3349,7 +3366,7 @@
         return _emitFunctionType(type, cacheType: cacheType);
       }
       var args = type.typeArguments;
-      List<JS.Expression> jsArgs;
+      List<js_ast.Expression> jsArgs;
       if (args.any((a) => !a.isDynamic)) {
         jsArgs = args.map((x) => _emitType(x, cacheType: cacheType)).toList();
       }
@@ -3363,23 +3380,23 @@
   }
 
   /// Emits the raw type corresponding to the [element].
-  JS.Expression _emitTypeDefiningElement(TypeDefiningElement e) {
+  js_ast.Expression _emitTypeDefiningElement(TypeDefiningElement e) {
     return _emitType(instantiateElementTypeToBounds(rules, e));
   }
 
-  JS.Expression _emitGenericClassType(
-      ParameterizedType t, List<JS.Expression> typeArgs) {
+  js_ast.Expression _emitGenericClassType(
+      ParameterizedType t, List<js_ast.Expression> typeArgs) {
     var genericName = _emitTopLevelNameNoInterop(t.element, suffix: '\$');
     return js.call('#(#)', [genericName, typeArgs]);
   }
 
-  JS.PropertyAccess _emitTopLevelName(Element e, {String suffix = ''}) {
+  js_ast.PropertyAccess _emitTopLevelName(Element e, {String suffix = ''}) {
     return _emitJSInterop(e) ?? _emitTopLevelNameNoInterop(e, suffix: suffix);
   }
 
-  JS.PropertyAccess _emitTopLevelNameNoInterop(Element e,
+  js_ast.PropertyAccess _emitTopLevelNameNoInterop(Element e,
       {String suffix = ''}) {
-    return JS.PropertyAccess(
+    return js_ast.PropertyAccess(
         emitLibraryName(e.library), _emitTopLevelMemberName(e, suffix: suffix));
   }
 
@@ -3387,13 +3404,13 @@
   ///
   /// NOTE: usually you should use [_emitTopLevelName] instead of this. This
   /// function does not handle JS interop.
-  JS.Expression _emitTopLevelMemberName(Element e, {String suffix = ''}) {
+  js_ast.Expression _emitTopLevelMemberName(Element e, {String suffix = ''}) {
     var name = getJSExportName(e) ?? _getElementName(e);
     return propertyName(name + suffix);
   }
 
   @override
-  JS.Expression visitAssignmentExpression(AssignmentExpression node) {
+  js_ast.Expression visitAssignmentExpression(AssignmentExpression node) {
     var left = node.leftHandSide;
     var right = node.rightHandSide;
     if (node.operator.type == TokenType.EQ) return _emitSet(left, right);
@@ -3403,7 +3420,7 @@
     return _emitOpAssign(left, right, op, node.staticElement, context: node);
   }
 
-  JS.MetaLet _emitOpAssign(
+  js_ast.MetaLet _emitOpAssign(
       Expression left, Expression right, String op, MethodElement element,
       {Expression context}) {
     if (op == '??') {
@@ -3414,11 +3431,11 @@
 
       // Handle the left hand side, to ensure each of its subexpressions are
       // evaluated only once.
-      var vars = <JS.MetaLetVariable, JS.Expression>{};
+      var vars = <js_ast.MetaLetVariable, js_ast.Expression>{};
       var x = _bindLeftHandSide(vars, left, context: left);
       // Capture the result of evaluating the left hand side in a temp.
       var t = _bindValue(vars, 't', x, context: x);
-      return JS.MetaLet(vars, [
+      return js_ast.MetaLet(vars, [
         js.call('# == null ? # : #',
             [_visitExpression(t), _emitSet(x, right), _visitExpression(t)])
       ]);
@@ -3426,7 +3443,7 @@
 
     // Desugar `x += y` as `x = x + y`, ensuring that if `x` has subexpressions
     // (for example, x is IndexExpression) we evaluate those once.
-    var vars = <JS.MetaLetVariable, JS.Expression>{};
+    var vars = <js_ast.MetaLetVariable, js_ast.Expression>{};
     var lhs = _bindLeftHandSide(vars, left, context: context);
     // TODO(leafp): The element for lhs here will be the setter element
     // instead of the getter element if lhs is a property access. This
@@ -3437,10 +3454,10 @@
 
     var castTo = getImplicitOperationCast(left);
     if (castTo != null) inc = CoercionReifier.castExpression(inc, castTo);
-    return JS.MetaLet(vars, [_emitSet(lhs, inc)]);
+    return js_ast.MetaLet(vars, [_emitSet(lhs, inc)]);
   }
 
-  JS.Expression _emitSet(Expression left, Expression right) {
+  js_ast.Expression _emitSet(Expression left, Expression right) {
     if (left is IndexExpression) {
       var target = _getTarget(left);
       if (_useNativeJsIndexer(target.staticType)) {
@@ -3500,7 +3517,8 @@
   // access to the target expression there (needed for `dart.replNameLookup`).
   String get _replSuffix => options.replCompile ? 'Repl' : '';
 
-  JS.Expression _badAssignment(String problem, Expression lhs, Expression rhs) {
+  js_ast.Expression _badAssignment(
+      String problem, Expression lhs, Expression rhs) {
     // TODO(sra): We should get here only for compiler bugs or weirdness due to
     // --unsafe-force-compile. Once those paths have been addressed, throw at
     // compile time.
@@ -3512,9 +3530,9 @@
   /// Emits assignment to a simple identifier. Handles all legal simple
   /// identifier assignment targets (local, top level library member, implicit
   /// `this` or class, etc.)
-  JS.Expression _emitSetSimpleIdentifier(
+  js_ast.Expression _emitSetSimpleIdentifier(
       SimpleIdentifier node, Expression right) {
-    JS.Expression unimplemented() {
+    js_ast.Expression unimplemented() {
       return _badAssignment("Unimplemented: unknown name '$node'", node, right);
     }
 
@@ -3543,7 +3561,7 @@
     // Unqualified class member. This could mean implicit `this`, or implicit
     // static from the same class.
     if (element is FieldElement) {
-      return _emitSetField(right, element, JS.This(), node);
+      return _emitSetField(right, element, js_ast.This(), node);
     }
 
     // We should not get here.
@@ -3551,41 +3569,42 @@
   }
 
   /// Emits assignment to a simple local variable or parameter.
-  JS.Expression _emitSetLocal(Element element, Expression rhs, AstNode left) {
-    JS.Expression target;
+  js_ast.Expression _emitSetLocal(
+      Element element, Expression rhs, AstNode left) {
+    js_ast.Expression target;
     if (element is TemporaryVariableElement) {
       // If this is one of our compiler's temporary variables, use its JS form.
       target = element.jsVariable;
     } else if (element is ParameterElement) {
       target = _emitParameter(element);
     } else {
-      target = JS.Identifier(element.name);
+      target = js_ast.Identifier(element.name);
     }
     target.sourceInformation = _nodeSpan(left);
     return _visitExpression(rhs).toAssignExpression(target);
   }
 
   /// Emits assignment to library scope element [element].
-  JS.Expression _emitSetTopLevel(
+  js_ast.Expression _emitSetTopLevel(
       PropertyAccessorElement element, Expression rhs) {
     return _visitExpression(rhs).toAssignExpression(_emitTopLevelName(element));
   }
 
   /// Emits assignment to a static field element or property.
-  JS.Expression _emitSetField(Expression right, FieldElement field,
-      JS.Expression jsTarget, SimpleIdentifier id) {
+  js_ast.Expression _emitSetField(Expression right, FieldElement field,
+      js_ast.Expression jsTarget, SimpleIdentifier id) {
     var classElem = field.enclosingElement;
     var isStatic = field.isStatic;
     var member = _emitMemberName(field.name,
         isStatic: isStatic, type: classElem.type, element: field.setter);
     jsTarget = isStatic
-        ? (JS.PropertyAccess(_emitStaticClassName(field), member)
+        ? (js_ast.PropertyAccess(_emitStaticClassName(field), member)
           ..sourceInformation = _nodeSpan(id))
         : _emitTargetAccess(jsTarget, member, field.setter, id);
     return _visitExpression(right).toAssignExpression(jsTarget);
   }
 
-  JS.Expression _emitNullSafeSet(PropertyAccess node, Expression right) {
+  js_ast.Expression _emitNullSafeSet(PropertyAccess node, Expression right) {
     // Emit `obj?.prop = expr` as:
     //
     //     (_ => _ == null ? null : _.prop = expr)(obj).
@@ -3594,31 +3613,32 @@
     //
     // However with MetaLet, we get clean code in statement or void context,
     // or when one of the expressions is stateless, which seems common.
-    var vars = <JS.MetaLetVariable, JS.Expression>{};
+    var vars = <js_ast.MetaLetVariable, js_ast.Expression>{};
     var left = _bindValue(vars, 'l', node.target);
     var body = js.call('# == null ? null : #', [
       _visitExpression(left),
       _emitSet(_stripNullAwareOp(node, left), right)
     ]);
-    return JS.MetaLet(vars, [body]);
+    return js_ast.MetaLet(vars, [body]);
   }
 
   @override
-  JS.Block visitExpressionFunctionBody(ExpressionFunctionBody node) {
-    return JS.Block([_visitExpression(node.expression).toReturn()]);
+  js_ast.Block visitExpressionFunctionBody(ExpressionFunctionBody node) {
+    return js_ast.Block([_visitExpression(node.expression).toReturn()]);
   }
 
   @override
-  JS.Block visitEmptyFunctionBody(EmptyFunctionBody node) => JS.Block([]);
+  js_ast.Block visitEmptyFunctionBody(EmptyFunctionBody node) =>
+      js_ast.Block([]);
 
   @override
-  JS.Block visitBlockFunctionBody(BlockFunctionBody node) {
-    return JS.Block(_visitStatementList(node.block.statements));
+  js_ast.Block visitBlockFunctionBody(BlockFunctionBody node) {
+    return js_ast.Block(_visitStatementList(node.block.statements));
   }
 
   @override
-  JS.Block visitBlock(Block node) =>
-      JS.Block(_visitStatementList(node.statements), isScope: true);
+  js_ast.Block visitBlock(Block node) =>
+      js_ast.Block(_visitStatementList(node.statements), isScope: true);
 
   @override
   visitMethodInvocation(MethodInvocation node) {
@@ -3672,7 +3692,8 @@
     return _emitMethodCall(target, node);
   }
 
-  JS.Expression _emitTarget(Expression target, Element member, bool isStatic) {
+  js_ast.Expression _emitTarget(
+      Expression target, Element member, bool isStatic) {
     if (isStatic) {
       if (member is ConstructorElement) {
         return emitConstructorAccess(member.enclosingElement.type)
@@ -3699,15 +3720,15 @@
     return result;
   }
 
-  /// Emits the [JS.PropertyAccess] for accessors or method calls to
+  /// Emits the [js_ast.PropertyAccess] for accessors or method calls to
   /// [jsTarget].[jsName], replacing `super` if it is not allowed in scope.
-  JS.Expression _emitTargetAccess(JS.Expression jsTarget, JS.Expression jsName,
-      Element member, AstNode node) {
-    JS.Expression result;
-    if (!_superAllowed && jsTarget is JS.Super && member != null) {
+  js_ast.Expression _emitTargetAccess(js_ast.Expression jsTarget,
+      js_ast.Expression jsName, Element member, AstNode node) {
+    js_ast.Expression result;
+    if (!_superAllowed && jsTarget is js_ast.Super && member != null) {
       result = _getSuperHelper(member, jsName);
     } else {
-      result = JS.PropertyAccess(jsTarget, jsName);
+      result = js_ast.PropertyAccess(jsTarget, jsName);
     }
     if (node != null) {
       // Use the full span for a cascade property so we can hover over `bar` in
@@ -3722,7 +3743,7 @@
     return result;
   }
 
-  JS.Expression _getSuperHelper(Element member, JS.Expression jsName) {
+  js_ast.Expression _getSuperHelper(Element member, js_ast.Expression jsName) {
     var jsMethod = _superHelpers.putIfAbsent(member.name, () {
       if (member is PropertyAccessorElement) {
         var isSetter = member.isSetter;
@@ -3731,31 +3752,31 @@
                 ? 'function(x) { super[#] = x; }'
                 : 'function() { return super[#]; }',
             [jsName]);
-        return JS.Method(JS.TemporaryId(member.variable.name), fn,
+        return js_ast.Method(js_ast.TemporaryId(member.variable.name), fn,
             isGetter: !isSetter, isSetter: isSetter);
       } else {
         var method = member as MethodElement;
-        var params =
-            List<JS.Identifier>.from(_emitTypeFormals(method.typeParameters));
+        var params = List<js_ast.Identifier>.from(
+            _emitTypeFormals(method.typeParameters));
         for (var param in method.parameters) {
           if (param.isNamed) {
             params.add(namedArgumentTemp);
             break;
           }
-          params.add(JS.Identifier(param.name));
+          params.add(js_ast.Identifier(param.name));
         }
 
         var fn = js.fun(
             'function(#) { return super[#](#); }', [params, jsName, params]);
         var name = method.name;
-        name = JS.friendlyNameForDartOperator[name] ?? name;
-        return JS.Method(JS.TemporaryId(name), fn);
+        name = js_ast.friendlyNameForDartOperator[name] ?? name;
+        return js_ast.Method(js_ast.TemporaryId(name), fn);
       }
     });
-    return JS.PropertyAccess(JS.This(), jsMethod.name);
+    return js_ast.PropertyAccess(js_ast.This(), jsMethod.name);
   }
 
-  JS.Expression _emitMethodCall(Expression target, MethodInvocation node) {
+  js_ast.Expression _emitMethodCall(Expression target, MethodInvocation node) {
     var argumentList = node.argumentList;
     var args = _emitArgumentList(argumentList);
     var typeArgs = _emitInvokeTypeArguments(node);
@@ -3768,8 +3789,8 @@
         _emitMemberName(name, type: type, isStatic: isStatic, element: element);
 
     if (isDynamicInvoke(target) || isDynamicInvoke(node.methodName)) {
-      JS.Expression jsTarget = _emitTarget(target, element, isStatic);
-      if (jsTarget is JS.Super) {
+      js_ast.Expression jsTarget = _emitTarget(target, element, isStatic);
+      if (jsTarget is js_ast.Super) {
         jsTarget =
             _emitTargetAccess(jsTarget, jsName, element, node.methodName);
         jsName = null;
@@ -3777,7 +3798,7 @@
       return _emitDynamicInvoke(jsTarget, typeArgs, jsName, args, argumentList);
     }
 
-    JS.Expression jsTarget = _emitTarget(target, element, isStatic);
+    js_ast.Expression jsTarget = _emitTarget(target, element, isStatic);
 
     // Handle Object methods that are supported by `null`.
     if (_isObjectMethodCall(name, argumentList.arguments) &&
@@ -3794,7 +3815,7 @@
       if (fromType is InterfaceType) {
         var callName = _getImplicitCallTarget(fromType);
         if (callName != null) {
-          jsTarget = JS.PropertyAccess(jsTarget, callName);
+          jsTarget = js_ast.PropertyAccess(jsTarget, callName);
         }
       }
     }
@@ -3803,14 +3824,14 @@
       jsTarget = _emitCast(castTo, jsTarget);
     }
     if (typeArgs != null) args.insertAll(0, typeArgs);
-    return JS.Call(jsTarget, args);
+    return js_ast.Call(jsTarget, args);
   }
 
-  JS.Expression _emitDynamicInvoke(
-      JS.Expression fn,
-      List<JS.Expression> typeArgs,
-      JS.Expression methodName,
-      List<JS.Expression> args,
+  js_ast.Expression _emitDynamicInvoke(
+      js_ast.Expression fn,
+      List<js_ast.Expression> typeArgs,
+      js_ast.Expression methodName,
+      List<js_ast.Expression> args,
       ArgumentList argumentList) {
     var jsArgs = <Object>[fn];
     String jsCode;
@@ -3856,19 +3877,19 @@
     return !isNullable(left) || !isNullable(right);
   }
 
-  JS.Expression _emitJSDoubleEq(List<JS.Expression> args,
+  js_ast.Expression _emitJSDoubleEq(List<js_ast.Expression> args,
       {bool negated = false}) {
     var op = negated ? '# != #' : '# == #';
     return js.call(op, args);
   }
 
-  JS.Expression _emitJSTripleEq(List<JS.Expression> args,
+  js_ast.Expression _emitJSTripleEq(List<js_ast.Expression> args,
       {bool negated = false}) {
     var op = negated ? '# !== #' : '# === #';
     return js.call(op, args);
   }
 
-  JS.Expression _emitCoreIdenticalCall(List<Expression> arguments,
+  js_ast.Expression _emitCoreIdenticalCall(List<Expression> arguments,
       {bool negated = false}) {
     if (arguments.length != 2) {
       // Shouldn't happen in typechecked code
@@ -3885,12 +3906,13 @@
       return _emitJSDoubleEq(args, negated: negated);
     }
     var code = negated ? '!#' : '#';
-    return js.call(code, JS.Call(_emitTopLevelName(_coreIdentical), args));
+    return js.call(code, js_ast.Call(_emitTopLevelName(_coreIdentical), args));
   }
 
   /// Emits a function call, to a top-level function, local function, or
   /// an expression.
-  JS.Node _emitFunctionCall(InvocationExpression node, [Expression function]) {
+  js_ast.Node _emitFunctionCall(InvocationExpression node,
+      [Expression function]) {
     function ??= node.function;
     var castTo = getImplicitOperationCast(function);
     if (castTo != null) {
@@ -3925,10 +3947,10 @@
       }
     }
 
-    return JS.Call(fn, args);
+    return js_ast.Call(fn, args);
   }
 
-  JS.Node _emitDebuggerCall(InvocationExpression node) {
+  js_ast.Node _emitDebuggerCall(InvocationExpression node) {
     var args = node.argumentList.arguments;
     var isStatement = node.parent is ExpressionStatement;
     if (args.isEmpty) {
@@ -3948,7 +3970,7 @@
     // to decide whether to break or not.
     //
     // We also need to return the value of `when`.
-    var jsArgs = <JS.Property>[];
+    var jsArgs = <js_ast.Property>[];
     var foundWhen = false;
     for (var arg in args) {
       var namedArg = arg as NamedExpression;
@@ -3960,16 +3982,16 @@
         //
         // For a single `message` argument, use `{message: ...}`, which
         // coerces to true (the default value of `when`).
-        ? (foundWhen ? jsArgs[0].value : JS.ObjectInitializer(jsArgs))
+        ? (foundWhen ? 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.ObjectInitializer(jsArgs));
+        : js.call('#.when', js_ast.ObjectInitializer(jsArgs));
     return isStatement
         ? js.statement('if (#) debugger;', when)
         : js.call('# && (() => { debugger; return true })()', when);
   }
 
-  List<JS.Expression> _emitInvokeTypeArguments(InvocationExpression node) {
+  List<js_ast.Expression> _emitInvokeTypeArguments(InvocationExpression node) {
     // add no reify generic check here: if (node.function)
     // node is Identifier
     var function = node.function;
@@ -3982,7 +4004,7 @@
 
   /// If `g` is a generic function type, and `f` is an instantiation of it,
   /// then this will return the type arguments to apply, otherwise null.
-  List<JS.Expression> _emitFunctionTypeArguments(
+  List<js_ast.Expression> _emitFunctionTypeArguments(
       AstNode node, DartType g, DartType f,
       [TypeArgumentList typeArgs]) {
     if (node is InvocationExpression) {
@@ -4030,7 +4052,7 @@
   }
 
   /// Emits code for the `JS(...)` macro.
-  JS.Node _emitForeignJS(MethodInvocation node, Element e) {
+  js_ast.Node _emitForeignJS(MethodInvocation node, Element e) {
     if (!isInlineJS(e)) return null;
 
     var args = node.argumentList.arguments;
@@ -4069,46 +4091,47 @@
     var result = js.parseForeignJS(source).instantiate(jsArgs);
 
     // `throw` is emitted as a statement by `parseForeignJS`.
-    assert(result is JS.Expression ||
-        result is JS.Statement && node.parent is ExpressionStatement);
+    assert(result is js_ast.Expression ||
+        result is js_ast.Statement && node.parent is ExpressionStatement);
     return result;
   }
 
   @override
-  JS.Node visitFunctionExpressionInvocation(
+  js_ast.Node visitFunctionExpressionInvocation(
           FunctionExpressionInvocation node) =>
       _emitFunctionCall(node);
 
-  List<JS.Expression> _emitArgumentList(ArgumentList node) {
-    var args = <JS.Expression>[];
-    var named = <JS.Property>[];
+  List<js_ast.Expression> _emitArgumentList(ArgumentList node) {
+    var args = <js_ast.Expression>[];
+    var named = <js_ast.Property>[];
     for (var arg in node.arguments) {
       if (arg is NamedExpression) {
         named.add(visitNamedExpression(arg));
       } else if (arg is MethodInvocation && isJsSpreadInvocation(arg)) {
-        args.add(JS.Spread(_visitExpression(arg.argumentList.arguments[0])));
+        args.add(
+            js_ast.Spread(_visitExpression(arg.argumentList.arguments[0])));
       } else {
         args.add(_visitExpression(arg));
       }
     }
     if (named.isNotEmpty) {
-      args.add(JS.ObjectInitializer(named));
+      args.add(js_ast.ObjectInitializer(named));
     }
     return args;
   }
 
   @override
-  JS.Property visitNamedExpression(NamedExpression node) {
+  js_ast.Property visitNamedExpression(NamedExpression node) {
     assert(node.parent is ArgumentList);
-    return JS.Property(
+    return js_ast.Property(
         propertyName(node.name.label.name), _visitExpression(node.expression));
   }
 
-  List<JS.Parameter> _emitParametersForElement(ExecutableElement member) {
-    var jsParams = <JS.Identifier>[];
+  List<js_ast.Parameter> _emitParametersForElement(ExecutableElement member) {
+    var jsParams = <js_ast.Identifier>[];
     for (var p in member.parameters) {
       if (p.isPositional) {
-        jsParams.add(JS.Identifier(p.name));
+        jsParams.add(js_ast.Identifier(p.name));
       } else {
         jsParams.add(namedArgumentTemp);
         break;
@@ -4117,10 +4140,10 @@
     return jsParams;
   }
 
-  List<JS.Parameter> _emitParameters(Iterable<FormalParameter> parameters) {
+  List<js_ast.Parameter> _emitParameters(Iterable<FormalParameter> parameters) {
     if (parameters == null) return [];
 
-    var result = <JS.Parameter>[];
+    var result = <js_ast.Parameter>[];
     for (var param in parameters) {
       if (param.isNamed) {
         result.add(namedArgumentTemp);
@@ -4133,19 +4156,19 @@
   }
 
   @override
-  JS.Statement visitExpressionStatement(ExpressionStatement node) =>
+  js_ast.Statement visitExpressionStatement(ExpressionStatement node) =>
       node.expression.accept(this).toStatement();
 
   @override
-  JS.EmptyStatement visitEmptyStatement(EmptyStatement node) =>
-      JS.EmptyStatement();
+  js_ast.EmptyStatement visitEmptyStatement(EmptyStatement node) =>
+      js_ast.EmptyStatement();
 
   @override
-  JS.Statement visitAssertStatement(AssertStatement node) =>
+  js_ast.Statement visitAssertStatement(AssertStatement node) =>
       _emitAssert(node.condition, node.message);
 
-  JS.Statement _emitAssert(Expression condition, Expression message) {
-    if (!options.enableAsserts) return JS.EmptyStatement();
+  js_ast.Statement _emitAssert(Expression condition, Expression message) {
+    if (!options.enableAsserts) return js_ast.EmptyStatement();
     // TODO(jmesserly): only emit in checked mode.
     var conditionType = condition.staticType;
     var jsCondition = _visitExpression(condition);
@@ -4165,7 +4188,7 @@
       jsCondition,
       runtimeModule,
       if (message == null)
-        JS.LiteralNull()
+        js_ast.LiteralNull()
       else
         _visitExpression(message),
       js.escapedString(location.sourceUrl.toString()),
@@ -4177,12 +4200,12 @@
   }
 
   @override
-  JS.Statement visitReturnStatement(ReturnStatement node) {
+  js_ast.Statement visitReturnStatement(ReturnStatement node) {
     return super.emitReturnStatement(_visitExpression(node.expression));
   }
 
   @override
-  JS.Statement visitYieldStatement(YieldStatement node) {
+  js_ast.Statement visitYieldStatement(YieldStatement node) {
     var jsExpr = _visitExpression(node.expression);
     var star = node.star != null;
     if (_asyncStarController != null) {
@@ -4201,7 +4224,7 @@
         _asyncStarController,
         helperName,
         jsExpr,
-        JS.Yield(null)..sourceInformation = _nodeStart(node)
+        js_ast.Yield(null)..sourceInformation = _nodeStart(node)
       ]);
     }
     // A normal yield in a sync*
@@ -4209,8 +4232,8 @@
   }
 
   @override
-  JS.Expression visitAwaitExpression(AwaitExpression node) {
-    return JS.Yield(_visitExpression(node.expression));
+  js_ast.Expression visitAwaitExpression(AwaitExpression node) {
+    return js_ast.Yield(_visitExpression(node.expression));
   }
 
   /// This is not used--we emit top-level fields as we are emitting the
@@ -4228,7 +4251,7 @@
   }
 
   @override
-  JS.Statement visitVariableDeclarationStatement(
+  js_ast.Statement visitVariableDeclarationStatement(
       VariableDeclarationStatement node) {
     // Special case a single variable with an initializer.
     // This helps emit cleaner code for things like:
@@ -4239,7 +4262,7 @@
       var initializer = variable.initializer;
       if (initializer != null) {
         var name = _emitVariableDef(variable.name);
-        JS.Expression value;
+        js_ast.Expression value;
         if (_annotatedNullCheck(variable.declaredElement)) {
           value = notNull(initializer);
         } else if (initializer is FunctionExpression) {
@@ -4253,7 +4276,7 @@
           //     dart.fn(f, typeOfF);
           //
           value = _emitArrowFunction(initializer);
-          return JS.Block([
+          return js_ast.Block([
             value.toVariableDeclaration(name),
             _emitFunctionTagged(
                     name, getStaticType(initializer) as FunctionType,
@@ -4270,15 +4293,16 @@
   }
 
   @override
-  JS.VariableDeclarationList visitVariableDeclarationList(
+  js_ast.VariableDeclarationList visitVariableDeclarationList(
       VariableDeclarationList node) {
     if (node == null) return null;
-    return JS.VariableDeclarationList(
+    return js_ast.VariableDeclarationList(
         'let', node.variables?.map(visitVariableDeclaration)?.toList());
   }
 
   @override
-  JS.VariableInitialization visitVariableDeclaration(VariableDeclaration node) {
+  js_ast.VariableInitialization visitVariableDeclaration(
+      VariableDeclaration node) {
     if (node.declaredElement is PropertyInducingElement) {
       // All fields are handled elsewhere.
       assert(false);
@@ -4286,7 +4310,7 @@
     }
 
     var name = _emitVariableDef(node.name);
-    return JS.VariableInitialization(
+    return js_ast.VariableInitialization(
         name, _visitInitializer(node.initializer, node.declaredElement));
   }
 
@@ -4319,35 +4343,36 @@
     return lazyFields;
   }
 
-  JS.Expression _visitInitializer(Expression init, Element variable) {
+  js_ast.Expression _visitInitializer(Expression init, Element variable) {
     // 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.LiteralNull();
+    if (init == null) return js_ast.LiteralNull();
     return _annotatedNullCheck(variable)
         ? notNull(init)
         : _visitExpression(init);
   }
 
-  JS.Statement _emitLazyFields(
-      JS.Expression objExpr,
+  js_ast.Statement _emitLazyFields(
+      js_ast.Expression objExpr,
       List<VariableDeclaration> fields,
-      JS.Expression Function(Element e) emitFieldName) {
-    var accessors = <JS.Method>[];
+      js_ast.Expression Function(Element e) emitFieldName) {
+    var accessors = <js_ast.Method>[];
 
     for (var node in fields) {
       var element = node.declaredElement;
       var access = emitFieldName(element);
-      accessors.add(JS.Method(
+      accessors.add(js_ast.Method(
           access,
           js.call('function() { return #; }',
-              _visitInitializer(node.initializer, element)) as JS.Fun,
+              _visitInitializer(node.initializer, element)) as js_ast.Fun,
           isGetter: true)
         ..sourceInformation =
-            _hoverComment(JS.PropertyAccess(objExpr, access), node.name));
+            _hoverComment(js_ast.PropertyAccess(objExpr, access), node.name));
 
       // TODO(jmesserly): currently uses a dummy setter to indicate writable.
       if (!node.isFinal && !node.isConst) {
-        accessors.add(JS.Method(access, js.call('function(_) {}') as JS.Fun,
+        accessors.add(js_ast.Method(
+            access, js.call('function(_) {}') as js_ast.Fun,
             isSetter: true));
       }
     }
@@ -4355,18 +4380,19 @@
     return runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]);
   }
 
-  JS.Expression _emitConstructorName(DartType type, String name) {
+  js_ast.Expression _emitConstructorName(DartType type, String name) {
     return _emitJSInterop(type.element) ??
-        JS.PropertyAccess(emitConstructorAccess(type), _constructorName(name));
+        js_ast.PropertyAccess(
+            emitConstructorAccess(type), _constructorName(name));
   }
 
   @override
-  JS.Expression visitConstructorName(ConstructorName node) {
+  js_ast.Expression visitConstructorName(ConstructorName node) {
     return _emitConstructorName(node.type.type, node.staticElement.name);
   }
 
-  JS.Expression _emitInstanceCreationExpression(
-      ConstructorElement element, InterfaceType type, List<JS.Expression> args,
+  js_ast.Expression _emitInstanceCreationExpression(ConstructorElement element,
+      InterfaceType type, List<js_ast.Expression> args,
       {bool isConst = false, ConstructorName ctorNode}) {
     if (element == null) {
       return _throwUnsafe('unresolved constructor: ${type?.name ?? '<null>'}'
@@ -4375,10 +4401,12 @@
 
     var classElem = type.element;
     if (_isObjectLiteral(classElem)) {
-      return args.isEmpty ? js.call('{}') : args.single as JS.ObjectInitializer;
+      return args.isEmpty
+          ? js.call('{}')
+          : args.single as js_ast.ObjectInitializer;
     }
 
-    JS.Expression emitNew() {
+    js_ast.Expression emitNew() {
       var name = element.name;
       if (args.isEmpty && classElem.source.isInSystemLibrary) {
         // Skip the slow SDK factory constructors when possible.
@@ -4414,8 +4442,8 @@
       var ctor = _emitConstructorName(type, name);
       if (ctorNode != null) ctor.sourceInformation = _nodeSpan(ctorNode);
       return element.isFactory && !_hasJSInteropAnnotation(classElem)
-          ? JS.Call(ctor, args)
-          : JS.New(ctor, args);
+          ? js_ast.Call(ctor, args)
+          : js_ast.New(ctor, args);
     }
 
     var result = emitNew();
@@ -4443,10 +4471,10 @@
 
   /// If the constant [value] is primitive, directly emit the
   /// corresponding JavaScript.  Otherwise, return null.
-  JS.Expression _emitDartObject(DartObject value,
+  js_ast.Expression _emitDartObject(DartObject value,
       {bool handleUnknown = false}) {
     if (value == null || value.isNull) {
-      return JS.LiteralNull();
+      return js_ast.LiteralNull();
     }
     var type = value.type;
     // Handle unknown value: when the declared variable wasn't found, and no
@@ -4457,7 +4485,7 @@
     // https://api.dartlang.org/stable/1.20.1/dart-core/bool/bool.fromEnvironment.html
     if (!value.hasKnownValue) {
       if (!handleUnknown) return null;
-      return type == types.boolType ? js.boolean(false) : JS.LiteralNull();
+      return type == types.boolType ? js.boolean(false) : js_ast.LiteralNull();
     }
     if (type == types.boolType) {
       return js.boolean(value.toBoolValue());
@@ -4484,7 +4512,7 @@
             value.toListValue().map(_emitDartObject).toList());
       }
       if (type.element == types.mapType.element) {
-        var entries = <JS.Expression>[];
+        var entries = <js_ast.Expression>[];
         value.toMapValue().forEach((key, value) {
           entries.add(_emitDartObject(key));
           entries.add(_emitDartObject(value));
@@ -4506,11 +4534,12 @@
           return _emitClassMemberElement(field, field.getter, null);
         }
         var args = ctor.positionalArguments.map(_emitDartObject).toList();
-        var named = <JS.Property>[];
+        var named = <js_ast.Property>[];
         ctor.namedArguments.forEach((name, value) {
-          named.add(JS.Property(propertyName(name), _emitDartObject(value)));
+          named
+              .add(js_ast.Property(propertyName(name), _emitDartObject(value)));
         });
-        if (named.isNotEmpty) args.add(JS.ObjectInitializer(named));
+        if (named.isNotEmpty) args.add(js_ast.ObjectInitializer(named));
         return _emitInstanceCreationExpression(ctor.constructor, type, args,
             isConst: true);
       }
@@ -4564,19 +4593,19 @@
         ctorNode: constructor);
   }
 
-  JS.Statement _nullParameterCheck(JS.Expression param) {
+  js_ast.Statement _nullParameterCheck(js_ast.Expression param) {
     var call = runtimeCall('argumentError((#))', [param]);
     return js.statement('if (# == null) #;', [param, call]);
   }
 
-  JS.Expression notNull(Expression expr) {
+  js_ast.Expression notNull(Expression expr) {
     if (expr == null) return null;
     var jsExpr = _visitExpression(expr);
     if (!isNullable(expr)) return jsExpr;
     return runtimeCall('notNull(#)', [jsExpr]);
   }
 
-  JS.Expression _emitEqualityOperator(BinaryExpression node, Token op) {
+  js_ast.Expression _emitEqualityOperator(BinaryExpression node, Token op) {
     var left = node.leftOperand;
     var right = node.rightOperand;
     var leftType = left.staticType;
@@ -4632,7 +4661,7 @@
   }
 
   @override
-  JS.Expression visitBinaryExpression(BinaryExpression node) {
+  js_ast.Expression visitBinaryExpression(BinaryExpression node) {
     var op = node.operator;
 
     // The operands of logical boolean operators are subject to boolean
@@ -4653,10 +4682,10 @@
       // This should be a hint or warning for dead code.
       if (!isNullable(left)) return _visitExpression(left);
 
-      var vars = <JS.MetaLetVariable, JS.Expression>{};
+      var vars = <js_ast.MetaLetVariable, js_ast.Expression>{};
       // Desugar `l ?? r` as `l != null ? l : r`
       var l = _visitExpression(_bindValue(vars, 'l', left, context: left));
-      return JS.MetaLet(vars, [
+      return js_ast.MetaLet(vars, [
         js.call('# != null ? # : #', [l, l, _visitExpression(right)])
       ]);
     }
@@ -4664,7 +4693,7 @@
     var leftType = getStaticType(left);
     var rightType = getStaticType(right);
 
-    JS.Expression operatorCall() {
+    js_ast.Expression operatorCall() {
       return _emitOperatorCall(left, op.lexeme, [right])
         ..sourceInformation = _getLocation(node.operator.offset);
     }
@@ -4677,12 +4706,12 @@
 
       /// Emits an inlined binary operation using the JS [code], adding null
       /// checks if needed to ensure we throw the appropriate error.
-      JS.Expression binary(String code) {
+      js_ast.Expression binary(String code) {
         return js.call(code, [notNull(left), notNull(right)])
           ..sourceInformation = _getLocation(node.operator.offset);
       }
 
-      JS.Expression bitwise(String code) {
+      js_ast.Expression bitwise(String code) {
         return _coerceBitOperationResultToUnsigned(node, binary(code));
       }
 
@@ -4691,7 +4720,7 @@
       ///
       /// Short circuiting operators should not be used in [code], because the
       /// null checks for both operands must happen unconditionally.
-      JS.Expression bitwiseBool(String code) {
+      js_ast.Expression bitwiseBool(String code) {
         return js.call(code, [notNull(left), _visitTest(right)])
           ..sourceInformation = _getLocation(node.operator.offset);
       }
@@ -4764,8 +4793,8 @@
   /// the interpretation of the 32-bit value from signed to unsigned.  Most
   /// JavaScript operations interpret their operands as signed and generate
   /// signed results.
-  JS.Expression _coerceBitOperationResultToUnsigned(
-      Expression node, JS.Expression uncoerced) {
+  js_ast.Expression _coerceBitOperationResultToUnsigned(
+      Expression node, js_ast.Expression uncoerced) {
     // Don't coerce if the parent will coerce.
     AstNode parent = _parentOperation(node);
     if (_nodeIsBitwiseOperation(parent)) return uncoerced;
@@ -4936,7 +4965,7 @@
       expr is NullLiteral || getStaticType(expr).isDartCoreNull;
 
   SimpleIdentifier _createTemporary(String name, DartType type,
-      {bool nullable = true, JS.Expression variable, bool dynamicInvoke}) {
+      {bool nullable = true, js_ast.Expression variable, bool dynamicInvoke}) {
     // We use an invalid source location to signal that this is a temporary.
     // See [_isTemporary].
     // TODO(jmesserly): alternatives are
@@ -4947,7 +4976,7 @@
     var id = astFactory
         .simpleIdentifier(StringToken(TokenType.IDENTIFIER, name, -1));
 
-    variable ??= JS.TemporaryId(name);
+    variable ??= js_ast.TemporaryId(name);
 
     var idElement =
         TemporaryVariableElement.forNode(id, variable, _currentElement);
@@ -4975,7 +5004,7 @@
   /// unless [expr] is a SimpleIdentifier, in which case a temporary is not
   /// needed.
   Expression _bindLeftHandSide(
-      Map<JS.MetaLetVariable, JS.Expression> scope, Expression expr,
+      Map<js_ast.MetaLetVariable, js_ast.Expression> scope, Expression expr,
       {Expression context}) {
     Expression result;
     if (expr is IndexExpression) {
@@ -5019,13 +5048,13 @@
   /// variables), then the resulting code will be simplified automatically.
   ///
   /// [scope] will be mutated to contain the new temporary's initialization.
-  Expression _bindValue(Map<JS.MetaLetVariable, JS.Expression> scope,
+  Expression _bindValue(Map<js_ast.MetaLetVariable, js_ast.Expression> scope,
       String name, Expression expr,
       {Expression context}) {
     // No need to do anything for stateless expressions.
     if (isStateless(_currentFunction, expr, context)) return expr;
 
-    var variable = JS.MetaLetVariable(name);
+    var variable = js_ast.MetaLetVariable(name);
     var t = _createTemporary(name, getStaticType(expr),
         variable: variable,
         dynamicInvoke: isDynamicInvoke(expr),
@@ -5050,10 +5079,10 @@
   ///     // pseudocode mix of Scheme and JS:
   ///     (let* (x1=expr1, x2=expr2, t=expr1[expr2]) { x1[x2] = t + 1; t })
   ///
-  /// The [JS.MetaLet] nodes automatically simplify themselves if they can.
+  /// The [js_ast.MetaLet] nodes automatically simplify themselves if they can.
   /// For example, if the result value is not used, then `t` goes away.
   @override
-  JS.Expression visitPostfixExpression(PostfixExpression node) {
+  js_ast.Expression visitPostfixExpression(PostfixExpression node) {
     var op = node.operator;
     var expr = node.operand;
 
@@ -5073,7 +5102,7 @@
 
     // Handle the left hand side, to ensure each of its subexpressions are
     // evaluated only once.
-    var vars = <JS.MetaLetVariable, JS.Expression>{};
+    var vars = <js_ast.MetaLetVariable, js_ast.Expression>{};
     var left = _bindLeftHandSide(vars, expr, context: expr);
 
     // Desugar `x++` as `(x1 = x0 + 1, x0)` where `x0` is the original value
@@ -5085,12 +5114,15 @@
       ..staticElement = node.staticElement
       ..staticType = getStaticType(expr);
 
-    var body = <JS.Expression>[_emitSet(left, increment), _visitExpression(x)];
-    return JS.MetaLet(vars, body, statelessResult: true);
+    var body = <js_ast.Expression>[
+      _emitSet(left, increment),
+      _visitExpression(x)
+    ];
+    return js_ast.MetaLet(vars, body, statelessResult: true);
   }
 
   @override
-  JS.Expression visitPrefixExpression(PrefixExpression node) {
+  js_ast.Expression visitPrefixExpression(PrefixExpression node) {
     var op = node.operator;
 
     // Logical negation, `!e`, is a boolean conversion context since it is
@@ -5103,7 +5135,7 @@
     if (jsTypeRep.unaryOperationIsPrimitive(dispatchType)) {
       if (op.lexeme == '~') {
         if (jsTypeRep.isNumber(dispatchType)) {
-          JS.Expression jsExpr = js.call('~#', notNull(expr));
+          js_ast.Expression jsExpr = js.call('~#', notNull(expr));
           return _coerceBitOperationResultToUnsigned(node, jsExpr);
         }
         return _emitOperatorCall(expr, op.lexeme[0], []);
@@ -5113,7 +5145,7 @@
       }
       if (op.lexeme == '++' || op.lexeme == '--') {
         // We need a null check, so the increment must be expanded out.
-        var vars = <JS.MetaLetVariable, JS.Expression>{};
+        var vars = <js_ast.MetaLetVariable, js_ast.Expression>{};
         var x = _bindLeftHandSide(vars, expr, context: expr);
 
         var one = ast.integerLiteral(1)..staticType = types.intType;
@@ -5121,7 +5153,7 @@
           ..staticElement = node.staticElement
           ..staticType = getStaticType(expr);
 
-        return JS.MetaLet(vars, [_emitSet(x, increment)]);
+        return js_ast.MetaLet(vars, [_emitSet(x, increment)]);
       }
       return js.call('$op#', notNull(expr));
     }
@@ -5148,33 +5180,35 @@
   visitCascadeExpression(CascadeExpression node) {
     var savedCascadeTemp = _cascadeTarget;
 
-    var vars = <JS.MetaLetVariable, JS.Expression>{};
+    var vars = <js_ast.MetaLetVariable, js_ast.Expression>{};
     _cascadeTarget = _bindValue(vars, '_', node.target, context: node);
     var sections = _visitExpressionList(node.cascadeSections);
     sections.add(_visitExpression(_cascadeTarget));
-    var result = JS.MetaLet(vars, sections, statelessResult: true);
+    var result = js_ast.MetaLet(vars, sections, statelessResult: true);
     _cascadeTarget = savedCascadeTemp;
     return result;
   }
 
   @override
-  JS.Expression visitParenthesizedExpression(ParenthesizedExpression node) =>
+  js_ast.Expression visitParenthesizedExpression(
+          ParenthesizedExpression node) =>
       // The printer handles precedence so we don't need to.
       _visitExpression(node.expression);
 
-  JS.Parameter _emitFormalParameter(FormalParameter node) {
+  js_ast.Parameter _emitFormalParameter(FormalParameter node) {
     var id = _emitParameter(node.declaredElement, declaration: true)
       ..sourceInformation = _nodeSpan(node);
     var isRestArg = node is! DefaultFormalParameter &&
         findAnnotation(node.declaredElement, isJsRestAnnotation) != null;
-    return isRestArg ? JS.RestParameter(id) : id;
+    return isRestArg ? js_ast.RestParameter(id) : id;
   }
 
   @override
-  JS.This visitThisExpression(ThisExpression node) => JS.This();
+  js_ast.This visitThisExpression(ThisExpression node) => js_ast.This();
 
   @override
-  JS.Expression visitSuperExpression(SuperExpression node) => JS.Super();
+  js_ast.Expression visitSuperExpression(SuperExpression node) =>
+      js_ast.Super();
 
   @override
   visitPrefixedIdentifier(PrefixedIdentifier node) {
@@ -5198,14 +5232,14 @@
     return _emitPropertyGet(_getTarget(node), node.propertyName, node);
   }
 
-  JS.Expression _emitNullSafe(Expression node) {
+  js_ast.Expression _emitNullSafe(Expression node) {
     // Desugar `obj?.name` as ((x) => x == null ? null : x.name)(obj)
     var target = _getTarget(node);
-    var vars = <JS.MetaLetVariable, JS.Expression>{};
+    var vars = <js_ast.MetaLetVariable, js_ast.Expression>{};
     var t = _bindValue(vars, 't', target, context: target);
 
     var desugared = _stripNullAwareOp(node, t);
-    return JS.MetaLet(vars, [
+    return js_ast.MetaLet(vars, [
       js.call('# == null ? null : #',
           [_visitExpression(t), _visitExpression(desugared)])
     ]);
@@ -5226,7 +5260,7 @@
     }
   }
 
-  List<JS.Expression> _getTypeArgs(Element member, DartType instantiated) {
+  List<js_ast.Expression> _getTypeArgs(Element member, DartType instantiated) {
     DartType type;
     if (member is ExecutableElement) {
       type = member.type;
@@ -5240,7 +5274,7 @@
   }
 
   /// Shared code for [PrefixedIdentifier] and [PropertyAccess].
-  JS.Expression _emitPropertyGet(
+  js_ast.Expression _emitPropertyGet(
       Expression receiver, SimpleIdentifier memberId, Expression accessNode) {
     var resultType = accessNode.staticType;
     var accessor = memberId.staticElement;
@@ -5262,17 +5296,17 @@
     }
 
     var jsTarget = _emitTarget(receiver, accessor, isStatic);
-    var isSuper = jsTarget is JS.Super;
+    var isSuper = jsTarget is js_ast.Super;
     if (isSuper &&
         accessor.isSynthetic &&
         field is FieldElementImpl &&
         !virtualFields.isVirtual(field)) {
       // If super.x is a sealed field, then x is an instance property since
       // subclasses cannot override x.
-      jsTarget = JS.This()..sourceInformation = jsTarget.sourceInformation;
+      jsTarget = js_ast.This()..sourceInformation = jsTarget.sourceInformation;
     }
 
-    JS.Expression result;
+    js_ast.Expression result;
     if (isObjectMember(memberName) && isNullable(receiver)) {
       if (_isObjectMethodTearoff(memberName)) {
         result = runtimeCall('bind(#, #)', [jsTarget, jsName]);
@@ -5311,7 +5345,7 @@
   bool _isDirectCallable(DartType t) =>
       t is FunctionType || t is InterfaceType && _usesJSInterop(t.element);
 
-  JS.Expression _getImplicitCallTarget(InterfaceType fromType) {
+  js_ast.Expression _getImplicitCallTarget(InterfaceType fromType) {
     var callMethod = fromType.lookUpInheritedMethod('call');
     if (callMethod == null || _usesJSInterop(fromType.element)) return null;
     return _emitMemberName('call', type: fromType, element: callMethod);
@@ -5322,7 +5356,7 @@
   /// **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.Expression _emitOperatorCall(
+  js_ast.Expression _emitOperatorCall(
       Expression target, String name, List<Expression> args,
       [Element element]) {
     // TODO(jmesserly): calls that don't pass `element` are probably broken for
@@ -5352,7 +5386,7 @@
   visitIndexExpression(IndexExpression node) {
     var target = _getTarget(node);
     if (_useNativeJsIndexer(target.staticType)) {
-      return JS.PropertyAccess(
+      return js_ast.PropertyAccess(
           _visitExpression(target), _visitExpression(node.index));
     }
     return _emitOperatorCall(target, '[]', [node.index], node.staticElement);
@@ -5378,7 +5412,7 @@
   }
 
   @override
-  JS.Expression visitConditionalExpression(ConditionalExpression node) {
+  js_ast.Expression visitConditionalExpression(ConditionalExpression node) {
     return js.call('# ? # : #', [
       _visitTest(node.condition),
       _visitExpression(node.thenExpression),
@@ -5387,12 +5421,12 @@
   }
 
   @override
-  JS.Expression visitThrowExpression(ThrowExpression node) {
+  js_ast.Expression visitThrowExpression(ThrowExpression node) {
     return runtimeCall('throw(#)', [_visitExpression(node.expression)]);
   }
 
   @override
-  JS.Expression visitRethrowExpression(RethrowExpression node) {
+  js_ast.Expression visitRethrowExpression(RethrowExpression node) {
     return runtimeCall(
         'rethrow(#)', [_emitSimpleIdentifier(_rethrowParameter)]);
   }
@@ -5403,32 +5437,33 @@
   ///
   ///     do var x = 5; while (false); // Dart
   ///     do { let x = 5; } while (false); // JS
-  JS.Statement _visitScope(Statement stmt) {
+  js_ast.Statement _visitScope(Statement stmt) {
     var result = _visitStatement(stmt);
-    if (result is JS.ExpressionStatement &&
-        result.expression is JS.VariableDeclarationList) {
-      return JS.Block([result]);
+    if (result is js_ast.ExpressionStatement &&
+        result.expression is js_ast.VariableDeclarationList) {
+      return js_ast.Block([result]);
     }
     return result;
   }
 
   @override
-  JS.Statement visitIfStatement(IfStatement node) {
-    return JS.If(_visitTest(node.condition), _visitScope(node.thenStatement),
-        _visitScope(node.elseStatement));
+  js_ast.Statement visitIfStatement(IfStatement node) {
+    return js_ast.If(_visitTest(node.condition),
+        _visitScope(node.thenStatement), _visitScope(node.elseStatement));
   }
 
   @override
-  JS.While visitWhileStatement(WhileStatement node) {
-    return JS.While(_visitTest(node.condition), _visitScope(node.body));
+  js_ast.While visitWhileStatement(WhileStatement node) {
+    return js_ast.While(_visitTest(node.condition), _visitScope(node.body));
   }
 
   @override
-  JS.Do visitDoStatement(DoStatement node) {
-    return JS.Do(_visitScope(node.body), _visitTest(node.condition));
+  js_ast.Do visitDoStatement(DoStatement node) {
+    return js_ast.Do(_visitScope(node.body), _visitTest(node.condition));
   }
 
-  JS.Statement _emitAwaitFor(ForEachParts forParts, JS.Statement jsBody) {
+  js_ast.Statement _emitAwaitFor(
+      ForEachParts forParts, js_ast.Statement jsBody) {
     // Emits `await for (var value in stream) ...`, which desugars as:
     //
     // let iter = new StreamIterator(stream);
@@ -5452,9 +5487,9 @@
         streamIterator.element.unnamedConstructor,
         streamIterator,
         [_visitExpression(forParts.iterable)]);
-    var iter = JS.TemporaryId('iter');
+    var iter = js_ast.TemporaryId('iter');
     SimpleIdentifier variable;
-    JS.Expression init;
+    js_ast.Expression init;
     if (forParts is ForEachPartsWithIdentifier) {
       variable = forParts.identifier;
       init = js
@@ -5475,11 +5510,11 @@
         [
           iter,
           createStreamIter,
-          JS.Yield(js.call('#.moveNext()', iter))
+          js_ast.Yield(js.call('#.moveNext()', iter))
             ..sourceInformation = _nodeStart(variable),
           init,
           jsBody,
-          JS.Yield(js.call('#.cancel()', iter))
+          js_ast.Yield(js.call('#.cancel()', iter))
             ..sourceInformation = _nodeStart(variable)
         ]);
   }
@@ -5487,7 +5522,7 @@
   @override
   visitBreakStatement(BreakStatement node) {
     var label = node.label;
-    return JS.Break(label?.name);
+    return js_ast.Break(label?.name);
   }
 
   @override
@@ -5521,7 +5556,7 @@
         }
       }
     }
-    return JS.Continue(label?.name);
+    return js_ast.Continue(label?.name);
   }
 
   @override
@@ -5530,11 +5565,11 @@
     _superAllowed = false;
     var finallyBlock = _visitStatement(node.finallyBlock)?.toBlock();
     _superAllowed = savedSuperAllowed;
-    return JS.Try(_visitStatement(node.body).toBlock(),
+    return js_ast.Try(_visitStatement(node.body).toBlock(),
         _visitCatch(node.catchClauses), finallyBlock);
   }
 
-  JS.Catch _visitCatch(NodeList<CatchClause> clauses) {
+  js_ast.Catch _visitCatch(NodeList<CatchClause> clauses) {
     if (clauses == null || clauses.isEmpty) return null;
 
     var caughtError = _createTemporary('e', types.dynamicType);
@@ -5554,7 +5589,8 @@
                 : null);
 
     // Rethrow if the exception type didn't match.
-    JS.Statement catchBody = JS.Throw(_emitSimpleIdentifier(caughtError));
+    js_ast.Statement catchBody =
+        js_ast.Throw(_emitSimpleIdentifier(caughtError));
     for (var clause in clauses.reversed) {
       catchBody = _catchClauseGuard(
           clause, catchBody, exceptionParameter, stackTraceParameter);
@@ -5575,17 +5611,17 @@
     }
     catchStatements.add(catchBody);
 
-    var catchVarDecl = _emitSimpleIdentifier(caughtError) as JS.Identifier;
+    var catchVarDecl = _emitSimpleIdentifier(caughtError) as js_ast.Identifier;
     _rethrowParameter = savedRethrow;
-    return JS.Catch(catchVarDecl, JS.Block(catchStatements));
+    return js_ast.Catch(catchVarDecl, js_ast.Block(catchStatements));
   }
 
-  JS.Statement _catchClauseGuard(
+  js_ast.Statement _catchClauseGuard(
       CatchClause node,
-      JS.Statement otherwise,
+      js_ast.Statement otherwise,
       SimpleIdentifier exceptionParameter,
       SimpleIdentifier stackTraceParameter) {
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     var vars = HashSet<String>();
 
     void declareVariable(SimpleIdentifier variable, SimpleIdentifier value) {
@@ -5603,7 +5639,7 @@
     }
 
     body.add(_visitStatement(node.body).toScopedBlock(vars));
-    var then = JS.Statement.from(body);
+    var then = js_ast.Statement.from(body);
 
     // Discard following clauses, if any, as they are unreachable.
     if (node.exceptionType == null ||
@@ -5613,32 +5649,32 @@
 
     var condition =
         _emitIsExpression(exceptionParameter, node.exceptionType.type);
-    return JS.If(condition, then, otherwise)
+    return js_ast.If(condition, then, otherwise)
       ..sourceInformation = _nodeStart(node);
   }
 
   @override
-  JS.SwitchCase visitSwitchCase(SwitchCase node) {
+  js_ast.SwitchCase visitSwitchCase(SwitchCase node) {
     var expr = _visitExpression(node.expression);
     var body = _visitStatementList(node.statements);
     if (node.labels.isNotEmpty) {
       body.insert(0, js.comment('Unimplemented case labels: ${node.labels}'));
     }
     // TODO(jmesserly): make sure we are statically checking fall through
-    return JS.SwitchCase(expr, JS.Block(body));
+    return js_ast.SwitchCase(expr, js_ast.Block(body));
   }
 
   @override
-  JS.SwitchCase visitSwitchDefault(SwitchDefault node) {
+  js_ast.SwitchCase visitSwitchDefault(SwitchDefault node) {
     var body = _visitStatementList(node.statements);
     if (node.labels.isNotEmpty) {
       body.insert(0, js.comment('Unimplemented case labels: ${node.labels}'));
     }
     // TODO(jmesserly): make sure we are statically checking fall through
-    return JS.SwitchCase.defaultCase(JS.Block(body));
+    return js_ast.SwitchCase.defaultCase(js_ast.Block(body));
   }
 
-  JS.SwitchCase _emitSwitchMember(SwitchMember node) {
+  js_ast.SwitchCase _emitSwitchMember(SwitchMember node) {
     if (node is SwitchCase) {
       return visitSwitchCase(node);
     } else {
@@ -5647,15 +5683,15 @@
   }
 
   @override
-  JS.Switch visitSwitchStatement(SwitchStatement node) => JS.Switch(
+  js_ast.Switch visitSwitchStatement(SwitchStatement node) => js_ast.Switch(
       _visitExpression(node.expression),
       node.members?.map(_emitSwitchMember)?.toList());
 
   @override
-  JS.Statement visitLabeledStatement(LabeledStatement node) {
+  js_ast.Statement visitLabeledStatement(LabeledStatement node) {
     var result = _visitStatement(node.statement);
     for (var label in node.labels.reversed) {
-      result = JS.LabeledStatement(label.label.name, result);
+      result = js_ast.LabeledStatement(label.label.name, result);
     }
     return result;
   }
@@ -5682,14 +5718,14 @@
           AnalysisError(_currentCompilationUnit.source, node.offset,
               node.length, invalidJSInteger, [lexeme, nearest]));
     }
-    return JS.LiteralNumber('$valueInJS');
+    return js_ast.LiteralNumber('$valueInJS');
   }
 
   @override
   visitDoubleLiteral(DoubleLiteral node) => js.number(node.value);
 
   @override
-  visitNullLiteral(NullLiteral node) => JS.LiteralNull();
+  visitNullLiteral(NullLiteral node) => js_ast.LiteralNull();
 
   @override
   visitSymbolLiteral(SymbolLiteral node) {
@@ -5697,7 +5733,7 @@
   }
 
   @override
-  JS.Expression visitListLiteral(ListLiteral node) {
+  js_ast.Expression visitListLiteral(ListLiteral node) {
     var elementType = (node.staticType as InterfaceType).typeArguments[0];
     var elements = _visitCollectionElementList(node.elements, elementType);
     if (!node.isConst) {
@@ -5706,7 +5742,7 @@
     return _emitConstList(elementType, elements);
   }
 
-  JS.Expression _emitSetLiteral(SetOrMapLiteral node) {
+  js_ast.Expression _emitSetLiteral(SetOrMapLiteral node) {
     var type = node.staticType as InterfaceType;
     var elementType = type.typeArguments[0];
     var jsElements = _visitCollectionElementList(node.elements, elementType);
@@ -5721,16 +5757,17 @@
         runtimeCall('constSet(#, [#])', [_emitType(elementType), jsElements]));
   }
 
-  JS.Expression _emitConstList(
-      DartType elementType, List<JS.Expression> elements) {
+  js_ast.Expression _emitConstList(
+      DartType elementType, List<js_ast.Expression> elements) {
     // dart.constList helper internally depends on _interceptors.JSArray.
     _declareBeforeUse(_jsArray);
     return cacheConst(
         runtimeCall('constList([#], #)', [elements, _emitType(elementType)]));
   }
 
-  JS.Expression _emitList(DartType itemType, List<JS.Expression> items) {
-    var list = JS.ArrayInitializer(items);
+  js_ast.Expression _emitList(
+      DartType itemType, List<js_ast.Expression> items) {
+    var list = js_ast.ArrayInitializer(items);
 
     // TODO(jmesserly): analyzer will usually infer `List<Object>` because
     // that is the least upper bound of the element types. So we rarely
@@ -5742,7 +5779,7 @@
     return js.call('#.of(#)', [_emitType(arrayType), list]);
   }
 
-  JS.Expression _emitMapLiteral(SetOrMapLiteral node) {
+  js_ast.Expression _emitMapLiteral(SetOrMapLiteral node) {
     var type = node.staticType as InterfaceType;
     var elementType = type.typeArguments[0];
     var jsElements = _visitCollectionElementList(node.elements, elementType);
@@ -5756,13 +5793,14 @@
     return _emitConstMap(type, jsElements);
   }
 
-  JS.Expression _emitConstMap(InterfaceType type, List<JS.Expression> entries) {
+  js_ast.Expression _emitConstMap(
+      InterfaceType type, List<js_ast.Expression> entries) {
     var typeArgs = type.typeArguments;
     return cacheConst(runtimeCall('constMap(#, #, [#])',
         [_emitType(typeArgs[0]), _emitType(typeArgs[1]), entries]));
   }
 
-  JS.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
+  js_ast.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) return _emitType(type);
     identity ??= jsTypeRep.isPrimitive(typeArgs[0]);
@@ -5770,7 +5808,7 @@
     return _emitType(type.instantiate(typeArgs));
   }
 
-  JS.Expression _emitSetImplType(InterfaceType type, {bool identity}) {
+  js_ast.Expression _emitSetImplType(InterfaceType type, {bool identity}) {
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) return _emitType(type);
     identity ??= jsTypeRep.isPrimitive(typeArgs[0]);
@@ -5779,19 +5817,19 @@
   }
 
   @override
-  JS.LiteralString visitSimpleStringLiteral(SimpleStringLiteral node) =>
+  js_ast.LiteralString visitSimpleStringLiteral(SimpleStringLiteral node) =>
       js.escapedString(node.value, '"');
 
   @override
-  JS.Expression visitAdjacentStrings(AdjacentStrings node) {
+  js_ast.Expression visitAdjacentStrings(AdjacentStrings node) {
     var nodes = node.strings;
     if (nodes == null || nodes.isEmpty) return null;
-    return JS.Expression.binary(_visitExpressionList(nodes), '+');
+    return js_ast.Expression.binary(_visitExpressionList(nodes), '+');
   }
 
   @override
-  JS.Expression visitStringInterpolation(StringInterpolation node) {
-    var parts = <JS.Expression>[];
+  js_ast.Expression visitStringInterpolation(StringInterpolation node) {
+    var parts = <js_ast.Expression>[];
     for (var elem in node.elements) {
       if (elem is InterpolationString) {
         if (elem.value.isEmpty) continue;
@@ -5805,7 +5843,7 @@
       }
     }
     if (parts.isEmpty) return js.string('');
-    return JS.Expression.binary(parts, '+');
+    return js_ast.Expression.binary(parts, '+');
   }
 
   @override
@@ -5818,33 +5856,33 @@
   /// Visit a Dart [node] that produces a JS expression, and attaches a source
   /// location.
   // TODO(jmesserly): parameter type should be `Expression`
-  JS.Expression _visitExpression(AstNode node) {
+  js_ast.Expression _visitExpression(AstNode node) {
     if (node == null) return null;
-    var e = node.accept<JS.Node>(this) as JS.Expression;
+    var e = node.accept<js_ast.Node>(this) as js_ast.Expression;
     e.sourceInformation ??= _nodeStart(node);
     return e;
   }
 
   /// Visits [nodes] with [_visitExpression].
-  List<JS.Expression> _visitExpressionList(Iterable<AstNode> nodes) {
+  List<js_ast.Expression> _visitExpressionList(Iterable<AstNode> nodes) {
     return nodes?.map(_visitExpression)?.toList();
   }
 
   /// Visit a Dart [node] that produces a JS statement, and marks its source
   /// location for debugging.
-  JS.Statement _visitStatement(AstNode node) {
+  js_ast.Statement _visitStatement(AstNode node) {
     if (node == null) return null;
-    var s = node.accept<JS.Node>(this) as JS.Statement;
+    var s = node.accept<js_ast.Node>(this) as js_ast.Statement;
     if (s is! Block) s.sourceInformation = _nodeStart(node);
     return s;
   }
 
   /// Visits [nodes] with [_visitStatement].
-  List<JS.Statement> _visitStatementList(Iterable<AstNode> nodes) {
+  List<js_ast.Statement> _visitStatementList(Iterable<AstNode> nodes) {
     return nodes?.map(_visitStatement)?.toList();
   }
 
-  /// Returns a [JS.Expression] for each [CollectionElement] in [nodes].
+  /// Returns a [js_ast.Expression] for each [CollectionElement] in [nodes].
   ///
   /// Visits all [nodes] in order and nested [CollectionElement]s depth first
   /// to produce [JS.Expresison]s intended to be used when outputing a
@@ -5862,7 +5900,7 @@
   ///       if (true) for (let i = 2; i < 10; i++) temp.push(i);
   ///       return temp;
   ///     })(), 10]
-  List<JS.Expression> _visitCollectionElementList(
+  List<js_ast.Expression> _visitCollectionElementList(
       Iterable<CollectionElement> nodes, DartType elementType) {
     /// Returns [body] wrapped in a function and a call.
     ///
@@ -5870,19 +5908,20 @@
     /// fucntion, call it, and yield the result of [yieldType].
     /// TODO(nshahan) Move to share between compilers. Need to work out a common
     /// emitLibraryName().
-    JS.Expression detectYieldAndCall(JS.Block body, InterfaceType yieldType) {
+    js_ast.Expression detectYieldAndCall(
+        js_ast.Block body, InterfaceType yieldType) {
       var finder = YieldFinder();
       body.accept(finder);
       if (finder.hasYield) {
-        var genFn = JS.Fun([], body, isGenerator: true);
+        var genFn = js_ast.Fun([], body, isGenerator: true);
         var asyncLibrary = emitLibraryName(types.futureType.element.library);
-        return JS.Yield(js.call(
+        return js_ast.Yield(js.call(
             '#.async(#, #)', [asyncLibrary, _emitType(yieldType), genFn]));
       }
-      return JS.Call(JS.ArrowFun([], body), []);
+      return js_ast.Call(js_ast.ArrowFun([], body), []);
     }
 
-    var expressions = <JS.Expression>[];
+    var expressions = <js_ast.Expression>[];
     for (var node in nodes) {
       if (_isUiAsCodeElement(node)) {
         // Create a temporary variable to build a new collection from.
@@ -5895,15 +5934,15 @@
 
         // Build up a list for the control-flow-collections element and wrap in
         // a function call that returns the list.
-        var functionBody = JS.Block([
+        var functionBody = js_ast.Block([
           items,
-          node.accept<JS.Node>(this) as JS.Statement,
-          JS.Return(_currentCollectionVariable)
+          node.accept<js_ast.Node>(this) as js_ast.Statement,
+          js_ast.Return(_currentCollectionVariable)
         ]);
         var functionCall = detectYieldAndCall(functionBody, arrayType);
 
         // Finally, spread the temporary control-flow-collections list.
-        expressions.add(JS.Spread(functionCall));
+        expressions.add(js_ast.Spread(functionCall));
         _currentCollectionVariable = previousCollectionVariable;
       } else if (node is MapLiteralEntry) {
         expressions.add(_visitExpression(node.key));
@@ -5917,12 +5956,12 @@
 
   /// Visits [node] with [_visitExpression] and wraps the result in a call to
   /// append it to the list tracked by [_currentCollectionVariable].
-  JS.Statement _visitNestedCollectionElement(CollectionElement node) {
-    JS.Statement pushToCurrentCollection(Expression value) => js.statement(
+  js_ast.Statement _visitNestedCollectionElement(CollectionElement node) {
+    js_ast.Statement pushToCurrentCollection(Expression value) => js.statement(
         '#.push(#)', [_currentCollectionVariable, _visitExpression(value)]);
 
     if (node is MapLiteralEntry) {
-      return JS.Block([
+      return js_ast.Block([
         pushToCurrentCollection(node.key),
         pushToCurrentCollection(node.value)
       ]);
@@ -5987,7 +6026,7 @@
   /// 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.Expression expr, AstNode node) {
+  HoverComment _hoverComment(js_ast.Expression expr, AstNode node) {
     var start = _getLocation(node.offset);
     var end = _getLocation(node.end);
     return start != null && end != null ? HoverComment(expr, start, end) : null;
@@ -6022,7 +6061,7 @@
   /// 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.Expression _visitTest(Expression node) {
+  js_ast.Expression _visitTest(Expression node) {
     if (node == null) return null;
 
     if (node is PrefixExpression && node.operator.lexeme == '!') {
@@ -6034,7 +6073,7 @@
       return _visitTest(node.expression);
     }
     if (node is BinaryExpression) {
-      JS.Expression shortCircuit(String code) {
+      js_ast.Expression shortCircuit(String code) {
         return js.call(code,
             [_visitTest(node.leftOperand), _visitTest(node.rightOperand)]);
       }
@@ -6056,7 +6095,8 @@
   ///
   /// Unlike call sites, we always have an element available, so we can use it
   /// directly rather than computing the relevant options for [_emitMemberName].
-  JS.Expression _declareMemberName(ExecutableElement e, {bool useExtension}) {
+  js_ast.Expression _declareMemberName(ExecutableElement e,
+      {bool useExtension}) {
     return _emitMemberName(_getElementName(e),
         isStatic: e.isStatic,
         useExtension:
@@ -6104,7 +6144,7 @@
   /// 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.Expression _emitMemberName(String name,
+  js_ast.Expression _emitMemberName(String name,
       {DartType type,
       bool isStatic = false,
       bool useExtension,
@@ -6123,9 +6163,9 @@
         var parts = runtimeName.split('.');
         if (parts.length < 2) return propertyName(runtimeName);
 
-        JS.Expression result = JS.Identifier(parts[0]);
+        js_ast.Expression result = js_ast.Identifier(parts[0]);
         for (int i = 1; i < parts.length; i++) {
-          result = JS.PropertyAccess(result, propertyName(parts[i]));
+          result = js_ast.PropertyAccess(result, propertyName(parts[i]));
         }
         return result;
       }
@@ -6138,7 +6178,7 @@
     useExtension ??= _isSymbolizedMember(type, name);
     // Rename members that conflict with standard JS members unless we are
     // actually try to access those JS members via interop.
-    name = JS.memberNameForDartMember(name, _isExternal(element));
+    name = js_ast.memberNameForDartMember(name, _isExternal(element));
     if (useExtension) {
       return getExtensionSymbolInternal(name);
     }
@@ -6151,7 +6191,7 @@
   /// The member [name] should be passed, as well as its [element] when it's
   /// available. If the element is `external`, the element is used to statically
   /// resolve the JS interop/dart:html static member. Otherwise it is ignored.
-  JS.Expression _emitStaticMemberName(String name, [Element element]) {
+  js_ast.Expression _emitStaticMemberName(String name, [Element element]) {
     if (element != null && _isExternal(element)) {
       var newName = getAnnotationName(element, isJSName) ??
           _getJSInteropStaticMemberName(element);
@@ -6316,7 +6356,7 @@
     return DynamicTypeImpl.instance;
   }
 
-  JS.Expression _throwUnsafe(String message) => runtimeCall(
+  js_ast.Expression _throwUnsafe(String message) => runtimeCall(
       'throw(Error(#))', [js.escapedString("compile error: $message")]);
 
   Null _unreachable(Object node) {
@@ -6403,7 +6443,7 @@
 
   /// Unused, handled by [visitMixinDeclaration].
   @override
-  JS.Node visitOnClause(OnClause node) => _unreachable(node);
+  js_ast.Node visitOnClause(OnClause node) => _unreachable(node);
 
   /// Unused, handled by imports/exports.
   @override
@@ -6469,8 +6509,8 @@
   @override
   visitWithClause(node) => _unreachable(node);
 
-  JS.For _emitFor(ForParts forParts, JS.Statement body) {
-    JS.Expression init;
+  js_ast.For _emitFor(ForParts forParts, js_ast.Statement body) {
+    js_ast.Expression init;
     if (forParts is ForPartsWithExpression) {
       init = _visitExpression(forParts.initialization);
     } else if (forParts is ForPartsWithDeclarations) {
@@ -6478,64 +6518,66 @@
     } else {
       throw new StateError('Unrecognized for loop parts');
     }
-    JS.Expression update;
+    js_ast.Expression update;
     if (forParts.updaters != null && forParts.updaters.isNotEmpty) {
-      update = JS.Expression.binary(
+      update = js_ast.Expression.binary(
               forParts.updaters.map(_visitExpression).toList(), ',')
           .toVoidExpression();
     }
-    return JS.For(init, _visitTest(forParts.condition), update, body);
+    return js_ast.For(init, _visitTest(forParts.condition), update, body);
   }
 
-  JS.Statement _emitForEach(ForEachParts forParts, JS.Statement jsBody) {
+  js_ast.Statement _emitForEach(
+      ForEachParts forParts, js_ast.Statement jsBody) {
     var jsIterable = _visitExpression(forParts.iterable);
-    JS.Expression jsLeftExpression;
+    js_ast.Expression jsLeftExpression;
     if (forParts is ForEachPartsWithIdentifier) {
       jsLeftExpression = _visitExpression(forParts.identifier);
     } else if (forParts is ForEachPartsWithDeclaration) {
       var id = _emitVariableDef(forParts.loopVariable.identifier);
       jsLeftExpression = js.call('let #', id);
       if (_annotatedNullCheck(forParts.loopVariable.declaredElement)) {
-        jsBody =
-            JS.Block([_nullParameterCheck(JS.Identifier(id.name)), jsBody]);
+        jsBody = js_ast.Block(
+            [_nullParameterCheck(js_ast.Identifier(id.name)), jsBody]);
       }
       if (variableIsReferenced(id.name, jsIterable)) {
-        var temp = JS.TemporaryId('iter');
-        return JS.Block([
+        var temp = js_ast.TemporaryId('iter');
+        return js_ast.Block([
           jsIterable.toVariableDeclaration(temp),
-          JS.ForOf(jsLeftExpression, temp, jsBody)
+          js_ast.ForOf(jsLeftExpression, temp, jsBody)
         ]);
       }
     } else {
       throw new StateError('Unrecognized for loop parts');
     }
-    return JS.ForOf(jsLeftExpression, jsIterable, jsBody);
+    return js_ast.ForOf(jsLeftExpression, jsIterable, jsBody);
   }
 
   @override
-  JS.Statement visitForElement(ForElement node) {
+  js_ast.Statement visitForElement(ForElement node) {
     var jsBody = _isUiAsCodeElement(node.body)
-        ? node.body.accept(this) as JS.Statement
+        ? node.body.accept(this) as js_ast.Statement
         : _visitNestedCollectionElement(node.body);
     return _forAdaptor(node.forLoopParts, node.awaitKeyword, jsBody);
   }
 
   @override
-  JS.Statement visitIfElement(IfElement node) {
+  js_ast.Statement visitIfElement(IfElement node) {
     var thenElement = _isUiAsCodeElement(node.thenElement)
-        ? node.thenElement.accept(this) as JS.Statement
+        ? node.thenElement.accept(this) as js_ast.Statement
         : _visitNestedCollectionElement(node.thenElement);
 
-    JS.Statement elseElement;
+    js_ast.Statement elseElement;
     if (node.elseElement != null) {
       if (_isUiAsCodeElement(node.elseElement)) {
-        elseElement = node.elseElement.accept<JS.Node>(this) as JS.Statement;
+        elseElement =
+            node.elseElement.accept<js_ast.Node>(this) as js_ast.Statement;
       } else {
         elseElement = _visitNestedCollectionElement(node.elseElement);
       }
     }
 
-    return JS.If(_visitTest(node.condition), thenElement, elseElement);
+    return js_ast.If(_visitTest(node.condition), thenElement, elseElement);
   }
 
   @override
@@ -6547,23 +6589,23 @@
       _unreachable(node);
 
   @override
-  JS.Statement visitForStatement(ForStatement node) =>
+  js_ast.Statement visitForStatement(ForStatement node) =>
       _forAdaptor(node.forLoopParts, node.awaitKeyword, _visitScope(node.body));
 
-  JS.Statement _forAdaptor(
-      ForLoopParts forParts, Token awaitKeyword, JS.Statement jsBody) {
+  js_ast.Statement _forAdaptor(
+      ForLoopParts forParts, Token awaitKeyword, js_ast.Statement jsBody) {
     /// Returns a new scoped block starting with [first] followed by [rest].
     ///
     /// Performs one level of scope flattening when [rest] is already a scoped
     /// block.
-    JS.Block insertFirst(JS.Statement first, JS.Statement rest) {
+    js_ast.Block insertFirst(js_ast.Statement first, js_ast.Statement rest) {
       var bodyStatements = [first];
-      if (rest is JS.Block) {
+      if (rest is js_ast.Block) {
         bodyStatements.addAll(rest.statements);
       } else {
         bodyStatements.add(rest);
       }
-      return JS.Block(bodyStatements);
+      return js_ast.Block(bodyStatements);
     }
 
     if (forParts is ForParts) {
@@ -6598,7 +6640,7 @@
       node.isSet ? _emitSetLiteral(node) : _emitMapLiteral(node);
 
   @override
-  JS.Statement visitSpreadElement(SpreadElement node) {
+  js_ast.Statement visitSpreadElement(SpreadElement node) {
     /// Returns `true` if [node] is or is a child element of a map literal.
     bool isMap(AstNode node) {
       if (node is SetOrMapLiteral) return node.isMap;
@@ -6609,8 +6651,8 @@
     /// Returns [expression] wrapped in an implict cast to [castType] or
     /// [expression] as provided if [castType] is `null` signifying that
     /// no cast is needed.
-    JS.Expression wrapInImplicitCast(
-            JS.Expression expression, DartType castType) =>
+    js_ast.Expression wrapInImplicitCast(
+            js_ast.Expression expression, DartType castType) =>
         castType == null ? expression : _emitCast(castType, expression);
 
     /// Returns a statement spreading the elements of [expression] into
@@ -6619,8 +6661,8 @@
     /// Expects the collection literal containing [expression] to be a list or
     /// set literal. Inserts implicit casts to [elementCastType] for each
     /// element if needed.
-    JS.Statement emitListOrSetSpread(
-        JS.Expression expression, DartType elementCastType) {
+    js_ast.Statement emitListOrSetSpread(
+        js_ast.Expression expression, DartType elementCastType) {
       var forEachTemp =
           _emitSimpleIdentifier(_createTemporary('i', types.dynamicType));
       return js.statement('#.forEach((#) => #.push(#))', [
@@ -6637,8 +6679,8 @@
     /// Expects the collection literal containing [expression] to be a map
     /// literal. Inserts implicit casts to [keyCastType] for keys and
     /// [valueCastType] for values if needed.
-    JS.Statement emitMapSpread(JS.Expression expression, DartType keyCastType,
-        DartType valueCastType) {
+    js_ast.Statement emitMapSpread(js_ast.Expression expression,
+        DartType keyCastType, DartType valueCastType) {
       var keyTemp =
           _emitSimpleIdentifier(_createTemporary('k', types.dynamicType));
       var valueTemp =
@@ -6659,7 +6701,7 @@
     /// Uses implict cast information from [node] to insert the correct casts
     /// for the collection elements when spreading. Inspects parents of [node]
     /// to determine the type of the enclosing collection literal.
-    JS.Statement emitSpread(JS.Expression expression, Expression node) {
+    js_ast.Statement emitSpread(js_ast.Expression expression, Expression node) {
       expression = wrapInImplicitCast(expression, getImplicitCast(node));
 
       // Start searching for a map literal at the parent of the SpreadElement.
@@ -6676,11 +6718,12 @@
     /// Uses implict cast information from [node] to insert the correct casts
     /// for the collection elements when spreading. Inspects parents of [node]
     /// to determine the type of the enclosing collection literal.
-    JS.Statement emitNullSafeSpread(JS.Expression expression, Expression node) {
+    js_ast.Statement emitNullSafeSpread(
+        js_ast.Expression expression, Expression node) {
       // TODO(nshahan) Could optimize out if we know the value is null.
       var spreadItems =
           _emitSimpleIdentifier(_createTemporary('items', getStaticType(node)));
-      return JS.Block([
+      return js_ast.Block([
         js.statement('let # = #', [spreadItems, expression]),
         js.statement(
             'if (# != null) #', [spreadItems, emitSpread(spreadItems, node)])
@@ -6714,7 +6757,7 @@
 /// variable. These objects use instance equality, and should be shared
 /// everywhere in the tree where they are treated as the same variable.
 class TemporaryVariableElement extends LocalVariableElementImpl {
-  final JS.Expression jsVariable;
+  final js_ast.Expression jsVariable;
 
   TemporaryVariableElement.forNode(
       Identifier name, this.jsVariable, Element enclosingElement)
diff --git a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
index 3997597..70bdc0a 100644
--- a/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/module_compiler.dart
@@ -15,12 +15,12 @@
 import 'package:path/path.dart' as path;
 import 'package:source_maps/source_maps.dart';
 
-import '../compiler/js_names.dart' as JS;
+import '../compiler/js_names.dart' as js_ast;
 import '../compiler/module_builder.dart'
     show transformModuleFormat, ModuleFormat;
 import '../compiler/shared_command.dart';
 import '../compiler/shared_compiler.dart';
-import '../js_ast/js_ast.dart' as JS;
+import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 import '../js_ast/source_map_printer.dart' show SourceMapPrintingContext;
 import 'code_generator.dart' show CodeGenerator;
@@ -95,7 +95,7 @@
     }
   }
 
-  JS.Program jsProgram;
+  js_ast.Program jsProgram;
   if (options.unsafeForceCompile || !errors.hasFatalErrors) {
     var codeGenerator = CodeGenerator(
         driver,
@@ -227,7 +227,7 @@
 
   /// The AST that will be used to generate the [code] and [sourceMap] for this
   /// module.
-  final JS.Program moduleTree;
+  final js_ast.Program moduleTree;
 
   /// The compiler options used to generate this module.
   final CompilerOptions options;
@@ -256,20 +256,21 @@
   // TODO(jmesserly): this should match our old logic, but I'm not sure we are
   // correctly handling the pointer from the .js file to the .map file.
   JSModuleCode getCode(ModuleFormat format, String jsUrl, String mapUrl) {
-    var opts = JS.JavaScriptPrintingOptions(
+    var opts = js_ast.JavaScriptPrintingOptions(
         allowKeywordsInProperties: true, allowSingleLineIfStatements: true);
-    JS.SimpleJavaScriptPrintingContext printer;
+    js_ast.SimpleJavaScriptPrintingContext printer;
     SourceMapBuilder sourceMap;
     if (options.sourceMap) {
       var sourceMapContext = SourceMapPrintingContext();
       sourceMap = sourceMapContext.sourceMap;
       printer = sourceMapContext;
     } else {
-      printer = JS.SimpleJavaScriptPrintingContext();
+      printer = js_ast.SimpleJavaScriptPrintingContext();
     }
 
     var tree = transformModuleFormat(format, moduleTree);
-    tree.accept(JS.Printer(opts, printer, localNamer: JS.TemporaryNamer(tree)));
+    tree.accept(
+        js_ast.Printer(opts, printer, localNamer: js_ast.TemporaryNamer(tree)));
 
     Map builtMap;
     if (options.sourceMap && sourceMap != null) {
diff --git a/pkg/dev_compiler/lib/src/analyzer/property_model.dart b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
index d63abc3..227afa7 100644
--- a/pkg/dev_compiler/lib/src/analyzer/property_model.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/property_model.dart
@@ -8,8 +8,7 @@
 import 'package:analyzer/dart/element/type.dart' show InterfaceType;
 import 'package:analyzer/src/dart/element/element.dart' show FieldElementImpl;
 
-import '../compiler/js_names.dart' as JS;
-import '../js_ast/js_ast.dart' as JS;
+import '../compiler/js_names.dart' as js_ast;
 import 'element_helpers.dart';
 import 'extension_types.dart';
 
@@ -176,7 +175,7 @@
   /// pair in JavaScript.
   ///
   /// The value property stores the symbol used for the field's storage slot.
-  final virtualFields = <FieldElement, JS.TemporaryId>{};
+  final virtualFields = <FieldElement, js_ast.TemporaryId>{};
 
   /// The set of inherited getters, used because JS getters/setters are paired,
   /// so if we're generating a setter we may need to emit a getter that calls
@@ -250,7 +249,7 @@
                 covariantParameters != null &&
                 covariantParameters.contains(setter.parameters[0]) &&
                 covariantPrivateMembers.contains(setter)) {
-          virtualFields[field] = JS.TemporaryId(name);
+          virtualFields[field] = js_ast.TemporaryId(name);
         }
       }
     }
diff --git a/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart b/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
index dc52e86..ffa6943 100644
--- a/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
+++ b/pkg/dev_compiler/lib/src/analyzer/type_utilities.dart
@@ -3,13 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:collection';
+
 import 'package:analyzer/dart/element/element.dart';
 import 'package:analyzer/src/dart/element/member.dart' show TypeParameterMember;
 import 'package:analyzer/dart/element/type.dart';
 
 import '../analyzer/element_helpers.dart';
-import '../compiler/js_names.dart' as JS;
-import '../js_ast/js_ast.dart' as JS;
+import '../compiler/js_names.dart' as js_ast;
+import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 
 Set<TypeParameterElement> freeTypeParameters(DartType t) {
@@ -54,11 +55,11 @@
   // Use a LinkedHashMap to maintain key insertion order so the generated code
   // is stable under slight perturbation.  (If this is not good enough we could
   // sort by name to canonicalize order.)
-  final _names = LinkedHashMap<DartType, JS.TemporaryId>(
+  final _names = LinkedHashMap<DartType, js_ast.TemporaryId>(
       equals: typesAreEqual, hashCode: typeHashCode);
   Iterable<DartType> get keys => _names.keys.toList();
 
-  JS.Statement _dischargeType(DartType type) {
+  js_ast.Statement _dischargeType(DartType type) {
     var name = _names.remove(type);
     if (name != null) {
       return js.statement('let #;', [name]);
@@ -69,8 +70,8 @@
   /// Emit a list of statements declaring the cache variables for
   /// types tracked by this table.  If [typeFilter] is given,
   /// only emit the types listed in the filter.
-  List<JS.Statement> discharge([Iterable<DartType> typeFilter]) {
-    var decls = <JS.Statement>[];
+  List<js_ast.Statement> discharge([Iterable<DartType> typeFilter]) {
+    var decls = <js_ast.Statement>[];
     var types = typeFilter ?? keys;
     for (var t in types) {
       var stmt = _dischargeType(t);
@@ -119,26 +120,26 @@
 
   /// Heuristically choose a good name for the cache and generator
   /// variables.
-  JS.TemporaryId chooseTypeName(DartType type) {
-    return JS.TemporaryId(_typeString(type));
+  js_ast.TemporaryId chooseTypeName(DartType type) {
+    return js_ast.TemporaryId(_typeString(type));
   }
 }
 
 /// _GeneratorTable tracks types which have been
 /// named and hoisted.
 class _GeneratorTable extends _CacheTable {
-  final _defs = LinkedHashMap<DartType, JS.Expression>(
+  final _defs = LinkedHashMap<DartType, js_ast.Expression>(
       equals: typesAreEqual, hashCode: typeHashCode);
 
-  final JS.Identifier _runtimeModule;
+  final js_ast.Identifier _runtimeModule;
 
   _GeneratorTable(this._runtimeModule);
 
   @override
-  JS.Statement _dischargeType(DartType t) {
+  js_ast.Statement _dischargeType(DartType t) {
     var name = _names.remove(t);
     if (name != null) {
-      JS.Expression init = _defs.remove(t);
+      js_ast.Expression init = _defs.remove(t);
       assert(init != null);
       return js.statement('let # = () => ((# = #.constFn(#))());',
           [name, name, _runtimeModule, init]);
@@ -149,7 +150,7 @@
   /// If [type] does not already have a generator name chosen for it,
   /// assign it one, using [typeRep] as the initializer for it.
   /// Emit the generator name.
-  JS.TemporaryId _nameType(DartType type, JS.Expression typeRep) {
+  js_ast.TemporaryId _nameType(DartType type, js_ast.Expression typeRep) {
     var temp = _names[type];
     if (temp == null) {
       _names[type] = temp = chooseTypeName(type);
@@ -169,12 +170,12 @@
   /// parameter.
   final _scopeDependencies = <TypeParameterElement, List<DartType>>{};
 
-  TypeTable(JS.Identifier runtime) : _generators = _GeneratorTable(runtime);
+  TypeTable(js_ast.Identifier runtime) : _generators = _GeneratorTable(runtime);
 
   /// Emit a list of statements declaring the cache variables and generator
   /// definitions tracked by the table.  If [formals] is present, only
   /// emit the definitions which depend on the formals.
-  List<JS.Statement> discharge([List<TypeParameterElement> formals]) {
+  List<js_ast.Statement> discharge([List<TypeParameterElement> formals]) {
     var filter = formals?.expand((p) => _scopeDependencies[p] ?? <DartType>[]);
     var stmts = [_generators].expand((c) => c.discharge(filter)).toList();
     formals?.forEach(_scopeDependencies.remove);
@@ -205,7 +206,8 @@
   /// Given a type [type], and a JS expression [typeRep] which implements it,
   /// add the type and its representation to the table, returning an
   /// expression which implements the type (but which caches the value).
-  JS.Expression nameType(ParameterizedType type, JS.Expression typeRep) {
+  js_ast.Expression nameType(
+      ParameterizedType type, js_ast.Expression typeRep) {
     if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
       return typeRep;
     }
@@ -223,10 +225,11 @@
   /// should be a function that is invoked to compute the type, rather than the
   /// type itself. This allows better integration with `lazyFn`, avoiding an
   /// extra level of indirection.
-  JS.Expression nameFunctionType(FunctionType type, JS.Expression typeRep,
+  js_ast.Expression nameFunctionType(
+      FunctionType type, js_ast.Expression typeRep,
       {bool lazy = false}) {
     if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
-      return lazy ? JS.ArrowFun([], typeRep) : typeRep;
+      return lazy ? js_ast.ArrowFun([], typeRep) : typeRep;
     }
 
     var name = _generators._nameType(type, typeRep);
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 6a3182d..21daddb 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -5,10 +5,8 @@
 import 'dart:collection';
 import 'package:meta/meta.dart';
 
-import '../compiler/js_metalet.dart' as JS;
-import '../compiler/js_names.dart' as JS;
-import '../compiler/js_utils.dart' as JS;
-import '../js_ast/js_ast.dart' as JS;
+import '../compiler/js_names.dart' as js_ast;
+import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 
 /// Shared code between Analyzer and Kernel backends.
@@ -20,34 +18,34 @@
   /// returned by any `return;` statement.
   ///
   /// This lets DDC use the setter method's return value directly.
-  final List<JS.Identifier> _operatorSetResultStack = [];
+  final List<js_ast.Identifier> _operatorSetResultStack = [];
 
   /// Private member names in this module, organized by their library.
-  final _privateNames = HashMap<Library, HashMap<String, JS.TemporaryId>>();
+  final _privateNames = HashMap<Library, HashMap<String, js_ast.TemporaryId>>();
 
   /// Extension member symbols for adding Dart members to JS types.
   ///
   /// These are added to the [extensionSymbolsModule]; see that field for more
   /// information.
-  final _extensionSymbols = <String, JS.TemporaryId>{};
+  final _extensionSymbols = <String, js_ast.TemporaryId>{};
 
   /// The set of libraries we are currently compiling, and the temporaries used
   /// to refer to them.
-  final _libraries = <Library, JS.Identifier>{};
+  final _libraries = <Library, js_ast.Identifier>{};
 
   /// Imported libraries, and the temporaries used to refer to them.
-  final _imports = <Library, JS.TemporaryId>{};
+  final _imports = <Library, js_ast.TemporaryId>{};
 
   /// The identifier used to reference DDC's core "dart:_runtime" library from
   /// generated JS code, typically called "dart" e.g. `dart.dcall`.
   @protected
-  JS.Identifier runtimeModule;
+  js_ast.Identifier runtimeModule;
 
   /// 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".
   @protected
-  JS.Identifier extensionSymbolsModule;
+  js_ast.Identifier extensionSymbolsModule;
 
   /// Whether we're currently building the SDK, which may require special
   /// bootstrapping logic.
@@ -60,18 +58,18 @@
   /// The temporary variable that stores named arguments (these are passed via a
   /// JS object literal, to match JS conventions).
   @protected
-  final namedArgumentTemp = JS.TemporaryId('opts');
+  final namedArgumentTemp = js_ast.TemporaryId('opts');
 
   /// The list of output module items, in the order they need to be emitted in.
   @protected
-  final moduleItems = <JS.ModuleItem>[];
+  final moduleItems = <js_ast.ModuleItem>[];
 
   /// Like [moduleItems] but for items that should be emitted after classes.
   ///
   /// This is used for deferred supertypes of mutually recursive non-generic
   /// classes.
   @protected
-  final afterClassDefItems = <JS.ModuleItem>[];
+  final afterClassDefItems = <js_ast.ModuleItem>[];
 
   /// The type used for private Dart [Symbol]s.
   @protected
@@ -126,12 +124,12 @@
 
   /// Emits the expression necessary to access a constructor of [type];
   @protected
-  JS.Expression emitConstructorAccess(InterfaceType type);
+  js_ast.Expression emitConstructorAccess(InterfaceType type);
 
   /// When compiling the body of a `operator []=` method, this will be non-null
   /// and will indicate the the value that should be returned from any `return;`
   /// statements.
-  JS.Identifier get _operatorSetResult {
+  js_ast.Identifier get _operatorSetResult {
     var stack = _operatorSetResultStack;
     return stack.isEmpty ? null : stack.last;
   }
@@ -141,12 +139,12 @@
   ///
   /// See also [exitFunction] and [emitReturnStatement].
   @protected
-  void enterFunction(String name, List<JS.Parameter> formals,
+  void enterFunction(String name, List<js_ast.Parameter> formals,
       bool Function() isLastParamMutated) {
     if (name == '[]=') {
       _operatorSetResultStack.add(isLastParamMutated()
-          ? JS.TemporaryId((formals.last as JS.Identifier).name)
-          : formals.last as JS.Identifier);
+          ? js_ast.TemporaryId((formals.last as js_ast.Identifier).name)
+          : formals.last as js_ast.Identifier);
     } else {
       _operatorSetResultStack.add(null);
     }
@@ -155,8 +153,8 @@
   /// Called when finished emitting methods/functions, and must correspond to a
   /// previous [enterFunction] call.
   @protected
-  JS.Block exitFunction(
-      String name, List<JS.Parameter> formals, JS.Block code) {
+  js_ast.Block exitFunction(
+      String name, List<js_ast.Parameter> formals, js_ast.Block code) {
     if (name == "==" &&
         formals.isNotEmpty &&
         currentLibraryUri.scheme != 'dart') {
@@ -177,7 +175,7 @@
       var valueParam = formals.last;
       var statements = code.statements;
       if (statements.isEmpty || !statements.last.alwaysReturns) {
-        statements.add(JS.Return(setOperatorResult));
+        statements.add(js_ast.Return(setOperatorResult));
       }
       if (!identical(setOperatorResult, valueParam)) {
         // If the value parameter was mutated, then we use a temporary
@@ -193,12 +191,14 @@
   /// Emits a return statement `return <value>;`, handling special rules for
   /// the `operator []=` method.
   @protected
-  JS.Statement emitReturnStatement(JS.Expression value) {
+  js_ast.Statement emitReturnStatement(js_ast.Expression value) {
     if (_operatorSetResult != null) {
-      var result = JS.Return(_operatorSetResult);
-      return value != null ? JS.Block([value.toStatement(), result]) : result;
+      var result = js_ast.Return(_operatorSetResult);
+      return value != null
+          ? js_ast.Block([value.toStatement(), result])
+          : result;
     }
-    return value != null ? value.toReturn() : JS.Return();
+    return value != null ? value.toReturn() : js_ast.Return();
   }
 
   /// Prepends the `dart.` and then uses [js.call] to parse the specified JS
@@ -213,13 +213,13 @@
   ///     dart.asInt(<expr>)
   ///
   @protected
-  JS.Expression runtimeCall(String code, [List<Object> args]) =>
+  js_ast.Expression runtimeCall(String code, [List<Object> args]) =>
       js.call('#.$code', <Object>[runtimeModule, ...?args]);
 
   /// Calls [runtimeCall] and uses `toStatement()` to convert the resulting
   /// expression into a statement.
   @protected
-  JS.Statement runtimeStatement(String code, [List<Object> args]) =>
+  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].
@@ -229,7 +229,7 @@
   /// member names, that won't collide at runtime, as required by the Dart
   /// language spec.
   @protected
-  JS.TemporaryId emitPrivateNameSymbol(Library library, String name) {
+  js_ast.TemporaryId emitPrivateNameSymbol(Library library, String name) {
     /// Initializes the JS `Symbol` for the private member [name] in [library].
     ///
     /// If the library is in the current JS module ([_libraries] contains it),
@@ -243,9 +243,9 @@
     /// 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.TemporaryId initPrivateNameSymbol() {
+    js_ast.TemporaryId initPrivateNameSymbol() {
       var idName = name.endsWith('=') ? name.replaceAll('=', '_') : name;
-      var id = JS.TemporaryId(idName);
+      var id = js_ast.TemporaryId(idName);
       moduleItems.add(js.statement('const # = #.privateName(#, #)',
           [id, runtimeModule, emitLibraryName(library), js.string(name)]));
       return id;
@@ -262,12 +262,13 @@
   /// `dart.defineValue(className, name, value)`. This is required when
   /// `FunctionNode.prototype` already defins a getters with the same name.
   @protected
-  JS.Expression defineValueOnClass(Class c, JS.Expression className,
-      JS.Expression nameExpr, JS.Expression value) {
+  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.LiteralString) {
+    if (nameExpr is js_ast.LiteralString) {
       var name = nameExpr.valueWithoutQuotes;
-      if (JS.isFunctionPrototypeGetter(name) || superclassHasStatic(c, name)) {
+      if (js_ast.isFunctionPrototypeGetter(name) ||
+          superclassHasStatic(c, name)) {
         return runtimeCall('defineValue(#, #, #)', args);
       }
     }
@@ -300,10 +301,10 @@
   /// per-module, though, as that would be relatively easy for the compiler to
   /// implement once we have a single Kernel backend).
   @protected
-  JS.Expression cacheConst(JS.Expression jsExpr) {
+  js_ast.Expression cacheConst(js_ast.Expression jsExpr) {
     if (currentFunction == null) return jsExpr;
 
-    var temp = JS.TemporaryId('const');
+    var temp = js_ast.TemporaryId('const');
     moduleItems.add(js.statement('let #;', [temp]));
     return js.call('# || (# = #)', [temp, temp, jsExpr]);
   }
@@ -313,11 +314,11 @@
   /// If the symbol refers to a private name, its library will be set to the
   /// [currentLibrary], so the Symbol is scoped properly.
   @protected
-  JS.Expression emitDartSymbol(String symbolName) {
+  js_ast.Expression emitDartSymbol(String symbolName) {
     // TODO(vsm): Handle qualified symbols correctly.
     var last = symbolName.split('.').last;
     var name = js.escapedString(symbolName, "'");
-    JS.Expression result;
+    js_ast.Expression result;
     if (last.startsWith('_')) {
       var nativeSymbol = emitPrivateNameSymbol(currentLibrary, last);
       result = js.call('new #.new(#, #)',
@@ -332,7 +333,7 @@
   /// Calls the `dart.const` function in "dart:_runtime" to canonicalize a
   /// constant instance of a user-defined class stored in [expr].
   @protected
-  JS.Expression canonicalizeConstObject(JS.Expression expr) =>
+  js_ast.Expression canonicalizeConstObject(js_ast.Expression expr) =>
       cacheConst(runtimeCall('const(#)', [expr]));
 
   /// Emits preamble for the module containing [libraries], and returns the
@@ -351,31 +352,31 @@
   /// [extensionSymbolsModule], as well as the [_libraries] map needed by
   /// [emitLibraryName].
   @protected
-  List<JS.ModuleItem> startModule(Iterable<Library> libraries) {
+  List<js_ast.ModuleItem> startModule(Iterable<Library> libraries) {
     isBuildingSdk = libraries.any(isSdkInternalRuntime);
     if (isBuildingSdk) {
       // Don't allow these to be renamed when we're building the SDK.
       // There is JS code in dart:* that depends on their names.
-      runtimeModule = JS.Identifier('dart');
-      extensionSymbolsModule = JS.Identifier('dartx');
+      runtimeModule = js_ast.Identifier('dart');
+      extensionSymbolsModule = js_ast.Identifier('dartx');
     } else {
       // Otherwise allow these to be renamed so users can write them.
-      runtimeModule = JS.TemporaryId('dart');
-      extensionSymbolsModule = JS.TemporaryId('dartx');
+      runtimeModule = js_ast.TemporaryId('dart');
+      extensionSymbolsModule = js_ast.TemporaryId('dartx');
     }
 
     // Initialize our library variables.
-    var items = <JS.ModuleItem>[];
-    var exports = <JS.NameSpecifier>[];
+    var items = <js_ast.ModuleItem>[];
+    var exports = <js_ast.NameSpecifier>[];
 
     if (isBuildingSdk) {
       // Bootstrap the ability to create Dart library objects.
-      var libraryProto = JS.TemporaryId('_library');
+      var libraryProto = js_ast.TemporaryId('_library');
       items.add(js.statement('const # = Object.create(null)', libraryProto));
       items.add(js.statement(
           'const # = Object.create(#)', [runtimeModule, libraryProto]));
       items.add(js.statement('#.library = #', [runtimeModule, libraryProto]));
-      exports.add(JS.NameSpecifier(runtimeModule));
+      exports.add(js_ast.NameSpecifier(runtimeModule));
     }
 
     for (var library in libraries) {
@@ -383,12 +384,12 @@
         _libraries[library] = runtimeModule;
         continue;
       }
-      var id = JS.TemporaryId(jsLibraryName(library));
+      var id = js_ast.TemporaryId(jsLibraryName(library));
       _libraries[library] = id;
 
       items.add(js.statement(
           'const # = Object.create(#.library)', [id, runtimeModule]));
-      exports.add(JS.NameSpecifier(id));
+      exports.add(js_ast.NameSpecifier(id));
     }
 
     // dart:_runtime has a magic module that holds extension method symbols.
@@ -397,15 +398,15 @@
       var id = extensionSymbolsModule;
       items.add(js.statement(
           'const # = Object.create(#.library)', [id, runtimeModule]));
-      exports.add(JS.NameSpecifier(id));
+      exports.add(js_ast.NameSpecifier(id));
     }
 
-    items.add(JS.ExportDeclaration(JS.ExportClause(exports)));
+    items.add(js_ast.ExportDeclaration(js_ast.ExportClause(exports)));
 
     if (isBuildingSdk) {
       // Initialize the private name function.
       // To bootstrap the SDK, this needs to be emitted before other code.
-      var symbol = JS.TemporaryId('_privateNames');
+      var symbol = js_ast.TemporaryId('_privateNames');
       items.add(js.statement('const # = Symbol("_privateNames")', symbol));
       items.add(js.statement(r'''
         #.privateName = function(library, name) {
@@ -423,16 +424,16 @@
 
   /// Returns the canonical name to refer to the Dart library.
   @protected
-  JS.Identifier emitLibraryName(Library library) {
+  js_ast.Identifier emitLibraryName(Library library) {
     // It's either one of the libraries in this module, or it's an import.
     return _libraries[library] ??
         _imports.putIfAbsent(
-            library, () => JS.TemporaryId(jsLibraryName(library)));
+            library, () => js_ast.TemporaryId(jsLibraryName(library)));
   }
 
   /// Emits imports and extension methods into [items].
   @protected
-  void emitImportsAndExtensionSymbols(List<JS.ModuleItem> items) {
+  void emitImportsAndExtensionSymbols(List<js_ast.ModuleItem> items) {
     var modules = Map<String, List<Library>>();
 
     for (var import in _imports.keys) {
@@ -454,20 +455,20 @@
       //     import {foo as foo$} from 'foo'; // if rename was needed
       //
       var imports =
-          libraries.map((l) => JS.NameSpecifier(_imports[l])).toList();
+          libraries.map((l) => js_ast.NameSpecifier(_imports[l])).toList();
       if (module == coreModuleName) {
-        imports.add(JS.NameSpecifier(runtimeModule));
-        imports.add(JS.NameSpecifier(extensionSymbolsModule));
+        imports.add(js_ast.NameSpecifier(runtimeModule));
+        imports.add(js_ast.NameSpecifier(extensionSymbolsModule));
       }
 
-      items.add(JS.ImportDeclaration(
+      items.add(js_ast.ImportDeclaration(
           namedImports: imports, from: js.string(module, "'")));
     });
 
     // Initialize extension symbols
     _extensionSymbols.forEach((name, id) {
-      JS.Expression value =
-          JS.PropertyAccess(extensionSymbolsModule, propertyName(name));
+      js_ast.Expression value =
+          js_ast.PropertyAccess(extensionSymbolsModule, propertyName(name));
       if (isBuildingSdk) {
         value = js.call('# = Symbol(#)', [value, js.string("dartx.$name")]);
       }
@@ -476,20 +477,20 @@
   }
 
   void _emitDebuggerExtensionInfo(String name) {
-    var properties = <JS.Property>[];
-    var parts = <JS.Property>[];
+    var properties = <js_ast.Property>[];
+    var parts = <js_ast.Property>[];
     _libraries.forEach((library, value) {
       // TODO(jacobr): we could specify a short library name instead of the
       // full library uri if we wanted to save space.
       var libraryName = js.escapedString(jsLibraryDebuggerName(library));
-      properties.add(JS.Property(libraryName, value));
+      properties.add(js_ast.Property(libraryName, value));
       var partNames = jsPartDebuggerNames(library);
       if (partNames.isNotEmpty) {
-        parts.add(JS.Property(libraryName, js.stringArray(partNames)));
+        parts.add(js_ast.Property(libraryName, js.stringArray(partNames)));
       }
     });
-    var module = JS.ObjectInitializer(properties, multiline: true);
-    var partMap = JS.ObjectInitializer(parts, multiline: true);
+    var module = js_ast.ObjectInitializer(properties, multiline: true);
+    var partMap = js_ast.ObjectInitializer(parts, multiline: true);
 
     // Track the module name for each library in the module.
     // This data is only required for debugging.
@@ -509,7 +510,8 @@
   /// Note, this function mutates the items list and returns it as the `body`
   /// field of the result.
   @protected
-  JS.Program finishModule(List<JS.ModuleItem> items, String moduleName) {
+  js_ast.Program finishModule(
+      List<js_ast.ModuleItem> items, String moduleName) {
     // 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 `startModule` and `finishModule` is very similar in both.
@@ -520,16 +522,16 @@
     moduleItems.clear();
 
     // Build the module.
-    return JS.Program(items, name: moduleName);
+    return js_ast.Program(items, name: moduleName);
   }
 
   /// Flattens blocks in [items] to a single list.
   ///
   /// This will not flatten blocks that are marked as being scopes.
   void _copyAndFlattenBlocks(
-      List<JS.ModuleItem> result, Iterable<JS.ModuleItem> items) {
+      List<js_ast.ModuleItem> result, Iterable<js_ast.ModuleItem> items) {
     for (var item in items) {
-      if (item is JS.Block && !item.isScope) {
+      if (item is js_ast.Block && !item.isScope) {
         _copyAndFlattenBlocks(result, item.statements);
       } else if (item != null) {
         result.add(item);
@@ -544,11 +546,11 @@
   /// Do not call this directly; you want [_emitMemberName], which knows how to
   /// handle the many details involved in naming.
   @protected
-  JS.TemporaryId getExtensionSymbolInternal(String name) {
+  js_ast.TemporaryId getExtensionSymbolInternal(String name) {
     return _extensionSymbols.putIfAbsent(
         name,
-        () => JS.TemporaryId(
-            '\$${JS.friendlyNameForDartOperator[name] ?? name}'));
+        () => js_ast.TemporaryId(
+            '\$${js_ast.friendlyNameForDartOperator[name] ?? name}'));
   }
 
   /// Shorthand for identifier-like property names.
@@ -556,7 +558,7 @@
   /// identifiers if it can.
   // TODO(jmesserly): avoid the round tripping through quoted form.
   @protected
-  JS.LiteralString propertyName(String name) => js.string(name, "'");
+  js_ast.LiteralString propertyName(String name) => js.string(name, "'");
 
   /// Unique identifier indicating the location to inline the source map.
   ///
@@ -568,7 +570,7 @@
 }
 
 /// Whether a variable with [name] is referenced in the [node].
-bool variableIsReferenced(String name, JS.Node node) {
+bool variableIsReferenced(String name, js_ast.Node node) {
   var finder = _IdentifierFinder.instance;
   finder.nameToFind = name;
   finder.found = false;
@@ -576,7 +578,7 @@
   return finder.found;
 }
 
-class _IdentifierFinder extends JS.BaseVisitor<void> {
+class _IdentifierFinder extends js_ast.BaseVisitor<void> {
   String nameToFind;
   bool found = false;
 
@@ -593,18 +595,18 @@
   }
 }
 
-class YieldFinder extends JS.BaseVisitor {
+class YieldFinder extends js_ast.BaseVisitor {
   bool hasYield = false;
   bool hasThis = false;
   bool _nestedFunction = false;
 
   @override
-  visitThis(JS.This node) {
+  visitThis(js_ast.This node) {
     hasThis = true;
   }
 
   @override
-  visitFunctionExpression(JS.FunctionExpression node) {
+  visitFunctionExpression(js_ast.FunctionExpression node) {
     var savedNested = _nestedFunction;
     _nestedFunction = true;
     super.visitFunctionExpression(node);
@@ -612,13 +614,13 @@
   }
 
   @override
-  visitYield(JS.Yield node) {
+  visitYield(js_ast.Yield node) {
     if (!_nestedFunction) hasYield = true;
     super.visitYield(node);
   }
 
   @override
-  visitNode(JS.Node node) {
+  visitNode(js_ast.Node node) {
     if (hasYield && hasThis) return; // found both, nothing more to do.
     super.visitNode(node);
   }
@@ -626,39 +628,40 @@
 
 /// Given the function [fn], returns a function declaration statement, binding
 /// `this` and `super` if necessary (using an arrow function).
-JS.Statement toBoundFunctionStatement(JS.Fun fn, JS.Identifier name) {
+js_ast.Statement toBoundFunctionStatement(
+    js_ast.Fun fn, js_ast.Identifier name) {
   if (usesThisOrSuper(fn)) {
     return js.statement('const # = (#) => {#}', [name, fn.params, fn.body]);
   } else {
-    return JS.FunctionDeclaration(name, fn);
+    return js_ast.FunctionDeclaration(name, fn);
   }
 }
 
 /// Returns whether [node] uses `this` or `super`.
-bool usesThisOrSuper(JS.Expression node) {
+bool usesThisOrSuper(js_ast.Expression node) {
   var finder = _ThisOrSuperFinder.instance;
   finder.found = false;
   node.accept(finder);
   return finder.found;
 }
 
-class _ThisOrSuperFinder extends JS.BaseVisitor<void> {
+class _ThisOrSuperFinder extends js_ast.BaseVisitor<void> {
   bool found = false;
 
   static final instance = _ThisOrSuperFinder();
 
   @override
-  visitThis(JS.This node) {
+  visitThis(js_ast.This node) {
     found = true;
   }
 
   @override
-  visitSuper(JS.Super node) {
+  visitSuper(js_ast.Super node) {
     found = true;
   }
 
   @override
-  visitNode(JS.Node node) {
+  visitNode(js_ast.Node node) {
     if (!found) super.visitNode(node);
   }
 }
diff --git a/pkg/dev_compiler/lib/src/js_ast/js_ast.dart b/pkg/dev_compiler/lib/src/js_ast/js_ast.dart
index ee8289e..bf84e7a 100644
--- a/pkg/dev_compiler/lib/src/js_ast/js_ast.dart
+++ b/pkg/dev_compiler/lib/src/js_ast/js_ast.dart
@@ -5,6 +5,7 @@
 library js_ast;
 
 import 'precedence.dart';
+// ignore: library_prefixes
 import 'characters.dart' as charCodes;
 
 part 'nodes.dart';
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 2e897f0..ca85c12 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -18,11 +18,11 @@
 import 'package:path/path.dart' as path;
 import 'package:source_maps/source_maps.dart' show SourceMapBuilder;
 
-import '../compiler/js_names.dart' as JS;
+import '../compiler/js_names.dart' as js_ast;
 import '../compiler/module_builder.dart';
 import '../compiler/shared_command.dart';
 import '../compiler/shared_compiler.dart';
-import '../js_ast/js_ast.dart' as JS;
+import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 import '../js_ast/source_map_printer.dart' show SourceMapPrintingContext;
 
@@ -386,7 +386,7 @@
   JSCode(this.code, this.sourceMap);
 }
 
-JSCode jsProgramToCode(JS.Program moduleTree, ModuleFormat format,
+JSCode jsProgramToCode(js_ast.Program moduleTree, ModuleFormat format,
     {bool buildSourceMap = false,
     bool inlineSourceMap = false,
     String jsUrl,
@@ -394,20 +394,21 @@
     Map<String, String> bazelMapping,
     String customScheme,
     String multiRootOutputPath}) {
-  var opts = JS.JavaScriptPrintingOptions(
+  var opts = js_ast.JavaScriptPrintingOptions(
       allowKeywordsInProperties: true, allowSingleLineIfStatements: true);
-  JS.SimpleJavaScriptPrintingContext printer;
+  js_ast.SimpleJavaScriptPrintingContext printer;
   SourceMapBuilder sourceMap;
   if (buildSourceMap) {
     var sourceMapContext = SourceMapPrintingContext();
     sourceMap = sourceMapContext.sourceMap;
     printer = sourceMapContext;
   } else {
-    printer = JS.SimpleJavaScriptPrintingContext();
+    printer = js_ast.SimpleJavaScriptPrintingContext();
   }
 
   var tree = transformModuleFormat(format, moduleTree);
-  tree.accept(JS.Printer(opts, printer, localNamer: JS.TemporaryNamer(tree)));
+  tree.accept(
+      js_ast.Printer(opts, printer, localNamer: js_ast.TemporaryNamer(tree)));
 
   Map builtMap;
   if (buildSourceMap && sourceMap != null) {
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 531ca40..5351443 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -15,12 +15,12 @@
 import 'package:kernel/type_environment.dart';
 import 'package:source_span/source_span.dart' show SourceLocation;
 
-import '../compiler/js_names.dart' as JS;
-import '../compiler/js_utils.dart' as JS;
+import '../compiler/js_names.dart' as js_ast;
+import '../compiler/js_utils.dart' as js_ast;
 import '../compiler/module_builder.dart' show pathToJSIdentifier;
 import '../compiler/shared_command.dart' show SharedCompilerOptions;
 import '../compiler/shared_compiler.dart';
-import '../js_ast/js_ast.dart' as JS;
+import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
 import '../js_ast/source_map_printer.dart' show NodeEnd, NodeSpan, HoverComment;
 import 'constants.dart';
@@ -35,10 +35,10 @@
 class ProgramCompiler extends Object
     with SharedCompiler<Library, Class, InterfaceType, FunctionNode>
     implements
-        StatementVisitor<JS.Statement>,
-        ExpressionVisitor<JS.Expression>,
-        DartTypeVisitor<JS.Expression>,
-        ConstantVisitor<JS.Expression> {
+        StatementVisitor<js_ast.Statement>,
+        ExpressionVisitor<js_ast.Expression>,
+        DartTypeVisitor<js_ast.Expression>,
+        ConstantVisitor<js_ast.Expression> {
   final SharedCompilerOptions options;
 
   /// Maps a library URI import, that is not in [_libraries], to the
@@ -52,15 +52,15 @@
   VariableDeclaration _rethrowParameter;
 
   /// In an async* function, this represents the stream controller parameter.
-  JS.TemporaryId _asyncStarController;
+  js_ast.TemporaryId _asyncStarController;
 
   Set<Class> _pendingClasses;
 
   /// Temporary variables mapped to their corresponding JavaScript variable.
-  final _tempVariables = <VariableDeclaration, JS.TemporaryId>{};
+  final _tempVariables = <VariableDeclaration, js_ast.TemporaryId>{};
 
   /// Let variables collected for the given function.
-  List<JS.TemporaryId> _letVariables;
+  List<js_ast.TemporaryId> _letVariables;
 
   /// The class that is emitting its base class or mixin references, otherwise
   /// null.
@@ -116,7 +116,7 @@
 
   bool _superAllowed = true;
 
-  final _superHelpers = Map<String, JS.Method>();
+  final _superHelpers = Map<String, js_ast.Method>();
 
   // Compilation of Kernel's [BreakStatement].
   //
@@ -257,7 +257,7 @@
 
   bool get emitMetadata => options.emitMetadata;
 
-  JS.Program emitModule(Component component, List<Component> summaries,
+  js_ast.Program emitModule(Component component, List<Component> summaries,
       List<Uri> summaryUris, Map<Uri, String> moduleImportForSummary) {
     if (moduleItems.isNotEmpty) {
       throw StateError('Can only call emitModule once.');
@@ -354,7 +354,7 @@
   String libraryToModule(Library library) {
     if (library.importUri.scheme == 'dart') {
       // TODO(jmesserly): we need to split out HTML.
-      return JS.dartSdkModule;
+      return js_ast.dartSdkModule;
     }
     var summary = _importToSummary[library];
     var moduleName = _summaryToModule[summary];
@@ -466,7 +466,7 @@
     if (c != null && _emittingClassExtends) _emitClass(c);
   }
 
-  JS.Statement _emitClassDeclaration(Class c) {
+  js_ast.Statement _emitClassDeclaration(Class c) {
     // Mixins are unrolled in _defineClass.
     if (c.isAnonymousMixin) return null;
 
@@ -481,8 +481,8 @@
     // https://github.com/dart-lang/sdk/issues/31003
     var className = c.typeParameters.isNotEmpty
         ? (c == _jsArrayClass
-            ? JS.Identifier(c.name)
-            : JS.TemporaryId(getLocalClassName(c)))
+            ? js_ast.Identifier(c.name)
+            : js_ast.TemporaryId(getLocalClassName(c)))
         : _emitTopLevelName(c);
 
     var savedClassProperties = _classProperties;
@@ -492,9 +492,9 @@
     var jsCtors = _defineConstructors(c, className);
     var jsMethods = _emitClassMethods(c);
 
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     _emitSuperHelperSymbols(body);
-    var deferredSupertypes = <JS.Statement>[];
+    var deferredSupertypes = <js_ast.Statement>[];
 
     // Emit the class, e.g. `core.Object = class Object { ... }`
     _defineClass(c, className, jsMethods, body, deferredSupertypes);
@@ -518,7 +518,7 @@
     }
     _emitClassMetadata(c.annotations, className, body);
 
-    var classDef = JS.Statement.from(body);
+    var classDef = js_ast.Statement.from(body);
     var typeFormals = c.typeParameters;
     if (typeFormals.isNotEmpty) {
       classDef = _defineClassTypeArguments(
@@ -535,13 +535,13 @@
     }
 
     _classProperties = savedClassProperties;
-    return JS.Statement.from(body);
+    return js_ast.Statement.from(body);
   }
 
   /// Wraps a possibly generic class in its type arguments.
-  JS.Statement _defineClassTypeArguments(
-      NamedNode c, List<TypeParameter> formals, JS.Statement body,
-      [JS.Expression className, List<JS.Statement> deferredBaseClass]) {
+  js_ast.Statement _defineClassTypeArguments(
+      NamedNode c, List<TypeParameter> formals, js_ast.Statement body,
+      [js_ast.Expression className, List<js_ast.Statement> deferredBaseClass]) {
     assert(formals.isNotEmpty);
     var name = getTopLevelName(c);
     var jsFormals = _emitTypeFormals(formals);
@@ -549,7 +549,7 @@
       jsFormals,
       _typeTable.discharge(formals),
       body,
-      className ?? JS.Identifier(name)
+      className ?? js_ast.Identifier(name)
     ]);
 
     var genericArgs = [
@@ -565,14 +565,15 @@
         [genericName, genericCall, _emitTopLevelName(c), genericName]);
   }
 
-  JS.Statement _emitClassStatement(Class c, JS.Expression className,
-      JS.Expression heritage, List<JS.Method> methods) {
+  js_ast.Statement _emitClassStatement(Class c, js_ast.Expression className,
+      js_ast.Expression heritage, List<js_ast.Method> methods) {
     if (c.typeParameters.isNotEmpty) {
-      return JS.ClassExpression(className as JS.Identifier, heritage, methods)
+      return js_ast.ClassExpression(
+              className as js_ast.Identifier, heritage, methods)
           .toStatement();
     }
-    var classExpr = JS.ClassExpression(
-        JS.TemporaryId(getLocalClassName(c)), heritage, methods);
+    var classExpr = js_ast.ClassExpression(
+        js_ast.TemporaryId(getLocalClassName(c)), heritage, methods);
     return js.statement('# = #;', [className, classExpr]);
   }
 
@@ -605,46 +606,50 @@
   /// minimal compiler and runtime changes.
   void _emitMixinStatement(
       Class c,
-      JS.Expression className,
-      JS.Expression heritage,
-      List<JS.Method> methods,
-      List<JS.Statement> body) {
+      js_ast.Expression className,
+      js_ast.Expression heritage,
+      List<js_ast.Method> methods,
+      List<js_ast.Statement> body) {
     var staticMethods = methods.where((m) => m.isStatic).toList();
     var instanceMethods = methods.where((m) => !m.isStatic).toList();
 
     body.add(_emitClassStatement(c, className, heritage, staticMethods));
-    var superclassId = JS.TemporaryId(getLocalClassName(c.superclass));
-    var classId = className is JS.Identifier
+    var superclassId = js_ast.TemporaryId(getLocalClassName(c.superclass));
+    var classId = className is js_ast.Identifier
         ? className
-        : JS.TemporaryId(getLocalClassName(c));
+        : js_ast.TemporaryId(getLocalClassName(c));
 
     var mixinMemberClass =
-        JS.ClassExpression(classId, superclassId, instanceMethods);
+        js_ast.ClassExpression(classId, superclassId, instanceMethods);
 
-    JS.Node arrowFnBody = mixinMemberClass;
-    var extensionInit = <JS.Statement>[];
+    js_ast.Node arrowFnBody = mixinMemberClass;
+    var extensionInit = <js_ast.Statement>[];
     _defineExtensionMembers(classId, extensionInit);
     if (extensionInit.isNotEmpty) {
       extensionInit.insert(0, mixinMemberClass.toStatement());
       extensionInit.add(classId.toReturn());
-      arrowFnBody = JS.Block(extensionInit);
+      arrowFnBody = js_ast.Block(extensionInit);
     }
 
     body.add(js.statement('#[#.mixinOn] = #', [
       className,
       runtimeModule,
-      JS.ArrowFun([superclassId], arrowFnBody)
+      js_ast.ArrowFun([superclassId], arrowFnBody)
     ]));
   }
 
-  void _defineClass(Class c, JS.Expression className, List<JS.Method> methods,
-      List<JS.Statement> body, List<JS.Statement> deferredSupertypes) {
+  void _defineClass(
+      Class c,
+      js_ast.Expression className,
+      List<js_ast.Method> methods,
+      List<js_ast.Statement> body,
+      List<js_ast.Statement> deferredSupertypes) {
     if (c == coreTypes.objectClass) {
       body.add(_emitClassStatement(c, className, null, methods));
       return;
     }
 
-    JS.Expression emitDeferredType(DartType t) {
+    js_ast.Expression emitDeferredType(DartType t) {
       if (t is InterfaceType && t.typeArguments.isNotEmpty) {
         _declareBeforeUse(t.classNode);
         return _emitGenericClassType(t, t.typeArguments.map(emitDeferredType));
@@ -709,8 +714,9 @@
 
     var hasUnnamedSuper = _hasUnnamedInheritedConstructor(superclass);
 
-    void emitMixinConstructors(JS.Expression className, InterfaceType mixin) {
-      JS.Statement mixinCtor;
+    void emitMixinConstructors(
+        js_ast.Expression className, InterfaceType mixin) {
+      js_ast.Statement mixinCtor;
       if (_hasUnnamedConstructor(mixin.classNode)) {
         mixinCtor = js.statement('#.#.call(this);', [
           emitClassRef(mixin),
@@ -732,7 +738,7 @@
             _emitSuperConstructorCall(className, name, jsParams),
         ];
         body.add(_addConstructorToClass(
-            c, className, name, JS.Fun(jsParams, JS.Block(ctorBody))));
+            c, className, name, js_ast.Fun(jsParams, js_ast.Block(ctorBody))));
       }
     }
 
@@ -775,8 +781,8 @@
         //     applyMixin(C, class C$ extends M { <methods>  });
         mixinBody.add(runtimeStatement('applyMixin(#, #)', [
           classExpr,
-          JS.ClassExpression(
-              JS.TemporaryId(getLocalClassName(c)), mixinClass, methods)
+          js_ast.ClassExpression(
+              js_ast.TemporaryId(getLocalClassName(c)), mixinClass, methods)
         ]));
       }
 
@@ -794,14 +800,14 @@
       var m = mixins[i];
       var mixinName =
           getLocalClassName(superclass) + '_' + getLocalClassName(m.classNode);
-      var mixinId = JS.TemporaryId(mixinName + '\$');
+      var mixinId = js_ast.TemporaryId(mixinName + '\$');
       // Bind the mixin class to a name to workaround a V8 bug with es6 classes
       // and anonymous function names.
       // TODO(leafp:) Eliminate this once the bug is fixed:
       // https://bugs.chromium.org/p/v8/issues/detail?id=7069
       body.add(js.statement("const # = #", [
         mixinId,
-        JS.ClassExpression(JS.TemporaryId(mixinName), baseClass, [])
+        js_ast.ClassExpression(js_ast.TemporaryId(mixinName), baseClass, [])
       ]));
 
       emitMixinConstructors(mixinId, m);
@@ -828,14 +834,15 @@
   }
 
   /// Defines all constructors for this class as ES5 constructors.
-  List<JS.Statement> _defineConstructors(Class c, JS.Expression className) {
-    var body = <JS.Statement>[];
+  List<js_ast.Statement> _defineConstructors(
+      Class c, js_ast.Expression className) {
+    var body = <js_ast.Statement>[];
     if (c.isAnonymousMixin || isMixinAliasClass(c)) {
       // We already handled this when we defined the class.
       return body;
     }
 
-    addConstructor(String name, JS.Expression jsCtor) {
+    addConstructor(String name, js_ast.Expression jsCtor) {
       body.add(_addConstructorToClass(c, className, name, jsCtor));
     }
 
@@ -861,9 +868,9 @@
     return body;
   }
 
-  JS.Statement _emitClassTypeTests(
-      Class c, JS.Expression className, List<JS.Statement> body) {
-    JS.Expression getInterfaceSymbol(Class interface) {
+  js_ast.Statement _emitClassTypeTests(
+      Class c, js_ast.Expression className, List<js_ast.Statement> body) {
+    js_ast.Expression getInterfaceSymbol(Class interface) {
       var library = interface.enclosingLibrary;
       if (library == coreTypes.coreLibrary ||
           library == coreTypes.asyncLibrary) {
@@ -880,7 +887,7 @@
       return null;
     }
 
-    void markSubtypeOf(JS.Expression testSymbol) {
+    void markSubtypeOf(js_ast.Expression testSymbol) {
       body.add(js.statement('#.prototype[#] = true', [className, testSymbol]));
     }
 
@@ -1054,7 +1061,7 @@
     if (isClassSymbol == null) {
       // TODO(jmesserly): we could export these symbols, if we want to mark
       // implemented interfaces for user-defined classes.
-      var id = JS.TemporaryId("_is_${getLocalClassName(c)}_default");
+      var id = js_ast.TemporaryId("_is_${getLocalClassName(c)}_default");
       moduleItems.add(
           js.statement('const # = Symbol(#);', [id, js.string(id.name, "'")]));
       isClassSymbol = id;
@@ -1073,21 +1080,21 @@
   }
 
   void _emitDartSymbols(
-      Iterable<JS.TemporaryId> vars, List<JS.ModuleItem> body) {
+      Iterable<js_ast.TemporaryId> 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.Statement> body) {
+  void _emitSuperHelperSymbols(List<js_ast.Statement> body) {
     _emitDartSymbols(
-        _superHelpers.values.map((m) => m.name as JS.TemporaryId), body);
+        _superHelpers.values.map((m) => m.name as js_ast.TemporaryId), body);
     _superHelpers.clear();
   }
 
   /// Emits static fields for a class, and initialize them eagerly if possible,
   /// otherwise define them as lazy properties.
-  void _emitStaticFields(Class c, List<JS.Statement> body) {
+  void _emitStaticFields(Class c, List<js_ast.Statement> body) {
     var fields = c.fields
         .where((f) => f.isStatic && getRedirectingFactories(f) == null)
         .toList();
@@ -1113,15 +1120,15 @@
     }
   }
 
-  void _emitClassMetadata(List<Expression> metadata, JS.Expression className,
-      List<JS.Statement> body) {
+  void _emitClassMetadata(List<Expression> metadata,
+      js_ast.Expression className, List<js_ast.Statement> body) {
     // Metadata
     if (emitMetadata && metadata.isNotEmpty) {
       body.add(js.statement('#[#.metadata] = #;', [
         className,
         runtimeModule,
-        _arrowFunctionWithLetScope(() =>
-            JS.ArrayInitializer(metadata.map(_instantiateAnnotation).toList()))
+        _arrowFunctionWithLetScope(() => js_ast.ArrayInitializer(
+            metadata.map(_instantiateAnnotation).toList()))
       ]));
     }
   }
@@ -1140,18 +1147,18 @@
   /// If a concrete class implements one of our extensions, we might need to
   /// add forwarders.
   void _defineExtensionMembers(
-      JS.Expression className, List<JS.Statement> body) {
+      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.memberNameForDartMember(e)))
+          .map((e) => propertyName(js_ast.memberNameForDartMember(e)))
           .toList();
       body.add(js.statement('#.#(#, #);', [
         runtimeModule,
         helperName,
         className,
-        JS.ArrayInitializer(names, multiline: names.length > 4)
+        js_ast.ArrayInitializer(names, multiline: names.length > 4)
       ]));
     }
 
@@ -1162,7 +1169,7 @@
 
   /// Emit the signature on the class recording the runtime type information
   void _emitClassSignature(
-      Class c, JS.Expression className, List<JS.Statement> body) {
+      Class c, js_ast.Expression className, List<js_ast.Statement> body) {
     var savedClass = _classEmittingSignatures;
     _classEmittingSignatures = c;
 
@@ -1176,30 +1183,30 @@
       ]));
     }
 
-    void emitSignature(String name, List<JS.Property> elements) {
+    void emitSignature(String name, List<js_ast.Property> elements) {
       if (elements.isEmpty) return;
 
       if (!name.startsWith('Static')) {
         var proto = c == coreTypes.objectClass
             ? js.call('Object.create(null)')
             : runtimeCall('get${name}s(#.__proto__)', [className]);
-        elements.insert(0, JS.Property(propertyName('__proto__'), proto));
+        elements.insert(0, js_ast.Property(propertyName('__proto__'), proto));
       }
       body.add(runtimeStatement('set${name}Signature(#, () => #)', [
         className,
-        JS.ObjectInitializer(elements, multiline: elements.length > 1)
+        js_ast.ObjectInitializer(elements, multiline: elements.length > 1)
       ]));
     }
 
     var extMethods = _classProperties.extensionMethods;
     var extAccessors = _classProperties.extensionAccessors;
-    var staticMethods = <JS.Property>[];
-    var instanceMethods = <JS.Property>[];
-    var staticGetters = <JS.Property>[];
-    var instanceGetters = <JS.Property>[];
-    var staticSetters = <JS.Property>[];
-    var instanceSetters = <JS.Property>[];
-    List<JS.Property> getSignatureList(Procedure p) {
+    var staticMethods = <js_ast.Property>[];
+    var instanceMethods = <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) {
       if (p.isStatic) {
         if (p.isGetter) {
           return staticGetters;
@@ -1242,7 +1249,7 @@
           reifiedType != _getMemberRuntimeType(memberOverride, c);
 
       if (needsSignature) {
-        JS.Expression type;
+        js_ast.Expression type;
         if (member.isAccessor) {
           type = _emitAnnotatedResult(
               _emitType(member.isGetter
@@ -1253,12 +1260,12 @@
         } else {
           type = _emitAnnotatedFunctionType(reifiedType, member);
         }
-        var property = JS.Property(_declareMemberName(member), type);
+        var property = js_ast.Property(_declareMemberName(member), type);
         var signatures = getSignatureList(member);
         signatures.add(property);
         if (!member.isStatic &&
             (extMethods.contains(name) || extAccessors.contains(name))) {
-          signatures.add(JS.Property(
+          signatures.add(js_ast.Property(
               _declareMemberName(member, useExtension: true), type));
         }
       }
@@ -1275,8 +1282,8 @@
       js.escapedString(jsLibraryDebuggerName(c.enclosingLibrary))
     ]));
 
-    var instanceFields = <JS.Property>[];
-    var staticFields = <JS.Property>[];
+    var instanceFields = <js_ast.Property>[];
+    var staticFields = <js_ast.Property>[];
 
     var classFields = c.fields.toList();
     for (var field in classFields) {
@@ -1287,13 +1294,13 @@
       var memberName = _declareMemberName(field);
       var fieldSig = _emitFieldSignature(field, c);
       (isStatic ? staticFields : instanceFields)
-          .add(JS.Property(memberName, fieldSig));
+          .add(js_ast.Property(memberName, fieldSig));
     }
     emitSignature('Field', instanceFields);
     emitSignature('StaticField', staticFields);
 
     if (emitMetadata) {
-      var constructors = <JS.Property>[];
+      var constructors = <js_ast.Property>[];
       var allConstructors = [
         ...c.constructors,
         ...c.procedures.where((p) => p.isFactory),
@@ -1302,7 +1309,7 @@
         var memberName = _constructorName(ctor.name.name);
         var type = _emitAnnotatedFunctionType(
             ctor.function.functionType.withoutTypeParameters, ctor);
-        constructors.add(JS.Property(memberName, type));
+        constructors.add(js_ast.Property(memberName, type));
       }
       emitSignature('Constructor', constructors);
     }
@@ -1317,14 +1324,14 @@
     _classEmittingSignatures = savedClass;
   }
 
-  JS.Expression _emitFieldSignature(Field field, Class fromClass) {
+  js_ast.Expression _emitFieldSignature(Field field, Class fromClass) {
     var type = _getTypeFromClass(field.type, field.enclosingClass, fromClass);
     var args = [_emitType(type)];
     var annotations = field.annotations;
     if (emitMetadata && annotations != null && annotations.isNotEmpty) {
       var savedUri = _currentUri;
       _currentUri = field.enclosingClass.fileUri;
-      args.add(JS.ArrayInitializer(
+      args.add(js_ast.ArrayInitializer(
           annotations.map(_instantiateAnnotation).toList()));
       _currentUri = savedUri;
     }
@@ -1367,8 +1374,8 @@
         .substituteType(type);
   }
 
-  JS.Expression _emitConstructor(
-      Constructor node, List<Field> fields, JS.Expression className) {
+  js_ast.Expression _emitConstructor(
+      Constructor node, List<Field> fields, js_ast.Expression className) {
     var savedUri = _currentUri;
     _currentUri = node.fileUri ?? savedUri;
     var params = _emitParameters(node.function);
@@ -1381,11 +1388,11 @@
     _currentUri = savedUri;
     end ??= _nodeEnd(node.enclosingClass.fileEndOffset);
 
-    return JS.Fun(params, JS.Block(body))..sourceInformation = end;
+    return js_ast.Fun(params, js_ast.Block(body))..sourceInformation = end;
   }
 
-  List<JS.Statement> _emitConstructorBody(
-      Constructor node, List<Field> fields, JS.Expression className) {
+  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
@@ -1427,7 +1434,7 @@
     return body;
   }
 
-  JS.Expression _constructorName(String name) {
+  js_ast.Expression _constructorName(String name) {
     if (name == '') {
       // Default constructors (factory or not) use `new` as their name.
       return propertyName('new');
@@ -1435,8 +1442,8 @@
     return _emitStaticMemberName(name);
   }
 
-  JS.Statement _emitRedirectingConstructor(
-      RedirectingInitializer node, JS.Expression className) {
+  js_ast.Statement _emitRedirectingConstructor(
+      RedirectingInitializer node, js_ast.Expression className) {
     var ctor = node.target;
     // We can't dispatch to the constructor with `this.new` as that might hit a
     // derived class constructor with the same name.
@@ -1447,13 +1454,13 @@
     ]);
   }
 
-  JS.Statement _emitSuperConstructorCallIfNeeded(
-      Class c, JS.Expression className,
+  js_ast.Statement _emitSuperConstructorCallIfNeeded(
+      Class c, js_ast.Expression className,
       [SuperInitializer superInit]) {
     if (c == coreTypes.objectClass) return null;
 
     Constructor ctor;
-    List<JS.Expression> args;
+    List<js_ast.Expression> args;
     if (superInit == null) {
       ctor = unnamedConstructor(c.superclass);
       args = [];
@@ -1470,8 +1477,8 @@
     return _emitSuperConstructorCall(className, ctor.name.name, args);
   }
 
-  JS.Statement _emitSuperConstructorCall(
-      JS.Expression className, String name, List<JS.Expression> args) {
+  js_ast.Statement _emitSuperConstructorCall(
+      js_ast.Expression className, String name, List<js_ast.Expression> args) {
     return js.statement('#.__proto__.#.call(this, #);',
         [className, _constructorName(name), args ?? []]);
   }
@@ -1499,7 +1506,7 @@
   ///   2. field initializing parameters,
   ///   3. constructor field initializers,
   ///   4. initialize fields not covered in 1-3
-  JS.Statement _initializeFields(List<Field> fields, [Constructor ctor]) {
+  js_ast.Statement _initializeFields(List<Field> fields, [Constructor ctor]) {
     // Run field initializers if they can have side-effects.
     Set<Field> ctorFields;
     if (ctor != null) {
@@ -1509,7 +1516,7 @@
             ..remove(null);
     }
 
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     emitFieldInit(Field f, Expression initializer, TreeNode hoverInfo) {
       var access = _classProperties.virtualFields[f] ?? _declareMemberName(f);
       var jsInit = _visitInitializer(initializer, f.annotations);
@@ -1543,20 +1550,20 @@
       }
     }
 
-    return JS.Statement.from(body);
+    return js_ast.Statement.from(body);
   }
 
-  JS.Expression _visitInitializer(
+  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.LiteralNull();
+    if (init == null) return js_ast.LiteralNull();
     return _annotatedNullCheck(annotations)
         ? notNull(init)
         : _visitExpression(init);
   }
 
-  JS.Expression notNull(Expression expr) {
+  js_ast.Expression notNull(Expression expr) {
     if (expr == null) return null;
     var jsExpr = _visitExpression(expr);
     if (!isNullable(expr)) return jsExpr;
@@ -1574,8 +1581,8 @@
             mixin.constructors.every((c) => c.isExternal);
   }
 
-  JS.Statement _addConstructorToClass(
-      Class c, JS.Expression className, String name, JS.Expression jsCtor) {
+  js_ast.Statement _addConstructorToClass(Class c, js_ast.Expression className,
+      String name, js_ast.Expression jsCtor) {
     jsCtor = defineValueOnClass(c, className, _constructorName(name), jsCtor);
     return js.statement('#.prototype = #.prototype;', [jsCtor, className]);
   }
@@ -1597,18 +1604,18 @@
     }
   }
 
-  List<JS.Method> _emitClassMethods(Class c) {
+  List<js_ast.Method> _emitClassMethods(Class c) {
     var virtualFields = _classProperties.virtualFields;
 
-    var jsMethods = <JS.Method>[];
+    var jsMethods = <js_ast.Method>[];
     bool hasJsPeer = _extensionTypes.isNativeClass(c);
     bool hasIterator = false;
 
     if (c == coreTypes.objectClass) {
       // Dart does not use ES6 constructors.
       // Add an error to catch any invalid usage.
-      jsMethods
-          .add(JS.Method(propertyName('constructor'), js.fun(r'''function() {
+      jsMethods.add(
+          js_ast.Method(propertyName('constructor'), js.fun(r'''function() {
                   throw Error("use `new " + #.typeName(#.getReifiedType(this)) +
                       ".new(...)` to create a Dart object");
               }''', [runtimeModule, runtimeModule])));
@@ -1619,7 +1626,7 @@
       //
       // This will become obsolete when
       // https://github.com/dart-lang/sdk/issues/31003 is addressed.
-      jsMethods.add(JS.Method(
+      jsMethods.add(js_ast.Method(
           propertyName('constructor'), js.fun(r'function() { return []; }')));
     }
 
@@ -1715,12 +1722,12 @@
   }
 
   /// Emits a method, getter, or setter.
-  JS.Method _emitMethodDeclaration(Procedure member) {
+  js_ast.Method _emitMethodDeclaration(Procedure member) {
     if (member.isAbstract) {
       return null;
     }
 
-    JS.Fun fn;
+    js_ast.Fun fn;
     if (member.isExternal && !member.isNoSuchMethodForwarder) {
       if (member.isStatic) {
         // TODO(vsm): Do we need to handle this case?
@@ -1731,27 +1738,28 @@
       fn = _emitFunction(member.function, member.name.name);
     }
 
-    return JS.Method(_declareMemberName(member), fn,
+    return js_ast.Method(_declareMemberName(member), fn,
         isGetter: member.isGetter,
         isSetter: member.isSetter,
         isStatic: member.isStatic)
       ..sourceInformation = _nodeEnd(member.fileEndOffset);
   }
 
-  JS.Fun _emitNativeFunctionBody(Procedure node) {
+  js_ast.Fun _emitNativeFunctionBody(Procedure node) {
     String name = getAnnotationName(node, isJSAnnotation) ?? node.name.name;
     if (node.isGetter) {
-      return JS.Fun([], js.block('{ return this.#; }', [name]));
+      return js_ast.Fun([], js.block('{ return this.#; }', [name]));
     } else if (node.isSetter) {
       var params = _emitParameters(node.function);
-      return JS.Fun(params, js.block('{ this.# = #; }', [name, params.last]));
+      return js_ast.Fun(
+          params, js.block('{ this.# = #; }', [name, params.last]));
     } else {
       return js.fun(
           'function (...args) { return this.#.apply(this, args); }', name);
     }
   }
 
-  List<JS.Method> _emitCovarianceCheckStub(Procedure member) {
+  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
@@ -1781,12 +1789,12 @@
       var setterType = substituteType(superMember.setterType);
       if (types.isTop(setterType)) return const [];
       return [
-        JS.Method(
+        js_ast.Method(
             name,
             js.fun('function(x) { return super.# = #; }',
-                [name, _emitCast(JS.Identifier('x'), setterType)]),
+                [name, _emitCast(js_ast.Identifier('x'), setterType)]),
             isSetter: true),
-        JS.Method(name, js.fun('function() { return super.#; }', [name]),
+        js_ast.Method(name, js.fun('function() { return super.#; }', [name]),
             isGetter: true)
       ];
     }
@@ -1796,16 +1804,16 @@
         substituteType(superMember.function.functionType) as FunctionType;
     var function = member.function;
 
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     var typeParameters = superMethodType.typeParameters;
     _emitCovarianceBoundsCheck(typeParameters, body);
 
     var typeFormals = _emitTypeFormals(typeParameters);
-    var jsParams = List<JS.Parameter>.from(typeFormals);
+    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 = JS.Identifier(param.name);
+      var jsParam = js_ast.Identifier(param.name);
       jsParams.add(jsParam);
 
       if (isCovariantParameter(param) &&
@@ -1829,7 +1837,8 @@
         body.add(js.statement('if (# in #) #;', [
           name,
           namedArgumentTemp,
-          _emitCast(JS.PropertyAccess(namedArgumentTemp, name), paramType.type)
+          _emitCast(
+              js_ast.PropertyAccess(namedArgumentTemp, name), paramType.type)
         ]));
       }
     }
@@ -1838,11 +1847,11 @@
 
     if (namedParameters.isNotEmpty) jsParams.add(namedArgumentTemp);
     body.add(js.statement('return super.#(#);', [name, jsParams]));
-    return [JS.Method(name, JS.Fun(jsParams, JS.Block(body)))];
+    return [js_ast.Method(name, js_ast.Fun(jsParams, js_ast.Block(body)))];
   }
 
   /// Emits a Dart factory constructor to a JS static method.
-  JS.Method _emitFactoryConstructor(Procedure node) {
+  js_ast.Method _emitFactoryConstructor(Procedure node) {
     if (node.isExternal || isUnsupportedFactoryConstructor(node)) return null;
 
     var function = node.function;
@@ -1858,14 +1867,14 @@
     /// [_emitFunction] instead.
     var jsBody = _emitSyncFunctionBody(function);
 
-    return JS.Method(_constructorName(node.name.name),
-        JS.Fun(_emitParameters(function), jsBody),
+    return js_ast.Method(_constructorName(node.name.name),
+        js_ast.Fun(_emitParameters(function), jsBody),
         isStatic: true)
       ..sourceInformation = _nodeEnd(node.fileEndOffset);
   }
 
   @override
-  JS.Expression emitConstructorAccess(InterfaceType type) {
+  js_ast.Expression emitConstructorAccess(InterfaceType type) {
     return _emitJSInterop(type.classNode) ?? visitInterfaceType(type);
   }
 
@@ -1876,23 +1885,24 @@
   /// 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.Method> _emitVirtualFieldAccessor(Field field) {
+  List<js_ast.Method> _emitVirtualFieldAccessor(Field field) {
     var virtualField = _classProperties.virtualFields[field];
     var name = _declareMemberName(field);
 
     var getter = js.fun('function() { return this[#]; }', [virtualField]);
-    var jsGetter = JS.Method(name, getter, isGetter: true)
+    var jsGetter = js_ast.Method(name, getter, isGetter: true)
       ..sourceInformation = _nodeStart(field);
 
-    var args = field.isFinal ? [JS.Super(), name] : [JS.This(), virtualField];
+    var args =
+        field.isFinal ? [js_ast.Super(), name] : [js_ast.This(), virtualField];
 
-    JS.Expression value = JS.Identifier('value');
+    js_ast.Expression value = js_ast.Identifier('value');
     if (!field.isFinal && isCovariantField(field)) {
       value = _emitCast(value, field.type);
     }
     args.add(value);
 
-    var jsSetter = JS.Method(
+    var jsSetter = js_ast.Method(
         name, js.fun('function(value) { #[#] = #; }', args),
         isSetter: true)
       ..sourceInformation = _nodeStart(field);
@@ -1904,25 +1914,25 @@
   /// 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.Method> _emitNativeFieldAccessors(Field field) {
+  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.Method>[];
+    var jsMethods = <js_ast.Method>[];
     assert(!field.isStatic);
 
     var name = getAnnotationName(field, isJSName) ?? field.name.name;
     // Generate getter
-    var fn = JS.Fun([], js.block('{ return this.#; }', [name]));
-    var method = JS.Method(_declareMemberName(field), fn, isGetter: true);
+    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 = JS.TemporaryId('value');
-      fn = JS.Fun([value], js.block('{ this.# = #; }', [name, value]));
-      method = JS.Method(_declareMemberName(field), fn, isSetter: true);
+      var value = js_ast.TemporaryId('value');
+      fn = js_ast.Fun([value], js.block('{ this.# = #; }', [name, value]));
+      method = js_ast.Method(_declareMemberName(field), fn, isSetter: true);
       jsMethods.add(method);
     }
 
@@ -1935,7 +1945,7 @@
   /// 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.Method _emitSuperAccessorWrapper(Procedure member,
+  js_ast.Method _emitSuperAccessorWrapper(Procedure member,
       Map<String, Procedure> getters, Map<String, Procedure> setters) {
     if (member.isAbstract) return null;
 
@@ -1946,7 +1956,7 @@
           _classProperties.inheritedSetters.contains(name)) {
         // Generate a setter that forwards to super.
         var fn = js.fun('function(value) { super[#] = value; }', [memberName]);
-        return JS.Method(memberName, fn, isSetter: true);
+        return js_ast.Method(memberName, fn, isSetter: true);
       }
     } else {
       assert(member.isSetter);
@@ -1954,7 +1964,7 @@
           _classProperties.inheritedGetters.contains(name)) {
         // Generate a getter that forwards to super.
         var fn = js.fun('function() { return super[#]; }', [memberName]);
-        return JS.Method(memberName, fn, isGetter: true);
+        return js_ast.Method(memberName, fn, isGetter: true);
       }
     }
     return null;
@@ -1968,7 +1978,7 @@
   /// 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.Method _emitIterable(Class c) {
+  js_ast.Method _emitIterable(Class c) {
     var iterable = hierarchy.getClassAsInstanceOf(c, coreTypes.iterableClass);
     if (iterable == null) return null;
 
@@ -1989,19 +1999,19 @@
 
     // Otherwise, emit the adapter method, which wraps the Dart iterator in
     // an ES6 iterator.
-    return JS.Method(
+    return js_ast.Method(
         js.call('Symbol.iterator'),
         js.call('function() { return new #.JsIterator(this.#); }', [
           runtimeModule,
           _emitMemberName('iterator', memberClass: coreTypes.iterableClass)
-        ]) as JS.Fun);
+        ]) as js_ast.Fun);
   }
 
-  JS.Expression _instantiateAnnotation(Expression node) =>
+  js_ast.Expression _instantiateAnnotation(Expression node) =>
       _visitExpression(node);
 
   void _registerExtensionType(
-      Class c, String jsPeerName, List<JS.Statement> body) {
+      Class c, String jsPeerName, List<js_ast.Statement> body) {
     var className = _emitTopLevelName(c);
     if (_typeRep.isPrimitive(c.rawType)) {
       body.add(runtimeStatement(
@@ -2041,24 +2051,27 @@
         emitLibraryName(_currentLibrary), fields, _emitTopLevelMemberName));
   }
 
-  JS.Statement _emitLazyFields(JS.Expression objExpr, Iterable<Field> fields,
-      JS.Expression Function(Field f) emitFieldName) {
-    var accessors = <JS.Method>[];
+  js_ast.Statement _emitLazyFields(
+      js_ast.Expression objExpr,
+      Iterable<Field> fields,
+      js_ast.Expression Function(Field f) emitFieldName) {
+    var accessors = <js_ast.Method>[];
     var savedUri = _currentUri;
 
     for (var field in fields) {
       _currentUri = field.fileUri;
       var access = emitFieldName(field);
-      accessors.add(
-          JS.Method(access, _emitStaticFieldInitializer(field), isGetter: true)
-            ..sourceInformation = _hoverComment(
-                JS.PropertyAccess(objExpr, access),
-                field.fileOffset,
-                field.name.name.length));
+      accessors.add(js_ast.Method(access, _emitStaticFieldInitializer(field),
+          isGetter: true)
+        ..sourceInformation = _hoverComment(
+            js_ast.PropertyAccess(objExpr, access),
+            field.fileOffset,
+            field.name.name.length));
 
       // TODO(jmesserly): currently uses a dummy setter to indicate writable.
       if (!field.isFinal && !field.isConst) {
-        accessors.add(JS.Method(access, js.call('function(_) {}') as JS.Fun,
+        accessors.add(js_ast.Method(
+            access, js.call('function(_) {}') as js_ast.Fun,
             isSetter: true));
       }
     }
@@ -2068,15 +2081,16 @@
     return runtimeStatement('defineLazy(#, { # })', [objExpr, accessors]);
   }
 
-  JS.Fun _emitStaticFieldInitializer(Field field) {
-    return JS.Fun(
+  js_ast.Fun _emitStaticFieldInitializer(Field field) {
+    return js_ast.Fun(
         [],
-        JS.Block(_withLetScope(() => [
-              JS.Return(_visitInitializer(field.initializer, field.annotations))
+        js_ast.Block(_withLetScope(() => [
+              js_ast.Return(
+                  _visitInitializer(field.initializer, field.annotations))
             ])));
   }
 
-  List<JS.Statement> _withLetScope(List<JS.Statement> visitBody()) {
+  List<js_ast.Statement> _withLetScope(List<js_ast.Statement> visitBody()) {
     var savedLetVariables = _letVariables;
     _letVariables = [];
 
@@ -2088,7 +2102,7 @@
     return body;
   }
 
-  JS.ArrowFun _arrowFunctionWithLetScope(JS.Expression visitBody()) {
+  js_ast.ArrowFun _arrowFunctionWithLetScope(js_ast.Expression visitBody()) {
     var savedLetVariables = _letVariables;
     _letVariables = [];
 
@@ -2096,11 +2110,11 @@
     var letVars = _initLetVariables();
 
     _letVariables = savedLetVariables;
-    return JS.ArrowFun(
-        [], letVars == null ? expr : JS.Block([letVars, expr.toReturn()]));
+    return js_ast.ArrowFun(
+        [], letVars == null ? expr : js_ast.Block([letVars, expr.toReturn()]));
   }
 
-  JS.PropertyAccess _emitTopLevelName(NamedNode n, {String suffix = ''}) {
+  js_ast.PropertyAccess _emitTopLevelName(NamedNode n, {String suffix = ''}) {
     return _emitJSInterop(n) ?? _emitTopLevelNameNoInterop(n, suffix: suffix);
   }
 
@@ -2108,7 +2122,7 @@
   ///
   /// Unlike call sites, we always have an element available, so we can use it
   /// directly rather than computing the relevant options for [_emitMemberName].
-  JS.Expression _declareMemberName(Member m, {bool useExtension}) {
+  js_ast.Expression _declareMemberName(Member m, {bool useExtension}) {
     return _emitMemberName(m.name.name,
         isStatic: m is Field ? m.isStatic : (m as Procedure).isStatic,
         useExtension:
@@ -2156,7 +2170,7 @@
   /// 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.Expression _emitMemberName(String name,
+  js_ast.Expression _emitMemberName(String name,
       {bool isStatic = false,
       bool useExtension,
       Member member,
@@ -2175,9 +2189,9 @@
         var parts = runtimeName.split('.');
         if (parts.length < 2) return propertyName(runtimeName);
 
-        JS.Expression result = JS.Identifier(parts[0]);
+        js_ast.Expression result = js_ast.Identifier(parts[0]);
         for (int i = 1; i < parts.length; i++) {
-          result = JS.PropertyAccess(result, propertyName(parts[i]));
+          result = js_ast.PropertyAccess(result, propertyName(parts[i]));
         }
         return result;
       }
@@ -2193,7 +2207,7 @@
     }
 
     useExtension ??= _isSymbolizedMember(memberClass, name);
-    name = JS.memberNameForDartMember(
+    name = js_ast.memberNameForDartMember(
         name, member is Procedure && member.isExternal);
     if (useExtension) {
       return getExtensionSymbolInternal(name);
@@ -2248,7 +2262,7 @@
             hierarchy.getDispatchTarget(c, Name(name), setter: true));
   }
 
-  JS.Expression _emitStaticMemberName(String name, [NamedNode member]) {
+  js_ast.Expression _emitStaticMemberName(String name, [NamedNode member]) {
     if (member != null) {
       var jsName = _emitJSInteropStaticMemberName(member);
       if (jsName != null) return jsName;
@@ -2280,7 +2294,7 @@
     return propertyName(name);
   }
 
-  JS.Expression _emitJSInteropStaticMemberName(NamedNode n) {
+  js_ast.Expression _emitJSInteropStaticMemberName(NamedNode n) {
     if (!usesJSInterop(n)) return null;
     var name = getAnnotationName(n, isPublicJSAnnotation);
     if (name != null) {
@@ -2295,9 +2309,9 @@
     return js.escapedString(name, "'");
   }
 
-  JS.PropertyAccess _emitTopLevelNameNoInterop(NamedNode n,
+  js_ast.PropertyAccess _emitTopLevelNameNoInterop(NamedNode n,
       {String suffix = ''}) {
-    return JS.PropertyAccess(emitLibraryName(getLibrary(n)),
+    return js_ast.PropertyAccess(emitLibraryName(getLibrary(n)),
         _emitTopLevelMemberName(n, suffix: suffix));
   }
 
@@ -2305,7 +2319,7 @@
   ///
   /// NOTE: usually you should use [_emitTopLevelName] instead of this. This
   /// function does not handle JS interop.
-  JS.Expression _emitTopLevelMemberName(NamedNode n, {String suffix = ''}) {
+  js_ast.Expression _emitTopLevelMemberName(NamedNode n, {String suffix = ''}) {
     var name = getJSExportName(n) ?? getTopLevelName(n);
     return propertyName(name + suffix);
   }
@@ -2318,18 +2332,18 @@
     return libraryJSName != null ? '$libraryJSName.$jsName' : jsName;
   }
 
-  JS.PropertyAccess _emitJSInterop(NamedNode n) {
+  js_ast.PropertyAccess _emitJSInterop(NamedNode n) {
     var jsName = _getJSNameWithoutGlobal(n);
     if (jsName == null) return null;
     return _emitJSInteropForGlobal(jsName);
   }
 
-  JS.PropertyAccess _emitJSInteropForGlobal(String name) {
+  js_ast.PropertyAccess _emitJSInteropForGlobal(String name) {
     var parts = name.split('.');
     if (parts.isEmpty) parts = [''];
-    JS.PropertyAccess access;
+    js_ast.PropertyAccess access;
     for (var part in parts) {
-      access = JS.PropertyAccess(
+      access = js_ast.PropertyAccess(
           access ?? runtimeCall('global'), js.escapedString(part, "'"));
     }
     return access;
@@ -2354,12 +2368,12 @@
     ]));
   }
 
-  JS.Method _emitLibraryAccessor(Procedure node) {
+  js_ast.Method _emitLibraryAccessor(Procedure node) {
     var savedUri = _currentUri;
     _currentUri = node.fileUri;
 
     var name = node.name.name;
-    var result = JS.Method(
+    var result = js_ast.Method(
         propertyName(name), _emitFunction(node.function, node.name.name),
         isGetter: node.isGetter, isSetter: node.isSetter)
       ..sourceInformation = _nodeEnd(node.fileEndOffset);
@@ -2368,17 +2382,17 @@
     return result;
   }
 
-  JS.Statement _emitLibraryFunction(Procedure p) {
+  js_ast.Statement _emitLibraryFunction(Procedure p) {
     var savedUri = _currentUri;
     _currentUri = p.fileUri;
 
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     var fn = _emitFunction(p.function, p.name.name)
       ..sourceInformation = _nodeEnd(p.fileEndOffset);
 
     if (_currentLibrary.importUri.scheme == 'dart' &&
         _isInlineJSFunction(p.function.body)) {
-      fn = JS.simplifyPassThroughArrowFunCallBody(fn);
+      fn = js_ast.simplifyPassThroughArrowFunCallBody(fn);
     }
 
     var nameExpr = _emitTopLevelName(p);
@@ -2394,10 +2408,10 @@
     }
 
     _currentUri = savedUri;
-    return JS.Statement.from(body);
+    return js_ast.Statement.from(body);
   }
 
-  JS.Expression _emitFunctionTagged(JS.Expression fn, FunctionType type,
+  js_ast.Expression _emitFunctionTagged(js_ast.Expression fn, FunctionType type,
       {bool topLevel = false}) {
     var lazy = topLevel && !_canEmitTypeAtTopLevel(type);
     var typeRep = visitFunctionType(type, lazy: lazy);
@@ -2436,31 +2450,33 @@
   }
 
   /// Emits a Dart [type] into code.
-  JS.Expression _emitType(DartType type) => type.accept(this) as JS.Expression;
+  js_ast.Expression _emitType(DartType type) =>
+      type.accept(this) as js_ast.Expression;
 
-  JS.Expression _emitInvalidNode(Node node, [String message = '']) {
+  js_ast.Expression _emitInvalidNode(Node node, [String message = '']) {
     if (message.isNotEmpty) message += ' ';
     return runtimeCall('throwUnimplementedError(#)',
         [js.escapedString('node <${node.runtimeType}> $message`$node`')]);
   }
 
   @override
-  JS.Expression defaultDartType(DartType type) => _emitInvalidNode(type);
+  js_ast.Expression defaultDartType(DartType type) => _emitInvalidNode(type);
 
   @override
-  JS.Expression visitInvalidType(InvalidType type) => defaultDartType(type);
+  js_ast.Expression visitInvalidType(InvalidType type) => defaultDartType(type);
 
   @override
-  JS.Expression visitDynamicType(DynamicType type) => runtimeCall('dynamic');
+  js_ast.Expression visitDynamicType(DynamicType type) =>
+      runtimeCall('dynamic');
 
   @override
-  JS.Expression visitVoidType(VoidType type) => runtimeCall('void');
+  js_ast.Expression visitVoidType(VoidType type) => runtimeCall('void');
 
   @override
-  JS.Expression visitBottomType(BottomType type) => runtimeCall('bottom');
+  js_ast.Expression visitBottomType(BottomType type) => runtimeCall('bottom');
 
   @override
-  JS.Expression visitInterfaceType(InterfaceType type) {
+  js_ast.Expression visitInterfaceType(InterfaceType type) {
     var c = type.classNode;
     _declareBeforeUse(c);
 
@@ -2488,7 +2504,7 @@
     }
 
     var args = type.typeArguments;
-    Iterable<JS.Expression> jsArgs;
+    Iterable<js_ast.Expression> jsArgs;
     if (args.any((a) => a != const DynamicType())) {
       jsArgs = args.map(_emitType);
     }
@@ -2511,14 +2527,15 @@
       !_emittingClassExtends && !_emittingClassSignatures ||
       _currentFunction != null;
 
-  JS.Expression _emitGenericClassType(
-      InterfaceType t, Iterable<JS.Expression> typeArgs) {
+  js_ast.Expression _emitGenericClassType(
+      InterfaceType t, Iterable<js_ast.Expression> typeArgs) {
     var genericName = _emitTopLevelNameNoInterop(t.classNode, suffix: '\$');
     return js.call('#(#)', [genericName, typeArgs]);
   }
 
   @override
-  JS.Expression visitFunctionType(type, {Member member, bool lazy = false}) {
+  js_ast.Expression visitFunctionType(type,
+      {Member member, bool lazy = false}) {
     var requiredTypes =
         type.positionalParameters.take(type.requiredParameterCount).toList();
     var function = member?.function;
@@ -2535,7 +2552,7 @@
     var rt = _emitType(type.returnType);
     var ra = _emitTypeNames(requiredTypes, requiredParams, member);
 
-    List<JS.Expression> typeParts;
+    List<js_ast.Expression> typeParts;
     if (namedTypes.isNotEmpty) {
       assert(optionalTypes.isEmpty);
       // TODO(vsm): Pass in annotations here as well.
@@ -2554,7 +2571,7 @@
     if (typeFormals.isNotEmpty) {
       var tf = _emitTypeFormals(typeFormals);
 
-      addTypeFormalsAsParameters(List<JS.Expression> elements) {
+      addTypeFormalsAsParameters(List<js_ast.Expression> elements) {
         var names = _typeTable.discharge(typeFormals);
         return names.isEmpty
             ? js.call('(#) => [#]', [tf, elements])
@@ -2606,7 +2623,8 @@
         : typeRep;
   }
 
-  JS.Expression _emitAnnotatedFunctionType(FunctionType type, Member member) {
+  js_ast.Expression _emitAnnotatedFunctionType(
+      FunctionType type, Member member) {
     var result = visitFunctionType(type, member: member);
 
     var annotations = member.annotations;
@@ -2614,7 +2632,7 @@
       // TODO(jmesserly): should we disable source info for annotations?
       var savedUri = _currentUri;
       _currentUri = member.enclosingClass.fileUri;
-      result = JS.ArrayInitializer(
+      result = js_ast.ArrayInitializer(
           [result]..addAll(annotations.map(_instantiateAnnotation)));
       _currentUri = savedUri;
     }
@@ -2622,46 +2640,46 @@
   }
 
   /// Emits an expression that lets you access statics on a [type] from code.
-  JS.Expression _emitConstructorAccess(InterfaceType type) {
+  js_ast.Expression _emitConstructorAccess(InterfaceType type) {
     return _emitJSInterop(type.classNode) ?? _emitType(type);
   }
 
-  JS.Expression _emitConstructorName(InterfaceType type, Member c) {
+  js_ast.Expression _emitConstructorName(InterfaceType type, Member c) {
     return _emitJSInterop(type.classNode) ??
-        JS.PropertyAccess(
+        js_ast.PropertyAccess(
             _emitConstructorAccess(type), _constructorName(c.name.name));
   }
 
   /// Emits an expression that lets you access statics on an [c] from code.
-  JS.Expression _emitStaticClassName(Class c) {
+  js_ast.Expression _emitStaticClassName(Class c) {
     _declareBeforeUse(c);
     return _emitTopLevelName(c);
   }
 
   // Wrap a result - usually a type - with its metadata.  The runtime is
   // responsible for unpacking this.
-  JS.Expression _emitAnnotatedResult(
-      JS.Expression result, List<Expression> metadata, Member member) {
+  js_ast.Expression _emitAnnotatedResult(
+      js_ast.Expression result, List<Expression> metadata, Member member) {
     if (emitMetadata && metadata.isNotEmpty) {
       // TODO(jmesserly): should we disable source info for annotations?
       var savedUri = _currentUri;
       _currentUri = member.enclosingClass.fileUri;
-      result = JS.ArrayInitializer(
+      result = js_ast.ArrayInitializer(
           [result]..addAll(metadata.map(_instantiateAnnotation)));
       _currentUri = savedUri;
     }
     return result;
   }
 
-  JS.ObjectInitializer _emitTypeProperties(Iterable<NamedType> types) {
-    return JS.ObjectInitializer(types
-        .map((t) => JS.Property(propertyName(t.name), _emitType(t.type)))
+  js_ast.ObjectInitializer _emitTypeProperties(Iterable<NamedType> types) {
+    return js_ast.ObjectInitializer(types
+        .map((t) => js_ast.Property(propertyName(t.name), _emitType(t.type)))
         .toList());
   }
 
-  JS.ArrayInitializer _emitTypeNames(List<DartType> types,
+  js_ast.ArrayInitializer _emitTypeNames(List<DartType> types,
       List<VariableDeclaration> parameters, Member member) {
-    var result = <JS.Expression>[];
+    var result = <js_ast.Expression>[];
     for (int i = 0; i < types.length; ++i) {
       var type = _emitType(types[i]);
       if (parameters != null) {
@@ -2669,21 +2687,21 @@
       }
       result.add(type);
     }
-    return JS.ArrayInitializer(result);
+    return js_ast.ArrayInitializer(result);
   }
 
   @override
-  JS.Expression visitTypeParameterType(TypeParameterType type) =>
+  js_ast.Expression visitTypeParameterType(TypeParameterType type) =>
       _emitTypeParameter(type.parameter);
 
-  JS.Identifier _emitTypeParameter(TypeParameter t) =>
-      JS.Identifier(getTypeParameterName(t));
+  js_ast.Identifier _emitTypeParameter(TypeParameter t) =>
+      js_ast.Identifier(getTypeParameterName(t));
 
   @override
-  JS.Expression visitTypedefType(TypedefType type) =>
+  js_ast.Expression visitTypedefType(TypedefType type) =>
       visitFunctionType(type.unalias as FunctionType);
 
-  JS.Fun _emitFunction(FunctionNode f, String name) {
+  js_ast.Fun _emitFunction(FunctionNode f, String name) {
     // normal function (sync), vs (sync*, async, async*)
     var isSync = f.asyncMarker == AsyncMarker.Sync;
     var formals = _emitParameters(f);
@@ -2698,26 +2716,26 @@
     // potentially mutated in Kernel. For now we assume all parameters are.
     super.enterFunction(name, formals, () => true);
 
-    JS.Block block =
+    js_ast.Block block =
         isSync ? _emitSyncFunctionBody(f) : _emitGeneratorFunctionBody(f, name);
 
     block = super.exitFunction(name, formals, block);
-    return JS.Fun(formals, block);
+    return js_ast.Fun(formals, block);
   }
 
-  List<JS.Parameter> _emitParameters(FunctionNode f) {
+  List<js_ast.Parameter> _emitParameters(FunctionNode f) {
     var positional = f.positionalParameters;
-    var result = List<JS.Parameter>.of(positional.map(_emitVariableDef));
+    var result = List<js_ast.Parameter>.of(positional.map(_emitVariableDef));
     if (positional.isNotEmpty &&
         f.requiredParameterCount == positional.length &&
         positional.last.annotations.any(isJsRestAnnotation)) {
-      result.last = JS.RestParameter(result.last as JS.Identifier);
+      result.last = js_ast.RestParameter(result.last as js_ast.Identifier);
     }
     if (f.namedParameters.isNotEmpty) result.add(namedArgumentTemp);
     return result;
   }
 
-  void _emitVirtualFieldSymbols(Class c, List<JS.Statement> body) {
+  void _emitVirtualFieldSymbols(Class c, List<js_ast.Statement> body) {
     _classProperties.virtualFields.forEach((field, virtualField) {
       body.add(js.statement('const # = Symbol(#);', [
         virtualField,
@@ -2726,9 +2744,9 @@
     });
   }
 
-  List<JS.Identifier> _emitTypeFormals(List<TypeParameter> typeFormals) {
+  List<js_ast.Identifier> _emitTypeFormals(List<TypeParameter> typeFormals) {
     return typeFormals
-        .map((t) => JS.Identifier(getTypeParameterName(t)))
+        .map((t) => js_ast.Identifier(getTypeParameterName(t)))
         .toList();
   }
 
@@ -2737,29 +2755,31 @@
   ///
   /// This is an internal part of [_emitGeneratorFunctionBody] and should not be
   /// called directly.
-  JS.Expression _emitGeneratorFunctionExpression(
+  js_ast.Expression _emitGeneratorFunctionExpression(
       FunctionNode function, String name) {
-    emitGeneratorFn(List<JS.Parameter> getParameters(JS.Block jsBody)) {
+    emitGeneratorFn(List<js_ast.Parameter> getParameters(js_ast.Block jsBody)) {
       var savedController = _asyncStarController;
       _asyncStarController = function.asyncMarker == AsyncMarker.AsyncStar
-          ? JS.TemporaryId('stream')
+          ? js_ast.TemporaryId('stream')
           : null;
 
-      JS.Expression gen;
+      js_ast.Expression gen;
       _superDisallowed(() {
         // Visit the body with our async* controller set.
         //
         // Note: we intentionally don't emit argument initializers here, because
         // they were already emitted outside of the generator expression.
-        var jsBody = JS.Block(_withCurrentFunction(
+        var jsBody = js_ast.Block(_withCurrentFunction(
             function, () => [_emitFunctionScopedBody(function)]));
-        var genFn = JS.Fun(getParameters(jsBody), jsBody, isGenerator: true);
+        var genFn =
+            js_ast.Fun(getParameters(jsBody), jsBody, isGenerator: true);
 
         // Name the function if possible, to get better stack traces.
         gen = genFn;
         if (name != null) {
-          gen = JS.NamedFunction(
-              JS.TemporaryId(JS.friendlyNameForDartOperator[name] ?? name),
+          gen = js_ast.NamedFunction(
+              js_ast.TemporaryId(
+                  js_ast.friendlyNameForDartOperator[name] ?? name),
               genFn);
         }
 
@@ -2792,7 +2812,7 @@
       var jsParams = _emitParameters(function);
       var mutatedParams = jsParams;
       var gen = emitGeneratorFn((fnBody) {
-        var mutatedVars = JS.findMutatedVariables(fnBody);
+        var mutatedVars = js_ast.findMutatedVariables(fnBody);
         mutatedParams = jsParams
             .where((id) => mutatedVars.contains(id.parameterName))
             .toList();
@@ -2857,7 +2877,7 @@
   ///
   /// To emit an `async`, `sync*`, or `async*` function body, use
   /// [_emitGeneratorFunctionBody] instead.
-  JS.Block _emitSyncFunctionBody(FunctionNode f) {
+  js_ast.Block _emitSyncFunctionBody(FunctionNode f) {
     assert(f.asyncMarker == AsyncMarker.Sync);
 
     var block = _withCurrentFunction(f, () {
@@ -2868,7 +2888,7 @@
       return block;
     });
 
-    return JS.Block(block);
+    return js_ast.Block(block);
   }
 
   /// Emits an `async`, `sync*`, or `async*` function body.
@@ -2882,18 +2902,18 @@
   ///
   /// To emit a `sync` function body (the default in Dart), use
   /// [_emitSyncFunctionBody] instead.
-  JS.Block _emitGeneratorFunctionBody(FunctionNode f, String name) {
+  js_ast.Block _emitGeneratorFunctionBody(FunctionNode f, String name) {
     assert(f.asyncMarker != AsyncMarker.Sync);
 
     var statements =
         _withCurrentFunction(f, () => _emitArgumentInitializers(f));
     statements.add(_emitGeneratorFunctionExpression(f, name).toReturn()
       ..sourceInformation = _nodeStart(f));
-    return JS.Block(statements);
+    return js_ast.Block(statements);
   }
 
-  List<JS.Statement> _withCurrentFunction(
-      FunctionNode fn, List<JS.Statement> action()) {
+  List<js_ast.Statement> _withCurrentFunction(
+      FunctionNode fn, List<js_ast.Statement> action()) {
     var savedFunction = _currentFunction;
     _currentFunction = fn;
     _nullableInference.enterFunction(fn);
@@ -2915,12 +2935,12 @@
 
   /// Emits argument initializers, which handles optional/named args, as well
   /// as generic type checks needed due to our covariance.
-  List<JS.Statement> _emitArgumentInitializers(FunctionNode f) {
-    var body = <JS.Statement>[];
+  List<js_ast.Statement> _emitArgumentInitializers(FunctionNode f) {
+    var body = <js_ast.Statement>[];
 
     _emitCovarianceBoundsCheck(f.typeParameters, body);
 
-    initParameter(VariableDeclaration p, JS.Identifier jsParam) {
+    initParameter(VariableDeclaration p, js_ast.Identifier jsParam) {
       if (isCovariantParameter(p)) {
         var castExpr = _emitCast(jsParam, p.type);
         if (!identical(castExpr, jsParam)) body.add(castExpr.toStatement());
@@ -2931,11 +2951,11 @@
     }
 
     for (var p in f.positionalParameters.take(f.requiredParameterCount)) {
-      var jsParam = JS.Identifier(p.name);
+      var jsParam = js_ast.Identifier(p.name);
       initParameter(p, jsParam);
     }
     for (var p in f.positionalParameters.skip(f.requiredParameterCount)) {
-      var jsParam = JS.Identifier(p.name);
+      var jsParam = js_ast.Identifier(p.name);
       var defaultValue = _defaultParamValue(p);
       if (defaultValue != null) {
         body.add(js.statement(
@@ -2982,23 +3002,23 @@
       !m.annotations
           .any((a) => isBuiltinAnnotation(a, '_js_helper', 'NoReifyGeneric'));
 
-  JS.Statement _nullParameterCheck(JS.Expression param) {
+  js_ast.Statement _nullParameterCheck(js_ast.Expression param) {
     var call = runtimeCall('argumentError((#))', [param]);
     return js.statement('if (# == null) #;', [param, call]);
   }
 
-  JS.Expression _defaultParamValue(VariableDeclaration p) {
+  js_ast.Expression _defaultParamValue(VariableDeclaration p) {
     if (p.annotations.any(isUndefinedAnnotation)) {
       return null;
     } else if (p.initializer != null) {
       return _visitExpression(p.initializer);
     } else {
-      return JS.LiteralNull();
+      return js_ast.LiteralNull();
     }
   }
 
   void _emitCovarianceBoundsCheck(
-      List<TypeParameter> typeFormals, List<JS.Statement> body) {
+      List<TypeParameter> typeFormals, List<js_ast.Statement> body) {
     for (var t in typeFormals) {
       if (t.isGenericCovariantImpl && !types.isTop(t.bound)) {
         body.add(runtimeStatement('checkTypeBound(#, #, #)', [
@@ -3010,19 +3030,19 @@
     }
   }
 
-  JS.Statement _visitStatement(Statement s) {
+  js_ast.Statement _visitStatement(Statement s) {
     if (s == null) return null;
-    var result = s.accept(this) as JS.Statement;
+    var result = s.accept(this) as js_ast.Statement;
     // TODO(jmesserly): is the `is! Block` still necessary?
     if (s is! Block) 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.LabeledStatement(name, result);
+    if (name != null) result = js_ast.LabeledStatement(name, result);
     return result;
   }
 
-  JS.Statement _emitFunctionScopedBody(FunctionNode f) {
+  js_ast.Statement _emitFunctionScopedBody(FunctionNode f) {
     var jsBody = _visitStatement(f.body);
     if (f.positionalParameters.isNotEmpty || f.namedParameters.isNotEmpty) {
       // Handle shadowing of parameters by local varaibles, which is allowed in
@@ -3043,7 +3063,7 @@
   }
 
   /// Visits [nodes] with [_visitExpression].
-  List<JS.Expression> _visitExpressionList(Iterable<Expression> nodes) {
+  List<js_ast.Expression> _visitExpressionList(Iterable<Expression> nodes) {
     return nodes?.map(_visitExpression)?.toList();
   }
 
@@ -3052,14 +3072,14 @@
   /// 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.Expression _visitTest(Expression node) {
+  js_ast.Expression _visitTest(Expression node) {
     if (node == null) return null;
 
     if (node is Not) {
       return visitNot(node);
     }
     if (node is LogicalExpression) {
-      JS.Expression shortCircuit(String code) {
+      js_ast.Expression shortCircuit(String code) {
         return js.call(code, [_visitTest(node.left), _visitTest(node.right)]);
       }
 
@@ -3078,9 +3098,9 @@
     return result;
   }
 
-  JS.Expression _visitExpression(Expression e) {
+  js_ast.Expression _visitExpression(Expression e) {
     if (e == null) return null;
-    var result = e.accept(this) as JS.Expression;
+    var result = e.accept(this) as js_ast.Expression;
     result.sourceInformation ??= _nodeStart(e);
     return result;
   }
@@ -3138,18 +3158,19 @@
   /// 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.Expression expr, int offset, int nameLength) {
+  HoverComment _hoverComment(
+      js_ast.Expression expr, int offset, int nameLength) {
     var start = _getLocation(offset);
     var end = _getLocation(offset + nameLength);
     return start != null && end != null ? HoverComment(expr, start, end) : null;
   }
 
   @override
-  JS.Statement defaultStatement(Statement node) =>
+  js_ast.Statement defaultStatement(Statement node) =>
       _emitInvalidNode(node).toStatement();
 
   @override
-  JS.Statement visitExpressionStatement(ExpressionStatement node) {
+  js_ast.Statement visitExpressionStatement(ExpressionStatement node) {
     var expr = node.expression;
     if (expr is StaticInvocation) {
       if (isInlineJS(expr.target)) {
@@ -3163,7 +3184,7 @@
   }
 
   @override
-  JS.Statement visitBlock(Block node) {
+  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
     // unncessary nested block.
@@ -3172,23 +3193,24 @@
     // slightly different (in Dart, there is a nested scope), but that's handled
     // by _emitSyncFunctionBody.
     var isScope = !identical(node.parent, _currentFunction);
-    return JS.Block(node.statements.map(_visitStatement).toList(),
+    return js_ast.Block(node.statements.map(_visitStatement).toList(),
         isScope: isScope);
   }
 
   @override
-  JS.Statement visitEmptyStatement(EmptyStatement node) => JS.EmptyStatement();
+  js_ast.Statement visitEmptyStatement(EmptyStatement node) =>
+      js_ast.EmptyStatement();
 
   @override
-  JS.Statement visitAssertBlock(AssertBlock node) {
+  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');
   }
 
   @override
-  JS.Statement visitAssertStatement(AssertStatement node) {
-    if (!options.enableAsserts) return JS.EmptyStatement();
+  js_ast.Statement visitAssertStatement(AssertStatement node) {
+    if (!options.enableAsserts) return js_ast.EmptyStatement();
     var condition = node.condition;
     var conditionType = condition.getStaticType(types);
     var jsCondition = _visitExpression(condition);
@@ -3213,7 +3235,7 @@
       jsCondition,
       runtimeModule,
       if (node.message == null)
-        JS.LiteralNull()
+        js_ast.LiteralNull()
       else
         _visitExpression(node.message),
       js.escapedString(location.sourceUrl.toString()),
@@ -3235,7 +3257,7 @@
   }
 
   @override
-  JS.Statement visitLabeledStatement(LabeledStatement node) {
+  js_ast.Statement visitLabeledStatement(LabeledStatement node) {
     List<LabeledStatement> saved;
     var target = _effectiveTargets[node];
     // If the effective target is known then this statement is either contained
@@ -3273,20 +3295,20 @@
   }
 
   @override
-  JS.Statement visitBreakStatement(BreakStatement node) {
+  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.Break(_switchLabelStates[node.target.body].label);
+      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.Break(null);
+      return js_ast.Break(null);
     }
     // Can it be compiled to a continue without a label?
     if (_currentContinueTargets.contains(node.target)) {
-      return JS.Continue(null);
+      return js_ast.Continue(null);
     }
 
     // Ensure the effective target is labeled.  Labels are named globally per
@@ -3304,10 +3326,10 @@
       current = (current as LabeledStatement).body;
     }
     if (identical(current, target)) {
-      return JS.Break(name);
+      return js_ast.Break(name);
     }
     // Otherwise it is a continue.
-    return JS.Continue(name);
+    return js_ast.Continue(name);
   }
 
   // Labeled loop bodies can be the target of a continue without a label
@@ -3327,7 +3349,7 @@
     return body;
   }
 
-  T translateLoop<T extends JS.Statement>(Statement node, T action()) {
+  T translateLoop<T extends js_ast.Statement>(Statement node, T action()) {
     List<LabeledStatement> savedBreakTargets;
     if (_currentBreakTargets.isNotEmpty &&
         _effectiveTargets[_currentBreakTargets.first] != node) {
@@ -3347,48 +3369,49 @@
   }
 
   @override
-  JS.While visitWhileStatement(WhileStatement node) {
+  js_ast.While visitWhileStatement(WhileStatement node) {
     return translateLoop(node, () {
       var condition = _visitTest(node.condition);
       var body = _visitScope(effectiveBodyOf(node, node.body));
-      return JS.While(condition, body);
+      return js_ast.While(condition, body);
     });
   }
 
   @override
-  JS.Do visitDoStatement(DoStatement node) {
+  js_ast.Do visitDoStatement(DoStatement node) {
     return translateLoop(node, () {
       var body = _visitScope(effectiveBodyOf(node, node.body));
       var condition = _visitTest(node.condition);
-      return JS.Do(body, condition);
+      return js_ast.Do(body, condition);
     });
   }
 
   @override
-  JS.For visitForStatement(ForStatement node) {
+  js_ast.For visitForStatement(ForStatement node) {
     return translateLoop(node, () {
-      emitForInitializer(VariableDeclaration v) => JS.VariableInitialization(
-          _emitVariableDef(v), _visitInitializer(v.initializer, v.annotations));
+      emitForInitializer(VariableDeclaration v) =>
+          js_ast.VariableInitialization(_emitVariableDef(v),
+              _visitInitializer(v.initializer, v.annotations));
 
       var init = node.variables.map(emitForInitializer).toList();
       var initList =
-          init.isEmpty ? null : JS.VariableDeclarationList('let', init);
+          init.isEmpty ? null : js_ast.VariableDeclarationList('let', init);
       var updates = node.updates;
-      JS.Expression update;
+      js_ast.Expression update;
       if (updates.isNotEmpty) {
-        update =
-            JS.Expression.binary(updates.map(_visitExpression).toList(), ',')
-                .toVoidExpression();
+        update = js_ast.Expression.binary(
+                updates.map(_visitExpression).toList(), ',')
+            .toVoidExpression();
       }
       var condition = _visitTest(node.condition);
       var body = _visitScope(effectiveBodyOf(node, node.body));
 
-      return JS.For(initList, condition, update, body);
+      return js_ast.For(initList, condition, update, body);
     });
   }
 
   @override
-  JS.Statement visitForInStatement(ForInStatement node) {
+  js_ast.Statement visitForInStatement(ForInStatement node) {
     return translateLoop(node, () {
       if (node.isAsync) {
         return _emitAwaitFor(node);
@@ -3399,20 +3422,22 @@
 
       var init = js.call('let #', _emitVariableDef(node.variable));
       if (_annotatedNullCheck(node.variable.annotations)) {
-        body = JS.Block(
+        body = js_ast.Block(
             [_nullParameterCheck(_emitVariableRef(node.variable)), body]);
       }
 
       if (variableIsReferenced(node.variable.name, iterable)) {
-        var temp = JS.TemporaryId('iter');
-        return JS.Block(
-            [iterable.toVariableDeclaration(temp), JS.ForOf(init, temp, body)]);
+        var temp = js_ast.TemporaryId('iter');
+        return js_ast.Block([
+          iterable.toVariableDeclaration(temp),
+          js_ast.ForOf(init, temp, body)
+        ]);
       }
-      return JS.ForOf(init, iterable, body);
+      return js_ast.ForOf(init, iterable, body);
     });
   }
 
-  JS.Statement _emitAwaitFor(ForInStatement node) {
+  js_ast.Statement _emitAwaitFor(ForInStatement node) {
     // Emits `await for (var value in stream) ...`, which desugars as:
     //
     // var iter = new StreamIterator(stream);
@@ -3431,14 +3456,14 @@
     // TODO(jmesserly): we may want a helper if these become common. For now the
     // full desugaring seems okay.
     var streamIterator = _asyncStreamIteratorClass.rawType;
-    var createStreamIter = JS.Call(
+    var createStreamIter = js_ast.Call(
         _emitConstructorName(
             streamIterator,
             _asyncStreamIteratorClass.procedures
                 .firstWhere((p) => p.isFactory && p.name.name == '')),
         [_visitExpression(node.iterable)]);
 
-    var iter = JS.TemporaryId('iter');
+    var iter = js_ast.TemporaryId('iter');
     return js.statement(
         '{'
         '  let # = #;'
@@ -3449,18 +3474,18 @@
         [
           iter,
           createStreamIter,
-          JS.Yield(js.call('#.moveNext()', iter))
+          js_ast.Yield(js.call('#.moveNext()', iter))
             ..sourceInformation = _nodeStart(node.variable),
           _emitVariableDef(node.variable),
           iter,
           _visitStatement(node.body),
-          JS.Yield(js.call('#.cancel()', iter))
+          js_ast.Yield(js.call('#.cancel()', iter))
             ..sourceInformation = _nodeStart(node.variable)
         ]);
   }
 
   @override
-  JS.Statement visitSwitchStatement(SwitchStatement node) {
+  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
@@ -3468,10 +3493,10 @@
     var previous = _inLabeledContinueSwitch;
     _inLabeledContinueSwitch = hasLabeledContinue(node);
 
-    var cases = <JS.SwitchCase>[];
+    var cases = <js_ast.SwitchCase>[];
 
     if (_inLabeledContinueSwitch) {
-      var labelState = JS.TemporaryId("labelState");
+      var labelState = js_ast.TemporaryId("labelState");
       // TODO(markzipan): Retrieve the real label name with source offsets
       var labelName = 'SL${_switchLabelStates.length}';
       _switchLabelStates[node] = SwitchLabelState(labelName, labelState);
@@ -3483,13 +3508,13 @@
       }
 
       var switchExpr = _visitExpression(node.expression);
-      var switchStmt = JS.Switch(labelState, cases);
-      var loopBody = JS.Block([switchStmt, JS.Break(null)]);
-      var loopStmt = JS.While(js.boolean(true), loopBody);
+      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.LabeledStatement(labelName, loopStmt);
-      var block = JS.Block([
+      var labeledStmt = js_ast.LabeledStatement(labelName, loopStmt);
+      var block = js_ast.Block([
         js.statement('let # = #', [labelState, switchExpr]),
         labeledStmt
       ]);
@@ -3502,7 +3527,7 @@
       if (subcases.isNotEmpty) cases.addAll(subcases);
     }
 
-    var stmt = JS.Switch(_visitExpression(node.expression), cases);
+    var stmt = js_ast.Switch(_visitExpression(node.expression), cases);
     _inLabeledContinueSwitch = previous;
     return stmt;
   }
@@ -3513,10 +3538,10 @@
   /// 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.SwitchCase> _visitSwitchCase(SwitchCase node,
+  List<js_ast.SwitchCase> _visitSwitchCase(SwitchCase node,
       {bool lastSwitchCase = false}) {
-    var cases = <JS.SwitchCase>[];
-    var emptyBlock = JS.Block.empty();
+    var cases = <js_ast.SwitchCase>[];
+    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;
@@ -3524,19 +3549,19 @@
         expressions.isNotEmpty && !node.isDefault ? expressions.last : null;
     for (var e in expressions) {
       var jsExpr = _visitExpression(e);
-      cases.add(JS.SwitchCase(jsExpr, e == lastExpr ? body : emptyBlock));
+      cases.add(js_ast.SwitchCase(jsExpr, e == lastExpr ? body : emptyBlock));
     }
     if (node.isDefault) {
-      cases.add(JS.SwitchCase.defaultCase(body));
+      cases.add(js_ast.SwitchCase.defaultCase(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
       assert(_switchLabelStates.containsKey(node.parent));
-      var breakStmt = JS.Break(_switchLabelStates[node.parent].label);
-      var switchBody = JS.Block(cases.last.body.statements..add(breakStmt));
-      var updatedSwitch = JS.SwitchCase(cases.last.expression, switchBody);
+      var breakStmt = js_ast.Break(_switchLabelStates[node.parent].label);
+      var switchBody = js_ast.Block(cases.last.body.statements..add(breakStmt));
+      var updatedSwitch = js_ast.SwitchCase(cases.last.expression, switchBody);
       cases.removeLast();
       cases.add(updatedSwitch);
     }
@@ -3544,7 +3569,7 @@
   }
 
   @override
-  JS.Statement visitContinueSwitchStatement(ContinueSwitchStatement node) {
+  js_ast.Statement visitContinueSwitchStatement(ContinueSwitchStatement node) {
     var switchStmt = node.target.parent;
     if (_inLabeledContinueSwitch &&
         _switchLabelStates.containsKey(switchStmt)) {
@@ -3555,8 +3580,8 @@
           ? js.call("Symbol('_default')", [])
           : _visitExpression(node.target.expressions[0]);
       var setStateStmt = js.statement("# = #", [switchState.variable, jsExpr]);
-      var continueStmt = JS.Continue(switchState.label);
-      return JS.Block([setStateStmt, continueStmt]);
+      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')
@@ -3564,8 +3589,8 @@
   }
 
   @override
-  JS.Statement visitIfStatement(IfStatement node) {
-    return JS.If(_visitTest(node.condition), _visitScope(node.then),
+  js_ast.Statement visitIfStatement(IfStatement node) {
+    return js_ast.If(_visitTest(node.condition), _visitScope(node.then),
         _visitScope(node.otherwise));
   }
 
@@ -3575,27 +3600,27 @@
   ///
   ///     do var x = 5; while (false); // Dart
   ///     do { let x = 5; } while (false); // JS
-  JS.Statement _visitScope(Statement stmt) {
+  js_ast.Statement _visitScope(Statement stmt) {
     var result = _visitStatement(stmt);
-    if (result is JS.ExpressionStatement &&
-        result.expression is JS.VariableDeclarationList) {
-      return JS.Block([result]);
+    if (result is js_ast.ExpressionStatement &&
+        result.expression is js_ast.VariableDeclarationList) {
+      return js_ast.Block([result]);
     }
     return result;
   }
 
   @override
-  JS.Statement visitReturnStatement(ReturnStatement node) {
+  js_ast.Statement visitReturnStatement(ReturnStatement node) {
     return super.emitReturnStatement(_visitExpression(node.expression));
   }
 
   @override
-  JS.Statement visitTryCatch(TryCatch node) {
-    return JS.Try(
+  js_ast.Statement visitTryCatch(TryCatch node) {
+    return js_ast.Try(
         _visitStatement(node.body).toBlock(), _visitCatch(node.catches), null);
   }
 
-  JS.Catch _visitCatch(List<Catch> clauses) {
+  js_ast.Catch _visitCatch(List<Catch> clauses) {
     if (clauses.isEmpty) return null;
 
     var caughtError = VariableDeclaration('#e');
@@ -3614,7 +3639,7 @@
                 ? VariableDeclaration('#st')
                 : null);
 
-    JS.Statement catchBody = JS.Throw(_emitVariableRef(caughtError));
+    js_ast.Statement catchBody = js_ast.Throw(_emitVariableRef(caughtError));
     for (var clause in clauses.reversed) {
       catchBody = _catchClauseGuard(
           clause, catchBody, exceptionParameter, stackTraceParameter);
@@ -3634,15 +3659,16 @@
       catchBody,
     ];
     _rethrowParameter = savedRethrow;
-    return JS.Catch(_emitVariableDef(caughtError), JS.Block(catchStatements));
+    return js_ast.Catch(
+        _emitVariableDef(caughtError), js_ast.Block(catchStatements));
   }
 
-  JS.Statement _catchClauseGuard(
+  js_ast.Statement _catchClauseGuard(
       Catch node,
-      JS.Statement otherwise,
+      js_ast.Statement otherwise,
       VariableDeclaration exceptionParameter,
       VariableDeclaration stackTraceParameter) {
-    var body = <JS.Statement>[];
+    var body = <js_ast.Statement>[];
     var vars = HashSet<String>();
 
     void declareVariable(
@@ -3659,34 +3685,34 @@
     declareVariable(node.stackTrace, stackTraceParameter);
 
     body.add(_visitStatement(node.body).toScopedBlock(vars));
-    var then = JS.Block(body);
+    var then = js_ast.Block(body);
 
     // Discard following clauses, if any, as they are unreachable.
     if (types.isTop(node.guard)) return then;
 
     var condition =
         _emitIsExpression(VariableGet(exceptionParameter), node.guard);
-    return JS.If(condition, then, otherwise)
+    return js_ast.If(condition, then, otherwise)
       ..sourceInformation = _nodeStart(node);
   }
 
   @override
-  JS.Statement visitTryFinally(TryFinally node) {
+  js_ast.Statement visitTryFinally(TryFinally node) {
     var body = _visitStatement(node.body);
     var finallyBlock =
         _superDisallowed(() => _visitStatement(node.finalizer).toBlock());
 
-    if (body is JS.Try && body.finallyPart == null) {
+    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.Try(body.body, body.catchPart, finallyBlock);
+      return js_ast.Try(body.body, body.catchPart, finallyBlock);
     }
-    return JS.Try(body.toBlock(), null, finallyBlock);
+    return js_ast.Try(body.toBlock(), null, finallyBlock);
   }
 
   @override
-  JS.Statement visitYieldStatement(YieldStatement node) {
+  js_ast.Statement visitYieldStatement(YieldStatement node) {
     var jsExpr = _visitExpression(node.expression);
     var star = node.isYieldStar;
     if (_asyncStarController != null) {
@@ -3705,7 +3731,7 @@
         _asyncStarController,
         helperName,
         jsExpr,
-        JS.Yield(null)..sourceInformation = _nodeStart(node)
+        js_ast.Yield(null)..sourceInformation = _nodeStart(node)
       ]);
     }
     // A normal yield in a sync*
@@ -3713,7 +3739,7 @@
   }
 
   @override
-  JS.Statement visitVariableDeclaration(VariableDeclaration node) {
+  js_ast.Statement visitVariableDeclaration(VariableDeclaration node) {
     // TODO(jmesserly): casts are sometimes required here.
     // Kernel does not represent these explicitly.
     var v = _emitVariableDef(node);
@@ -3722,15 +3748,15 @@
   }
 
   @override
-  JS.Statement visitFunctionDeclaration(FunctionDeclaration node) {
+  js_ast.Statement visitFunctionDeclaration(FunctionDeclaration node) {
     var func = node.function;
     var fn = _emitFunction(func, node.variable.name);
 
     var name = _emitVariableDef(node.variable);
-    JS.Statement declareFn;
+    js_ast.Statement declareFn;
     declareFn = toBoundFunctionStatement(fn, name);
     if (_reifyFunctionType(func)) {
-      declareFn = JS.Block([
+      declareFn = js_ast.Block([
         declareFn,
         _emitFunctionTagged(_emitVariableRef(node.variable), func.functionType)
             .toStatement()
@@ -3740,22 +3766,23 @@
   }
 
   @override
-  JS.Expression defaultExpression(Expression node) => _emitInvalidNode(node);
+  js_ast.Expression defaultExpression(Expression node) =>
+      _emitInvalidNode(node);
 
   @override
-  JS.Expression defaultBasicLiteral(BasicLiteral node) =>
+  js_ast.Expression defaultBasicLiteral(BasicLiteral node) =>
       defaultExpression(node);
 
   @override
-  JS.Expression visitInvalidExpression(InvalidExpression node) =>
+  js_ast.Expression visitInvalidExpression(InvalidExpression node) =>
       defaultExpression(node);
 
   @override
-  JS.Expression visitConstantExpression(ConstantExpression node) =>
-      node.constant.accept(this) as JS.Expression;
+  js_ast.Expression visitConstantExpression(ConstantExpression node) =>
+      node.constant.accept(this) as js_ast.Expression;
 
   @override
-  JS.Expression visitVariableGet(VariableGet node) {
+  js_ast.Expression visitVariableGet(VariableGet node) {
     var v = node.variable;
     var id = _emitVariableRef(v);
     if (id.name == v.name) {
@@ -3764,29 +3791,29 @@
     return id;
   }
 
-  JS.Identifier _emitVariableRef(VariableDeclaration v) {
+  js_ast.Identifier _emitVariableRef(VariableDeclaration v) {
     var name = v.name;
     if (name == null || name.startsWith('#')) {
       name = name == null ? 't${_tempVariables.length}' : name.substring(1);
-      return _tempVariables.putIfAbsent(v, () => JS.TemporaryId(name));
+      return _tempVariables.putIfAbsent(v, () => js_ast.TemporaryId(name));
     }
-    return JS.Identifier(name);
+    return js_ast.Identifier(name);
   }
 
   /// 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.Identifier _emitVariableDef(VariableDeclaration v) {
+  js_ast.Identifier _emitVariableDef(VariableDeclaration v) {
     return _emitVariableRef(v)..sourceInformation = _nodeStart(v);
   }
 
-  JS.Statement _initLetVariables() {
+  js_ast.Statement _initLetVariables() {
     if (_letVariables.isEmpty) return null;
-    var result = JS.VariableDeclarationList(
+    var result = js_ast.VariableDeclarationList(
             'let',
             _letVariables
-                .map((v) => JS.VariableInitialization(v, null))
+                .map((v) => js_ast.VariableInitialization(v, null))
                 .toList())
         .toStatement();
     _letVariables.clear();
@@ -3795,33 +3822,33 @@
 
   // TODO(jmesserly): resugar operators for kernel, such as ++x, x++, x+=.
   @override
-  JS.Expression visitVariableSet(VariableSet node) =>
+  js_ast.Expression visitVariableSet(VariableSet node) =>
       _visitExpression(node.value)
           .toAssignExpression(_emitVariableRef(node.variable));
 
   @override
-  JS.Expression visitPropertyGet(PropertyGet node) {
+  js_ast.Expression visitPropertyGet(PropertyGet node) {
     return _emitPropertyGet(
         node.receiver, node.interfaceTarget, node.name.name);
   }
 
   @override
-  JS.Expression visitPropertySet(PropertySet node) {
+  js_ast.Expression visitPropertySet(PropertySet node) {
     return _emitPropertySet(
         node.receiver, node.interfaceTarget, node.value, node.name.name);
   }
 
   @override
-  JS.Expression visitDirectPropertyGet(DirectPropertyGet node) {
+  js_ast.Expression visitDirectPropertyGet(DirectPropertyGet node) {
     return _emitPropertyGet(node.receiver, node.target);
   }
 
   @override
-  JS.Expression visitDirectPropertySet(DirectPropertySet node) {
+  js_ast.Expression visitDirectPropertySet(DirectPropertySet node) {
     return _emitPropertySet(node.receiver, node.target, node.value);
   }
 
-  JS.Expression _emitPropertyGet(Expression receiver, Member member,
+  js_ast.Expression _emitPropertyGet(Expression receiver, Member member,
       [String memberName]) {
     memberName ??= member.name.name;
     // TODO(jmesserly): should tearoff of `.call` on a function type be
@@ -3856,7 +3883,7 @@
     if (_reifyTearoff(member)) {
       return runtimeCall('bind(#, #)', [jsReceiver, jsName]);
     } else {
-      return JS.PropertyAccess(jsReceiver, jsName);
+      return js_ast.PropertyAccess(jsReceiver, jsName);
     }
   }
 
@@ -3865,7 +3892,7 @@
   // access to the target expression there (needed for `dart.replNameLookup`).
   String get _replSuffix => options.replCompile ? 'Repl' : '';
 
-  JS.Expression _emitPropertySet(
+  js_ast.Expression _emitPropertySet(
       Expression receiver, Member member, Expression value,
       [String memberName]) {
     var jsName =
@@ -3882,7 +3909,7 @@
   }
 
   @override
-  JS.Expression visitSuperPropertyGet(SuperPropertyGet node) {
+  js_ast.Expression visitSuperPropertyGet(SuperPropertyGet node) {
     var target = node.interfaceTarget;
     var jsTarget = _emitSuperTarget(target);
     if (_reifyTearoff(target)) {
@@ -3892,16 +3919,17 @@
   }
 
   @override
-  JS.Expression visitSuperPropertySet(SuperPropertySet node) {
+  js_ast.Expression visitSuperPropertySet(SuperPropertySet node) {
     var target = node.interfaceTarget;
     var jsTarget = _emitSuperTarget(target, setter: true);
     return _visitExpression(node.value).toAssignExpression(jsTarget);
   }
 
   @override
-  JS.Expression visitStaticGet(StaticGet node) => _emitStaticGet(node.target);
+  js_ast.Expression visitStaticGet(StaticGet node) =>
+      _emitStaticGet(node.target);
 
-  JS.Expression _emitStaticGet(Member target) {
+  js_ast.Expression _emitStaticGet(Member target) {
     // TODO(vsm): Re-inline constants.  See:
     // https://github.com/dart-lang/sdk/issues/36285
     var result = _emitStaticTarget(target);
@@ -3915,23 +3943,23 @@
   }
 
   @override
-  JS.Expression visitStaticSet(StaticSet node) {
+  js_ast.Expression visitStaticSet(StaticSet node) {
     return _visitExpression(node.value)
         .toAssignExpression(_emitStaticTarget(node.target));
   }
 
   @override
-  JS.Expression visitMethodInvocation(MethodInvocation node) {
+  js_ast.Expression visitMethodInvocation(MethodInvocation node) {
     return _emitMethodCall(
         node.receiver, node.interfaceTarget, node.arguments, node);
   }
 
   @override
-  JS.Expression visitDirectMethodInvocation(DirectMethodInvocation node) {
+  js_ast.Expression visitDirectMethodInvocation(DirectMethodInvocation node) {
     return _emitMethodCall(node.receiver, node.target, node.arguments, node);
   }
 
-  JS.Expression _emitMethodCall(Expression receiver, Member target,
+  js_ast.Expression _emitMethodCall(Expression receiver, Member target,
       Arguments arguments, InvocationExpression node) {
     var name = node.name.name;
 
@@ -3957,7 +3985,7 @@
         return _emitDynamicInvoke(jsReceiver, null, args, arguments);
       } else if (_isDirectCallable(receiverType)) {
         // Call methods on function types should be handled as function calls.
-        return JS.Call(jsReceiver, args);
+        return js_ast.Call(jsReceiver, args);
       }
     }
 
@@ -3988,8 +4016,11 @@
     return js.call('#.#(#)', [jsReceiver, jsName, args]);
   }
 
-  JS.Expression _emitDynamicInvoke(JS.Expression fn, JS.Expression methodName,
-      Iterable<JS.Expression> args, Arguments arguments) {
+  js_ast.Expression _emitDynamicInvoke(
+      js_ast.Expression fn,
+      js_ast.Expression methodName,
+      Iterable<js_ast.Expression> args,
+      Arguments arguments) {
     var jsArgs = <Object>[fn];
     String jsCode;
 
@@ -4026,7 +4057,7 @@
   bool _isDirectCallable(DartType t) =>
       t is FunctionType || t is InterfaceType && usesJSInterop(t.classNode);
 
-  JS.Expression _getImplicitCallTarget(InterfaceType from) {
+  js_ast.Expression _getImplicitCallTarget(InterfaceType from) {
     var c = from.classNode;
     var member = hierarchy.getInterfaceMember(c, Name("call"));
     if (member is Procedure && !member.isAccessor && !usesJSInterop(c)) {
@@ -4038,7 +4069,7 @@
   bool _isDynamicOrFunction(DartType t) =>
       t == coreTypes.functionClass.rawType || t == const DynamicType();
 
-  JS.Expression _emitUnaryOperator(
+  js_ast.Expression _emitUnaryOperator(
       Expression expr, Member target, InvocationExpression node) {
     var op = node.name.name;
     if (target != null) {
@@ -4062,8 +4093,8 @@
   /// the interpretation of the 32-bit value from signed to unsigned.  Most
   /// JavaScript operations interpret their operands as signed and generate
   /// signed results.
-  JS.Expression _coerceBitOperationResultToUnsigned(
-      Expression node, JS.Expression uncoerced) {
+  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)) {
@@ -4203,7 +4234,7 @@
     return bitWidth(expr, 0) < 32;
   }
 
-  JS.Expression _emitBinaryOperator(Expression left, Member target,
+  js_ast.Expression _emitBinaryOperator(Expression left, Member target,
       Expression right, InvocationExpression node) {
     var op = node.name.name;
     if (op == '==') return _emitEqualityOperator(left, target, right);
@@ -4223,11 +4254,11 @@
 
         /// Emits an inlined binary operation using the JS [code], adding null
         /// checks if needed to ensure we throw the appropriate error.
-        JS.Expression binary(String code) {
+        js_ast.Expression binary(String code) {
           return js.call(code, [notNull(left), notNull(right)]);
         }
 
-        JS.Expression bitwise(String code) {
+        js_ast.Expression bitwise(String code) {
           return _coerceBitOperationResultToUnsigned(node, binary(code));
         }
 
@@ -4236,7 +4267,7 @@
         ///
         /// Short circuiting operators should not be used in [code], because the
         /// null checks for both operands must happen unconditionally.
-        JS.Expression bitwiseBool(String code) {
+        js_ast.Expression bitwiseBool(String code) {
           return js.call(code, [notNull(left), _visitTest(right)]);
         }
 
@@ -4307,7 +4338,7 @@
     return _emitOperatorCall(left, target, op, [right]);
   }
 
-  JS.Expression _emitEqualityOperator(
+  js_ast.Expression _emitEqualityOperator(
       Expression left, Member target, Expression right,
       {bool negated = false}) {
     var targetClass = target?.enclosingClass;
@@ -4364,7 +4395,7 @@
   /// **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.Expression _emitOperatorCall(
+  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.
@@ -4391,20 +4422,20 @@
 
   // TODO(jmesserly): optimize super operators for kernel
   @override
-  JS.Expression visitSuperMethodInvocation(SuperMethodInvocation node) {
+  js_ast.Expression visitSuperMethodInvocation(SuperMethodInvocation node) {
     var target = node.interfaceTarget;
-    return JS.Call(_emitSuperTarget(target),
+    return js_ast.Call(_emitSuperTarget(target),
         _emitArgumentList(node.arguments, target: target));
   }
 
-  /// Emits the [JS.PropertyAccess] for accessors or method calls to
+  /// Emits the [js_ast.PropertyAccess] for accessors or method calls to
   /// [jsTarget].[jsName], replacing `super` if it is not allowed in scope.
-  JS.PropertyAccess _emitSuperTarget(Member member, {bool setter = false}) {
+  js_ast.PropertyAccess _emitSuperTarget(Member member, {bool setter = false}) {
     var jsName = _emitMemberName(member.name.name, member: member);
     if (member is Field && !virtualFields.isVirtual(member)) {
-      return JS.PropertyAccess(JS.This(), jsName);
+      return js_ast.PropertyAccess(js_ast.This(), jsName);
     }
-    if (_superAllowed) return JS.PropertyAccess(JS.Super(), 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.
@@ -4421,30 +4452,30 @@
                 : 'function() { return super[#]; }',
             [jsName]);
 
-        return JS.Method(JS.TemporaryId(name), fn,
+        return js_ast.Method(js_ast.TemporaryId(name), fn,
             isGetter: !setter, isSetter: setter);
       } else {
         var function = member.function;
         var params = [
           ..._emitTypeFormals(function.typeParameters),
           for (var param in function.positionalParameters)
-            JS.Identifier(param.name),
+            js_ast.Identifier(param.name),
           if (function.namedParameters.isNotEmpty) namedArgumentTemp,
         ];
 
         var fn = js.fun(
             'function(#) { return super[#](#); }', [params, jsName, params]);
-        name = JS.friendlyNameForDartOperator[name] ?? name;
-        return JS.Method(JS.TemporaryId(name), fn);
+        name = js_ast.friendlyNameForDartOperator[name] ?? name;
+        return js_ast.Method(js_ast.TemporaryId(name), fn);
       }
     });
-    return JS.PropertyAccess(JS.This(), jsMethod.name);
+    return js_ast.PropertyAccess(js_ast.This(), jsMethod.name);
   }
 
   @override
-  JS.Expression visitStaticInvocation(StaticInvocation node) {
+  js_ast.Expression visitStaticInvocation(StaticInvocation node) {
     var target = node.target;
-    if (isInlineJS(target)) return _emitInlineJSCode(node) as JS.Expression;
+    if (isInlineJS(target)) return _emitInlineJSCode(node) as js_ast.Expression;
     if (target.isFactory) return _emitFactoryInvocation(node);
 
     // Optimize some internal SDK calls.
@@ -4469,12 +4500,12 @@
       return _emitCoreIdenticalCall(node.arguments.positional);
     }
     if (_isDebuggerCall(target)) {
-      return _emitDebuggerCall(node) as JS.Expression;
+      return _emitDebuggerCall(node) as js_ast.Expression;
     }
 
     var fn = _emitStaticTarget(target);
     var args = _emitArgumentList(node.arguments, target: target);
-    return JS.Call(fn, args);
+    return js_ast.Call(fn, args);
   }
 
   bool _isDebuggerCall(Procedure target) {
@@ -4482,7 +4513,7 @@
         target.enclosingLibrary.importUri.toString() == 'dart:developer';
   }
 
-  JS.Node _emitDebuggerCall(StaticInvocation node) {
+  js_ast.Node _emitDebuggerCall(StaticInvocation node) {
     var args = node.arguments.named;
     var isStatement = node.parent is ExpressionStatement;
     if (args.isEmpty) {
@@ -4510,17 +4541,17 @@
         // coerces to true (the default value of `when`).
         ? (args[0].name == 'when'
             ? jsArgs[0].value
-            : JS.ObjectInitializer(jsArgs))
+            : 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.ObjectInitializer(jsArgs));
+        : js.call('#.when', js_ast.ObjectInitializer(jsArgs));
     return isStatement
         ? js.statement('if (#) debugger;', when)
         : js.call('# && (() => { debugger; return true })()', when);
   }
 
   /// Emits the target of a [StaticInvocation], [StaticGet], or [StaticSet].
-  JS.Expression _emitStaticTarget(Member target) {
+  js_ast.Expression _emitStaticTarget(Member target) {
     var c = target.enclosingClass;
     if (c != null) {
       // A static native element should just forward directly to the JS type's
@@ -4534,13 +4565,13 @@
           return runtimeCall('global.#.#', [nativeName[0], memberName]);
         }
       }
-      return JS.PropertyAccess(_emitStaticClassName(c),
+      return js_ast.PropertyAccess(_emitStaticClassName(c),
           _emitStaticMemberName(target.name.name, target));
     }
     return _emitTopLevelName(target);
   }
 
-  List<JS.Expression> _emitArgumentList(Arguments node,
+  List<js_ast.Expression> _emitArgumentList(Arguments node,
       {bool types = true, Member target}) {
     types = types && _reifyGenericFunction(target);
     return [
@@ -4549,20 +4580,20 @@
         if (arg is StaticInvocation &&
             isJSSpreadInvocation(arg.target) &&
             arg.arguments.positional.length == 1)
-          JS.Spread(_visitExpression(arg.arguments.positional[0]))
+          js_ast.Spread(_visitExpression(arg.arguments.positional[0]))
         else
           _visitExpression(arg),
       if (node.named.isNotEmpty)
-        JS.ObjectInitializer(node.named.map(_emitNamedExpression).toList()),
+        js_ast.ObjectInitializer(node.named.map(_emitNamedExpression).toList()),
     ];
   }
 
-  JS.Property _emitNamedExpression(NamedExpression arg) {
-    return JS.Property(propertyName(arg.name), _visitExpression(arg.value));
+  js_ast.Property _emitNamedExpression(NamedExpression arg) {
+    return js_ast.Property(propertyName(arg.name), _visitExpression(arg.value));
   }
 
   /// Emits code for the `JS(...)` macro.
-  JS.Node _emitInlineJSCode(StaticInvocation node) {
+  js_ast.Node _emitInlineJSCode(StaticInvocation node) {
     var args = node.arguments.positional;
     // arg[0] is static return type, used in `RestrictedStaticTypeAnalyzer`
     var code = args[1];
@@ -4604,8 +4635,8 @@
 
     var result = js.parseForeignJS(source).instantiate(jsArgs);
 
-    assert(result is JS.Expression ||
-        result is JS.Statement && node.parent is ExpressionStatement);
+    assert(result is js_ast.Expression ||
+        result is js_ast.Statement && node.parent is ExpressionStatement);
     return result;
   }
 
@@ -4635,19 +4666,19 @@
   /// [_notNullLocals].
   bool isNullable(Expression expr) => _nullableInference.isNullable(expr);
 
-  JS.Expression _emitJSDoubleEq(List<JS.Expression> args,
+  js_ast.Expression _emitJSDoubleEq(List<js_ast.Expression> args,
       {bool negated = false}) {
     var op = negated ? '# != #' : '# == #';
     return js.call(op, args);
   }
 
-  JS.Expression _emitJSTripleEq(List<JS.Expression> args,
+  js_ast.Expression _emitJSTripleEq(List<js_ast.Expression> args,
       {bool negated = false}) {
     var op = negated ? '# !== #' : '# === #';
     return js.call(op, args);
   }
 
-  JS.Expression _emitCoreIdenticalCall(List<Expression> args,
+  js_ast.Expression _emitCoreIdenticalCall(List<Expression> args,
       {bool negated = false}) {
     if (args.length != 2) {
       // Shouldn't happen in typechecked code
@@ -4664,21 +4695,21 @@
       return _emitJSDoubleEq(jsArgs, negated: negated);
     }
     var code = negated ? '!#' : '#';
-    return js.call(
-        code, JS.Call(_emitTopLevelName(coreTypes.identicalProcedure), jsArgs));
+    return js.call(code,
+        js_ast.Call(_emitTopLevelName(coreTypes.identicalProcedure), jsArgs));
   }
 
   @override
-  JS.Expression visitConstructorInvocation(ConstructorInvocation node) {
+  js_ast.Expression visitConstructorInvocation(ConstructorInvocation node) {
     var ctor = node.target;
     var args = node.arguments;
-    var result = JS.New(_emitConstructorName(node.constructedType, ctor),
+    var result = js_ast.New(_emitConstructorName(node.constructedType, ctor),
         _emitArgumentList(args, types: false));
 
     return node.isConst ? canonicalizeConstObject(result) : result;
   }
 
-  JS.Expression _emitFactoryInvocation(StaticInvocation node) {
+  js_ast.Expression _emitFactoryInvocation(StaticInvocation node) {
     var args = node.arguments;
     var ctor = node.target;
     var ctorClass = ctor.enclosingClass;
@@ -4693,7 +4724,7 @@
     if (isFromEnvironmentInvocation(coreTypes, node)) {
       var value = _constants.evaluate(node);
       if (value is PrimitiveConstant) {
-        return value.accept(this) as JS.Expression;
+        return value.accept(this) as js_ast.Expression;
       }
     }
 
@@ -4730,20 +4761,20 @@
       }
     }
 
-    var result = JS.Call(_emitConstructorName(type, ctor),
+    var result = js_ast.Call(_emitConstructorName(type, ctor),
         _emitArgumentList(args, types: false));
 
     return node.isConst ? canonicalizeConstObject(result) : result;
   }
 
-  JS.Expression _emitJSInteropNew(Member ctor, Arguments args) {
+  js_ast.Expression _emitJSInteropNew(Member ctor, Arguments args) {
     var ctorClass = ctor.enclosingClass;
     if (isJSAnonymousType(ctorClass)) return _emitObjectLiteral(args);
-    return JS.New(_emitConstructorName(ctorClass.rawType, ctor),
+    return js_ast.New(_emitConstructorName(ctorClass.rawType, ctor),
         _emitArgumentList(args, types: false));
   }
 
-  JS.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
+  js_ast.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) return _emitType(type);
     identity ??= _typeRep.isPrimitive(typeArgs[0]);
@@ -4751,7 +4782,7 @@
     return _emitType(InterfaceType(c, typeArgs));
   }
 
-  JS.Expression _emitSetImplType(InterfaceType type, {bool identity}) {
+  js_ast.Expression _emitSetImplType(InterfaceType type, {bool identity}) {
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) return _emitType(type);
     identity ??= _typeRep.isPrimitive(typeArgs[0]);
@@ -4759,15 +4790,15 @@
     return _emitType(InterfaceType(c, typeArgs));
   }
 
-  JS.Expression _emitObjectLiteral(Arguments node) {
+  js_ast.Expression _emitObjectLiteral(Arguments node) {
     var args = _emitArgumentList(node, types: false);
     if (args.isEmpty) return js.call('{}');
-    assert(args.single is JS.ObjectInitializer);
+    assert(args.single is js_ast.ObjectInitializer);
     return args.single;
   }
 
   @override
-  JS.Expression visitNot(Not node) {
+  js_ast.Expression visitNot(Not node) {
     var operand = node.operand;
     if (operand is MethodInvocation && operand.name.name == '==') {
       return _emitEqualityOperator(operand.receiver, operand.interfaceTarget,
@@ -4789,14 +4820,14 @@
   }
 
   @override
-  JS.Expression visitLogicalExpression(LogicalExpression node) {
+  js_ast.Expression visitLogicalExpression(LogicalExpression node) {
     // The operands of logical boolean operators are subject to boolean
     // conversion.
     return _visitTest(node);
   }
 
   @override
-  JS.Expression visitConditionalExpression(ConditionalExpression node) {
+  js_ast.Expression visitConditionalExpression(ConditionalExpression node) {
     return js.call('# ? # : #', [
       _visitTest(node.condition),
       _visitExpression(node.then),
@@ -4806,11 +4837,11 @@
   }
 
   @override
-  JS.Expression visitStringConcatenation(StringConcatenation node) {
-    var parts = <JS.Expression>[];
+  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.LiteralString && jsExpr.valueWithoutQuotes.isEmpty) {
+      if (jsExpr is js_ast.LiteralString && jsExpr.valueWithoutQuotes.isEmpty) {
         continue;
       }
       parts.add(e.getStaticType(types) == types.stringType && !isNullable(e)
@@ -4818,13 +4849,13 @@
           : runtimeCall('str(#)', [jsExpr]));
     }
     if (parts.isEmpty) return js.string('');
-    return JS.Expression.binary(parts, '+');
+    return js_ast.Expression.binary(parts, '+');
   }
 
   @override
-  JS.Expression visitListConcatenation(ListConcatenation node) {
+  js_ast.Expression visitListConcatenation(ListConcatenation node) {
     // Only occurs inside unevaluated constants.
-    List<JS.Expression> entries = [];
+    List<js_ast.Expression> entries = [];
     _concatenate(Expression node) {
       if (node is ListConcatenation) {
         node.lists.forEach(_concatenate);
@@ -4844,9 +4875,9 @@
   }
 
   @override
-  JS.Expression visitSetConcatenation(SetConcatenation node) {
+  js_ast.Expression visitSetConcatenation(SetConcatenation node) {
     // Only occurs inside unevaluated constants.
-    List<JS.Expression> entries = [];
+    List<js_ast.Expression> entries = [];
     _concatenate(Expression node) {
       if (node is SetConcatenation) {
         node.sets.forEach(_concatenate);
@@ -4866,9 +4897,9 @@
   }
 
   @override
-  JS.Expression visitMapConcatenation(MapConcatenation node) {
+  js_ast.Expression visitMapConcatenation(MapConcatenation node) {
     // Only occurs inside unevaluated constants.
-    List<JS.Expression> entries = [];
+    List<js_ast.Expression> entries = [];
     _concatenate(Expression node) {
       if (node is MapConcatenation) {
         node.maps.forEach(_concatenate);
@@ -4894,17 +4925,17 @@
   }
 
   @override
-  JS.Expression visitInstanceCreation(InstanceCreation node) {
+  js_ast.Expression visitInstanceCreation(InstanceCreation node) {
     // Only occurs inside unevaluated constants.
     throw new UnsupportedError("Instance creation");
   }
 
   @override
-  JS.Expression visitIsExpression(IsExpression node) {
+  js_ast.Expression visitIsExpression(IsExpression node) {
     return _emitIsExpression(node.operand, node.type);
   }
 
-  JS.Expression _emitIsExpression(Expression operand, DartType type) {
+  js_ast.Expression _emitIsExpression(Expression operand, DartType type) {
     // Generate `is` as `dart.is` or `typeof` depending on the RHS type.
     var lhs = _visitExpression(operand);
     var typeofName = _typeRep.typeFor(type).primitiveTypeOf;
@@ -4917,7 +4948,7 @@
   }
 
   @override
-  JS.Expression visitAsExpression(AsExpression node) {
+  js_ast.Expression visitAsExpression(AsExpression node) {
     Expression fromExpr = node.operand;
     var to = node.type;
     var jsFrom = _visitExpression(fromExpr);
@@ -4961,7 +4992,7 @@
     return _emitCast(jsFrom, to, implicit: isTypeError);
   }
 
-  JS.Expression _emitCast(JS.Expression expr, DartType type,
+  js_ast.Expression _emitCast(js_ast.Expression expr, DartType type,
       {bool implicit = true}) {
     if (types.isTop(type)) return expr;
 
@@ -4970,14 +5001,14 @@
   }
 
   @override
-  JS.Expression visitSymbolLiteral(SymbolLiteral node) =>
+  js_ast.Expression visitSymbolLiteral(SymbolLiteral node) =>
       emitDartSymbol(node.value);
 
   @override
-  JS.Expression visitTypeLiteral(TypeLiteral node) =>
+  js_ast.Expression visitTypeLiteral(TypeLiteral node) =>
       _emitTypeLiteral(node.type);
 
-  JS.Expression _emitTypeLiteral(DartType type) {
+  js_ast.Expression _emitTypeLiteral(DartType type) {
     var typeRep = _emitType(type);
     // If the type is a type literal expression in Dart code, wrap the raw
     // runtime type in a "Type" instance.
@@ -4985,19 +5016,19 @@
   }
 
   @override
-  JS.Expression visitThisExpression(ThisExpression node) => JS.This();
+  js_ast.Expression visitThisExpression(ThisExpression node) => js_ast.This();
 
   @override
-  JS.Expression visitRethrow(Rethrow node) {
+  js_ast.Expression visitRethrow(Rethrow node) {
     return runtimeCall('rethrow(#)', [_emitVariableRef(_rethrowParameter)]);
   }
 
   @override
-  JS.Expression visitThrow(Throw node) =>
+  js_ast.Expression visitThrow(Throw node) =>
       runtimeCall('throw(#)', [_visitExpression(node.expression)]);
 
   @override
-  JS.Expression visitListLiteral(ListLiteral node) {
+  js_ast.Expression visitListLiteral(ListLiteral node) {
     var elementType = node.typeArgument;
     var elements = _visitExpressionList(node.expressions);
     // TODO(markzipan): remove const check when we use front-end const eval
@@ -5007,8 +5038,9 @@
     return _emitConstList(elementType, elements);
   }
 
-  JS.Expression _emitList(DartType itemType, List<JS.Expression> items) {
-    var list = JS.ArrayInitializer(items);
+  js_ast.Expression _emitList(
+      DartType itemType, List<js_ast.Expression> items) {
+    var list = js_ast.ArrayInitializer(items);
 
     // TODO(jmesserly): analyzer will usually infer `List<Object>` because
     // that is the least upper bound of the element types. So we rarely
@@ -5020,8 +5052,8 @@
     return js.call('#.of(#)', [_emitType(arrayType), list]);
   }
 
-  JS.Expression _emitConstList(
-      DartType elementType, List<JS.Expression> elements) {
+  js_ast.Expression _emitConstList(
+      DartType elementType, List<js_ast.Expression> elements) {
     // dart.constList helper internally depends on _interceptors.JSArray.
     _declareBeforeUse(_jsArrayClass);
     return cacheConst(
@@ -5029,7 +5061,7 @@
   }
 
   @override
-  JS.Expression visitSetLiteral(SetLiteral node) {
+  js_ast.Expression visitSetLiteral(SetLiteral node) {
     // TODO(markzipan): remove const check when we use front-end const eval
     if (!node.isConst) {
       var setType = visitInterfaceType(
@@ -5044,14 +5076,14 @@
         node.typeArgument, _visitExpressionList(node.expressions));
   }
 
-  JS.Expression _emitConstSet(
-      DartType elementType, List<JS.Expression> elements) {
+  js_ast.Expression _emitConstSet(
+      DartType elementType, List<js_ast.Expression> elements) {
     return cacheConst(
         runtimeCall('constSet(#, [#])', [_emitType(elementType), elements]));
   }
 
   @override
-  JS.Expression visitMapLiteral(MapLiteral node) {
+  js_ast.Expression visitMapLiteral(MapLiteral node) {
     var entries = [
       for (var e in node.entries) ...[
         _visitExpression(e.key),
@@ -5071,71 +5103,72 @@
     return _emitConstMap(node.keyType, node.valueType, entries);
   }
 
-  JS.Expression _emitConstMap(
-      DartType keyType, DartType valueType, List<JS.Expression> entries) {
+  js_ast.Expression _emitConstMap(
+      DartType keyType, DartType valueType, List<js_ast.Expression> entries) {
     return cacheConst(runtimeCall('constMap(#, #, [#])',
         [_emitType(keyType), _emitType(valueType), entries]));
   }
 
   @override
-  JS.Expression visitAwaitExpression(AwaitExpression node) =>
-      JS.Yield(_visitExpression(node.operand));
+  js_ast.Expression visitAwaitExpression(AwaitExpression node) =>
+      js_ast.Yield(_visitExpression(node.operand));
 
   @override
-  JS.Expression visitFunctionExpression(FunctionExpression node) {
+  js_ast.Expression visitFunctionExpression(FunctionExpression node) {
     var fn = _emitArrowFunction(node);
     if (!_reifyFunctionType(node.function)) return fn;
     return _emitFunctionTagged(fn, node.getStaticType(types) as FunctionType);
   }
 
-  JS.ArrowFun _emitArrowFunction(FunctionExpression node) {
-    JS.Fun f = _emitFunction(node.function, null);
-    JS.Node body = f.body;
+  js_ast.ArrowFun _emitArrowFunction(FunctionExpression node) {
+    js_ast.Fun f = _emitFunction(node.function, null);
+    js_ast.Node body = f.body;
 
     // Simplify `=> { return e; }` to `=> e`
-    if (body is JS.Block) {
-      var block = body as JS.Block;
+    if (body is js_ast.Block) {
+      var block = body as js_ast.Block;
       if (block.statements.length == 1) {
-        JS.Statement s = block.statements[0];
-        if (s is JS.Block) {
-          block = s as JS.Block;
+        js_ast.Statement s = block.statements[0];
+        if (s is js_ast.Block) {
+          block = s as js_ast.Block;
           s = block.statements.length == 1 ? block.statements[0] : null;
         }
-        if (s is JS.Return && s.value != null) body = s.value;
+        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.ArrowFun(f.params, body);
+    return js_ast.ArrowFun(f.params, body);
   }
 
   @override
-  JS.Expression visitStringLiteral(StringLiteral node) =>
+  js_ast.Expression visitStringLiteral(StringLiteral node) =>
       js.escapedString(node.value, '"');
 
   @override
-  JS.Expression visitIntLiteral(IntLiteral node) => js.uint64(node.value);
+  js_ast.Expression visitIntLiteral(IntLiteral node) => js.uint64(node.value);
 
   @override
-  JS.Expression visitDoubleLiteral(DoubleLiteral node) => js.number(node.value);
+  js_ast.Expression visitDoubleLiteral(DoubleLiteral node) =>
+      js.number(node.value);
 
   @override
-  JS.Expression visitBoolLiteral(BoolLiteral node) =>
-      JS.LiteralBool(node.value);
+  js_ast.Expression visitBoolLiteral(BoolLiteral node) =>
+      js_ast.LiteralBool(node.value);
 
   @override
-  JS.Expression visitNullLiteral(NullLiteral node) => JS.LiteralNull();
+  js_ast.Expression visitNullLiteral(NullLiteral node) => js_ast.LiteralNull();
 
   @override
-  JS.Expression visitLet(Let node) {
+  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.Assignment(temp, init);
+        init = js_ast.Assignment(temp, init);
         _letVariables.add(temp);
       } else {
         // TODO(jmesserly): make sure this doesn't happen on any performance
@@ -5143,37 +5176,37 @@
         //
         // Annotations on a top-level, non-lazy function type should be the only
         // remaining use.
-        return JS.Call(JS.ArrowFun([temp], body), [init]);
+        return js_ast.Call(js_ast.ArrowFun([temp], body), [init]);
       }
     }
-    return JS.Binary(',', init, body);
+    return js_ast.Binary(',', init, body);
   }
 
   @override
-  JS.Expression visitBlockExpression(BlockExpression node) {
+  js_ast.Expression visitBlockExpression(BlockExpression node) {
     var jsExpr = _visitExpression(node.value);
     var jsStmts = [
       for (var s in node.body.statements) _visitStatement(s),
-      JS.Return(jsExpr),
+      js_ast.Return(jsExpr),
     ];
-    var jsBlock = JS.Block(jsStmts);
+    var jsBlock = js_ast.Block(jsStmts);
     // BlockExpressions with async operations must be constructed
     // with a generator instead of a lambda.
     var finder = YieldFinder();
     jsBlock.accept(finder);
     if (finder.hasYield) {
-      var genFn = JS.Fun([], jsBlock, isGenerator: true);
+      var genFn = js_ast.Fun([], jsBlock, isGenerator: true);
       var asyncLibrary = emitLibraryName(coreTypes.asyncLibrary);
       var returnType = _emitType(node.getStaticType(types));
       var asyncCall =
           js.call('#.async(#, #)', [asyncLibrary, returnType, genFn]);
-      return JS.Yield(asyncCall);
+      return js_ast.Yield(asyncCall);
     }
-    return JS.Call(JS.ArrowFun([], jsBlock), []);
+    return js_ast.Call(js_ast.ArrowFun([], jsBlock), []);
   }
 
   @override
-  JS.Expression visitInstantiation(Instantiation node) {
+  js_ast.Expression visitInstantiation(Instantiation node) {
     return runtimeCall('gbind(#, #)', [
       _visitExpression(node.expression),
       node.typeArguments.map(_emitType).toList()
@@ -5181,7 +5214,7 @@
   }
 
   @override
-  JS.Expression visitLoadLibrary(LoadLibrary node) =>
+  js_ast.Expression visitLoadLibrary(LoadLibrary node) =>
       runtimeCall('loadLibrary()');
 
   // TODO(jmesserly): DDC loads all libraries eagerly.
@@ -5189,7 +5222,7 @@
   // https://github.com/dart-lang/sdk/issues/27776
   // https://github.com/dart-lang/sdk/issues/27777
   @override
-  JS.Expression visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) =>
+  js_ast.Expression visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) =>
       js.boolean(true);
 
   bool _reifyFunctionType(FunctionNode f) {
@@ -5236,16 +5269,18 @@
         findAnnotation(node, test), 'name') as String;
   }
 
-  JS.Expression visitConstant(Constant node) =>
-      node.accept(this) as JS.Expression;
+  js_ast.Expression visitConstant(Constant node) =>
+      node.accept(this) as js_ast.Expression;
   @override
-  JS.Expression visitNullConstant(NullConstant node) => JS.LiteralNull();
+  js_ast.Expression visitNullConstant(NullConstant node) =>
+      js_ast.LiteralNull();
   @override
-  JS.Expression visitBoolConstant(BoolConstant node) => js.boolean(node.value);
+  js_ast.Expression visitBoolConstant(BoolConstant node) =>
+      js.boolean(node.value);
   @override
-  JS.Expression visitIntConstant(IntConstant node) => js.number(node.value);
+  js_ast.Expression visitIntConstant(IntConstant node) => js.number(node.value);
   @override
-  JS.Expression visitDoubleConstant(DoubleConstant node) {
+  js_ast.Expression visitDoubleConstant(DoubleConstant node) {
     var value = node.value;
 
     // Emit the constant as an integer, if possible.
@@ -5263,20 +5298,20 @@
   }
 
   @override
-  JS.Expression visitStringConstant(StringConstant node) =>
+  js_ast.Expression visitStringConstant(StringConstant node) =>
       js.escapedString(node.value, '"');
 
   // DDC does not currently use the non-primivite constant nodes; rather these
   // are emitted via their normal expression nodes.
   @override
-  JS.Expression defaultConstant(Constant node) => _emitInvalidNode(node);
+  js_ast.Expression defaultConstant(Constant node) => _emitInvalidNode(node);
 
   @override
-  JS.Expression visitSymbolConstant(SymbolConstant node) =>
+  js_ast.Expression visitSymbolConstant(SymbolConstant node) =>
       emitDartSymbol(node.name);
 
   @override
-  JS.Expression visitMapConstant(MapConstant node) {
+  js_ast.Expression visitMapConstant(MapConstant node) {
     var entries = [
       for (var e in node.entries) ...[
         visitConstant(e.key),
@@ -5287,42 +5322,42 @@
   }
 
   @override
-  JS.Expression visitListConstant(ListConstant node) => _emitConstList(
+  js_ast.Expression visitListConstant(ListConstant node) => _emitConstList(
       node.typeArgument, node.entries.map(visitConstant).toList());
 
   @override
-  JS.Expression visitSetConstant(SetConstant node) => _emitConstSet(
+  js_ast.Expression visitSetConstant(SetConstant node) => _emitConstSet(
       node.typeArgument, node.entries.map(visitConstant).toList());
 
   @override
-  JS.Expression visitInstanceConstant(InstanceConstant node) {
+  js_ast.Expression visitInstanceConstant(InstanceConstant node) {
     entryToProperty(MapEntry<Reference, Constant> entry) {
-      var constant = entry.value.accept(this) as JS.Expression;
+      var constant = entry.value.accept(this) as js_ast.Expression;
       var member = entry.key.asField;
-      return JS.Property(
+      return js_ast.Property(
           _emitMemberName(member.name.name, member: member), constant);
     }
 
     var type = visitInterfaceType(node.getType(types) as InterfaceType);
     var prototype = js.call("#.prototype", [type]);
     var properties = [
-      JS.Property(propertyName("__proto__"), prototype),
+      js_ast.Property(propertyName("__proto__"), prototype),
       for (var e in node.fieldValues.entries) entryToProperty(e),
     ];
     return canonicalizeConstObject(
-        JS.ObjectInitializer(properties, multiline: true));
+        js_ast.ObjectInitializer(properties, multiline: true));
   }
 
   @override
-  JS.Expression visitTearOffConstant(TearOffConstant node) =>
+  js_ast.Expression visitTearOffConstant(TearOffConstant node) =>
       _emitStaticGet(node.procedure);
 
   @override
-  JS.Expression visitTypeLiteralConstant(TypeLiteralConstant node) =>
+  js_ast.Expression visitTypeLiteralConstant(TypeLiteralConstant node) =>
       _emitTypeLiteral(node.type);
 
   @override
-  JS.Expression visitPartialInstantiationConstant(
+  js_ast.Expression visitPartialInstantiationConstant(
           PartialInstantiationConstant node) =>
       runtimeCall('gbind(#, #)', [
         visitConstant(node.tearOffConstant),
@@ -5330,7 +5365,7 @@
       ]);
 
   @override
-  JS.Expression visitUnevaluatedConstant(UnevaluatedConstant node) =>
+  js_ast.Expression visitUnevaluatedConstant(UnevaluatedConstant node) =>
       _visitExpression(node.expression);
 }
 
@@ -5383,7 +5418,7 @@
 
 class SwitchLabelState {
   String label;
-  JS.Identifier variable;
+  js_ast.Identifier variable;
 
   SwitchLabelState(this.label, this.variable);
 }
diff --git a/pkg/dev_compiler/lib/src/kernel/property_model.dart b/pkg/dev_compiler/lib/src/kernel/property_model.dart
index df0444b..7c5bcee 100644
--- a/pkg/dev_compiler/lib/src/kernel/property_model.dart
+++ b/pkg/dev_compiler/lib/src/kernel/property_model.dart
@@ -7,8 +7,8 @@
 import 'package:kernel/core_types.dart';
 import 'package:kernel/kernel.dart';
 import 'package:kernel/type_environment.dart';
-import '../compiler/js_names.dart' as JS;
-import '../js_ast/js_ast.dart' as JS;
+
+import '../compiler/js_names.dart' as js_ast;
 import 'kernel_helpers.dart';
 import 'native_types.dart';
 
@@ -183,7 +183,7 @@
   /// pair in JavaScript.
   ///
   /// The value property stores the symbol used for the field's storage slot.
-  final virtualFields = <Field, JS.TemporaryId>{};
+  final virtualFields = <Field, js_ast.TemporaryId>{};
 
   /// The set of inherited getters, used because JS getters/setters are paired,
   /// so if we're generating a setter we may need to emit a getter that calls
@@ -246,7 +246,7 @@
           fieldModel.isVirtual(field) ||
           field.isCovariant ||
           field.isGenericCovariantImpl) {
-        virtualFields[field] = JS.TemporaryId(name);
+        virtualFields[field] = js_ast.TemporaryId(name);
       }
     }
   }
diff --git a/pkg/dev_compiler/lib/src/kernel/type_table.dart b/pkg/dev_compiler/lib/src/kernel/type_table.dart
index 7dd63c9..076075c 100644
--- a/pkg/dev_compiler/lib/src/kernel/type_table.dart
+++ b/pkg/dev_compiler/lib/src/kernel/type_table.dart
@@ -4,9 +4,9 @@
 
 import 'package:kernel/kernel.dart';
 
-import '../js_ast/js_ast.dart' as JS;
+import '../compiler/js_names.dart' as js_ast;
+import '../js_ast/js_ast.dart' as js_ast;
 import '../js_ast/js_ast.dart' show js;
-import '../compiler/js_names.dart' as JS;
 
 Set<TypeParameter> freeTypeParameters(DartType t) {
   var result = Set<TypeParameter>();
@@ -37,10 +37,10 @@
   // Use a LinkedHashMap to maintain key insertion order so the generated code
   // is stable under slight perturbation.  (If this is not good enough we could
   // sort by name to canonicalize order.)
-  final _names = <DartType, JS.TemporaryId>{};
+  final _names = <DartType, js_ast.TemporaryId>{};
   Iterable<DartType> get keys => _names.keys.toList();
 
-  JS.Statement _dischargeType(DartType type) {
+  js_ast.Statement _dischargeType(DartType type) {
     var name = _names.remove(type);
     if (name != null) {
       return js.statement('let #;', [name]);
@@ -51,8 +51,8 @@
   /// Emit a list of statements declaring the cache variables for
   /// types tracked by this table.  If [typeFilter] is given,
   /// only emit the types listed in the filter.
-  List<JS.Statement> discharge([Iterable<DartType> typeFilter]) {
-    var decls = <JS.Statement>[];
+  List<js_ast.Statement> discharge([Iterable<DartType> typeFilter]) {
+    var decls = <js_ast.Statement>[];
     var types = typeFilter ?? keys;
     for (var t in types) {
       var stmt = _dischargeType(t);
@@ -102,25 +102,25 @@
 
   /// Heuristically choose a good name for the cache and generator
   /// variables.
-  JS.TemporaryId chooseTypeName(DartType type) {
-    return JS.TemporaryId(_typeString(type));
+  js_ast.TemporaryId chooseTypeName(DartType type) {
+    return js_ast.TemporaryId(_typeString(type));
   }
 }
 
 /// _GeneratorTable tracks types which have been
 /// named and hoisted.
 class _GeneratorTable extends _CacheTable {
-  final _defs = <DartType, JS.Expression>{};
+  final _defs = <DartType, js_ast.Expression>{};
 
-  final JS.Identifier _runtimeModule;
+  final js_ast.Identifier _runtimeModule;
 
   _GeneratorTable(this._runtimeModule);
 
   @override
-  JS.Statement _dischargeType(DartType t) {
+  js_ast.Statement _dischargeType(DartType t) {
     var name = _names.remove(t);
     if (name != null) {
-      JS.Expression init = _defs.remove(t);
+      js_ast.Expression init = _defs.remove(t);
       assert(init != null);
       return js.statement('let # = () => ((# = #.constFn(#))());',
           [name, name, _runtimeModule, init]);
@@ -131,7 +131,7 @@
   /// If [type] does not already have a generator name chosen for it,
   /// assign it one, using [typeRep] as the initializer for it.
   /// Emit the generator name.
-  JS.TemporaryId _nameType(DartType type, JS.Expression typeRep) {
+  js_ast.TemporaryId _nameType(DartType type, js_ast.Expression typeRep) {
     var temp = _names[type];
     if (temp == null) {
       _names[type] = temp = chooseTypeName(type);
@@ -151,12 +151,12 @@
   /// parameter.
   final _scopeDependencies = <TypeParameter, List<DartType>>{};
 
-  TypeTable(JS.Identifier runtime) : _generators = _GeneratorTable(runtime);
+  TypeTable(js_ast.Identifier runtime) : _generators = _GeneratorTable(runtime);
 
   /// Emit a list of statements declaring the cache variables and generator
   /// definitions tracked by the table.  If [formals] is present, only
   /// emit the definitions which depend on the formals.
-  List<JS.Statement> discharge([List<TypeParameter> formals]) {
+  List<js_ast.Statement> discharge([List<TypeParameter> formals]) {
     var filter = formals?.expand((p) => _scopeDependencies[p] ?? <DartType>[]);
     var stmts = _generators.discharge(filter);
     formals?.forEach(_scopeDependencies.remove);
@@ -186,7 +186,7 @@
   /// Given a type [type], and a JS expression [typeRep] which implements it,
   /// add the type and its representation to the table, returning an
   /// expression which implements the type (but which caches the value).
-  JS.Expression nameType(DartType type, JS.Expression typeRep) {
+  js_ast.Expression nameType(DartType type, js_ast.Expression typeRep) {
     if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
       return typeRep;
     }
@@ -200,10 +200,11 @@
   /// should be a function that is invoked to compute the type, rather than the
   /// type itself. This allows better integration with `lazyFn`, avoiding an
   /// extra level of indirection.
-  JS.Expression nameFunctionType(FunctionType type, JS.Expression typeRep,
+  js_ast.Expression nameFunctionType(
+      FunctionType type, js_ast.Expression typeRep,
       {bool lazy = false}) {
     if (!_generators.isNamed(type) && recordScopeDependencies(type)) {
-      return lazy ? JS.ArrowFun([], typeRep) : typeRep;
+      return lazy ? js_ast.ArrowFun([], typeRep) : typeRep;
     }
     var name = _generators._nameType(type, typeRep);
     return lazy ? name : js.call('#()', [name]);
