Version 2.18.0-221.0.dev

Merge commit 'fed11104ee8dd97862271db5a0dc70fa6d249654' into 'dev'
diff --git a/DEPS b/DEPS
index e0f095f..1c07751 100644
--- a/DEPS
+++ b/DEPS
@@ -66,8 +66,8 @@
   # The list of revisions for these tools comes from Fuchsia, here:
   # https://fuchsia.googlesource.com/integration/+/HEAD/toolchain
   # If there are problems with the toolchain, contact fuchsia-toolchain@.
-  "clang_revision": "c2592c374e469f343ecea82d6728609650924259",
-  "gn_revision": "d7c2209cebcfe37f46dba7be4e1a7000ffc342fb",
+  "clang_revision": "aaaf8e4c409f080f35ea227b20dc6ac8a45c2fa4",
+  "gn_revision": "e62d4e1938a45babc9afb6db543f388cd1802a52",
 
   # Scripts that make 'git cl format' work.
   "clang_format_scripts_rev": "bb994c6f067340c1135eb43eed84f4b33cfa7397",
diff --git a/build/config/compiler/BUILD.gn b/build/config/compiler/BUILD.gn
index f2984fb..49b5efc 100644
--- a/build/config/compiler/BUILD.gn
+++ b/build/config/compiler/BUILD.gn
@@ -545,6 +545,7 @@
       "-Wno-microsoft-unqualified-friend",
       "-Wno-unknown-argument",  # icu
       "-Wno-unused-value",  # crashpad
+      "-Wno-deprecated-non-prototype",  # zlib
     ]
   } else {
     default_warning_flags += [
@@ -576,6 +577,7 @@
     default_warning_flags += [
       "-Wno-tautological-constant-compare",
       "-Wno-unused-but-set-variable",  # icu
+      "-Wno-deprecated-non-prototype",  # zlib
     ]
   } else {
     default_warning_flags +=
diff --git a/pkg/compiler/lib/src/common/work.dart b/pkg/compiler/lib/src/common/work.dart
index c7ca7c9..a36d6b0 100644
--- a/pkg/compiler/lib/src/common/work.dart
+++ b/pkg/compiler/lib/src/common/work.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.10
-
 library dart2js.common.work;
 
 import '../elements/entities.dart' show MemberEntity;
diff --git a/pkg/compiler/lib/src/enqueue.dart b/pkg/compiler/lib/src/enqueue.dart
index a664e0d..7618902 100644
--- a/pkg/compiler/lib/src/enqueue.dart
+++ b/pkg/compiler/lib/src/enqueue.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.10
-
 library dart2js.enqueue;
 
 import 'common/elements.dart' show ElementEnvironment;
@@ -82,7 +80,8 @@
   // side-effects.
   static bool skipEnqueuerCheckForTesting = false;
 
-  bool queueIsClosed;
+  bool get queueIsClosed;
+  set queueIsClosed(bool closed);
 
   bool get queueIsEmpty;
 
@@ -110,8 +109,8 @@
 
   CompilerTask get task;
   void checkClass(ClassEntity cls);
-  void processStaticUse(MemberEntity member, StaticUse staticUse);
-  void processTypeUse(MemberEntity member, TypeUse typeUse);
+  void processStaticUse(MemberEntity? member, StaticUse staticUse);
+  void processTypeUse(MemberEntity? member, TypeUse typeUse);
   void processDynamicUse(DynamicUse dynamicUse);
   void processConstantUse(ConstantUse constantUse);
   EnqueuerListener get listener;
@@ -129,7 +128,7 @@
     task.measureSubtask('resolution.check', () {
       // Run through the classes and see if we need to enqueue more methods.
       for (ClassEntity classElement in directlyInstantiatedClasses) {
-        for (ClassEntity currentClass = classElement;
+        for (ClassEntity? currentClass = classElement;
             currentClass != null;
             currentClass = elementEnvironment.getSuperClass(currentClass)) {
           checkClass(currentClass);
diff --git a/pkg/compiler/lib/src/ir/cached_static_type.dart b/pkg/compiler/lib/src/ir/cached_static_type.dart
index fa192c5..d25cf28 100644
--- a/pkg/compiler/lib/src/ir/cached_static_type.dart
+++ b/pkg/compiler/lib/src/ir/cached_static_type.dart
@@ -23,7 +23,7 @@
       : super(staticTypeContext.typeEnvironment);
 
   @override
-  ir.DartType getStaticType(ir.Expression node) => node.accept(this)!;
+  ir.DartType getStaticType(ir.Expression node) => node.accept(this);
 
   @override
   ir.DartType getForInIteratorType(ir.ForInStatement node) =>
diff --git a/pkg/compiler/lib/src/ir/element_map.dart b/pkg/compiler/lib/src/ir/element_map.dart
index 6b61632..1b4030d 100644
--- a/pkg/compiler/lib/src/ir/element_map.dart
+++ b/pkg/compiler/lib/src/ir/element_map.dart
@@ -8,7 +8,6 @@
 import '../common.dart';
 import '../common/elements.dart';
 import '../elements/entities.dart';
-import '../elements/indexed.dart';
 import '../elements/types.dart';
 import '../ordered_typeset.dart';
 import '../universe/call_structure.dart';
@@ -63,6 +62,6 @@
   DartType substByContext(DartType type, InterfaceType context);
   FunctionType? getCallType(InterfaceType type);
   int getHierarchyDepth(covariant ClassEntity cls);
-  DartType getTypeVariableBound(IndexedTypeVariable typeVariable);
+  DartType getTypeVariableBound(covariant TypeVariableEntity typeVariable);
   List<Variance> getTypeVariableVariances(covariant ClassEntity cls);
 }
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index da1366e..25cb12d 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -206,7 +206,7 @@
   }
 
   @override
-  Null handleFunctionDeclaration(ir.FunctionDeclaration node) {
+  void handleFunctionDeclaration(ir.FunctionDeclaration node) {
     registerLocalFunction(node);
     handleAsyncMarker(node.function);
   }
@@ -550,7 +550,7 @@
   }
 
   @override
-  Null visitSwitchStatement(ir.SwitchStatement node) {
+  ir.DartType visitSwitchStatement(ir.SwitchStatement node) {
     registerSwitchStatementNode(node);
     return super.visitSwitchStatement(node);
   }
diff --git a/pkg/compiler/lib/src/ir/static_type.dart b/pkg/compiler/lib/src/ir/static_type.dart
index 061804e..d2719fc 100644
--- a/pkg/compiler/lib/src/ir/static_type.dart
+++ b/pkg/compiler/lib/src/ir/static_type.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.10
-
 import 'package:front_end/src/api_unstable/dart2js.dart'
     show operatorFromString;
 import 'package:kernel/ast.dart' as ir;
@@ -60,15 +58,15 @@
 /// the readily compute static types of subexpressions.
 abstract class StaticTypeVisitor extends StaticTypeBase {
   final StaticTypeCacheImpl _staticTypeCache;
-  Map<ir.Expression, TypeMap> typeMapsForTesting;
+  Map<ir.Expression, TypeMap>? typeMapsForTesting;
   // TODO(johnniwinther): Change the key to `InstanceGet` when the old method
   //  invocation encoding is no longer used.
   final Map<ir.Expression, RuntimeTypeUseData> _pendingRuntimeTypeUseData = {};
 
   final ir.ClassHierarchy hierarchy;
 
-  ThisInterfaceType _thisType;
-  ir.Library _currentLibrary;
+  ThisInterfaceType? _thisType;
+  ir.Library? _currentLibrary;
 
   StaticTypeVisitor(
       ir.TypeEnvironment typeEnvironment, this.hierarchy, this._staticTypeCache)
@@ -91,40 +89,37 @@
 
   @override
   ThisInterfaceType get thisType {
-    assert(_thisType != null);
-    return _thisType;
+    return _thisType!;
   }
 
-  void set thisType(ThisInterfaceType value) {
+  void set thisType(ThisInterfaceType? value) {
     assert(value == null || _thisType == null);
     _thisType = value;
   }
 
   ir.Library get currentLibrary {
-    assert(_currentLibrary != null);
-    return _currentLibrary;
+    return _currentLibrary!;
   }
 
-  void set currentLibrary(ir.Library value) {
+  void set currentLibrary(ir.Library? value) {
     assert(value == null || _currentLibrary == null);
     _currentLibrary = value;
   }
 
-  bool completes(ir.DartType type) => type != const DoesNotCompleteType();
+  bool completes(ir.DartType? type) => type != const DoesNotCompleteType();
 
-  Set<ir.VariableDeclaration> _currentVariables;
-  final Set<ir.VariableDeclaration> _invalidatedVariables =
-      Set<ir.VariableDeclaration>();
+  Set<ir.VariableDeclaration>? _currentVariables;
+  final Set<ir.VariableDeclaration> _invalidatedVariables = {};
 
-  TypeMap _typeMapBase = const TypeMap();
-  TypeMap _typeMapWhenTrue;
-  TypeMap _typeMapWhenFalse;
+  TypeMap? _typeMapBase = const TypeMap();
+  TypeMap? _typeMapWhenTrue;
+  TypeMap? _typeMapWhenFalse;
 
   /// Joins [_typeMapWhenTrue] and [_typeMapWhenFalse] and stores the result
   /// in [_typeMapBase].
   void _flattenTypeMap() {
     if (_typeMapBase == null) {
-      _typeMapBase = _typeMapWhenTrue.join(_typeMapWhenFalse);
+      _typeMapBase = _typeMapWhenTrue!.join(_typeMapWhenFalse!);
       _typeMapWhenTrue = _typeMapWhenFalse = null;
     }
   }
@@ -133,7 +128,7 @@
   /// the most recent node is not taken into account.
   TypeMap get typeMap {
     _flattenTypeMap();
-    return _typeMapBase;
+    return _typeMapBase!;
   }
 
   /// Sets the local variable type promotions for when the boolean value of
@@ -145,7 +140,7 @@
 
   /// Returns the local variable type promotions for when the boolean value of
   /// the most recent node is `true`.
-  TypeMap get typeMapWhenTrue => _typeMapWhenTrue ?? _typeMapBase;
+  TypeMap get typeMapWhenTrue => _typeMapWhenTrue ?? _typeMapBase!;
 
   /// Sets the local variable type promotions for when the boolean value of
   /// the most recent node is `true`.
@@ -156,7 +151,7 @@
 
   /// Returns the local variable type promotions for when the boolean value of
   /// the most recent node is `false`.
-  TypeMap get typeMapWhenFalse => _typeMapWhenFalse ?? _typeMapBase;
+  TypeMap get typeMapWhenFalse => _typeMapWhenFalse ?? _typeMapBase!;
 
   /// Sets the local variable type promotions for when the boolean value of
   /// the most recent node is `false`.
@@ -166,31 +161,30 @@
   }
 
   @override
-  ir.DartType defaultNode(ir.Node node) =>
-      throw UnsupportedError('Unhandled node $node (${node.runtimeType})');
-
-  @override
-  Null visitComponent(ir.Component node) {
+  ir.DartType visitComponent(ir.Component node) {
     visitNodes(node.libraries);
+    return const ir.VoidType();
   }
 
   @override
-  Null visitLibrary(ir.Library node) {
+  ir.DartType visitLibrary(ir.Library node) {
     visitNodes(node.classes);
     visitNodes(node.procedures);
     visitNodes(node.fields);
+    return const ir.VoidType();
   }
 
   @override
-  Null visitClass(ir.Class node) {
+  ir.DartType visitClass(ir.Class node) {
     visitNodes(node.constructors);
     visitNodes(node.procedures);
     visitNodes(node.fields);
+    return const ir.VoidType();
   }
 
-  ir.InterfaceType getInterfaceTypeOf(ir.DartType type) {
+  ir.InterfaceType? getInterfaceTypeOf(ir.DartType type) {
     while (type is ir.TypeParameterType) {
-      type = (type as ir.TypeParameterType).parameter.bound;
+      type = type.parameter.bound;
     }
     if (type is ir.InterfaceType) {
       return type;
@@ -222,7 +216,7 @@
           .rawType(superclass, currentLibrary.nonNullable);
     }
     while (type is ir.TypeParameterType) {
-      type = (type as ir.TypeParameterType).parameter.bound;
+      type = type.parameter.bound;
     }
     if (type is ir.NullType ||
         type is ir.NeverType &&
@@ -232,7 +226,7 @@
           .bottomInterfaceType(superclass, currentLibrary.nullable);
     }
     if (type is ir.InterfaceType) {
-      ir.InterfaceType upcastType = typeEnvironment.getTypeAsInstanceOf(
+      ir.InterfaceType? upcastType = typeEnvironment.getTypeAsInstanceOf(
           type, superclass, currentLibrary, typeEnvironment.coreTypes);
       if (upcastType != null) return upcastType;
     }
@@ -241,7 +235,7 @@
         .rawType(superclass, currentLibrary.nonNullable);
   }
 
-  ir.Member _resolveDynamicTarget(ir.DartType receiverType, ir.Name name) {
+  ir.Member? _resolveDynamicTarget(ir.DartType receiverType, ir.Name name) {
     if (receiverType is ir.InterfaceType) {
       return hierarchy.getInterfaceMember(receiverType.classNode, name);
     }
@@ -250,9 +244,9 @@
 
   ir.DartType _computeInstanceGetType(
       ir.DartType receiverType, ir.Member interfaceTarget) {
-    ir.Class superclass = interfaceTarget.enclosingClass;
-    receiverType = getTypeAsInstanceOf(receiverType, superclass);
-    return ir.Substitution.fromInterfaceType(receiverType)
+    ir.Class superclass = interfaceTarget.enclosingClass!;
+    final castType = getTypeAsInstanceOf(receiverType, superclass);
+    return ir.Substitution.fromInterfaceType(castType)
         .substituteType(interfaceTarget.getterType);
   }
 
@@ -272,7 +266,7 @@
   // TODO(johnniwinther): Change [node] to `InstanceGet` when the old method
   // invocation encoding is no longer used.
   void handleRuntimeTypeUse(ir.Expression node, RuntimeTypeUseKind kind,
-      ir.DartType receiverType, ir.DartType argumentType) {}
+      ir.DartType? receiverType, ir.DartType? argumentType) {}
 
   void handleRuntimeTypeGet(ir.DartType receiverType, ir.Expression node) {
     RuntimeTypeUseData data =
@@ -304,7 +298,7 @@
   ir.DartType visitDynamicGet(ir.DynamicGet node) {
     ir.DartType receiverType = visitNode(node.receiver);
     ir.DartType resultType = super.visitDynamicGet(node);
-    ir.Member interfaceTarget = _resolveDynamicTarget(receiverType, node.name);
+    ir.Member? interfaceTarget = _resolveDynamicTarget(receiverType, node.name);
     if (interfaceTarget != null) {
       resultType = _computeInstanceGetType(receiverType, interfaceTarget);
       ir.InstanceGet instanceGet = ir.InstanceGet(
@@ -381,7 +375,7 @@
   void handleInstanceSet(ir.Expression node, ir.DartType receiverType,
       ir.Member interfaceTarget, ir.DartType valueType) {}
 
-  ir.Member _resolveDynamicSet(ir.DartType receiverType, ir.Name name) {
+  ir.Member? _resolveDynamicSet(ir.DartType receiverType, ir.Name name) {
     if (receiverType is ir.InterfaceType) {
       return hierarchy.getInterfaceMember(receiverType.classNode, name,
           setter: true);
@@ -391,13 +385,13 @@
 
   ir.DartType _computeInstanceSetType(
       ir.DartType receiverType, ir.Member interfaceTarget) {
-    ir.Class superclass = interfaceTarget.enclosingClass;
+    ir.Class superclass = interfaceTarget.enclosingClass!;
     ir.Substitution receiverSubstitution = ir.Substitution.fromInterfaceType(
         getTypeAsInstanceOf(receiverType, superclass));
     return receiverSubstitution.substituteType(interfaceTarget.setterType);
   }
 
-  ir.AsExpression _createImplicitAsIfNeeded(
+  ir.AsExpression? _createImplicitAsIfNeeded(
       ir.Expression value, ir.DartType valueType, ir.DartType setterType) {
     if (!typeEnvironment.isSubtypeOf(
         valueType, setterType, ir.SubtypeCheckMode.ignoringNullabilities)) {
@@ -413,12 +407,12 @@
   ir.DartType visitDynamicSet(ir.DynamicSet node) {
     ir.DartType receiverType = visitNode(node.receiver);
     ir.DartType valueType = visitNode(node.value);
-    ir.Member interfaceTarget = _resolveDynamicSet(receiverType, node.name);
+    ir.Member? interfaceTarget = _resolveDynamicSet(receiverType, node.name);
     if (interfaceTarget != null) {
       ir.DartType setterType =
           _computeInstanceSetType(receiverType, interfaceTarget);
       ir.Expression value = node.value;
-      ir.AsExpression implicitCast =
+      ir.AsExpression? implicitCast =
           _createImplicitAsIfNeeded(value, valueType, setterType);
       if (implicitCast != null) {
         value = implicitCast;
@@ -457,25 +451,14 @@
         typeEnvironment.isSpecialCasedBinaryOperator(interfaceTarget);
   }
 
-  ir.Member _getMember(ir.Class cls, String name) {
-    for (ir.Member member in cls.members) {
-      if (member.name.text == name) return member;
-    }
-    throw fail("Member '$name' not found in $cls");
-  }
-
-  ir.Procedure _objectEquals;
-  ir.Procedure get objectEquals =>
-      _objectEquals ??= _getMember(typeEnvironment.coreTypes.objectClass, '==');
-
   /// Returns [receiverType] narrowed to enclosing class of [interfaceTarget].
   ///
   /// If [interfaceTarget] is `null` or `receiverType` is _not_ `dynamic` no
   /// narrowing is performed.
   ir.DartType _narrowInstanceReceiver(
-      ir.Member interfaceTarget, ir.DartType receiverType) {
+      ir.Member? interfaceTarget, ir.DartType receiverType) {
     if (interfaceTarget != null && receiverType == const ir.DynamicType()) {
-      receiverType = interfaceTarget.enclosingClass.getThisType(
+      receiverType = interfaceTarget.enclosingClass!.getThisType(
           typeEnvironment.coreTypes,
           interfaceTarget.enclosingLibrary.nonNullable);
     }
@@ -535,7 +518,7 @@
 
   /// Returns `true` if [member] can be called with the structure of
   /// [arguments].
-  bool _isApplicableToMember(ir.Arguments arguments, ir.Member member) {
+  bool _isApplicableToMember(ir.Arguments arguments, ir.Member? member) {
     if (member is ir.Procedure) {
       if (member.kind == ir.ProcedureKind.Setter ||
           member.kind == ir.ProcedureKind.Factory) {
@@ -549,7 +532,7 @@
             member.function.typeParameters.length,
             member.function.requiredParameterCount,
             member.function.positionalParameters.length,
-            () => member.function.namedParameters.map((p) => p.name).toSet());
+            () => member.function.namedParameters.map((p) => p.name!).toSet());
       }
     } else if (member is ir.Field) {
       return _isApplicableToType(arguments, member.type);
@@ -565,11 +548,10 @@
   void _updateMethodInvocationTarget(ir.InvocationExpression node,
       ArgumentTypes argumentTypes, ir.DartType functionType) {
     if (functionType is! ir.FunctionType) return;
-    ir.FunctionType parameterTypes = functionType;
     Map<int, ir.DartType> neededPositionalChecks = {};
     for (int i = 0; i < node.arguments.positional.length; i++) {
       ir.DartType argumentType = argumentTypes.positional[i];
-      ir.DartType parameterType = parameterTypes.positionalParameters[i];
+      ir.DartType parameterType = functionType.positionalParameters[i];
       if (!typeEnvironment.isSubtypeOf(argumentType, parameterType,
           ir.SubtypeCheckMode.ignoringNullabilities)) {
         neededPositionalChecks[i] = parameterType;
@@ -581,7 +563,7 @@
         argumentIndex++) {
       ir.NamedExpression namedArgument = node.arguments.named[argumentIndex];
       ir.DartType argumentType = argumentTypes.named[argumentIndex];
-      ir.DartType parameterType = parameterTypes.namedParameters
+      ir.DartType parameterType = functionType.namedParameters
           .singleWhere((namedType) => namedType.name == namedArgument.name)
           .type;
       if (!typeEnvironment.isSubtypeOf(argumentType, parameterType,
@@ -600,7 +582,7 @@
     // to ensure that the arguments are evaluated before any implicit cast.
 
     ir.Expression updateArgument(ir.Expression expression, ir.TreeNode parent,
-        ir.DartType argumentType, ir.DartType checkedParameterType) {
+        ir.DartType argumentType, ir.DartType? checkedParameterType) {
       ir.VariableDeclaration variable =
           ir.VariableDeclaration.forValue(expression, type: argumentType);
       // Visit the newly created variable declaration.
@@ -652,7 +634,7 @@
     dummy.replaceWith(body);
   }
 
-  ir.Member _resolveDynamicInvocationTarget(
+  ir.Member? _resolveDynamicInvocationTarget(
       ir.DartType receiverType, ir.Name name, ir.Arguments arguments) {
     // TODO(34602): Remove when `interfaceTarget` is set on synthetic calls to
     // ==.
@@ -660,10 +642,10 @@
         arguments.types.isEmpty &&
         arguments.positional.length == 1 &&
         arguments.named.isEmpty) {
-      return objectEquals;
+      return typeEnvironment.coreTypes.objectEquals;
     }
     if (receiverType is ir.InterfaceType) {
-      ir.Member member =
+      ir.Member? member =
           hierarchy.getInterfaceMember(receiverType.classNode, name);
       if (_isApplicableToMember(arguments, member)) {
         return member;
@@ -700,7 +682,7 @@
       ir.Member interfaceTarget,
       ir.Arguments arguments,
       ArgumentTypes argumentTypes) {
-    ir.Class superclass = interfaceTarget.enclosingClass;
+    ir.Class superclass = interfaceTarget.enclosingClass!;
     ir.Substitution receiverSubstitution = ir.Substitution.fromInterfaceType(
         getTypeAsInstanceOf(receiverType, superclass));
     ir.DartType getterType =
@@ -727,7 +709,7 @@
       ir.DartType resultType = typeEnvironment
           .getTypeOfSpecialCasedBinaryOperator(receiverType, argumentType);
       return ir.FunctionType(
-          <ir.DartType>[argumentType], resultType, currentLibrary.nonNullable);
+          [argumentType], resultType, currentLibrary.nonNullable);
     }
     return getterType;
   }
@@ -760,26 +742,12 @@
   }
 
   ArgumentTypes _visitArguments(ir.Arguments arguments) {
-    List<ir.DartType> positional;
-    List<ir.DartType> named;
-    if (arguments.positional.isEmpty) {
-      positional = const <ir.DartType>[];
-    } else {
-      positional = List<ir.DartType>.filled(arguments.positional.length, null);
-      int index = 0;
-      for (ir.Expression argument in arguments.positional) {
-        positional[index++] = visitNode(argument);
-      }
-    }
-    if (arguments.named.isEmpty) {
-      named = const <ir.DartType>[];
-    } else {
-      named = List<ir.DartType>.filled(arguments.named.length, null);
-      int index = 0;
-      for (ir.NamedExpression argument in arguments.named) {
-        named[index++] = visitNode(argument);
-      }
-    }
+    final positional = arguments.positional.isEmpty
+        ? const <ir.DartType>[]
+        : arguments.positional.map(visitNode).toList(growable: false);
+    final named = arguments.named.isEmpty
+        ? const <ir.DartType>[]
+        : arguments.named.map(visitNode).toList(growable: false);
     return ArgumentTypes(positional, named);
   }
 
@@ -837,7 +805,7 @@
     ir.DartType functionType = _computeInstanceInvocationType(
         receiverType, interfaceTarget, node.arguments, argumentTypes);
     if (functionType != node.functionType) {
-      node.functionType = functionType;
+      node.functionType = functionType as ir.FunctionType;
       // TODO(johnniwinther): To provide the static guarantee that arguments
       // of a statically typed call have been checked against the parameter
       // types we need to call [_updateMethodInvocationTarget]. This can create
@@ -881,13 +849,13 @@
   ir.DartType visitDynamicInvocation(ir.DynamicInvocation node) {
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
     ir.DartType receiverType = visitNode(node.receiver);
-    ir.Member interfaceTarget = _resolveDynamicInvocationTarget(
+    ir.Member? interfaceTarget = _resolveDynamicInvocationTarget(
         receiverType, node.name, node.arguments);
     if (interfaceTarget != null) {
       // We can turn the dynamic invocation into an instance invocation.
       ir.DartType functionType = _computeInstanceInvocationType(
           receiverType, interfaceTarget, node.arguments, argumentTypes);
-      ir.Expression replacement;
+      ir.InvocationExpression replacement;
       if (interfaceTarget is ir.Field ||
           (interfaceTarget is ir.Procedure && interfaceTarget.isGetter)) {
         // This should actually be a function invocation of an instance get but
@@ -904,7 +872,8 @@
       } else {
         replacement = ir.InstanceInvocation(ir.InstanceAccessKind.Instance,
             node.receiver, node.name, node.arguments,
-            interfaceTarget: interfaceTarget, functionType: functionType)
+            interfaceTarget: interfaceTarget as ir.Procedure,
+            functionType: functionType as ir.FunctionType)
           ..fileOffset = node.fileOffset;
       }
       _replaceExpression(node, replacement);
@@ -1013,15 +982,13 @@
 
   @override
   ir.DartType visitVariableGet(ir.VariableGet node) {
-    if (typeMapsForTesting != null) {
-      typeMapsForTesting[node] = typeMap;
-    }
+    typeMapsForTesting?[node] = typeMap;
     ir.DartType promotedType = typeMap.typeOf(node, typeEnvironment);
     assert(
         node.promotedType == null ||
             promotedType is ir.NullType ||
             promotedType is ir.FutureOrType ||
-            typeEnvironment.isSubtypeOf(promotedType, node.promotedType,
+            typeEnvironment.isSubtypeOf(promotedType, node.promotedType!,
                 ir.SubtypeCheckMode.ignoringNullabilities),
         "Unexpected promotion of ${node.variable} in ${node.parent}. "
         "Expected ${node.promotedType}, found $promotedType");
@@ -1036,7 +1003,7 @@
   ir.DartType visitVariableSet(ir.VariableSet node) {
     ir.DartType resultType = super.visitVariableSet(node);
     handleVariableSet(node, resultType);
-    if (!_currentVariables.contains(node.variable)) {
+    if (!_currentVariables!.contains(node.variable)) {
       _invalidatedVariables.add(node.variable);
       typeMap = typeMap.remove([node.variable]);
     } else {
@@ -1117,18 +1084,22 @@
   @override
   ir.DartType visitSuperPropertyGet(ir.SuperPropertyGet node) {
     ir.DartType resultType;
-    if (node.interfaceTarget == null) {
+    final interfaceTarget = node.interfaceTarget;
+    if (interfaceTarget == null) {
       // TODO(johnniwinther): Resolve and set the target here.
       resultType = const ir.DynamicType();
     } else {
-      ir.Class declaringClass = node.interfaceTarget.enclosingClass;
+      ir.Class declaringClass = interfaceTarget.enclosingClass!;
       if (declaringClass.typeParameters.isEmpty) {
-        resultType = node.interfaceTarget.superGetterType;
+        resultType = interfaceTarget.superGetterType;
       } else {
-        ir.DartType receiver = typeEnvironment.getTypeAsInstanceOf(thisType,
-            declaringClass, currentLibrary, typeEnvironment.coreTypes);
+        ir.InterfaceType receiver = typeEnvironment.getTypeAsInstanceOf(
+            thisType,
+            declaringClass,
+            currentLibrary,
+            typeEnvironment.coreTypes)!;
         resultType = ir.Substitution.fromInterfaceType(receiver)
-            .substituteType(node.interfaceTarget.superGetterType);
+            .substituteType(interfaceTarget.superGetterType);
       }
     }
     _staticTypeCache._expressionTypes[node] = resultType;
@@ -1153,18 +1124,18 @@
   ir.DartType visitSuperMethodInvocation(ir.SuperMethodInvocation node) {
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
     ir.DartType returnType;
-    if (node.interfaceTarget == null) {
+    final interfaceTarget = node.interfaceTarget;
+    if (interfaceTarget == null) {
       // TODO(johnniwinther): Resolve and set the target here.
       returnType = const ir.DynamicType();
     } else {
-      ir.Class superclass = node.interfaceTarget.enclosingClass;
+      ir.Class superclass = interfaceTarget.enclosingClass!;
       ir.InterfaceType receiverType = typeEnvironment.getTypeAsInstanceOf(
-          thisType, superclass, currentLibrary, typeEnvironment.coreTypes);
+          thisType, superclass, currentLibrary, typeEnvironment.coreTypes)!;
       returnType = ir.Substitution.fromInterfaceType(receiverType)
-          .substituteType(node.interfaceTarget.function.returnType);
+          .substituteType(interfaceTarget.function.returnType);
       returnType = ir.Substitution.fromPairs(
-              node.interfaceTarget.function.typeParameters,
-              node.arguments.types)
+              interfaceTarget.function.typeParameters, node.arguments.types)
           .substituteType(returnType);
     }
     _staticTypeCache._expressionTypes[node] = returnType;
@@ -1208,8 +1179,8 @@
     return super.visitNot(node);
   }
 
-  ir.DartType _handleConditional(
-      ir.Expression condition, ir.TreeNode then, ir.TreeNode otherwise) {
+  ir.DartType? _handleConditional(
+      ir.Expression condition, ir.TreeNode then, ir.TreeNode? otherwise) {
     visitNode(condition);
     TypeMap afterConditionWhenTrue = typeMapWhenTrue;
     TypeMap afterConditionWhenFalse = typeMapWhenFalse;
@@ -1217,7 +1188,7 @@
     ir.DartType thenType = visitNode(then);
     TypeMap afterThen = typeMap;
     typeMap = afterConditionWhenFalse;
-    ir.DartType otherwiseType = visitNode(otherwise);
+    ir.DartType? otherwiseType = visitNodeOrNull(otherwise);
     TypeMap afterOtherwise = typeMap;
     if (completes(thenType) && completes(otherwiseType)) {
       typeMap = afterThen.join(afterOtherwise);
@@ -1284,7 +1255,8 @@
 
   @override
   ir.DartType visitInstantiation(ir.Instantiation node) {
-    ir.FunctionType expressionType = visitNode(node.expression);
+    ir.FunctionType expressionType =
+        visitNode(node.expression) as ir.FunctionType;
     ir.DartType resultType = _computeInstantiationType(node, expressionType);
     _staticTypeCache._expressionTypes[node] = resultType;
     handleInstantiation(node, expressionType, resultType);
@@ -1295,7 +1267,7 @@
   ir.DartType visitBlock(ir.Block node) {
     assert(_pendingRuntimeTypeUseData.isEmpty,
         "Incomplete RuntimeTypeUseData: $_pendingRuntimeTypeUseData");
-    ir.DartType type;
+    ir.DartType? type;
     for (ir.Statement statement in node.statements) {
       if (!completes(visitNode(statement))) {
         type = const DoesNotCompleteType();
@@ -1303,13 +1275,13 @@
     }
     assert(_pendingRuntimeTypeUseData.isEmpty,
         "Incomplete RuntimeTypeUseData: $_pendingRuntimeTypeUseData");
-    return type;
+    return type ?? const ir.VoidType();
   }
 
   @override
   ir.DartType visitExpressionStatement(ir.ExpressionStatement node) {
     if (completes(visitNode(node.expression))) {
-      return null;
+      return const ir.VoidType();
     } else {
       return const DoesNotCompleteType();
     }
@@ -1422,9 +1394,10 @@
   }
 
   @override
-  Null visitMapLiteralEntry(ir.MapLiteralEntry entry) {
+  ir.DartType visitMapLiteralEntry(ir.MapLiteralEntry entry) {
     visitNode(entry.key);
     visitNode(entry.value);
+    return const ir.VoidType();
   }
 
   void handleFunctionExpression(ir.FunctionExpression node) {}
@@ -1435,12 +1408,12 @@
         typeMap.remove(variableScopeModel.getScopeFor(node).assignedVariables);
     typeMap = typeMap.remove(variableScopeModel.assignedVariables);
     ir.DartType returnType = super.visitFunctionExpression(node);
-    Set<ir.VariableDeclaration> _oldVariables = _currentVariables;
+    Set<ir.VariableDeclaration>? _oldVariables = _currentVariables;
     _currentVariables = {};
     visitSignature(node.function);
-    visitNode(node.function.body);
+    visitNodeOrNull(node.function.body);
     handleFunctionExpression(node);
-    _invalidatedVariables.removeAll(_currentVariables);
+    _invalidatedVariables.removeAll(_currentVariables!);
     _currentVariables = _oldVariables;
     typeMap = beforeClosure;
     return returnType;
@@ -1456,9 +1429,10 @@
   }
 
   @override
-  Null visitSwitchCase(ir.SwitchCase node) {
+  ir.DartType visitSwitchCase(ir.SwitchCase node) {
     visitNodes(node.expressions);
     visitNode(node.body);
+    return const ir.VoidType();
   }
 
   @override
@@ -1467,8 +1441,9 @@
   }
 
   @override
-  Null visitLabeledStatement(ir.LabeledStatement node) {
+  ir.DartType visitLabeledStatement(ir.LabeledStatement node) {
     visitNode(node.body);
+    return const ir.VoidType();
   }
 
   @override
@@ -1477,44 +1452,50 @@
   }
 
   @override
-  Null visitYieldStatement(ir.YieldStatement node) {
+  ir.DartType visitYieldStatement(ir.YieldStatement node) {
     visitNode(node.expression);
+    return const ir.VoidType();
   }
 
   @override
-  Null visitAssertInitializer(ir.AssertInitializer node) {
+  ir.DartType visitAssertInitializer(ir.AssertInitializer node) {
     visitNode(node.statement);
+    return const ir.VoidType();
   }
 
   void handleFieldInitializer(ir.FieldInitializer node) {}
 
   @override
-  Null visitFieldInitializer(ir.FieldInitializer node) {
+  ir.DartType visitFieldInitializer(ir.FieldInitializer node) {
     visitNode(node.value);
     handleFieldInitializer(node);
+    return const ir.VoidType();
   }
 
   void handleRedirectingInitializer(
       ir.RedirectingInitializer node, ArgumentTypes argumentTypes) {}
 
   @override
-  Null visitRedirectingInitializer(ir.RedirectingInitializer node) {
+  ir.DartType visitRedirectingInitializer(ir.RedirectingInitializer node) {
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
     handleRedirectingInitializer(node, argumentTypes);
+    return const ir.VoidType();
   }
 
   void handleSuperInitializer(
       ir.SuperInitializer node, ArgumentTypes argumentTypes) {}
 
   @override
-  Null visitSuperInitializer(ir.SuperInitializer node) {
+  ir.DartType visitSuperInitializer(ir.SuperInitializer node) {
     ArgumentTypes argumentTypes = _visitArguments(node.arguments);
     handleSuperInitializer(node, argumentTypes);
+    return const ir.VoidType();
   }
 
   @override
-  Null visitLocalInitializer(ir.LocalInitializer node) {
+  ir.DartType visitLocalInitializer(ir.LocalInitializer node) {
     visitNode(node.variable);
+    return const ir.VoidType();
   }
 
   @override
@@ -1522,33 +1503,35 @@
       visitNode(node.value);
 
   @override
-  Null visitEmptyStatement(ir.EmptyStatement node) {}
+  ir.DartType visitEmptyStatement(ir.EmptyStatement node) =>
+      const ir.VoidType();
 
   @override
-  Null visitForStatement(ir.ForStatement node) {
+  ir.DartType visitForStatement(ir.ForStatement node) {
     visitNodes(node.variables);
     TypeMap beforeLoop = typeMap =
         typeMap.remove(variableScopeModel.getScopeFor(node).assignedVariables);
-    visitNode(node.condition);
+    visitNodeOrNull(node.condition);
     typeMap = typeMapWhenTrue;
     visitNode(node.body);
     visitNodes(node.updates);
     typeMap = beforeLoop;
+    return const ir.VoidType();
   }
 
   void handleForInStatement(ir.ForInStatement node, ir.DartType iterableType,
       ir.DartType iteratorType) {}
 
   @override
-  Null visitForInStatement(ir.ForInStatement node) {
+  ir.DartType visitForInStatement(ir.ForInStatement node) {
     // For sync for-in [iterableType] is a subtype of `Iterable`, for async
     // for-in [iterableType] is a subtype of `Stream`.
     ir.DartType iterableType = visitNode(node.iterable);
     ir.DartType iteratorType = const ir.DynamicType();
-    ir.InterfaceType iterableInterfaceType = getInterfaceTypeOf(iterableType);
+    ir.InterfaceType? iterableInterfaceType = getInterfaceTypeOf(iterableType);
     if (iterableInterfaceType != null) {
       if (node.isAsync) {
-        ir.InterfaceType streamType = typeEnvironment.getTypeAsInstanceOf(
+        ir.InterfaceType? streamType = typeEnvironment.getTypeAsInstanceOf(
             iterableInterfaceType,
             typeEnvironment.coreTypes.streamClass,
             currentLibrary,
@@ -1560,15 +1543,15 @@
               streamType.typeArguments);
         }
       } else {
-        ir.Member member = hierarchy.getInterfaceMember(
+        ir.Member? member = hierarchy.getInterfaceMember(
             iterableInterfaceType.classNode, ir.Name(Identifiers.iterator));
         if (member != null) {
           iteratorType = ir.Substitution.fromInterfaceType(
                   typeEnvironment.getTypeAsInstanceOf(
                       iterableInterfaceType,
-                      member.enclosingClass,
+                      member.enclosingClass!,
                       currentLibrary,
-                      typeEnvironment.coreTypes))
+                      typeEnvironment.coreTypes)!)
               .substituteType(member.getterType);
         }
       }
@@ -1580,31 +1563,34 @@
     visitNode(node.body);
     handleForInStatement(node, iterableType, iteratorType);
     typeMap = beforeLoop;
+    return const ir.VoidType();
   }
 
   @override
-  Null visitDoStatement(ir.DoStatement node) {
+  ir.DartType visitDoStatement(ir.DoStatement node) {
     TypeMap beforeLoop = typeMap =
         typeMap.remove(variableScopeModel.getScopeFor(node).assignedVariables);
     visitNode(node.body);
     visitNode(node.condition);
     typeMap = beforeLoop;
+    return const ir.VoidType();
   }
 
   @override
-  Null visitWhileStatement(ir.WhileStatement node) {
+  ir.DartType visitWhileStatement(ir.WhileStatement node) {
     TypeMap beforeLoop = typeMap =
         typeMap.remove(variableScopeModel.getScopeFor(node).assignedVariables);
     visitNode(node.condition);
     typeMap = typeMapWhenTrue;
     visitNode(node.body);
     typeMap = beforeLoop;
+    return const ir.VoidType();
   }
 
   void handleSwitchStatement(ir.SwitchStatement node) {}
 
   @override
-  Null visitSwitchStatement(ir.SwitchStatement node) {
+  ir.DartType visitSwitchStatement(ir.SwitchStatement node) {
     visitNode(node.expression);
     TypeMap afterExpression = typeMap;
     VariableScope scope = variableScopeModel.getScopeFor(node);
@@ -1617,37 +1603,42 @@
     }
     handleSwitchStatement(node);
     typeMap = afterStatement;
+    return const ir.VoidType();
   }
 
   @override
   ir.DartType visitReturnStatement(ir.ReturnStatement node) {
-    visitNode(node.expression);
+    visitNodeOrNull(node.expression);
     return const DoesNotCompleteType();
   }
 
   @override
   ir.DartType visitIfStatement(ir.IfStatement node) {
-    return _handleConditional(node.condition, node.then, node.otherwise);
+    _handleConditional(node.condition, node.then, node.otherwise);
+    return const ir.VoidType();
   }
 
   @override
-  Null visitTryCatch(ir.TryCatch node) {
+  ir.DartType visitTryCatch(ir.TryCatch node) {
     visitNode(node.body);
     visitNodes(node.catches);
+    return const ir.VoidType();
   }
 
   void handleCatch(ir.Catch node) {}
 
   @override
-  Null visitCatch(ir.Catch node) {
+  ir.DartType visitCatch(ir.Catch node) {
     handleCatch(node);
     visitNode(node.body);
+    return const ir.VoidType();
   }
 
   @override
-  Null visitTryFinally(ir.TryFinally node) {
+  ir.DartType visitTryFinally(ir.TryFinally node) {
     visitNode(node.body);
     visitNode(node.finalizer);
+    return const ir.VoidType();
   }
 
   void handleTypeLiteral(ir.TypeLiteral node) {}
@@ -1669,39 +1660,41 @@
   void handleAssertStatement(ir.AssertStatement node) {}
 
   @override
-  Null visitAssertStatement(ir.AssertStatement node) {
+  ir.DartType visitAssertStatement(ir.AssertStatement node) {
     TypeMap beforeCondition = typeMap;
     visitNode(node.condition);
     TypeMap afterConditionWhenTrue = typeMapWhenTrue;
     TypeMap afterConditionWhenFalse = typeMapWhenFalse;
     typeMap = afterConditionWhenFalse;
-    visitNode(node.message);
+    visitNodeOrNull(node.message);
     handleAssertStatement(node);
     typeMap = useAsserts ? afterConditionWhenTrue : beforeCondition;
+    return const ir.VoidType();
   }
 
   void handleFunctionDeclaration(ir.FunctionDeclaration node) {}
 
   @override
-  Null visitFunctionDeclaration(ir.FunctionDeclaration node) {
+  ir.DartType visitFunctionDeclaration(ir.FunctionDeclaration node) {
     TypeMap beforeClosure =
         typeMap.remove(variableScopeModel.getScopeFor(node).assignedVariables);
     typeMap = typeMap.remove(variableScopeModel.assignedVariables);
-    Set<ir.VariableDeclaration> _oldVariables = _currentVariables;
+    Set<ir.VariableDeclaration>? _oldVariables = _currentVariables;
     _currentVariables = {};
     visitSignature(node.function);
-    visitNode(node.function.body);
+    visitNodeOrNull(node.function.body);
     handleFunctionDeclaration(node);
-    _invalidatedVariables.removeAll(_currentVariables);
+    _invalidatedVariables.removeAll(_currentVariables!);
     _currentVariables = _oldVariables;
     typeMap = beforeClosure;
+    return const ir.VoidType();
   }
 
   void handleParameter(ir.VariableDeclaration node) {}
 
   void visitParameter(ir.VariableDeclaration node) {
-    _currentVariables.add(node);
-    visitNode(node.initializer);
+    _currentVariables?.add(node);
+    visitNodeOrNull(node.initializer);
     handleParameter(node);
   }
 
@@ -1716,70 +1709,76 @@
   void handleProcedure(ir.Procedure node) {}
 
   @override
-  Null visitProcedure(ir.Procedure node) {
+  ir.DartType visitProcedure(ir.Procedure node) {
     thisType = ThisInterfaceType.from(node.enclosingClass?.getThisType(
         typeEnvironment.coreTypes, node.enclosingLibrary.nonNullable));
     _currentVariables = {};
     currentLibrary = node.enclosingLibrary;
     visitSignature(node.function);
-    visitNode(node.function.body);
+    visitNodeOrNull(node.function.body);
     handleProcedure(node);
-    _invalidatedVariables.removeAll(_currentVariables);
+    _invalidatedVariables.removeAll(_currentVariables!);
     _currentVariables = null;
     thisType = null;
     currentLibrary = null;
+    return const ir.VoidType();
   }
 
   void handleConstructor(ir.Constructor node) {}
 
   @override
-  Null visitConstructor(ir.Constructor node) {
+  ir.DartType visitConstructor(ir.Constructor node) {
     thisType = ThisInterfaceType.from(node.enclosingClass.getThisType(
         typeEnvironment.coreTypes, node.enclosingLibrary.nonNullable));
     _currentVariables = {};
     currentLibrary = node.enclosingLibrary;
     visitSignature(node.function);
     visitNodes(node.initializers);
-    visitNode(node.function.body);
+    visitNodeOrNull(node.function.body);
     handleConstructor(node);
-    _invalidatedVariables.removeAll(_currentVariables);
+    _invalidatedVariables.removeAll(_currentVariables!);
     _currentVariables = null;
     thisType = null;
     currentLibrary = null;
+    return const ir.VoidType();
   }
 
   void handleField(ir.Field node) {}
 
   @override
-  Null visitField(ir.Field node) {
+  ir.DartType visitField(ir.Field node) {
     thisType = ThisInterfaceType.from(node.enclosingClass?.getThisType(
         typeEnvironment.coreTypes, node.enclosingLibrary.nonNullable));
     _currentVariables = {};
     currentLibrary = node.enclosingLibrary;
-    visitNode(node.initializer);
+    visitNodeOrNull(node.initializer);
     handleField(node);
-    _invalidatedVariables.removeAll(_currentVariables);
+    _invalidatedVariables.removeAll(_currentVariables!);
     _currentVariables = null;
     thisType = null;
     currentLibrary = null;
+    return const ir.VoidType();
   }
 
   void handleVariableDeclaration(ir.VariableDeclaration node) {}
 
   void _processLocalVariable(ir.VariableDeclaration node) {
-    _currentVariables.add(node);
-    ir.DartType type = visitNode(node.initializer);
-    if (node.initializer != null &&
-        variableScopeModel.isEffectivelyFinal(node) &&
-        inferEffectivelyFinalVariableTypes) {
-      node.type = type;
+    _currentVariables?.add(node);
+    final initializer = node.initializer;
+    if (initializer != null) {
+      ir.DartType type = visitNode(initializer);
+      if (variableScopeModel.isEffectivelyFinal(node) &&
+          inferEffectivelyFinalVariableTypes) {
+        node.type = type;
+      }
     }
   }
 
   @override
-  Null visitVariableDeclaration(ir.VariableDeclaration node) {
+  ir.DartType visitVariableDeclaration(ir.VariableDeclaration node) {
     _processLocalVariable(node);
     handleVariableDeclaration(node);
+    return const ir.VoidType();
   }
 
   void handleConstantExpression(ir.ConstantExpression node) {}
@@ -1817,19 +1816,19 @@
   final ir.DartType declaredType;
 
   /// The types that the local variable is known to be an instance of.
-  final Set<ir.DartType> trueTypes;
+  final Set<ir.DartType>? trueTypes;
 
   /// The types that the local variable is known _not_ to be an instance of.
-  final Set<ir.DartType> falseTypes;
-
-  int _hashCode;
+  final Set<ir.DartType>? falseTypes;
 
   TypeHolder(this.declaredType, this.trueTypes, this.falseTypes);
 
   /// Computes a single type that soundly represents the promoted type of the
   /// local variable on this single path.
-  ir.DartType typeOf(ir.TypeEnvironment typeEnvironment) {
+  ir.DartType? typeOf(ir.TypeEnvironment typeEnvironment) {
     ir.DartType candidate = declaredType;
+    final trueTypes = this.trueTypes;
+    final falseTypes = this.falseTypes;
     if (falseTypes != null) {
       // TODO(johnniwinther): Special-case the `== null` representation to
       // make it faster.
@@ -1863,13 +1862,8 @@
   }
 
   @override
-  int get hashCode {
-    if (_hashCode == null) {
-      _hashCode = Hashing.setHash(falseTypes,
-          Hashing.setHash(trueTypes, Hashing.objectHash(declaredType)));
-    }
-    return _hashCode;
-  }
+  late final int hashCode = Hashing.setHash(
+      falseTypes, Hashing.setHash(trueTypes, Hashing.objectHash(declaredType)));
 
   @override
   bool operator ==(other) {
@@ -1884,6 +1878,8 @@
       StringBuffer sb, String Function(Iterable<ir.DartType>) typesToText) {
     sb.write('{');
     String comma = '';
+    final trueTypes = this.trueTypes;
+    final falseTypes = this.falseTypes;
     if (trueTypes != null) {
       sb.write('true:');
       sb.write(typesToText(trueTypes));
@@ -1937,27 +1933,27 @@
   /// local variable. If [isTrue] is `true`, the local variable is known to
   /// be an instance of [type]. If [isTrue] is `false`, the local variable is
   /// known _not_ to be an instance of [type].
-  TargetInfo promote(ir.DartType type, {bool isTrue}) {
-    Set<TypeHolder> newTypeHolders = Set<TypeHolder>();
+  TargetInfo promote(ir.DartType type, {required bool isTrue}) {
+    Set<TypeHolder> newTypeHolders = {};
 
-    bool addTypeHolder(TypeHolder typeHolder) {
+    bool addTypeHolder(TypeHolder? typeHolder) {
       bool changed = false;
 
-      Set<ir.DartType> addAsCopy(Set<ir.DartType> set, ir.DartType type) {
+      Set<ir.DartType> addAsCopy(Set<ir.DartType>? set, ir.DartType type) {
         Set<ir.DartType> result;
         if (set == null) {
-          result = Set<ir.DartType>();
+          result = {};
         } else if (set.contains(type)) {
           return set;
         } else {
-          result = Set<ir.DartType>.from(set);
+          result = Set.of(set);
         }
         changed = true;
         return result..add(type);
       }
 
-      Set<ir.DartType> trueTypes = typeHolder?.trueTypes;
-      Set<ir.DartType> falseTypes = typeHolder?.falseTypes;
+      Set<ir.DartType>? trueTypes = typeHolder?.trueTypes;
+      Set<ir.DartType>? falseTypes = typeHolder?.falseTypes;
       if (isTrue) {
         trueTypes = addAsCopy(trueTypes, type);
       } else {
@@ -1983,7 +1979,7 @@
     if (typesOfInterest.contains(type)) {
       newTypesOfInterest = typesOfInterest;
     } else {
-      newTypesOfInterest = Set<ir.DartType>.from(typesOfInterest)..add(type);
+      newTypesOfInterest = {...typesOfInterest, type};
       changed = true;
     }
     return changed
@@ -1995,12 +1991,12 @@
   /// or the [other] type.
   ///
   /// Returns `null` if the join is empty.
-  TargetInfo join(TargetInfo other) {
+  TargetInfo? join(TargetInfo? other) {
     if (other == null) return null;
     if (identical(this, other)) return this;
 
-    Set<TypeHolder> newTypeHolders = Set<TypeHolder>();
-    Set<ir.DartType> newTypesOfInterest = Set<ir.DartType>();
+    Set<TypeHolder> newTypeHolders = {};
+    Set<ir.DartType> newTypesOfInterest = {};
 
     /// Adds the [typeHolders] to [newTypeHolders] for types in
     /// [otherTypesOfInterest] while removing the information
@@ -2011,9 +2007,10 @@
         Set<ir.DartType> otherFalseTypes,
         Iterable<ir.DartType> otherTypesOfInterest) {
       for (TypeHolder typeHolder in typeHolders) {
-        Set<ir.DartType> newTrueTypes;
-        if (typeHolder.trueTypes != null) {
-          newTrueTypes = Set<ir.DartType>.from(typeHolder.trueTypes);
+        Set<ir.DartType>? newTrueTypes;
+        final holderTrueTypes = typeHolder.trueTypes;
+        if (holderTrueTypes != null) {
+          newTrueTypes = Set.of(holderTrueTypes);
 
           /// Only types in [otherTypesOfInterest] has information from all
           /// paths.
@@ -2029,9 +2026,10 @@
             newTypesOfInterest.addAll(newTrueTypes);
           }
         }
-        Set<ir.DartType> newFalseTypes;
-        if (typeHolder.falseTypes != null) {
-          newFalseTypes = Set<ir.DartType>.from(typeHolder.falseTypes);
+        Set<ir.DartType>? newFalseTypes;
+        final holderFalseTypes = typeHolder.falseTypes;
+        if (holderFalseTypes != null) {
+          newFalseTypes = Set.of(holderFalseTypes);
 
           /// Only types in [otherTypesOfInterest] has information from all
           /// paths.
@@ -2055,25 +2053,29 @@
       }
     }
 
-    Set<ir.DartType> thisTrueTypes = Set<ir.DartType>();
-    Set<ir.DartType> thisFalseTypes = Set<ir.DartType>();
+    Set<ir.DartType> thisTrueTypes = {};
+    Set<ir.DartType> thisFalseTypes = {};
     for (TypeHolder typeHolder in typeHolders) {
-      if (typeHolder.trueTypes != null) {
-        thisTrueTypes.addAll(typeHolder.trueTypes);
+      final holderTrueTypes = typeHolder.trueTypes;
+      final holderFalseTypes = typeHolder.falseTypes;
+      if (holderTrueTypes != null) {
+        thisTrueTypes.addAll(holderTrueTypes);
       }
-      if (typeHolder.falseTypes != null) {
-        thisFalseTypes.addAll(typeHolder.falseTypes);
+      if (holderFalseTypes != null) {
+        thisFalseTypes.addAll(holderFalseTypes);
       }
     }
 
-    Set<ir.DartType> otherTrueTypes = Set<ir.DartType>();
-    Set<ir.DartType> otherFalseTypes = Set<ir.DartType>();
+    Set<ir.DartType> otherTrueTypes = {};
+    Set<ir.DartType> otherFalseTypes = {};
     for (TypeHolder typeHolder in other.typeHolders) {
-      if (typeHolder.trueTypes != null) {
-        otherTrueTypes.addAll(typeHolder.trueTypes);
+      final holderTrueTypes = typeHolder.trueTypes;
+      final holderFalseTypes = typeHolder.falseTypes;
+      if (holderTrueTypes != null) {
+        otherTrueTypes.addAll(holderTrueTypes);
       }
-      if (typeHolder.falseTypes != null) {
-        otherFalseTypes.addAll(typeHolder.falseTypes);
+      if (holderFalseTypes != null) {
+        otherFalseTypes.addAll(holderFalseTypes);
       }
     }
 
@@ -2092,10 +2094,10 @@
 
   /// Computes a single type that soundly represents the promoted type of the
   /// local variable on all possible paths.
-  ir.DartType typeOf(ir.TypeEnvironment typeEnvironment) {
-    ir.DartType candidate = null;
+  ir.DartType? typeOf(ir.TypeEnvironment typeEnvironment) {
+    ir.DartType? candidate = null;
     for (TypeHolder typeHolder in typeHolders) {
-      ir.DartType type = typeHolder.typeOf(typeEnvironment);
+      ir.DartType? type = typeHolder.typeOf(typeEnvironment);
       if (type == null) {
         // We cannot promote. No single type is most specific.
         return null;
@@ -2165,10 +2167,9 @@
   /// be an instance of [type]. If [isTrue] is `false`, the local [variable] is
   /// known _not_ to be an instance of [type].
   TypeMap promote(ir.VariableDeclaration variable, ir.DartType type,
-      {bool isTrue}) {
-    Map<ir.VariableDeclaration, TargetInfo> newInfoMap =
-        Map<ir.VariableDeclaration, TargetInfo>.from(_targetInfoMap);
-    TargetInfo targetInfo = newInfoMap[variable];
+      {required bool isTrue}) {
+    Map<ir.VariableDeclaration, TargetInfo> newInfoMap = Map.of(_targetInfoMap);
+    TargetInfo? targetInfo = newInfoMap[variable];
     bool changed = false;
     if (targetInfo != null) {
       TargetInfo result = targetInfo.promote(type, isTrue: isTrue);
@@ -2176,10 +2177,8 @@
       targetInfo = result;
     } else {
       changed = true;
-      Set<ir.DartType> trueTypes =
-          isTrue ? (Set<ir.DartType>()..add(type)) : null;
-      Set<ir.DartType> falseTypes =
-          isTrue ? null : (Set<ir.DartType>()..add(type));
+      Set<ir.DartType>? trueTypes = isTrue ? {type} : null;
+      Set<ir.DartType>? falseTypes = isTrue ? null : {type};
       TypeHolder typeHolder = TypeHolder(variable.type, trueTypes, falseTypes);
       targetInfo = TargetInfo(
           variable.type, <TypeHolder>[typeHolder], <ir.DartType>[type]);
@@ -2196,7 +2195,7 @@
     Map<ir.VariableDeclaration, TargetInfo> newInfoMap = {};
     bool changed = false;
     _targetInfoMap.forEach((ir.VariableDeclaration variable, TargetInfo info) {
-      TargetInfo result = info.join(other._targetInfoMap[variable]);
+      TargetInfo? result = info.join(other._targetInfoMap[variable]);
       changed |= !identical(info, result);
       if (result != null) {
         // Add only non-empty information.
@@ -2224,7 +2223,7 @@
   /// Returns the [TypeMap] where type information for `node.variable` is
   /// reduced to the promotions upheld by an assignment to `node.variable` of
   /// the static [type].
-  TypeMap reduce(ir.VariableSet node, ir.DartType type,
+  TypeMap reduce(ir.VariableSet node, ir.DartType? type,
       ir.TypeEnvironment typeEnvironment) {
     Map<ir.VariableDeclaration, TargetInfo> newInfoMap = {};
     bool changed = false;
@@ -2233,7 +2232,7 @@
         newInfoMap[variable] = info;
       } else if (type != null) {
         changed = true;
-        Set<ir.DartType> newTypesOfInterest = Set<ir.DartType>();
+        Set<ir.DartType> newTypesOfInterest = {};
         for (ir.DartType typeOfInterest in info.typesOfInterest) {
           if (typeEnvironment.isSubtypeOf(type, typeOfInterest,
               ir.SubtypeCheckMode.ignoringNullabilities)) {
@@ -2249,8 +2248,8 @@
           // to have _no_ target info.
           TypeHolder typeHolderIfNonNull =
               TypeHolder(info.declaredType, newTypesOfInterest, null);
-          TypeHolder typeHolderIfNull = TypeHolder(info.declaredType, null,
-              Set<ir.DartType>()..add(info.declaredType));
+          TypeHolder typeHolderIfNull =
+              TypeHolder(info.declaredType, null, {info.declaredType});
           newInfoMap[variable] = TargetInfo(
               info.declaredType,
               <TypeHolder>[typeHolderIfNonNull, typeHolderIfNull],
@@ -2266,8 +2265,8 @@
   /// Computes a single type that soundly represents the promoted type of
   /// `node.variable` on all possible paths.
   ir.DartType typeOf(ir.VariableGet node, ir.TypeEnvironment typeEnvironment) {
-    TargetInfo info = _targetInfoMap[node.variable];
-    ir.DartType type;
+    TargetInfo? info = _targetInfoMap[node.variable];
+    ir.DartType? type;
     if (info != null) {
       type = info.typeOf(typeEnvironment);
     }
diff --git a/pkg/compiler/lib/src/ir/static_type_base.dart b/pkg/compiler/lib/src/ir/static_type_base.dart
index 79ed5f4..9357bb0 100644
--- a/pkg/compiler/lib/src/ir/static_type_base.dart
+++ b/pkg/compiler/lib/src/ir/static_type_base.dart
@@ -55,14 +55,11 @@
 /// expression kind. For instance method invocations whose static type depend
 /// on the static types of the receiver and type arguments and the signature
 /// of the targeted procedure.
-abstract class StaticTypeBase extends ir.Visitor<ir.DartType?>
-    with ir.VisitorNullMixin<ir.DartType> {
+abstract class StaticTypeBase extends ir.TreeVisitor<ir.DartType> {
   final ir.TypeEnvironment _typeEnvironment;
 
   StaticTypeBase(this._typeEnvironment);
 
-  fail(String message) => message;
-
   ir.TypeEnvironment get typeEnvironment => _typeEnvironment;
 
   ir.StaticTypeContext get staticTypeContext;
@@ -70,33 +67,28 @@
   ThisInterfaceType get thisType;
 
   @override
-  ir.DartType? defaultNode(ir.Node node) {
-    return null;
+  ir.DartType defaultTreeNode(ir.TreeNode node) {
+    throw UnsupportedError('Unhandled node $node (${node.runtimeType})');
   }
 
-  ir.DartType? visitNode(ir.Node? node) {
-    return node?.accept(this);
-  }
+  ir.DartType visitNode(ir.TreeNode node) => node.accept(this);
 
-  Null visitNodes(List<ir.Node> nodes) {
-    for (ir.Node node in nodes) {
+  ir.DartType? visitNodeOrNull(ir.TreeNode? node) => node?.accept(this);
+
+  void visitNodes(Iterable<ir.TreeNode> nodes) {
+    for (ir.TreeNode node in nodes) {
       visitNode(node);
     }
   }
 
   @override
-  ir.DartType defaultExpression(ir.Expression node) {
-    throw fail('Unhandled node $node (${node.runtimeType})');
-  }
-
-  @override
   ir.DartType visitAsExpression(ir.AsExpression node) {
     return node.type;
   }
 
   @override
   ir.DartType visitAwaitExpression(ir.AwaitExpression node) {
-    return typeEnvironment.flatten(visitNode(node.operand)!);
+    return typeEnvironment.flatten(visitNode(node.operand));
   }
 
   @override
@@ -150,7 +142,7 @@
   }
 
   @override
-  ir.DartType? visitVariableSet(ir.VariableSet node) {
+  ir.DartType visitVariableSet(ir.VariableSet node) {
     return visitNode(node.value);
   }
 
@@ -161,12 +153,12 @@
   ir.DartType visitStaticGet(ir.StaticGet node) => node.target.getterType;
 
   @override
-  ir.DartType? visitStaticSet(ir.StaticSet node) {
+  ir.DartType visitStaticSet(ir.StaticSet node) {
     return visitNode(node.value);
   }
 
   @override
-  ir.DartType? visitSuperPropertySet(ir.SuperPropertySet node) {
+  ir.DartType visitSuperPropertySet(ir.SuperPropertySet node) {
     return visitNode(node.value);
   }
 
@@ -205,12 +197,12 @@
   }
 
   @override
-  ir.DartType? visitLet(ir.Let node) {
+  ir.DartType visitLet(ir.Let node) {
     return visitNode(node.body);
   }
 
   @override
-  ir.DartType? visitBlockExpression(ir.BlockExpression node) {
+  ir.DartType visitBlockExpression(ir.BlockExpression node) {
     return visitNode(node.value);
   }
 
diff --git a/pkg/compiler/lib/src/ir/types.dart b/pkg/compiler/lib/src/ir/types.dart
index a14ddbb..c12988a 100644
--- a/pkg/compiler/lib/src/ir/types.dart
+++ b/pkg/compiler/lib/src/ir/types.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.10
-
 import '../common/elements.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
@@ -27,7 +25,7 @@
   }
 
   @override
-  InterfaceType getSupertype(ClassEntity cls) {
+  InterfaceType? getSupertype(ClassEntity cls) {
     return elementMap.getSuperType(cls);
   }
 
@@ -42,7 +40,7 @@
   }
 
   @override
-  InterfaceType asInstanceOf(InterfaceType type, ClassEntity cls) {
+  InterfaceType? asInstanceOf(InterfaceType type, ClassEntity cls) {
     return elementMap.asInstanceOf(type, cls);
   }
 
@@ -52,7 +50,7 @@
   }
 
   @override
-  FunctionType getCallType(InterfaceType type) => elementMap.getCallType(type);
+  FunctionType? getCallType(InterfaceType type) => elementMap.getCallType(type);
 
   @override
   void checkTypeVariableBounds<T>(
@@ -64,7 +62,7 @@
     assert(typeVariables.length == typeArguments.length);
     for (int index = 0; index < typeArguments.length; index++) {
       DartType typeArgument = typeArguments[index];
-      TypeVariableType typeVariable = typeVariables[index];
+      final typeVariable = typeVariables[index] as TypeVariableType;
       DartType bound = subst(typeArguments, typeVariables,
           elementMap.getTypeVariableBound(typeVariable.element));
       checkTypeVariableBound(context, typeArgument, typeVariable, bound);
@@ -96,7 +94,7 @@
 
   @override
   InterfaceType substByContext(InterfaceType type, InterfaceType context) {
-    return elementMap.substByContext(type, context);
+    return elementMap.substByContext(type, context) as InterfaceType;
   }
 
   @override
diff --git a/pkg/compiler/lib/src/ir/visitors.dart b/pkg/compiler/lib/src/ir/visitors.dart
index aea9e7d..c752997 100644
--- a/pkg/compiler/lib/src/ir/visitors.dart
+++ b/pkg/compiler/lib/src/ir/visitors.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.10
-
 import 'package:kernel/ast.dart' as ir;
 
 import '../constants/constant_system.dart' as constant_system;
@@ -14,15 +12,15 @@
 
 /// Visitor that converts string literals and concatenations of string literals
 /// into the string value.
-class Stringifier extends ir.ExpressionVisitor<String> {
+class Stringifier extends ir.ExpressionVisitor<String?> {
   @override
   String visitStringLiteral(ir.StringLiteral node) => node.value;
 
   @override
-  String visitStringConcatenation(ir.StringConcatenation node) {
+  String? visitStringConcatenation(ir.StringConcatenation node) {
     StringBuffer sb = StringBuffer();
     for (ir.Expression expression in node.expressions) {
-      String value = expression.accept(this);
+      String? value = expression.accept(this);
       if (value == null) return null;
       sb.write(value);
     }
@@ -30,7 +28,7 @@
   }
 
   @override
-  String visitConstantExpression(ir.ConstantExpression node) {
+  String? visitConstantExpression(ir.ConstantExpression node) {
     ir.Constant constant = node.constant;
     if (constant is ir.StringConstant) {
       return constant.value;
@@ -39,11 +37,11 @@
   }
 
   @override
-  String defaultExpression(ir.Expression node) => null;
+  String? defaultExpression(ir.Expression node) => null;
 }
 
 /// Visitor that converts kernel dart types into [DartType].
-class DartTypeConverter extends ir.DartTypeVisitor<DartType /*!*/ > {
+class DartTypeConverter extends ir.DartTypeVisitor<DartType> {
   final IrToElementMap elementMap;
   final Map<ir.TypeParameter, DartType> currentFunctionTypeParameters =
       <ir.TypeParameter, DartType>{};
@@ -83,8 +81,6 @@
         throw UnsupportedError(
             'Undetermined nullability on $nullabilitySource');
     }
-    throw UnsupportedError(
-        'Unexpected nullability $nullability on $nullabilitySource');
   }
 
   DartType visitType(ir.DartType type) {
@@ -92,7 +88,8 @@
   }
 
   InterfaceType visitSupertype(ir.Supertype node) =>
-      visitInterfaceType(node.asInterfaceType).withoutNullability;
+      visitInterfaceType(node.asInterfaceType).withoutNullability
+          as InterfaceType;
 
   List<DartType> visitTypes(List<ir.DartType> types) {
     return List.generate(
@@ -101,7 +98,7 @@
 
   @override
   DartType visitTypeParameterType(ir.TypeParameterType node) {
-    DartType typeParameter = currentFunctionTypeParameters[node.parameter];
+    DartType? typeParameter = currentFunctionTypeParameters[node.parameter];
     if (typeParameter != null) {
       return _convertNullability(typeParameter, node);
     }
@@ -118,7 +115,7 @@
   @override
   DartType visitFunctionType(ir.FunctionType node) {
     int index = 0;
-    List<FunctionTypeVariable> typeVariables;
+    List<FunctionTypeVariable>? typeVariables;
     for (ir.TypeParameter typeParameter in node.typeParameters) {
       FunctionTypeVariable typeVariable =
           _dartTypes.functionTypeVariable(index);
@@ -229,7 +226,7 @@
   ConstantValue visitStaticTearOffConstant(ir.StaticTearOffConstant node) {
     ir.Procedure member = node.target;
     FunctionEntity function = elementMap.getMethod(member);
-    DartType type = elementMap.getFunctionType(member.function);
+    final type = elementMap.getFunctionType(member.function);
     return FunctionConstantValue(function, type);
   }
 
@@ -239,7 +236,8 @@
     for (ir.DartType type in node.types) {
       typeArguments.add(elementMap.getDartType(type));
     }
-    FunctionConstantValue function = visitConstant(node.tearOffConstant);
+    final function =
+        visitConstant(node.tearOffConstant) as FunctionConstantValue;
     return InstantiationConstantValue(typeArguments, function);
   }
 
@@ -261,7 +259,7 @@
     for (ir.Constant element in node.entries) {
       elements.add(visitConstant(element));
     }
-    DartType type = elementMap.commonElements
+    final type = elementMap.commonElements
         .listType(elementMap.getDartType(node.typeArgument));
     return constant_system.createList(
         elementMap.commonElements, type, elements);
@@ -273,7 +271,7 @@
     for (ir.Constant element in node.entries) {
       elements.add(visitConstant(element));
     }
-    DartType type = elementMap.commonElements
+    final type = elementMap.commonElements
         .setType(elementMap.getDartType(node.typeArgument));
     return constant_system.createSet(elementMap.commonElements, type, elements);
   }
@@ -286,7 +284,7 @@
       keys.add(visitConstant(element.key));
       values.add(visitConstant(element.value));
     }
-    DartType type = elementMap.commonElements.mapType(
+    final type = elementMap.commonElements.mapType(
         elementMap.getDartType(node.keyType),
         elementMap.getDartType(node.valueType));
     return constant_system.createMap(
diff --git a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
index 1f84c63..15f9436 100644
--- a/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
+++ b/pkg/compiler/lib/src/js_backend/checked_mode_helpers.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.10
-
 // TODO(39733): This file exists now just to register the use of
 // 'boolConversionCheck'. Fix the registration and remove this file.
 
diff --git a/pkg/compiler/lib/src/js_backend/native_data.dart b/pkg/compiler/lib/src/js_backend/native_data.dart
index 348af11..6bfc3f0 100644
--- a/pkg/compiler/lib/src/js_backend/native_data.dart
+++ b/pkg/compiler/lib/src/js_backend/native_data.dart
@@ -270,6 +270,7 @@
   }
 
   /// Returns the list of non-directive native tag words for [cls].
+  @override
   List<String> getNativeTagsOfClass(ClassEntity cls) {
     return _nativeClassTagInfo[cls].names;
   }
diff --git a/pkg/compiler/lib/src/js_backend/native_data_interfaces.dart b/pkg/compiler/lib/src/js_backend/native_data_interfaces.dart
index 405d858..f2e7f67 100644
--- a/pkg/compiler/lib/src/js_backend/native_data_interfaces.dart
+++ b/pkg/compiler/lib/src/js_backend/native_data_interfaces.dart
@@ -11,4 +11,6 @@
   bool isJsInteropClass(ClassEntity element);
 
   bool isNativeClass(ClassEntity element);
+
+  List<String> getNativeTagsOfClass(ClassEntity cls);
 }
diff --git a/pkg/compiler/lib/src/js_model/element_map_impl.dart b/pkg/compiler/lib/src/js_model/element_map_impl.dart
index 149eb78..d23fd743 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -1380,7 +1380,7 @@
     return lookup;
   }
 
-  String _getStringArgument(ir.StaticInvocation node, int index) {
+  String /*?*/ _getStringArgument(ir.StaticInvocation node, int index) {
     return node.arguments.positional[index].accept(Stringifier());
   }
 
diff --git a/pkg/compiler/lib/src/kernel/element_map_impl.dart b/pkg/compiler/lib/src/kernel/element_map_impl.dart
index 192973e..46cbef3 100644
--- a/pkg/compiler/lib/src/kernel/element_map_impl.dart
+++ b/pkg/compiler/lib/src/kernel/element_map_impl.dart
@@ -1013,7 +1013,7 @@
     return lookup;
   }
 
-  String _getStringArgument(ir.StaticInvocation node, int index) {
+  String /*?*/ _getStringArgument(ir.StaticInvocation node, int index) {
     return node.arguments.positional[index].accept(Stringifier());
   }
 
@@ -1448,14 +1448,16 @@
 
   /// NativeBasicData is need for computation of the default super class.
   NativeBasicData get nativeBasicData {
-    if (_nativeBasicData == null) {
-      _nativeBasicData = nativeBasicDataBuilder.close(elementEnvironment);
+    var data = _nativeBasicData;
+    if (data == null) {
+      data =
+          _nativeBasicData = nativeBasicDataBuilder.close(elementEnvironment);
       assert(
           _nativeBasicData != null,
           failedAt(NO_LOCATION_SPANNABLE,
               "NativeBasicData has not been computed yet."));
     }
-    return _nativeBasicData;
+    return data;
   }
 
   /// Adds libraries in [component] to the set of libraries.
diff --git a/pkg/compiler/lib/src/native/resolver.dart b/pkg/compiler/lib/src/native/resolver.dart
index dcdc80d..c445602 100644
--- a/pkg/compiler/lib/src/native/resolver.dart
+++ b/pkg/compiler/lib/src/native/resolver.dart
@@ -2,14 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.10
-
 import '../common.dart';
 import '../common/elements.dart' show KElementEnvironment;
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../elements/types.dart';
-import '../js_backend/native_data.dart';
+import '../js_backend/native_data_interfaces.dart';
 
 /// Determines all native classes in a set of libraries.
 class NativeClassFinder {
@@ -24,7 +22,7 @@
   Iterable<ClassEntity> computeNativeClasses(Iterable<Uri> libraries) {
     Set<ClassEntity> nativeClasses = {};
     libraries.forEach((uri) => _processNativeClassesInLibrary(
-        _elementEnvironment.lookupLibrary(uri), nativeClasses));
+        _elementEnvironment.lookupLibrary(uri)!, nativeClasses));
     _processSubclassesOfNativeClasses(libraries, nativeClasses);
     return nativeClasses;
   }
@@ -49,7 +47,7 @@
     // Since we map from dispatch tags to classes, a dispatch tag must be used
     // on only one native class.
     for (String tag in _nativeBasicData.getNativeTagsOfClass(cls)) {
-      ClassEntity owner = _tagOwner[tag];
+      ClassEntity? owner = _tagOwner[tag];
       if (owner != null) {
         if (owner != cls) {
           failedAt(cls, "Tag '$tag' already in use by '${owner.name}'");
@@ -62,7 +60,7 @@
 
   /// Returns the name of the super class of [cls] or `null` of [cls] has
   /// no explicit superclass.
-  String _findExtendsNameOfClass(covariant ClassEntity cls) {
+  String? _findExtendsNameOfClass(covariant ClassEntity cls) {
     return _elementEnvironment
         .getSuperClass(cls, skipUnnamedMixinApplications: true)
         ?.name;
@@ -82,9 +80,9 @@
     Map<String, Set<ClassEntity>> potentialExtends = {};
 
     libraries.forEach((Uri uri) {
-      LibraryEntity library = _elementEnvironment.lookupLibrary(uri);
+      LibraryEntity library = _elementEnvironment.lookupLibrary(uri)!;
       _elementEnvironment.forEachClass(library, (ClassEntity cls) {
-        String extendsName = _findExtendsNameOfClass(cls);
+        String? extendsName = _findExtendsNameOfClass(cls);
         if (extendsName != null) {
           Set<ClassEntity> potentialSubclasses =
               potentialExtends.putIfAbsent(extendsName, () => {});
@@ -97,22 +95,20 @@
     // [potentialExtends], and then check that the properly resolved class is in
     // fact a subclass of a native class.
 
-    ClassEntity nativeSuperclassOf(ClassEntity cls) {
+    ClassEntity? nativeSuperclassOf(ClassEntity cls) {
       if (_nativeBasicData.isNativeClass(cls)) return cls;
-      ClassEntity superclass = _elementEnvironment.getSuperClass(cls);
+      ClassEntity? superclass = _elementEnvironment.getSuperClass(cls);
       if (superclass == null) return null;
       return nativeSuperclassOf(superclass);
     }
 
     void walkPotentialSubclasses(ClassEntity element) {
       if (nativeClassesAndSubclasses.contains(element)) return;
-      ClassEntity nativeSuperclass = nativeSuperclassOf(element);
+      ClassEntity? nativeSuperclass = nativeSuperclassOf(element);
       if (nativeSuperclass != null) {
         nativeClassesAndSubclasses.add(element);
-        Set<ClassEntity> potentialSubclasses = potentialExtends[element.name];
-        if (potentialSubclasses != null) {
-          potentialSubclasses.forEach(walkPotentialSubclasses);
-        }
+        Set<ClassEntity>? potentialSubclasses = potentialExtends[element.name];
+        potentialSubclasses?.forEach(walkPotentialSubclasses);
       }
     }
 
@@ -121,20 +117,11 @@
   }
 }
 
-/// Returns `true` if [value] is named annotation based on [annotationClass].
-bool isAnnotation(
-    Spannable spannable, ConstantValue value, ClassEntity annotationClass) {
-  if (value is ConstructedConstantValue) {
-    return value.type.element == annotationClass;
-  }
-  return null;
-}
-
 /// Extracts the name if [value] is a named annotation based on
 /// [annotationClass], otherwise returns `null`.
-String readAnnotationName(DartTypes dartTypes, Spannable spannable,
+String? readAnnotationName(DartTypes dartTypes, Spannable spannable,
     ConstantValue value, ClassEntity annotationClass,
-    {String defaultValue}) {
+    {String? defaultValue}) {
   if (value is ConstructedConstantValue) {
     if (value.type.element != annotationClass) return null;
 
@@ -144,10 +131,11 @@
       failedAt(spannable,
           'Annotations needs one string: ${value.toStructuredText(dartTypes)}');
       return null;
-    } else if (fields.single is StringConstantValue) {
-      StringConstantValue specStringConstant = fields.single;
-      return specStringConstant.stringValue;
-    } else if (defaultValue != null && fields.single is NullConstantValue) {
+    }
+    final field = fields.single;
+    if (field is StringConstantValue) {
+      return field.stringValue;
+    } else if (defaultValue != null && field is NullConstantValue) {
       return defaultValue;
     } else {
       failedAt(spannable,
diff --git a/pkg/compiler/test/analyses/analysis_helper.dart b/pkg/compiler/test/analyses/analysis_helper.dart
index f7a975c..251ed4d 100644
--- a/pkg/compiler/test/analyses/analysis_helper.dart
+++ b/pkg/compiler/test/analyses/analysis_helper.dart
@@ -312,8 +312,8 @@
   }
 
   @override
-  ir.DartType visitNode(ir.Node node) {
-    ir.DartType staticType = node?.accept(this);
+  ir.DartType visitNode(ir.TreeNode node) {
+    ir.DartType staticType = node.accept(this);
     assert(
         node is! ir.Expression ||
             staticType is ir.NullType ||
diff --git a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
index 924057d0..76ced98 100644
--- a/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
+++ b/pkg/dev_compiler/lib/src/compiler/shared_compiler.dart
@@ -144,10 +144,6 @@
   @protected
   Library get coreLibrary;
 
-  /// The import URI of current library.
-  @protected
-  Uri get currentLibraryUri;
-
   /// The current function being compiled, if any.
   @protected
   FunctionNode? get currentFunction;
diff --git a/pkg/dev_compiler/lib/src/kernel/command.dart b/pkg/dev_compiler/lib/src/kernel/command.dart
index 713f095..becb100 100644
--- a/pkg/dev_compiler/lib/src/kernel/command.dart
+++ b/pkg/dev_compiler/lib/src/kernel/command.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:async';
 import 'dart:convert' show json;
 import 'dart:io';
@@ -46,8 +44,8 @@
 /// The result may also contain a [previousResult], which can be passed back in
 /// for batch/worker executions to attempt to existing state.
 Future<CompilerResult> compile(ParsedArguments args,
-    {fe.InitializedCompilerState compilerState,
-    Map<Uri, List<int>> inputDigests}) {
+    {fe.InitializedCompilerState? compilerState,
+    Map<Uri, List<int>>? inputDigests}) {
   if (compilerState != null && !args.isBatchOrWorker) {
     throw ArgumentError(
         'previousResult requires --batch or --bazel_worker mode/');
@@ -83,10 +81,10 @@
     '${ddcArgParser.usage}';
 
 Future<CompilerResult> _compile(List<String> args,
-    {fe.InitializedCompilerState compilerState,
+    {fe.InitializedCompilerState? compilerState,
     bool isWorker = false,
     bool useIncrementalCompiler = false,
-    Map<Uri, List<int>> inputDigests}) async {
+    Map<Uri, List<int>>? inputDigests}) async {
   // TODO(jmesserly): refactor options to share code with dartdevc CLI.
   var argParser = ArgParser(allowTrailingOptions: true)
     ..addFlag('help',
@@ -98,7 +96,9 @@
         defaultsTo: false,
         hide: true)
     ..addFlag('track-widget-creation',
-        help: 'Enable inspecting of Flutter widgets.', hide: true)
+        help: 'Enable inspecting of Flutter widgets.',
+        defaultsTo: false,
+        hide: true)
     // TODO(jmesserly): add verbose help to show hidden options
     ..addOption('dart-sdk-summary',
         help: 'The path to the Dart SDK summary file.', hide: true)
@@ -198,9 +198,10 @@
 
   var summaryPaths = options.summaryModules.keys.toList();
   var summaryModules = Map.fromIterables(
-      summaryPaths.map(sourcePathToUri), options.summaryModules.values);
-  var sdkSummaryPath = argResults['dart-sdk-summary'] as String;
-  var librarySpecPath = argResults['libraries-file'] as String;
+      summaryPaths.map(sourcePathToUri).cast<Uri>(),
+      options.summaryModules.values);
+  var sdkSummaryPath = argResults['dart-sdk-summary'] as String?;
+  var librarySpecPath = argResults['libraries-file'] as String?;
   if (sdkSummaryPath == null) {
     sdkSummaryPath =
         defaultSdkSummaryPath(soundNullSafety: options.soundNullSafety);
@@ -246,7 +247,8 @@
   // TODO(jmesserly): conceptually CFE should not need a .packages file to
   // resolve package URIs that are in the input summaries, but it seems to.
   // This needs further investigation.
-  var packageFile = argResults['packages'] as String ?? _findPackagesFilePath();
+  var packageFile =
+      argResults['packages'] as String? ?? _findPackagesFilePath();
 
   var succeeded = true;
   void diagnosticMessageHandler(fe.DiagnosticMessage message) {
@@ -259,17 +261,19 @@
   var explicitExperimentalFlags = fe.parseExperimentalFlags(options.experiments,
       onError: stderr.writeln, onWarning: print);
 
-  var trackWidgetCreation =
-      argResults['track-widget-creation'] as bool ?? false;
+  var trackWidgetCreation = argResults['track-widget-creation'] as bool;
 
   var compileSdk = argResults['compile-sdk'] == true;
   var oldCompilerState = compilerState;
-  List<Component> doneAdditionalDills;
-  fe.IncrementalCompiler incrementalCompiler;
-  fe.WorkerInputComponent cachedSdkInput;
   var recordUsedInputs = argResults['used-inputs-file'] != null;
   var additionalDills = summaryModules.keys.toList();
+  fe.DdcResult? result;
 
+  // TODO(jmesserly): is there a cleaner way to do this?
+  //
+  // Ideally we'd manage our own batch compilation caching rather than rely on
+  // `initializeCompiler`. Also we should be able to pass down Components for
+  // SDK and summaries.
   if (!useIncrementalCompiler) {
     compilerState = fe.initializeCompiler(
         oldCompilerState,
@@ -287,13 +291,15 @@
         environmentDefines: declaredVariables,
         nnbdMode:
             options.soundNullSafety ? fe.NnbdMode.Strong : fe.NnbdMode.Weak);
+    result = await fe.compile(compilerState, inputs, diagnosticMessageHandler);
   } else {
     // If digests weren't given and if not in worker mode, create fake data and
     // ensure we don't have a previous state (as that wouldn't be safe with
     // fake input digests).
-    if (!isWorker && (inputDigests == null || inputDigests.isEmpty)) {
+    inputDigests ??= {};
+    if (!isWorker && inputDigests.isEmpty) {
       oldCompilerState = null;
-      inputDigests ??= {};
+
       if (!compileSdk) {
         inputDigests[sourcePathToUri(sdkSummaryPath)] = const [0];
       }
@@ -301,8 +307,8 @@
         inputDigests[uri] = const [0];
       }
     }
-
-    doneAdditionalDills = List<Component>(summaryModules.length);
+    var doneAdditionalDills =
+        List.filled(summaryModules.length, dummyComponent);
     compilerState = await fe.initializeIncrementalCompiler(
         oldCompilerState,
         {
@@ -327,21 +333,9 @@
         trackNeededDillLibraries: recordUsedInputs,
         nnbdMode:
             options.soundNullSafety ? fe.NnbdMode.Strong : fe.NnbdMode.Weak);
-    incrementalCompiler = compilerState.incrementalCompiler;
-    cachedSdkInput =
-        compilerState.workerInputCache[sourcePathToUri(sdkSummaryPath)];
-  }
-
-  // TODO(jmesserly): is there a cleaner way to do this?
-  //
-  // Ideally we'd manage our own batch compilation caching rather than rely on
-  // `initializeCompiler`. Also we should be able to pass down Components for
-  // SDK and summaries.
-  //
-  fe.DdcResult result;
-  if (!useIncrementalCompiler) {
-    result = await fe.compile(compilerState, inputs, diagnosticMessageHandler);
-  } else {
+    var incrementalCompiler = compilerState.incrementalCompiler!;
+    var cachedSdkInput =
+        compilerState.workerInputCache![sourcePathToUri(sdkSummaryPath)];
     compilerState.options.onDiagnostic = diagnosticMessageHandler;
     var incrementalCompilerResult = await incrementalCompiler.computeDelta(
         entryPoints: inputs,
@@ -349,9 +343,9 @@
         trackNeededDillLibraries: recordUsedInputs);
     result = fe.DdcResult(
         incrementalCompilerResult.component,
-        cachedSdkInput.component,
+        cachedSdkInput?.component,
         doneAdditionalDills,
-        incrementalCompilerResult.classHierarchy,
+        incrementalCompilerResult.classHierarchy!,
         incrementalCompilerResult.neededDillLibraries);
   }
   compilerState.options.onDiagnostic = null; // See http://dartbug.com/36983.
@@ -393,7 +387,7 @@
     kernel.BinaryPrinter(sink).writeComponentFile(component);
     outFiles.add(sink.flush().then((_) => sink.close()));
   }
-  String fullDillUri;
+  String? fullDillUri;
   if (argResults['experimental-output-compiled-kernel'] as bool) {
     if (outPaths.length > 1) {
       print(
@@ -433,7 +427,7 @@
   final summaryToModule = Map<Component, String>.identity();
   for (var i = 0; i < result.additionalDills.length; i++) {
     var additionalDill = result.additionalDills[i];
-    var moduleImport = summaryModules[additionalDills[i]];
+    var moduleImport = summaryModules[additionalDills[i]]!;
     for (var l in additionalDill.libraries) {
       assert(!importToSummary.containsKey(l));
       importToSummary[l] = additionalDill;
@@ -487,12 +481,12 @@
   if (recordUsedInputs) {
     var usedOutlines = <Uri>{};
     if (useIncrementalCompiler) {
-      var neededDillLibraries = result.neededDillLibraries;
-      compilerState.incrementalCompiler.updateNeededDillLibrariesWithHierarchy(
+      var neededDillLibraries = result.neededDillLibraries!;
+      compilerState.incrementalCompiler!.updateNeededDillLibrariesWithHierarchy(
           neededDillLibraries, result.classHierarchy);
       for (var lib in neededDillLibraries) {
         if (lib.importUri.isScheme('dart')) continue;
-        var uri = compilerState.libraryToInputDill[lib.importUri];
+        var uri = compilerState.libraryToInputDill![lib.importUri];
         if (uri == null) {
           throw StateError('Library ${lib.importUri} was recorded as used, '
               'but was not in the list of known libraries.');
@@ -650,20 +644,20 @@
   ///
   /// The source paths will initially be absolute paths. They can be adjusted
   /// using [placeSourceMap].
-  final Map sourceMap;
+  final Map? sourceMap;
 
   /// Module and library information
   ///
   /// The [metadata] is a contract between compiler and the debugger,
   /// helping the debugger map between libraries, modules, source paths.
   /// see: https://goto.google.com/dart-web-debugger-metadata
-  final ModuleMetadata metadata;
+  final ModuleMetadata? metadata;
 
   /// Module debug symbols.
   ///
   /// The [symbols] is a contract between compiler and the debugger,
   /// helping the debugger map between dart and JS objects.
-  final ModuleSymbols symbols;
+  final ModuleSymbols? symbols;
 
   JSCode(this.code, this.sourceMap, {this.symbols, this.metadata});
 }
@@ -677,18 +671,18 @@
     bool inlineSourceMap = false,
     bool emitDebugMetadata = false,
     bool emitDebugSymbols = false,
-    String jsUrl,
-    String mapUrl,
-    String fullDillUri,
-    String sourceMapBase,
-    String customScheme,
-    String multiRootOutputPath,
-    ProgramCompiler compiler,
-    Component component}) {
+    String? jsUrl,
+    String? mapUrl,
+    String? fullDillUri,
+    String? sourceMapBase,
+    String? customScheme,
+    String? multiRootOutputPath,
+    ProgramCompiler? compiler,
+    Component? component}) {
   var opts = js_ast.JavaScriptPrintingOptions(
       allowKeywordsInProperties: true, allowSingleLineIfStatements: true);
   js_ast.SimpleJavaScriptPrintingContext printer;
-  SourceMapBuilder sourceMap;
+  SourceMapBuilder? sourceMap;
   if (buildSourceMap) {
     var sourceMapContext = SourceMapPrintingContext();
     sourceMap = sourceMapContext.sourceMap;
@@ -702,9 +696,9 @@
   tree.accept(js_ast.Printer(opts, printer,
       localNamer: js_ast.TemporaryNamer(tree, nameListener)));
 
-  Map builtMap;
+  Map? builtMap;
   if (buildSourceMap && sourceMap != null) {
-    builtMap = placeSourceMap(sourceMap.build(jsUrl), mapUrl, customScheme,
+    builtMap = placeSourceMap(sourceMap.build(jsUrl!), mapUrl!, customScheme,
         multiRootOutputPath: multiRootOutputPath, sourceMapBase: sourceMapBase);
     var jsDir = p.dirname(p.fromUri(jsUrl));
     var relative = p.relative(p.fromUri(mapUrl), from: jsDir);
@@ -733,19 +727,19 @@
   // our runtime metrics gathering would obtain this information from the
   // compilation server, not the browser.  We don't yet have the infra for that.
   var compileTimeStatistics = {
-    'dartSize': component != null ? _computeDartSize(component) : null,
+    'dartSize': _computeDartSize(component!),
     'sourceMapSize': encodedMap.length
   };
   text = text.replaceFirst(
       SharedCompiler.metricsLocationID, '$compileTimeStatistics');
 
   var debugMetadata = emitDebugMetadata
-      ? _emitMetadata(moduleTree, component, mapUrl, jsUrl, fullDillUri)
+      ? _emitMetadata(moduleTree, component, mapUrl!, jsUrl!, fullDillUri)
       : null;
 
   var debugSymbols = emitDebugSymbols
       ? _emitSymbols(
-          compiler, moduleTree.name, nameListener.identifierNames, component)
+          compiler!, moduleTree.name!, nameListener!.identifierNames, component)
       : null;
 
   return JSCode(text, builtMap, symbols: debugSymbols, metadata: debugMetadata);
@@ -759,17 +753,26 @@
 /// names used when outputting the JavaScript.
 ModuleSymbols _emitSymbols(ProgramCompiler compiler, String moduleName,
     Map<js_ast.Identifier, String> identifierNames, Component component) {
+  /// Returns the name selected in the final Javascript for [id].
+  String lookupName(js_ast.Identifier id) {
+    var name = identifierNames[id];
+    if (name == null) {
+      throw Exception('No recorded naming decision found for Identifier with '
+          'name: ${id.name}');
+    }
+    return name;
+  }
+
   var classJsNames = <Class, String>{
-    for (var e in compiler.classIdentifiers.entries)
-      e.key: identifierNames[e.value],
+    for (var e in compiler.classIdentifiers.entries) e.key: lookupName(e.value),
   };
   var procedureJsNames = <Procedure, String>{
     for (var e in compiler.procedureIdentifiers.entries)
-      e.key: identifierNames[e.value],
+      e.key: lookupName(e.value),
   };
   var variableJsNames = <VariableDeclaration, String>{
     for (var e in compiler.variableIdentifiers.entries)
-      e.key: identifierNames[e.value],
+      e.key: lookupName(e.value),
   };
 
   return ModuleSymbolsCollector(moduleName, classJsNames, compiler.memberNames,
@@ -778,10 +781,10 @@
 }
 
 ModuleMetadata _emitMetadata(js_ast.Program program, Component component,
-    String sourceMapUri, String moduleUri, String fullDillUri) {
+    String sourceMapUri, String moduleUri, String? fullDillUri) {
   var metadata = ModuleMetadata(
-      program.name,
-      loadFunctionName(program.name),
+      program.name!,
+      loadFunctionName(program.name!),
       sourceMapUri,
       moduleUri,
       fullDillUri,
@@ -803,7 +806,7 @@
   var declaredVariables = <String, String>{};
   for (var i = 0; i < args.length;) {
     var arg = args[i];
-    String rest;
+    String? rest;
     const defineFlag = '--define';
     if (arg.startsWith('-D') && arg.length > 2) {
       rest = arg.substring(2);
@@ -835,7 +838,7 @@
 
 /// The default path of the kernel summary for the Dart SDK given the
 /// [soundNullSafety] mode.
-String defaultSdkSummaryPath({bool soundNullSafety}) {
+String defaultSdkSummaryPath({required bool soundNullSafety}) {
   var outlineDill = soundNullSafety ? 'ddc_outline_sound.dill' : 'ddc_sdk.dill';
   return p.join(getSdkPath(), 'lib', '_internal', outlineDill);
 }
@@ -850,7 +853,7 @@
 ///
 /// Checks for a `.dart_tool/package_config.json` file in the current working
 /// directory, or in any parent directory.
-String _findPackagesFilePath() {
+String? _findPackagesFilePath() {
   // TODO(jmesserly): this was copied from package:package_config/discovery.dart
   // Unfortunately the relevant function is not public. CFE APIs require a URI
   // to the .packages file, rather than letting us provide the package map data.
@@ -872,9 +875,9 @@
 }
 
 /// Inputs must be absolute paths. Returns null if no prefixing path is found.
-String _longestPrefixingPath(Uri baseUri, List<Uri> prefixingPaths) {
+String? _longestPrefixingPath(Uri baseUri, List<Uri> prefixingPaths) {
   var basePath = baseUri.path;
-  return prefixingPaths.fold(null, (String previousValue, Uri element) {
+  return prefixingPaths.fold(null, (String? previousValue, Uri element) {
     if (basePath.startsWith(element.path) &&
         (previousValue == null || previousValue.length < element.path.length)) {
       return element.path;
diff --git a/pkg/dev_compiler/lib/src/kernel/compiler.dart b/pkg/dev_compiler/lib/src/kernel/compiler.dart
index 6fe471c..f8e15fd 100644
--- a/pkg/dev_compiler/lib/src/kernel/compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/compiler.dart
@@ -2,12 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:collection';
 import 'dart:convert';
 import 'dart:math' show max, min;
 
+import 'package:collection/collection.dart'
+    show IterableExtension, IterableNullableExtension;
 import 'package:front_end/src/api_unstable/ddc.dart';
 import 'package:js_shared/synced/embedded_names.dart' show JsGetName, JsBuiltin;
 import 'package:kernel/class_hierarchy.dart';
@@ -61,7 +61,7 @@
   ///
   /// This mapping is used when generating the symbol information for the
   /// module.
-  final memberNames = <Member, String>{};
+  final Map<Member, String> memberNames = <Member, String>{};
 
   /// Maps each `Procedure` node compiled in the module to the `Identifier`s
   /// used to name the class in JavaScript.
@@ -89,18 +89,18 @@
   final Map<Component, String> _summaryToModule;
 
   /// The variable for the current catch clause
-  VariableDeclaration _rethrowParameter;
+  VariableDeclaration? _rethrowParameter;
 
   /// In an async* function, this represents the stream controller parameter.
-  js_ast.TemporaryId _asyncStarController;
+  js_ast.TemporaryId? _asyncStarController;
 
-  Set<Class> _pendingClasses;
+  Set<Class>? _pendingClasses;
 
   /// Temporary variables mapped to their corresponding JavaScript variable.
   final _tempVariables = <VariableDeclaration, js_ast.TemporaryId>{};
 
   /// Let variables collected for the given function.
-  List<js_ast.TemporaryId> _letVariables;
+  List<js_ast.TemporaryId>? _letVariables;
 
   final _constTable = js_ast.Identifier('CT');
 
@@ -120,10 +120,10 @@
   ///
   /// This is not used when inside the class method bodies, or for other type
   /// information such as `implements`.
-  Class _classEmittingExtends;
+  Class? _classEmittingExtends;
 
   /// The class that is emitting its signature information, otherwise null.
-  Class _classEmittingSignatures;
+  Class? _classEmittingSignatures;
 
   /// True when a class is emitting a deferred class hierarchy.
   bool _emittingDeferredType = false;
@@ -133,16 +133,16 @@
   ///
   ///     _currentClass == _classEmittingTopLevel
   ///
-  Class _currentClass;
+  Class? _currentClass;
 
   /// The current source file URI for emitting in the source map.
-  Uri _currentUri;
+  Uri? _currentUri;
 
-  Component _component;
+  late Component _component;
 
-  Library _currentLibrary;
+  Library? _currentLibrary;
 
-  FunctionNode _currentFunction;
+  FunctionNode? _currentFunction;
 
   /// Whether the current function needs to insert parameter checks.
   ///
@@ -156,7 +156,7 @@
   bool _isInForeignJS = false;
 
   /// Table of named and possibly hoisted types.
-  TypeTable _typeTable;
+  late TypeTable _typeTable;
 
   /// The global extension type table.
   // TODO(jmesserly): rename to `_nativeTypes`
@@ -172,7 +172,7 @@
 
   /// Information about virtual and overridden fields/getters/setters in the
   /// class we're currently compiling, or `null` if we aren't compiling a class.
-  ClassPropertyModel _classProperties;
+  ClassPropertyModel? _classProperties;
 
   /// Information about virtual fields for all libraries in the current build
   /// unit.
@@ -284,7 +284,7 @@
       SharedCompilerOptions options,
       Map<Library, Component> importToSummary,
       Map<Component, String> summaryToModule,
-      {CoreTypes coreTypes}) {
+      {CoreTypes? coreTypes}) {
     coreTypes ??= CoreTypes(component);
     var types = TypeEnvironment(coreTypes, hierarchy);
     var constants = DevCompilerConstants();
@@ -337,16 +337,13 @@
             'dart:_runtime', 'assertInterop') as Procedure;
 
   @override
-  Uri get currentLibraryUri => _currentLibrary.importUri;
-
-  @override
-  Library get currentLibrary => _currentLibrary;
+  Library? get currentLibrary => _currentLibrary;
 
   @override
   Library get coreLibrary => _coreTypes.coreLibrary;
 
   @override
-  FunctionNode get currentFunction => _currentFunction;
+  FunctionNode? get currentFunction => _currentFunction;
 
   @override
   InterfaceType get privateSymbolType =>
@@ -409,10 +406,11 @@
 
     // Collect all class/type Element -> Node mappings
     // in case we need to forward declare any classes.
-    _pendingClasses = HashSet.identity();
+    var classes = HashSet<Class>.identity();
     for (var l in libraries) {
-      _pendingClasses.addAll(l.classes);
+      classes.addAll(l.classes);
     }
+    _pendingClasses = classes;
 
     // Insert a circular reference so neither the constant table or its cache
     // are optimized away by V8. Required for expression evaluation.
@@ -482,7 +480,7 @@
         break;
       default:
         throw StateError('Unsupported Null Safety mode ${component.mode}, '
-            'in ${component?.location?.file}.');
+            'in ${component.location?.file}.');
     }
     if (!isBuildingSdk) {
       items.add(
@@ -508,7 +506,7 @@
   }
 
   @override
-  String jsLibraryAlias(Library library) {
+  String? jsLibraryAlias(Library library) {
     var uri = library.importUri.normalizePath();
     if (uri.isScheme('dart')) return null;
 
@@ -556,7 +554,7 @@
       // TODO(jmesserly): we need to split out HTML.
       return js_ast.dartSdkModule;
     }
-    var summary = _importToSummary[library];
+    var summary = _importToSummary[library]!;
     var moduleName = _summaryToModule[summary];
     if (moduleName == null) {
       throw StateError('Could not find module name for library "$library" '
@@ -573,7 +571,7 @@
     // See _emitClass.
     assert(_currentLibrary == null);
     _currentLibrary = library;
-    _staticTypeContext.enterLibrary(_currentLibrary);
+    _staticTypeContext.enterLibrary(_currentLibrary!);
 
     if (isBuildingSdk) {
       containerizeSymbols = _isWebLibrary(library.importUri);
@@ -606,7 +604,7 @@
       _emitTopLevelFields(library.fields);
     }
 
-    _staticTypeContext.leaveLibrary(_currentLibrary);
+    _staticTypeContext.leaveLibrary(_currentLibrary!);
     _currentLibrary = null;
   }
 
@@ -620,7 +618,7 @@
   }
 
   void _emitExport(Reference export) {
-    var library = _currentLibrary;
+    var library = _currentLibrary!;
 
     // We only need to export main as it is the only method part of the
     // publicly exposed JS API for a library.
@@ -643,7 +641,7 @@
   /// Because D depends on B, we'll emit B first if needed. However C is not
   /// used by top-level JavaScript code, so we can ignore that dependency.
   void _emitClass(Class c) {
-    if (!_pendingClasses.remove(c)) return;
+    if (!_pendingClasses!.remove(c)) return;
 
     var savedClass = _currentClass;
     var savedLibrary = _currentLibrary;
@@ -659,7 +657,7 @@
     }
 
     // The const table depends on dart.defineLazy, so emit it after the SDK.
-    if (isSdkInternalRuntime(_currentLibrary)) {
+    if (isSdkInternalRuntime(_currentLibrary!)) {
       _constTableInsertionIndex = moduleItems.length;
     }
 
@@ -678,7 +676,7 @@
   /// If we are not emitting top-level code, this does nothing, because all
   /// declarations are assumed to be available before we start execution.
   /// See [startTopLevel].
-  void _declareBeforeUse(Class c) {
+  void _declareBeforeUse(Class? c) {
     if (c != null && _emittingClassExtends) {
       _emitClass(c);
     }
@@ -710,7 +708,7 @@
     var body = <js_ast.Statement>[];
 
     // ClassPropertyModel.build introduces symbols for virtual field accessors.
-    _classProperties.virtualFields.forEach((field, virtualField) {
+    _classProperties!.virtualFields.forEach((field, virtualField) {
       // TODO(vsm): Clean up this logic.
       //
       // Typically, [emitClassPrivateNameSymbol] creates a new symbol.  If it
@@ -785,10 +783,12 @@
 
   /// Wraps a possibly generic class in its type arguments.
   js_ast.Statement _defineClassTypeArguments(
-      NamedNode c, List<TypeParameter> formals, js_ast.Statement body,
-      [js_ast.Expression className, List<js_ast.Statement> deferredBaseClass]) {
+      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);
 
     // Checks for explicitly set variance to avoid emitting legacy covariance
@@ -803,16 +803,12 @@
       body = js_ast.Statement.from([body, varianceStatement]);
     }
 
-    var typeConstructor = js.call('(#) => { #; #; return #; }', [
-      jsFormals,
-      _typeTable.dischargeFreeTypes(formals),
-      body,
-      className ?? _emitIdentifier(name)
-    ]);
+    var typeConstructor = js.call('(#) => { #; #; return #; }',
+        [jsFormals, _typeTable.dischargeFreeTypes(formals), body, className]);
 
     var genericArgs = [
       typeConstructor,
-      if (deferredBaseClass != null && deferredBaseClass.isNotEmpty)
+      if (deferredBaseClass.isNotEmpty)
         js.call('(#) => { #; }', [jsFormals, deferredBaseClass]),
     ];
 
@@ -842,7 +838,7 @@
   }
 
   js_ast.Statement _emitClassStatement(Class c, js_ast.Expression className,
-      js_ast.Expression heritage, List<js_ast.Method> methods) {
+      js_ast.Expression? heritage, List<js_ast.Method> methods) {
     if (c.typeParameters.isNotEmpty) {
       var classIdentifier = className as js_ast.Identifier;
       if (_options.emitDebugSymbols) classIdentifiers[c] = classIdentifier;
@@ -893,7 +889,7 @@
     var instanceMethods = methods.where((m) => !m.isStatic).toList();
 
     body.add(_emitClassStatement(c, className, heritage, staticMethods));
-    var superclassId = _emitTemporaryId(getLocalClassName(c.superclass));
+    var superclassId = _emitTemporaryId(getLocalClassName(c.superclass!));
     var classId = className is js_ast.Identifier
         ? className
         : _emitTemporaryId(getLocalClassName(c));
@@ -981,14 +977,14 @@
           if (t.typeArguments.any(defer)) return true;
           var mixin = tc.mixedInType;
           return mixin != null && defer(mixin.asInterfaceType) ||
-              defer(tc.supertype.asInterfaceType);
+              defer(tc.supertype!.asInterfaceType);
         }
         if (t is FutureOrType) {
           if (c == _coreTypes.deprecatedFutureOrClass) return true;
           if (!visited.add(t)) return false;
           if (defer(t.typeArgument)) return true;
           return defer(
-              _coreTypes.deprecatedFutureOrClass.supertype.asInterfaceType);
+              _coreTypes.deprecatedFutureOrClass.supertype!.asInterfaceType);
         }
         if (t is TypedefType) {
           return t.typeArguments.any(defer);
@@ -1027,9 +1023,9 @@
     /// Walks up the superclass chain looking for the first actual class
     /// skipping any synthetic classes inserted by the CFE.
     Class superClassAsWritten(Class c) {
-      var superclass = c.superclass;
+      var superclass = c.superclass!;
       while (superclass.isAnonymousMixin) {
-        superclass = superclass.superclass;
+        superclass = superclass.superclass!;
       }
       return superclass;
     }
@@ -1040,14 +1036,14 @@
     // TODO(jmesserly): consider using Kernel's mixin unrolling.
     var superclass = superClassAsWritten(c);
     var supertype = identical(c.superclass, superclass)
-        ? c.supertype.asInterfaceType
-        : _hierarchy.getClassAsInstanceOf(c, superclass).asInterfaceType;
+        ? c.supertype!.asInterfaceType
+        : _hierarchy.getClassAsInstanceOf(c, superclass)!.asInterfaceType;
     // All mixins (real and anonymous) classes applied to c.
     var mixinApplications = [
       if (c.mixedInClass != null) c.mixedInClass,
-      for (var sc = c.superclass;
+      for (var sc = c.superclass!;
           sc.isAnonymousMixin && sc.mixedInClass != null;
-          sc = sc.superclass)
+          sc = sc.superclass!)
         sc,
     ].reversed.toList();
 
@@ -1055,7 +1051,7 @@
 
     void emitMixinConstructors(
         js_ast.Expression className, InterfaceType mixin) {
-      js_ast.Statement mixinCtor;
+      js_ast.Statement? mixinCtor;
       if (_hasUnnamedConstructor(mixin.classNode)) {
         mixinCtor = js.statement('#.#.call(this);', [
           emitClassRef(mixin),
@@ -1096,7 +1092,7 @@
       // the 'extends' clause for generics for cyclic dependencies and append
       // them later with 'setBaseClass'.
       supertype =
-          _coreTypes.rawType(supertype.classNode, _currentLibrary.nonNullable);
+          _coreTypes.rawType(supertype.classNode, _currentLibrary!.nonNullable);
     }
     var baseClass = emitClassRef(supertype);
 
@@ -1108,7 +1104,7 @@
       // code paths, or will these always need special handling?
       body.add(_emitClassStatement(c, className, baseClass, []));
 
-      var m = c.mixedInType.asInterfaceType;
+      var m = c.mixedInType!.asInterfaceType;
       var deferMixin = shouldDefer(m);
       var mixinClass = deferMixin
           ? emitDeferredType(m, emitNullability: false)
@@ -1153,11 +1149,11 @@
     //
     // Also, we need to generate one extra level of nesting for alias classes.
     for (var i = 0; i < mixinApplications.length; i++) {
-      var m = mixinApplications[i];
-      var mixinClass = m.isAnonymousMixin ? m.mixedInClass : m;
+      var m = mixinApplications[i]!;
+      var mixinClass = m.isAnonymousMixin ? m.mixedInClass! : m;
       _declareBeforeUse(mixinClass);
       var mixinType =
-          _hierarchy.getClassAsInstanceOf(c, mixinClass).asInterfaceType;
+          _hierarchy.getClassAsInstanceOf(c, mixinClass)!.asInterfaceType;
       var mixinName =
           '${getLocalClassName(superclass)}_${getLocalClassName(mixinClass)}';
       var mixinId = _emitTemporaryId('$mixinName\$');
@@ -1175,7 +1171,8 @@
 
       var forwardingMethodStubs = <js_ast.Method>[];
       for (var s in forwardingSetters.values) {
-        forwardingMethodStubs.add(_emitMethodDeclaration(s));
+        var stub = _emitMethodDeclaration(s);
+        if (stub != null) forwardingMethodStubs.add(stub);
         // If there are getters matching the setters somewhere above in the
         // class hierarchy we must also generate a forwarding getter due to the
         // representation used in the compiled JavaScript.
@@ -1258,9 +1255,9 @@
     return body;
   }
 
-  js_ast.Statement _emitClassTypeTests(
+  js_ast.Statement? _emitClassTypeTests(
       Class c, js_ast.Expression className, List<js_ast.Statement> body) {
-    js_ast.Expression getInterfaceSymbol(Class interface) {
+    js_ast.Expression? getInterfaceSymbol(Class interface) {
       var library = interface.enclosingLibrary;
       if (library == _coreTypes.coreLibrary ||
           library == _coreTypes.asyncLibrary) {
@@ -1389,7 +1386,7 @@
       ]));
     }
 
-    var props = _classProperties;
+    var props = _classProperties!;
     emitExtensions('defineExtensionMethods', props.extensionMethods);
     emitExtensions('defineExtensionAccessors', props.extensionAccessors);
   }
@@ -1436,8 +1433,8 @@
       body.add(setSignature);
     }
 
-    var extMethods = _classProperties.extensionMethods;
-    var extAccessors = _classProperties.extensionAccessors;
+    var extMethods = _classProperties!.extensionMethods;
+    var extAccessors = _classProperties!.extensionAccessors;
     var staticMethods = <js_ast.Property>[];
     var instanceMethods = <js_ast.Property>[];
     var staticGetters = <js_ast.Property>[];
@@ -1486,7 +1483,7 @@
       // emit a signature on this class.  Otherwise we will inherit the
       // signature from the superclass.
       var memberOverride = c.superclass != null
-          ? _hierarchy.getDispatchTarget(c.superclass, member.name,
+          ? _hierarchy.getDispatchTarget(c.superclass!, member.name,
               setter: member.isSetter)
           : null;
 
@@ -1500,7 +1497,7 @@
               ? reifiedType.returnType
               : reifiedType.positionalParameters[0]);
         } else {
-          type = visitFunctionType(reifiedType, member: member);
+          type = visitFunctionType(reifiedType);
         }
         var property = js_ast.Property(_declareMemberName(member), type);
         var signatures = getSignatureList(member);
@@ -1533,7 +1530,7 @@
       // signatures are only used by the debugger and are not needed for runtime
       // correctness.
       var memberName = _declareMemberName(field);
-      var fieldSig = _emitFieldSignature(field, c);
+      var fieldSig = _emitClassFieldSignature(field, c);
       // TODO(40273) Skip static fields when the debugger consumes signature
       // information from symbol files.
       (field.isStatic ? staticFields : instanceFields)
@@ -1554,8 +1551,8 @@
     _classEmittingSignatures = savedClass;
   }
 
-  js_ast.Expression _emitFieldSignature(Field field, Class fromClass) {
-    var type = _typeFromClass(field.type, field.enclosingClass, fromClass);
+  js_ast.Expression _emitClassFieldSignature(Field field, Class fromClass) {
+    var type = _typeFromClass(field.type, field.enclosingClass!, fromClass);
     var args = [_emitType(type)];
     return runtimeCall(
         field.isFinal ? 'finalFieldType(#)' : 'fieldType(#)', [args]);
@@ -1576,7 +1573,7 @@
           ? _coreTypes.objectRawType(member.enclosingLibrary.nullable)
           : p.type;
       NamedType reifyNamedParameter(VariableDeclaration p) =>
-          NamedType(p.name, reifyParameter(p));
+          NamedType(p.name!, reifyParameter(p));
 
       // TODO(jmesserly): do covariant type parameter bounds also need to be
       // reified as `Object`?
@@ -1589,21 +1586,21 @@
               .typeParameters,
           requiredParameterCount: f.requiredParameterCount);
     }
-    return _typeFromClass(result, member.enclosingClass, fromClass)
+    return _typeFromClass(result, member.enclosingClass!, fromClass)
         as FunctionType;
   }
 
   DartType _typeFromClass(DartType type, Class superclass, Class subclass) {
     if (identical(superclass, subclass)) return type;
     return Substitution.fromSupertype(
-            _hierarchy.getClassAsInstanceOf(subclass, superclass))
+            _hierarchy.getClassAsInstanceOf(subclass, superclass)!)
         .substituteType(type);
   }
 
   js_ast.Expression _emitConstructor(
       Constructor node, List<Field> fields, js_ast.Expression className) {
     var savedUri = _currentUri;
-    _currentUri = node.fileUri ?? savedUri;
+    _currentUri = node.fileUri;
     _staticTypeContext.enterMember(node);
     var params = _emitParameters(node.function);
     var body = _withCurrentFunction(
@@ -1649,11 +1646,10 @@
     // If no superinitializer is provided, an implicit superinitializer of the
     // form `super()` is added at the end of the initializer list, unless the
     // enclosing class is class Object.
-    var superCall = node.initializers.firstWhere((i) => i is SuperInitializer,
-        orElse: () => null) as SuperInitializer;
+    var superCall = node.initializers.whereType<SuperInitializer>().firstOrNull;
     var jsSuper = _emitSuperConstructorCallIfNeeded(cls, className, superCall);
     if (jsSuper != null) {
-      body.add(jsSuper..sourceInformation = _nodeStart(superCall));
+      body.add(jsSuper..sourceInformation = _nodeStart(superCall!));
     }
 
     body.add(_emitFunctionScopedBody(fn));
@@ -1688,15 +1684,14 @@
     return js_ast.Block(jsInitializers);
   }
 
-  js_ast.Statement _emitSuperConstructorCallIfNeeded(
-      Class c, js_ast.Expression className,
-      [SuperInitializer superInit]) {
+  js_ast.Statement? _emitSuperConstructorCallIfNeeded(
+      Class c, js_ast.Expression className, SuperInitializer? superInit) {
     if (c == _coreTypes.objectClass) return null;
 
     Constructor ctor;
     List<js_ast.Expression> args;
     if (superInit == null) {
-      ctor = unnamedConstructor(c.superclass);
+      ctor = unnamedConstructor(c.superclass!)!;
       args = [];
     } else {
       ctor = superInit.target;
@@ -1714,10 +1709,10 @@
   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 ?? []]);
+        [className, _constructorName(name), args]);
   }
 
-  bool _hasUnnamedInheritedConstructor(Class c) {
+  bool _hasUnnamedInheritedConstructor(Class? c) {
     if (c == null) return false;
     return _hasUnnamedConstructor(c) || _hasUnnamedSuperConstructor(c);
   }
@@ -1727,7 +1722,7 @@
         _hasUnnamedInheritedConstructor(c.superclass);
   }
 
-  bool _hasUnnamedConstructor(Class c) {
+  bool _hasUnnamedConstructor(Class? c) {
     if (c == null || c == _coreTypes.objectClass) return false;
     var ctor = unnamedConstructor(c);
     if (ctor != null && !ctor.isSynthetic) return true;
@@ -1740,19 +1735,16 @@
   ///   2. field initializing parameters,
   ///   3. constructor field initializers,
   ///   4. initialize fields not covered in 1-3
-  js_ast.Statement _initializeFields(List<Field> fields, [Constructor ctor]) {
+  js_ast.Statement _initializeFields(List<Field> fields, [Constructor? ctor]) {
     // Run field initializers if they can have side-effects.
-    Set<Field> ctorFields;
-    if (ctor != null) {
-      ctorFields = ctor.initializers
-          .map((c) => c is FieldInitializer ? c.field : null)
-          .toSet()
-        ..remove(null);
-    }
+    var ctorFields = ctor?.initializers
+        .whereType<FieldInitializer>()
+        .map((c) => c.field)
+        .toSet();
 
     var body = <js_ast.Statement>[];
-    void emitFieldInit(Field f, Expression initializer, TreeNode hoverInfo) {
-      var virtualField = _classProperties.virtualFields[f];
+    void emitFieldInit(Field f, Expression? initializer, TreeNode hoverInfo) {
+      var virtualField = _classProperties!.virtualFields[f];
 
       // Avoid calling getSymbol on _declareMemberName since _declareMemberName
       // calls _emitMemberName downstream, which already invokes getSymbol.
@@ -1796,7 +1788,7 @@
   }
 
   js_ast.Expression _visitInitializer(
-      Expression init, List<Expression> annotations) {
+      Expression? init, List<Expression> annotations) {
     // explicitly initialize to null, to avoid getting `undefined`.
     // TODO(jmesserly): do this only for vars that aren't definitely assigned.
     if (init == null) return js_ast.LiteralNull();
@@ -1806,7 +1798,6 @@
   }
 
   js_ast.Expression notNull(Expression expr) {
-    if (expr == null) return null;
     var jsExpr = _visitExpression(expr);
     if (!isNullable(expr)) return jsExpr;
     return runtimeCall('notNull(#)', [jsExpr]);
@@ -1833,23 +1824,24 @@
   bool superclassHasStatic(Class c, String memberName) {
     // Note: because we're only considering statics, we can ignore mixins.
     // We're only trying to find conflicts due to JS inheriting statics.
+    var superclass = c.superclass;
     var name = Name(memberName, c.enclosingLibrary);
     while (true) {
-      c = c.superclass;
-      if (c == null) return false;
-      for (var m in c.members) {
+      if (superclass == null) return false;
+      for (var m in superclass.members) {
         if (m.name == name &&
             (m is Procedure && m.isStatic || m is Field && m.isStatic)) {
           return true;
         }
       }
+      superclass = superclass.superclass;
     }
   }
 
   List<js_ast.Method> _emitClassMethods(Class c) {
-    var virtualFields = _classProperties.virtualFields;
+    var virtualFields = _classProperties!.virtualFields;
 
-    var jsMethods = <js_ast.Method>[];
+    var jsMethods = <js_ast.Method?>[];
     var hasJsPeer = _extensionTypes.isNativeClass(c);
     var hasIterator = false;
 
@@ -1875,7 +1867,7 @@
           propertyName('constructor'), js.fun(r'function() { return []; }')));
     }
 
-    Set<Member> redirectingFactories;
+    Set<Member>? redirectingFactories;
     var staticFieldNames = <Name>{};
     for (var m in c.fields) {
       if (m.isStatic) {
@@ -1917,7 +1909,7 @@
       // bogus file URI, that is mismatched compared to the offsets. This causes
       // a crash when we look up the location. So for those forwarders, we just
       // suppress source spans.
-      _currentUri = m.isNoSuchMethodForwarder ? null : (m.fileUri ?? savedUri);
+      _currentUri = m.isNoSuchMethodForwarder ? null : m.fileUri;
       if (_isForwardingStub(m)) {
         // TODO(jmesserly): is there any other kind of forwarding stub?
         jsMethods.addAll(_emitCovarianceCheckStub(m));
@@ -1956,12 +1948,12 @@
     // Add all of the super helper methods
     jsMethods.addAll(_superHelpers.values);
 
-    return jsMethods.where((m) => m != null).toList();
+    return jsMethods.whereNotNull().toList();
   }
 
   bool _isForwardingStub(Procedure member) {
     if (member.isForwardingStub || member.isForwardingSemiStub) {
-      if (!_currentLibrary.importUri.isScheme('dart')) return true;
+      if (!_currentLibrary!.importUri.isScheme('dart')) return true;
       // TODO(jmesserly): external methods in the SDK seem to get incorrectly
       // tagged as forwarding stubs even if they are patched. Perhaps there is
       // an ordering issue in CFE. So for now we pattern match to see if it
@@ -1981,7 +1973,7 @@
   }
 
   /// Emits a method, getter, or setter.
-  js_ast.Method _emitMethodDeclaration(Procedure member) {
+  js_ast.Method? _emitMethodDeclaration(Procedure member) {
     if (member.isAbstract) {
       return null;
     }
@@ -2052,15 +2044,16 @@
     if (superMember == null) return const [];
 
     DartType substituteType(DartType t) {
-      return _typeFromClass(t, superMember.enclosingClass, enclosingClass);
+      return _typeFromClass(t, superMember.enclosingClass!, enclosingClass!);
     }
 
+    var superMemberFunction = superMember.function;
     var name = _declareMemberName(member);
     if (member.isSetter) {
       if (superMember is Field && isCovariantField(superMember) ||
           superMember is Procedure &&
               isCovariantParameter(
-                  superMember.function.positionalParameters[0])) {
+                  superMemberFunction!.positionalParameters[0])) {
         return const [];
       }
       var setterType = substituteType(superMember.superSetterType);
@@ -2077,7 +2070,7 @@
     }
     assert(!member.isAccessor);
 
-    var superMethodType = substituteType(superMember.function
+    var superMethodType = substituteType(superMemberFunction!
             .computeThisFunctionType(superMember.enclosingLibrary.nonNullable))
         as FunctionType;
     var function = member.function;
@@ -2091,11 +2084,11 @@
     var positionalParameters = function.positionalParameters;
     for (var i = 0, n = positionalParameters.length; i < n; i++) {
       var param = positionalParameters[i];
-      var jsParam = _emitIdentifier(param.name);
+      var jsParam = _emitIdentifier(param.name!);
       jsParams.add(jsParam);
 
       if (isCovariantParameter(param) &&
-          !isCovariantParameter(superMember.function.positionalParameters[i])) {
+          !isCovariantParameter(superMemberFunction.positionalParameters[i])) {
         var check = _emitCast(jsParam, superMethodType.positionalParameters[i]);
         if (i >= function.requiredParameterCount) {
           body.add(js.statement('if (# !== void 0) #;', [jsParam, check]));
@@ -2107,9 +2100,9 @@
     var namedParameters = function.namedParameters;
     for (var param in namedParameters) {
       if (isCovariantParameter(param) &&
-          !isCovariantParameter(superMember.function.namedParameters
+          !isCovariantParameter(superMemberFunction.namedParameters
               .firstWhere((n) => n.name == param.name))) {
-        var name = propertyName(param.name);
+        var name = propertyName(param.name!);
         var paramType = superMethodType.namedParameters
             .firstWhere((n) => n.name == param.name);
         body.add(js.statement('if (# in #) #;', [
@@ -2129,7 +2122,7 @@
   }
 
   /// Emits a Dart factory constructor to a JS static method.
-  js_ast.Method _emitFactoryConstructor(Procedure node) {
+  js_ast.Method? _emitFactoryConstructor(Procedure node) {
     if (node.isExternal || isUnsupportedFactoryConstructor(node)) return null;
 
     var function = node.function;
@@ -2167,7 +2160,7 @@
   /// exist, resulting in a runtime error. Even if they did exist, that's the
   /// wrong behavior if a new field was declared.
   List<js_ast.Method> _emitVirtualFieldAccessor(Field field) {
-    var virtualField = _classProperties.virtualFields[field];
+    var virtualField = _classProperties!.virtualFields[field]!;
     var virtualFieldSymbol = getSymbol(virtualField);
     var name = _declareMemberName(field);
 
@@ -2228,7 +2221,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_ast.Method _emitSuperAccessorWrapper(Procedure member,
+  js_ast.Method? _emitSuperAccessorWrapper(Procedure member,
       Map<String, Procedure> getters, Map<String, Procedure> setters) {
     if (member.isAbstract) return null;
 
@@ -2236,7 +2229,7 @@
     var memberName = _declareMemberName(member);
     if (member.isGetter) {
       if (!setters.containsKey(name) &&
-          _classProperties.inheritedSetters.contains(name)) {
+          _classProperties!.inheritedSetters.contains(name)) {
         // Generate a setter that forwards to super.
         var fn = js.fun('function(value) { super[#] = value; }', [memberName]);
         return js_ast.Method(memberName, fn, isSetter: true);
@@ -2244,7 +2237,7 @@
     } else {
       assert(member.isSetter);
       if (!getters.containsKey(name) &&
-          _classProperties.inheritedGetters.contains(name)) {
+          _classProperties!.inheritedGetters.contains(name)) {
         // Generate a getter that forwards to super.
         var fn = js.fun('function() { return super[#]; }', [memberName]);
         return js_ast.Method(memberName, fn, isGetter: true);
@@ -2261,18 +2254,18 @@
   /// This will return `null` if the adapter was already added on a super type,
   /// otherwise it returns the adapter code.
   // TODO(jmesserly): should we adapt `Iterator` too?
-  js_ast.Method _emitIterable(Class c) {
+  js_ast.Method? _emitIterable(Class c) {
     var iterable = _hierarchy.getClassAsInstanceOf(c, _coreTypes.iterableClass);
     if (iterable == null) return null;
-
+    var superclass = c.superclass!;
     // If a parent had an `iterator` (concrete or abstract) or implements
     // Iterable, we know the adapter is already there, so we can skip it as a
     // simple code size optimization.
-    var parent = _hierarchy.getDispatchTarget(c.superclass, Name('iterator'));
+    var parent = _hierarchy.getDispatchTarget(superclass, Name('iterator'));
     if (parent != null) return null;
 
     var parentIterable =
-        _hierarchy.getClassAsInstanceOf(c.superclass, _coreTypes.iterableClass);
+        _hierarchy.getClassAsInstanceOf(superclass, _coreTypes.iterableClass);
     if (parentIterable != null) return null;
 
     if (c.enclosingLibrary.importUri.isScheme('dart') &&
@@ -2304,7 +2297,7 @@
   }
 
   void _emitTopLevelFields(List<Field> fields) {
-    if (isSdkInternalRuntime(_currentLibrary)) {
+    if (isSdkInternalRuntime(_currentLibrary!)) {
       /// Treat dart:_runtime fields as safe to eagerly evaluate.
       // TODO(jmesserly): it'd be nice to avoid this special case.
       var lazyFields = <Field>[];
@@ -2348,7 +2341,7 @@
 
     if (fields.isEmpty) return;
     moduleItems.add(_emitLazyMembers(
-        emitLibraryName(_currentLibrary), fields, _emitTopLevelMemberName));
+        emitLibraryName(_currentLibrary!), fields, _emitTopLevelMemberName));
   }
 
   js_ast.Statement _emitLazyMembers(
@@ -2398,7 +2391,7 @@
     return runtimeStatement('defineLazy(#, { # }, #)', [
       objExpr,
       accessors,
-      js.boolean(!_currentLibrary.isNonNullableByDefault)
+      js.boolean(!_currentLibrary!.isNonNullableByDefault)
     ]);
   }
 
@@ -2431,7 +2424,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_ast.Expression _declareMemberName(Member m, {bool useExtension}) {
+  js_ast.Expression _declareMemberName(Member m, {bool? useExtension}) {
     var c = m.enclosingClass;
     return _emitMemberName(m.name.text,
         isStatic: m is Field ? m.isStatic : (m as Procedure).isStatic,
@@ -2482,13 +2475,13 @@
   ///
   js_ast.Expression _emitMemberName(String name,
       {bool isStatic = false,
-      bool useExtension,
-      Member member,
-      Class memberClass}) {
+      bool? useExtension,
+      Member? member,
+      Class? memberClass}) {
     // Static members skip the rename steps and may require JS interop renames.
     if (isStatic) {
       var memberName = _emitStaticMemberName(name, member);
-      if (!isTearOffLowering(member)) {
+      if (member != null && !isTearOffLowering(member)) {
         // No need to track the names of methods that were created by the CFE
         // lowering and don't exist in the original source code.
         memberNames[member] = memberName.valueWithoutQuotes;
@@ -2518,12 +2511,17 @@
     memberClass ??= member?.enclosingClass;
     if (name.startsWith('_')) {
       // Use the library that this private member's name is scoped to.
-      var memberLibrary = member?.name?.library ??
+      var memberLibrary = member?.name.library ??
           memberClass?.enclosingLibrary ??
-          _currentLibrary;
-      // Wrap the name as a symbol here so it matches what you would find at
-      // runtime when you get all properties and symbols from an instance.
-      memberNames[member] = 'Symbol($name)';
+          _currentLibrary!;
+      if (member != null) {
+        // TODO(40273) Move this name collection to another location.
+        // We really only want to collect member names when the member is created,
+        // not called.
+        // Wrap the name as a symbol here so it matches what you would find at
+        // runtime when you get all properties and symbols from an instance.
+        memberNames[member] = 'Symbol($name)';
+      }
       return getSymbol(emitPrivateNameSymbol(memberLibrary, name));
     }
 
@@ -2534,7 +2532,12 @@
       return getSymbol(getExtensionSymbolInternal(name));
     }
     var memberName = propertyName(name);
-    memberNames[member] = memberName.valueWithoutQuotes;
+    if (member != null) {
+      // TODO(40273) Move this name collection to another location.
+      // We really only want to collect member names when the member is created,
+      // not called.
+      memberNames[member] = memberName.valueWithoutQuotes;
+    }
     return memberName;
   }
 
@@ -2545,7 +2548,7 @@
   /// Note, this is an underlying assumption here that, if another native type
   /// subtypes this one, it also forwards this member to its underlying native
   /// one without renaming.
-  bool _isSymbolizedMember(Class c, String name) {
+  bool _isSymbolizedMember(Class? c, String name) {
     if (c == null) {
       return _isObjectMember(name);
     }
@@ -2559,7 +2562,7 @@
         // If the native member needs to be null-checked and we're running in
         // sound null-safety, we require symbolizing it in order to access the
         // null-check at the member definition.
-        if (_isNullCheckableNative(member)) return true;
+        if (_isNullCheckableNative(member!)) return true;
         var jsName = _annotationName(member, isJSName);
         return jsName != null && jsName != name;
       } else {
@@ -2574,9 +2577,9 @@
     return _extensionTypes.isNativeInterface(c);
   }
 
-  final _forwardingCache = HashMap<Class, Map<String, Member>>();
+  final _forwardingCache = HashMap<Class, Map<String, Member?>>();
 
-  Member _lookupForwardedMember(Class c, String name) {
+  Member? _lookupForwardedMember(Class c, String name) {
     // We only care about public methods.
     if (name.startsWith('_')) return null;
 
@@ -2589,7 +2592,7 @@
             _hierarchy.getDispatchTarget(c, Name(name), setter: true));
   }
 
-  js_ast.LiteralString _emitStaticMemberName(String name, [NamedNode member]) {
+  js_ast.LiteralString _emitStaticMemberName(String name, [NamedNode? member]) {
     if (member != null) {
       var jsName = _emitJSInteropStaticMemberName(member);
       if (jsName != null) return jsName;
@@ -2643,10 +2646,10 @@
     return f;
   }
 
-  js_ast.LiteralString _emitJSInteropStaticMemberName(NamedNode n) {
+  js_ast.LiteralString? _emitJSInteropStaticMemberName(NamedNode n) {
     if (!usesJSInterop(n)) return null;
     var name = _annotationName(n, isPublicJSAnnotation) ?? getTopLevelName(n);
-    assert(name != null && !name.contains('.'),
+    assert(!name.contains('.'),
         'JS interop checker rejects dotted names on static class members');
     return js.escapedString(name, "'");
   }
@@ -2677,7 +2680,7 @@
     return propertyName(name + suffix);
   }
 
-  bool _isExternal(Member m) {
+  bool _isExternal(Member? m) {
     // Corresponds to the names in memberNameForDartMember in
     // compiler/js_names.dart.
     const renamedJsMembers = ['prototype', 'constructor'];
@@ -2685,7 +2688,7 @@
       if (m.isExternal) return true;
       if (m.isNoSuchMethodForwarder) {
         if (renamedJsMembers.contains(m.name.text)) {
-          return _hasExternalProcedure(m.enclosingClass, m.name.text);
+          return _hasExternalProcedure(m.enclosingClass!, m.name.text);
         }
       }
     }
@@ -2703,9 +2706,8 @@
     while (classes.isNotEmpty) {
       var c = classes.removeFirst();
       var classesToCheck = [
-        if (c.supertype != null) c.supertype.classNode,
-        for (var t in c.implementedTypes)
-          if (t.classNode != null) t.classNode,
+        if (c.supertype != null) c.supertype!.classNode,
+        for (var t in c.implementedTypes) t.classNode,
       ];
       classes.addAll(classesToCheck);
       for (var procedure in c.procedures) {
@@ -2718,20 +2720,20 @@
     return false;
   }
 
-  String _jsNameWithoutGlobal(NamedNode n) {
+  String? _jsNameWithoutGlobal(NamedNode n) {
     if (!usesJSInterop(n)) return null;
     var libraryJSName = _annotationName(getLibrary(n), isPublicJSAnnotation);
     var jsName = _annotationName(n, isPublicJSAnnotation) ?? getTopLevelName(n);
     return libraryJSName != null ? '$libraryJSName.$jsName' : jsName;
   }
 
-  String _emitJsNameWithoutGlobal(NamedNode n) {
+  String? _emitJsNameWithoutGlobal(NamedNode n) {
     if (!usesJSInterop(n)) return null;
     setEmitIfIncrementalLibrary(getLibrary(n));
     return _jsNameWithoutGlobal(n);
   }
 
-  js_ast.PropertyAccess _emitJSInterop(NamedNode n) {
+  js_ast.PropertyAccess? _emitJSInterop(NamedNode n) {
     var jsName = _emitJsNameWithoutGlobal(n);
     if (jsName == null) return null;
     return _emitJSInteropForGlobal(jsName);
@@ -2740,12 +2742,12 @@
   js_ast.PropertyAccess _emitJSInteropForGlobal(String name) {
     var parts = name.split('.');
     if (parts.isEmpty) parts = [''];
-    js_ast.PropertyAccess access;
+    js_ast.PropertyAccess? access;
     for (var part in parts) {
       access = js_ast.PropertyAccess(
           access ?? runtimeCall('global'), js.escapedString(part, "'"));
     }
-    return access;
+    return access!;
   }
 
   void _emitLibraryProcedures(Library library) {
@@ -2762,7 +2764,7 @@
   void _emitLibraryAccessors(Iterable<Procedure> accessors) {
     if (accessors.isEmpty) return;
     moduleItems.add(runtimeStatement('copyProperties(#, { # })', [
-      emitLibraryName(_currentLibrary),
+      emitLibraryName(_currentLibrary!),
       accessors.map(_emitLibraryAccessor).toList()
     ]));
   }
@@ -2793,7 +2795,7 @@
     var fn = _emitFunction(p.function, p.name.text)
       ..sourceInformation = _nodeEnd(p.fileEndOffset);
 
-    if (_currentLibrary.importUri.isScheme('dart') &&
+    if (_currentLibrary!.importUri.isScheme('dart') &&
         _isInlineJSFunction(p.function.body)) {
       fn = js_ast.simplifyPassThroughArrowFunCallBody(fn);
     }
@@ -2856,11 +2858,11 @@
   bool _canEmitTypeAtTopLevel(DartType type) {
     assert(isKnownDartTypeImplementor(type));
     if (type is InterfaceType) {
-      return !_pendingClasses.contains(type.classNode) &&
+      return !_pendingClasses!.contains(type.classNode) &&
           type.typeArguments.every(_canEmitTypeAtTopLevel);
     }
     if (type is FutureOrType) {
-      return !_pendingClasses.contains(_coreTypes.deprecatedFutureOrClass) &&
+      return !_pendingClasses!.contains(_coreTypes.deprecatedFutureOrClass) &&
           _canEmitTypeAtTopLevel(type.typeArgument);
     }
     if (type is FunctionType) {
@@ -2993,7 +2995,7 @@
       {bool emitNullability = true}) {
     var c = type.classNode;
     _declareBeforeUse(c);
-    js_ast.Expression typeRep;
+    js_ast.Expression? typeRep;
 
     // Type parameters don't matter as JS interop types cannot be reified.
     // package:js types fall under either named or anonymous types. Named types
@@ -3017,7 +3019,7 @@
     }
 
     var args = type.typeArguments;
-    Iterable<js_ast.Expression> jsArgs;
+    Iterable<js_ast.Expression>? jsArgs;
     if (args.any((a) => a != const DynamicType())) {
       jsArgs = args.map(_emitType);
     }
@@ -3066,7 +3068,7 @@
     _declareBeforeUse(_coreTypes.deprecatedFutureOrClass);
 
     var arg = type.typeArgument;
-    js_ast.Expression typeRep;
+    js_ast.Expression? typeRep;
     if (arg != const DynamicType()) {
       // We force nullability to non-nullable to prevent caching nullable
       // and non-nullable generic types separately (e.g., C<T> and C<T>?).
@@ -3098,8 +3100,8 @@
 
   void /* Never */ _undeterminedNullabilityError(DartType type) =>
       throw UnsupportedError(
-          'Undetermined Nullability encounted while compiling '
-          '${currentLibrary.fileUri}, which contains the type: $type.');
+          'Undetermined Nullability encountered while compiling '
+          '${_currentLibrary!.fileUri}, which contains the type: $type.');
 
   /// Wraps [typeRep] in the appropriate wrapper for the given [nullability].
   ///
@@ -3147,19 +3149,11 @@
   }
 
   @override
-  js_ast.Expression visitFunctionType(type,
-      {Member member, bool lazy = false}) {
+  js_ast.Expression visitFunctionType(type, {bool lazy = false}) {
     var requiredTypes =
         type.positionalParameters.take(type.requiredParameterCount).toList();
-    var function = member?.function;
-    var requiredParams = function?.positionalParameters
-        ?.take(type.requiredParameterCount)
-        ?.toList();
     var optionalTypes =
         type.positionalParameters.skip(type.requiredParameterCount).toList();
-    var optionalParams = function?.positionalParameters
-        ?.skip(type.requiredParameterCount)
-        ?.toList();
 
     var namedTypes = <NamedType>[];
     var requiredNamedTypes = <NamedType>[];
@@ -3169,7 +3163,7 @@
     var allNamedTypes = type.namedParameters;
 
     var returnType = _emitType(type.returnType);
-    var requiredArgs = _emitTypeNames(requiredTypes, requiredParams, member);
+    var requiredArgs = _emitTypeNames(requiredTypes);
 
     List<js_ast.Expression> typeParts;
     if (allNamedTypes.isNotEmpty) {
@@ -3179,7 +3173,7 @@
       typeParts = [returnType, requiredArgs, namedArgs, requiredNamedArgs];
     } else if (optionalTypes.isNotEmpty) {
       assert(allNamedTypes.isEmpty);
-      var optionalArgs = _emitTypeNames(optionalTypes, optionalParams, member);
+      var optionalArgs = _emitTypeNames(optionalTypes);
       typeParts = [returnType, requiredArgs, optionalArgs];
     } else {
       typeParts = [returnType, requiredArgs];
@@ -3278,8 +3272,7 @@
   /// Emits a list of types and their metadata annotations to code.
   ///
   /// Annotatable contexts include typedefs and method/function declarations.
-  js_ast.ArrayInitializer _emitTypeNames(List<DartType> types,
-          List<VariableDeclaration> parameters, Member member) =>
+  js_ast.ArrayInitializer _emitTypeNames(List<DartType> types) =>
       js_ast.ArrayInitializer([for (var type in types) _emitType(type)]);
 
   @override
@@ -3313,7 +3306,7 @@
 
   /// Set incremental mode for expression compilation.
   ///
-  /// Called for each expression compilation to set the intremental mode
+  /// Called for each expression compilation to set the incremental mode
   /// and clear referenced items.
   ///
   /// The compiler cannot revert to non-incremental mode, and requires the
@@ -3345,10 +3338,10 @@
   /// Triggers incremental mode, which only emits symbols, types, constants,
   /// libraries, and uris referenced in the expression compilation result.
   js_ast.Fun emitFunctionIncremental(List<ModuleItem> items, Library library,
-      Class cls, FunctionNode functionNode, String name) {
+      Class? cls, FunctionNode functionNode, String name) {
     // Setup context.
     _currentLibrary = library;
-    _staticTypeContext.enterLibrary(_currentLibrary);
+    _staticTypeContext.enterLibrary(_currentLibrary!);
     _currentClass = cls;
 
     // Keep all symbols in containers.
@@ -3386,7 +3379,7 @@
       setEmitIfIncrementalLibrary(library);
     }
     emitImports(items);
-    emitExportsAsImports(items, _currentLibrary);
+    emitExportsAsImports(items, _currentLibrary!);
 
     return js_ast.Fun(fun.params, body);
   }
@@ -3405,7 +3398,7 @@
     return constTable;
   }
 
-  js_ast.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);
@@ -3471,7 +3464,7 @@
   /// This is an internal part of [_emitGeneratorFunctionBody] and should not be
   /// called directly.
   js_ast.Expression _emitGeneratorFunctionExpression(
-      FunctionNode function, String name) {
+      FunctionNode function, String? name) {
     js_ast.Expression emitGeneratorFn(
         List<js_ast.Parameter> Function(js_ast.Block jsBody) getParameters) {
       var savedController = _asyncStarController;
@@ -3479,7 +3472,7 @@
           ? _emitTemporaryId('stream')
           : null;
 
-      js_ast.Expression gen;
+      late js_ast.Expression gen;
       _superDisallowed(() {
         // Visit the body with our async* controller set.
         //
@@ -3491,16 +3484,19 @@
             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_ast.NamedFunction(
-              _emitTemporaryId(
-                  js_ast.friendlyNameForDartOperator[name] ?? name),
-              genFn);
+        var fnExpression = name != null
+            ? js_ast.NamedFunction(
+                _emitTemporaryId(
+                    js_ast.friendlyNameForDartOperator[name] ?? name),
+                genFn)
+            : genFn;
+
+        fnExpression.sourceInformation = _nodeEnd(function.fileEndOffset);
+        if (usesThisOrSuper(fnExpression)) {
+          fnExpression = js.call('#.bind(this)', fnExpression);
         }
 
-        gen.sourceInformation = _nodeEnd(function.fileEndOffset);
-        if (usesThisOrSuper(gen)) gen = js.call('#.bind(this)', gen);
+        gen = fnExpression;
       });
 
       _asyncStarController = savedController;
@@ -3553,7 +3549,7 @@
       // `await` is generated as `yield`.
       //
       // _AsyncStarImpl has an example of the generated code.
-      var gen = emitGeneratorFn((_) => [_asyncStarController]);
+      var gen = emitGeneratorFn((_) => [_asyncStarController!]);
 
       var returnType = _expectedReturnType(function, _coreTypes.streamClass);
       var asyncStarImpl = _emitInterfaceType(
@@ -3574,12 +3570,12 @@
     //
     // In the body of an `async`, `await` is generated simply as `yield`.
     var gen = emitGeneratorFn((_) => []);
-    var returnType = _currentLibrary.isNonNullableByDefault
-        ? function.futureValueType
+    var returnType = _currentLibrary!.isNonNullableByDefault
+        ? function.futureValueType!
         // Otherwise flatten the return type because futureValueType(T) is not
         // defined for legacy libraries.
         : _types.flatten(function
-            .computeThisFunctionType(_currentLibrary.nonNullable)
+            .computeThisFunctionType(_currentLibrary!.nonNullable)
             .returnType);
     return js.call('#.async(#, #)',
         [emitLibraryName(_coreTypes.asyncLibrary), _emitType(returnType), gen]);
@@ -3588,7 +3584,7 @@
   /// Gets the expected return type of a `sync*` or `async*` body.
   DartType _expectedReturnType(FunctionNode f, Class expected) {
     var type =
-        f.computeThisFunctionType(_currentLibrary.nonNullable).returnType;
+        f.computeThisFunctionType(_currentLibrary!.nonNullable).returnType;
     if (type is InterfaceType) {
       var matchArguments =
           _hierarchy.getTypeArgumentsAsInstanceOf(type, expected);
@@ -3601,7 +3597,7 @@
   ///
   /// To emit an `async`, `sync*`, or `async*` function body, use
   /// [_emitGeneratorFunctionBody] instead.
-  js_ast.Block _emitSyncFunctionBody(FunctionNode f, String name) {
+  js_ast.Block _emitSyncFunctionBody(FunctionNode f, String? name) {
     assert(f.asyncMarker == AsyncMarker.Sync);
 
     var block = _withCurrentFunction(f, () {
@@ -3622,11 +3618,11 @@
   /// - Run the argument initializers. These must be run synchronously
   ///   (e.g. covariance checks), and this helps performance.
   /// - Return the generator function, wrapped with the appropriate type
-  ///   (`Future`, `Itearble`, and `Stream` respectively).
+  ///   (`Future`, `Iterable`, and `Stream` respectively).
   ///
   /// To emit a `sync` function body (the default in Dart), use
   /// [_emitSyncFunctionBody] instead.
-  js_ast.Block _emitGeneratorFunctionBody(FunctionNode f, String name) {
+  js_ast.Block _emitGeneratorFunctionBody(FunctionNode f, String? name) {
     assert(f.asyncMarker != AsyncMarker.Sync);
 
     var statements =
@@ -3664,7 +3660,7 @@
   /// Emits argument initializers, which handles optional/named args, as well
   /// as generic type checks needed due to our covariance.
   List<js_ast.Statement> _emitArgumentInitializers(
-      FunctionNode f, String name) {
+      FunctionNode f, String? name) {
     var body = <js_ast.Statement>[];
 
     _emitCovarianceBoundsCheck(f.typeParameters, body);
@@ -3706,10 +3702,11 @@
         var check = js.statement(' if (#) #;', [
           condition,
           runtimeCall('nullFailed(#, #, #, #)', [
-            _cacheUri(location?.file?.toString()),
+            location != null
+                ? _cacheUri(location.file.toString())
+                : NullLiteral(),
             js.number(location?.line ?? -1),
             js.number(location?.column ?? -1),
-            // ignore: unnecessary_string_interpolations
             js.escapedString('${p.name}')
           ])
         ]);
@@ -3727,7 +3724,7 @@
       // Parameters will be passed using their real names, not the (possibly
       // renamed) local variable.
       var jsParam = _emitVariableDef(p);
-      var paramName = js.string(p.name, "'");
+      var paramName = js.string(p.name!, "'");
       var defaultValue = _defaultParamValue(p);
       if (defaultValue != null) {
         // TODO(ochafik): Fix `'prop' in obj` to please Closure's renaming.
@@ -3753,8 +3750,8 @@
       }
     }
 
-    // '_checkParametes = false' is only needed once, while processing formal
-    // parameters of the synthetic function from expression evalaluation - it
+    // '_checkParameters = false' is only needed once, while processing formal
+    // parameters of the synthetic function from expression evaluation - it
     // will be called from emitFunctionIncremental, which is a top-level API
     // for expression compilation.
     // Here we either are done with processing those formals, or compiling
@@ -3769,7 +3766,7 @@
   bool _annotatedNotNull(List<Expression> annotations) =>
       annotations.any(_nullableInference.isNotNullAnnotation);
 
-  bool _reifyGenericFunction(Member m) =>
+  bool _reifyGenericFunction(Member? m) =>
       m == null ||
       !m.enclosingLibrary.importUri.isScheme('dart') ||
       !m.annotations
@@ -3780,11 +3777,11 @@
     return js.statement('if (# == null) #;', [param, call]);
   }
 
-  js_ast.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);
+      return _visitExpression(p.initializer!);
     } else {
       return js_ast.LiteralNull();
     }
@@ -3798,14 +3795,13 @@
           _emitTypeParameterType(TypeParameterType(t, Nullability.undetermined),
               emitNullability: false),
           _emitType(t.bound),
-          propertyName(t.name)
+          propertyName(t.name!)
         ]));
       }
     }
   }
 
   js_ast.Statement _visitStatement(Statement s) {
-    if (s == null) return null;
     var result = s.accept(this);
 
     // In most cases, a Dart expression statement with a child expression
@@ -3839,9 +3835,9 @@
   }
 
   js_ast.Statement _emitFunctionScopedBody(FunctionNode f) {
-    var jsBody = _visitStatement(f.body);
+    var jsBody = _visitStatement(f.body!);
     if (f.positionalParameters.isNotEmpty || f.namedParameters.isNotEmpty) {
-      // Handle shadowing of parameters by local varaibles, which is allowed in
+      // Handle shadowing of parameters by local variables, which is allowed in
       // Dart but not in JS.
       //
       // We need this for all function types, including generator-based ones
@@ -3849,8 +3845,8 @@
       // named argument initialization, and sync* functions also emit locally
       // modified parameters into the function's scope.
       var parameterNames = {
-        for (var p in f.positionalParameters) p.name,
-        for (var p in f.namedParameters) p.name,
+        for (var p in f.positionalParameters) p.name!,
+        for (var p in f.namedParameters) p.name!,
       };
 
       return jsBody.toScopedBlock(parameterNames);
@@ -3860,7 +3856,7 @@
 
   /// Visits [nodes] with [_visitExpression].
   List<js_ast.Expression> _visitExpressionList(Iterable<Expression> nodes) {
-    return nodes?.map(_visitExpression)?.toList();
+    return nodes.map(_visitExpression).toList();
   }
 
   /// Generates an expression for a boolean conversion context (if, while, &&,
@@ -3869,8 +3865,6 @@
   // TODO(sra): When nullablility is available earlier, it would be cleaner to
   // build an input AST where the boolean conversion is a single AST node.
   js_ast.Expression _visitTest(Expression node) {
-    if (node == null) return null;
-
     if (node is Not) {
       return visitNot(node);
     }
@@ -3886,7 +3880,7 @@
 
     if (node is AsExpression && node.isTypeError) {
       assert(node.getStaticType(_staticTypeContext) ==
-          _types.coreTypes.boolRawType(currentLibrary.nonNullable));
+          _types.coreTypes.boolRawType(_currentLibrary!.nonNullable));
       return runtimeCall('dtest(#)', [_visitExpression(node.operand)]);
     }
 
@@ -3896,7 +3890,6 @@
   }
 
   js_ast.Expression _visitExpression(Expression e) {
-    if (e == null) return null;
     if (e is ConstantExpression) {
       return visitConstant(e.constant);
     }
@@ -3909,7 +3902,7 @@
   ///
   /// This is the most common kind of marking, and is used for most expressions
   /// and statements.
-  SourceLocation _nodeStart(TreeNode node) =>
+  SourceLocation? _nodeStart(TreeNode node) =>
       _toSourceLocation(node.fileOffset);
 
   /// Gets the end position of [node] for use in source mapping.
@@ -3920,22 +3913,22 @@
   /// This can be used to complete a hover span, when we know the start position
   /// has already been emitted. For example, `foo.bar` we only need to mark the
   /// end of `.bar` to ensure `foo.bar` has a hover tooltip.
-  NodeEnd _nodeEnd(int endOffset) {
+  NodeEnd? _nodeEnd(int endOffset) {
     var loc = _toSourceLocation(endOffset);
     return loc != null ? NodeEnd(loc) : null;
   }
 
   /// Combines [_nodeStart] with the variable name length to produce a hoverable
-  /// span for the varaible.
+  /// span for the variable.
   //
   // TODO(jmesserly): we need a lot more nodes to support hover.
-  NodeSpan _variableSpan(int offset, int nameLength) {
+  NodeSpan? _variableSpan(int offset, int nameLength) {
     var start = _toSourceLocation(offset);
     var end = _toSourceLocation(offset + nameLength);
     return start != null && end != null ? NodeSpan(start, end) : null;
   }
 
-  SourceLocation _toSourceLocation(int offset) {
+  SourceLocation? _toSourceLocation(int offset) {
     if (offset == -1) return null;
     var fileUri = _currentUri;
     if (fileUri == null) return null;
@@ -3959,7 +3952,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(
+  HoverComment? _hoverComment(
       js_ast.Expression expr, int offset, int nameLength) {
     var start = _toSourceLocation(offset);
     var end = _toSourceLocation(offset + nameLength);
@@ -3988,7 +3981,7 @@
   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.
+    // unnecessary nested block.
     //
     // NOTE: we do sometimes need to handle this because Dart and JS rules are
     // slightly different (in Dart, there is a nested scope), but that's handled
@@ -4035,18 +4028,18 @@
     }
 
     var encodedSource =
-        node.enclosingComponent.uriToSource[node.location.file].source;
+        node.enclosingComponent!.uriToSource[node.location!.file]!.source;
     var source = utf8.decode(encodedSource, allowMalformed: true);
     var conditionSource =
         source.substring(node.conditionStartOffset, node.conditionEndOffset);
-    var location = _toSourceLocation(node.conditionStartOffset);
+    var location = _toSourceLocation(node.conditionStartOffset)!;
     return js.statement(' if (!#) #;', [
       jsCondition,
       runtimeCall('assertFailed(#, #, #, #, #)', [
         if (node.message == null)
           js_ast.LiteralNull()
         else
-          _visitExpression(node.message),
+          _visitExpression(node.message!),
         _cacheUri(location.sourceUrl.toString()),
         // Lines and columns are typically printed with 1 based indexing.
         js.number(location.line + 1),
@@ -4068,18 +4061,17 @@
 
   @override
   js_ast.Statement visitLabeledStatement(LabeledStatement node) {
-    List<LabeledStatement> saved;
-    var target = _effectiveTargets[node];
+    List<LabeledStatement>? saved;
     // If the effective target is known then this statement is either contained
     // in a labeled statement or a loop.  It has already been processed when
     // the enclosing statement was visited.
-    if (target == null) {
+    if (!_effectiveTargets.containsKey(node)) {
       // Find the effective target by bypassing and collecting labeled
       // statements.
       var statements = [node];
-      target = node.body;
+      var target = node.body;
       while (target is LabeledStatement) {
-        var labeled = target as LabeledStatement;
+        var labeled = target;
         statements.add(labeled);
         target = labeled.body;
       }
@@ -4110,7 +4102,7 @@
     // implicit label due to their being wrapped in a loop.
     if (_inLabeledContinueSwitch &&
         _switchLabelStates.containsKey(node.target.body)) {
-      return js_ast.Break(_switchLabelStates[node.target.body].label);
+      return js_ast.Break(_switchLabelStates[node.target.body]!.label);
     }
     // Can it be compiled to a break without a label?
     if (_currentBreakTargets.contains(node.target)) {
@@ -4126,14 +4118,14 @@
     //
     // TODO(markzipan): Retrieve the real label name with source offsets
     var target = _effectiveTargets[node.target];
-    var name = _labelNames[target];
+    var name = _labelNames[target!];
     if (name == null) _labelNames[target] = name = 'L${_labelNames.length}';
 
     // It is a break if the target labeled statement encloses the effective
     // target.
     Statement current = node.target;
     while (current is LabeledStatement) {
-      current = (current as LabeledStatement).body;
+      current = current.body;
     }
     if (identical(current, target)) {
       return js_ast.Break(name);
@@ -4151,7 +4143,7 @@
     // it is not possible to continue to an outer loop without a label.
     _currentContinueTargets = <LabeledStatement>[];
     while (body is LabeledStatement) {
-      var labeled = body as LabeledStatement;
+      var labeled = body;
       _currentContinueTargets.add(labeled);
       _effectiveTargets[labeled] = loop;
       body = labeled.body;
@@ -4161,7 +4153,7 @@
 
   T _translateLoop<T extends js_ast.Statement>(
       Statement node, T Function() action) {
-    List<LabeledStatement> savedBreakTargets;
+    List<LabeledStatement>? savedBreakTargets;
     if (_currentBreakTargets.isNotEmpty &&
         _effectiveTargets[_currentBreakTargets.first] != node) {
       // If breaking without a label targets some other (outer) loop, then
@@ -4208,13 +4200,14 @@
       var initList =
           init.isEmpty ? null : js_ast.VariableDeclarationList('let', init);
       var updates = node.updates;
-      js_ast.Expression update;
+      js_ast.Expression? update;
       if (updates.isNotEmpty) {
         update = js_ast.Expression.binary(
                 updates.map(_visitExpression).toList(), ',')
             .toVoidExpression();
       }
-      var condition = _visitTest(node.condition);
+      var condition =
+          node.condition != null ? _visitTest(node.condition!) : null;
       var body = _visitScope(_effectiveBodyOf(node, node.body));
 
       return js_ast.For(initList, condition, update, body);
@@ -4237,7 +4230,8 @@
             [_nullParameterCheck(_emitVariableRef(node.variable)), body]);
       }
 
-      if (variableIsReferenced(node.variable.name, iterable)) {
+      if (node.variable.name != null &&
+          variableIsReferenced(node.variable.name!, iterable)) {
         var temp = _emitTemporaryId('iter');
         return js_ast.Block([
           iterable.toVariableDeclaration(temp),
@@ -4267,7 +4261,7 @@
     // TODO(jmesserly): we may want a helper if these become common. For now the
     // full desugaring seems okay.
     var streamIterator = _coreTypes.rawType(
-        _asyncStreamIteratorClass, currentLibrary.nonNullable);
+        _asyncStreamIteratorClass, _currentLibrary!.nonNullable);
     var createStreamIter = js_ast.Call(
         _emitConstructorName(
             streamIterator,
@@ -4378,8 +4372,9 @@
     // last case to escape the additional loop around the switch.
     if (lastSwitchCase && _inLabeledContinueSwitch && cases.isNotEmpty) {
       // TODO(markzipan): avoid generating unreachable breaks
+      var switchStmt = node.parent as SwitchStatement;
       assert(_switchLabelStates.containsKey(node.parent));
-      var breakStmt = js_ast.Break(_switchLabelStates[node.parent].label);
+      var breakStmt = js_ast.Break(_switchLabelStates[switchStmt]!.label);
       var switchBody = js_ast.Block(cases.last.body.statements..add(breakStmt));
       var lastCase = cases.last;
       var updatedSwitch = lastCase is js_ast.Case
@@ -4393,10 +4388,10 @@
 
   @override
   js_ast.Statement visitContinueSwitchStatement(ContinueSwitchStatement node) {
-    var switchStmt = node.target.parent;
+    var switchStmt = node.target.parent as SwitchStatement;
     if (_inLabeledContinueSwitch &&
         _switchLabelStates.containsKey(switchStmt)) {
-      var switchState = _switchLabelStates[switchStmt];
+      var switchState = _switchLabelStates[switchStmt]!;
       // Use the first constant expression that can match the collated switch
       // case. Use an unused symbol otherwise to force the default case.
       var jsExpr = node.target.expressions.isEmpty
@@ -4420,11 +4415,11 @@
         if (condition.value) {
           return _visitScope(node.then).toStatement();
         } else {
-          return _visitScope(node.otherwise).toStatement();
+          return _visitScope(node.otherwise!).toStatement();
         }
       }
       return js_ast.If(
-          condition, _visitScope(node.then), _visitScope(node.otherwise));
+          condition, _visitScope(node.then), _visitScope(node.otherwise!));
     }
 
     if (condition is js_ast.LiteralBool) {
@@ -4459,7 +4454,9 @@
 
   @override
   js_ast.Statement visitReturnStatement(ReturnStatement node) {
-    return super.emitReturnStatement(_visitExpression(node.expression));
+    var expression = node.expression;
+    var value = expression == null ? null : _visitExpression(expression);
+    return super.emitReturnStatement(value);
   }
 
   @override
@@ -4468,7 +4465,7 @@
         _visitStatement(node.body).toBlock(), _visitCatch(node.catches), null);
   }
 
-  js_ast.Catch _visitCatch(List<Catch> clauses) {
+  js_ast.Catch? _visitCatch(List<Catch> clauses) {
     if (clauses.isEmpty) return null;
 
     var caughtError = VariableDeclaration('#e');
@@ -4513,14 +4510,14 @@
       Catch node,
       js_ast.Statement otherwise,
       VariableDeclaration exceptionParameter,
-      VariableDeclaration stackTraceParameter) {
+      VariableDeclaration? stackTraceParameter) {
     var body = <js_ast.Statement>[];
     var vars = HashSet<String>();
 
     void declareVariable(
-        VariableDeclaration variable, VariableDeclaration value) {
-      if (variable == null) return;
-      vars.add(variable.name);
+        VariableDeclaration? variable, VariableDeclaration? value) {
+      if (variable == null || value == null) return;
+      vars.add(variable.name!);
       if (variable.name != value.name) {
         body.add(js.statement('let # = #',
             [_emitVariableDef(variable), _emitVariableRef(value)]));
@@ -4605,7 +4602,7 @@
       declareFn = js_ast.Block([
         declareFn,
         _emitFunctionTagged(_emitVariableRef(node.variable),
-                func.computeThisFunctionType(_currentLibrary.nonNullable))
+                func.computeThisFunctionType(_currentLibrary!.nonNullable))
             .toStatement()
       ]);
     }
@@ -4630,7 +4627,7 @@
 
   @override
   js_ast.Expression canonicalizeConstObject(js_ast.Expression expr) {
-    if (isSdkInternalRuntime(_currentLibrary)) {
+    if (isSdkInternalRuntime(_currentLibrary!)) {
       return super.canonicalizeConstObject(expr);
     }
     return runtimeCall('const(#)', [expr]);
@@ -4641,7 +4638,7 @@
     var v = node.variable;
     var id = _emitVariableRef(v);
     if (id.name == v.name) {
-      id.sourceInformation = _variableSpan(node.fileOffset, v.name.length);
+      id.sourceInformation = _variableSpan(node.fileOffset, v.name!.length);
     }
     return id;
   }
@@ -4650,7 +4647,7 @@
     var name = v.name;
     if (name == null || name.startsWith('#')) {
       name = name == null ? 't${_tempVariables.length}' : name.substring(1);
-      return _tempVariables.putIfAbsent(v, () => _emitTemporaryId(name));
+      return _tempVariables.putIfAbsent(v, () => _emitTemporaryId(name!));
     }
     return _emitIdentifier(name);
   }
@@ -4665,15 +4662,13 @@
     return identifier;
   }
 
-  js_ast.Statement _initLetVariables() {
-    if (_letVariables.isEmpty) return null;
-    var result = js_ast.VariableDeclarationList(
-            'let',
-            _letVariables
-                .map((v) => js_ast.VariableInitialization(v, null))
-                .toList())
+  js_ast.Statement? _initLetVariables() {
+    var letVars = _letVariables!;
+    if (letVars.isEmpty) return null;
+    var result = js_ast.VariableDeclarationList('let',
+            letVars.map((v) => js_ast.VariableInitialization(v, null)).toList())
         .toStatement();
-    _letVariables.clear();
+    letVars.clear();
     return result;
   }
 
@@ -4711,9 +4706,8 @@
         node.receiver, node.interfaceTarget, node.value, node.name.text);
   }
 
-  js_ast.Expression _emitPropertyGet(Expression receiver, Member member,
-      [String memberName]) {
-    memberName ??= member.name.text;
+  js_ast.Expression _emitPropertyGet(
+      Expression receiver, Member? member, String memberName) {
     // TODO(jmesserly): should tearoff of `.call` on a function type be
     // encoded as a different node, or possibly eliminated?
     // (Regardless, we'll still need to handle the callable JS interop classes.)
@@ -4743,7 +4737,7 @@
       return runtimeCall('dload$_replSuffix(#, #)', [jsReceiver, jsName]);
     }
 
-    if (_reifyTearoff(member)) {
+    if (member != null && _reifyTearoff(member)) {
       return runtimeCall('bind(#, #)', [jsReceiver, jsName]);
     } else if (member is Procedure &&
         !member.isAccessor &&
@@ -4762,14 +4756,12 @@
   bool _isNullCheckableNative(Member member) {
     var c = member.enclosingClass;
     return _options.soundNullSafety &&
-        member != null &&
         member.isExternal &&
         c != null &&
         _extensionTypes.isNativeClass(c) &&
         member is Procedure &&
-        member.function != null &&
         member.function.returnType.isPotentiallyNonNullable &&
-        _isWebLibrary(member.enclosingLibrary?.importUri);
+        _isWebLibrary(member.enclosingLibrary.importUri);
   }
 
   // TODO(jmesserly): can we encapsulate REPL name lookups and remove this?
@@ -4777,11 +4769,9 @@
   // access to the target expression there (needed for `dart.replNameLookup`).
   String get _replSuffix => _options.replCompile ? 'Repl' : '';
 
-  js_ast.Expression _emitPropertySet(
-      Expression receiver, Member member, Expression value,
-      [String memberName]) {
-    var jsName =
-        _emitMemberName(memberName ?? member.name.text, member: member);
+  js_ast.Expression _emitPropertySet(Expression receiver, Member? member,
+      Expression value, String memberName) {
+    var jsName = _emitMemberName(memberName, member: member);
 
     if (member != null && isJsMember(member)) {
       value = _assertInterop(value);
@@ -4800,12 +4790,12 @@
   @override
   js_ast.Expression visitAbstractSuperPropertyGet(
       AbstractSuperPropertyGet node) {
-    return _emitSuperPropertyGet(node.interfaceTarget);
+    return _emitSuperPropertyGet(node.interfaceTarget!);
   }
 
   @override
   js_ast.Expression visitSuperPropertyGet(SuperPropertyGet node) {
-    return _emitSuperPropertyGet(node.interfaceTarget);
+    return _emitSuperPropertyGet(node.interfaceTarget!);
   }
 
   js_ast.Expression _emitSuperPropertyGet(Member target) {
@@ -4823,12 +4813,12 @@
   @override
   js_ast.Expression visitAbstractSuperPropertySet(
       AbstractSuperPropertySet node) {
-    return _emitSuperPropertySet(node.interfaceTarget, node.value);
+    return _emitSuperPropertySet(node.interfaceTarget!, node.value);
   }
 
   @override
   js_ast.Expression visitSuperPropertySet(SuperPropertySet node) {
-    return _emitSuperPropertySet(node.interfaceTarget, node.value);
+    return _emitSuperPropertySet(node.interfaceTarget!, node.value);
   }
 
   js_ast.Expression _emitSuperPropertySet(Member target, Expression value) {
@@ -4852,7 +4842,7 @@
       // escape.
       return _emitFunctionTagged(
           result,
-          target.function
+          target.function!
               .computeThisFunctionType(target.enclosingLibrary.nonNullable));
     }
     return result;
@@ -4910,7 +4900,7 @@
         negated: false);
   }
 
-  js_ast.Expression _emitMethodCall(Expression receiver, Member target,
+  js_ast.Expression _emitMethodCall(Expression receiver, Member? target,
       Arguments arguments, InvocationExpression node) {
     var name = node.name.text;
 
@@ -4999,7 +4989,7 @@
     // TODO(jmesserly): remove when Kernel desugars this for us.
     // Handle `o.m(a)` where `o.m` is a getter returning a class with `call`.
     if (target is Field || target is Procedure && target.isAccessor) {
-      var fromType = target.getterType;
+      var fromType = target!.getterType;
       if (fromType is InterfaceType) {
         var callName = _implicitCallTarget(fromType);
         if (callName != null) {
@@ -5012,7 +5002,7 @@
 
   js_ast.Expression _emitDynamicInvoke(
       js_ast.Expression fn,
-      js_ast.Expression methodName,
+      js_ast.Expression? methodName,
       Iterable<js_ast.Expression> args,
       Arguments arguments) {
     var jsArgs = <Object>[fn];
@@ -5051,7 +5041,7 @@
   bool _isDirectCallable(DartType t) =>
       t is FunctionType || (t is InterfaceType && usesJSInterop(t.classNode));
 
-  js_ast.Expression _implicitCallTarget(InterfaceType from) {
+  js_ast.Expression? _implicitCallTarget(InterfaceType from) {
     var c = from.classNode;
     var member = _hierarchy.getInterfaceMember(c, Name('call'));
     if (member is Procedure && !member.isAccessor && !usesJSInterop(c)) {
@@ -5066,10 +5056,10 @@
       t == const DynamicType();
 
   js_ast.Expression _emitUnaryOperator(
-      Expression expr, Member target, InvocationExpression node) {
+      Expression expr, Member? target, InvocationExpression node) {
     var op = node.name.text;
     if (target != null) {
-      var dispatchType = _coreTypes.legacyRawType(target.enclosingClass);
+      var dispatchType = _coreTypes.legacyRawType(target.enclosingClass!);
       if (_typeRep.unaryOperationIsPrimitive(dispatchType)) {
         if (op == '~') {
           if (_typeRep.isNumber(dispatchType)) {
@@ -5103,9 +5093,9 @@
     // If the consumer of the expression is '==' or '!=' with a constant that
     // fits in 31 bits, adding a coercion does not change the result of the
     // comparison, e.g.  `a & ~b == 0`.
-    Expression left;
-    Expression right;
-    String op;
+    Expression? left;
+    late Expression right;
+    late String op;
     if (parent is InvocationExpression &&
         parent.arguments.positional.length == 1) {
       op = parent.name.text;
@@ -5147,7 +5137,7 @@
     return false;
   }
 
-  int _asIntInRange(Expression expr, int low, int high) {
+  int? _asIntInRange(Expression expr, int low, int high) {
     if (expr is IntLiteral) {
       if (expr.value >= low && expr.value <= high) return expr.value;
       return null;
@@ -5243,7 +5233,7 @@
     return bitWidth(expr, 0) < 32;
   }
 
-  js_ast.Expression _emitBinaryOperator(Expression left, Member target,
+  js_ast.Expression _emitBinaryOperator(Expression left, Member? target,
       Expression right, InvocationExpression node) {
     var op = node.name.text;
     if (op == '==') return _emitEqualityOperator(left, target, right);
@@ -5251,7 +5241,7 @@
     // TODO(jmesserly): using the target type here to work around:
     // https://github.com/dart-lang/sdk/issues/33293
     if (target != null) {
-      var targetClass = target.enclosingClass;
+      var targetClass = target.enclosingClass!;
       var leftType = _coreTypes.legacyRawType(targetClass);
       var rightType = right.getStaticType(_staticTypeContext);
 
@@ -5354,7 +5344,7 @@
   }
 
   js_ast.Expression _emitEqualityOperator(
-      Expression left, Member target, Expression right,
+      Expression left, Member? target, Expression right,
       {bool negated = false}) {
     var targetClass = target?.enclosingClass;
     var leftType = left.getStaticType(_staticTypeContext);
@@ -5414,7 +5404,7 @@
   /// `obj.name(args)` because that could be a getter followed by a call.
   /// See [visitMethodInvocation].
   js_ast.Expression _emitOperatorCall(
-      Expression receiver, Member target, String name, List<Expression> args) {
+      Expression receiver, Member? target, String name, List<Expression> args) {
     // TODO(jmesserly): calls that don't pass `element` are probably broken for
     // `super` calls from disallowed super locations.
     var memberName = _emitMemberName(name, member: target);
@@ -5442,12 +5432,12 @@
   @override
   js_ast.Expression visitAbstractSuperMethodInvocation(
       AbstractSuperMethodInvocation node) {
-    return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments);
+    return _emitSuperMethodInvocation(node.interfaceTarget!, node.arguments);
   }
 
   @override
   js_ast.Expression visitSuperMethodInvocation(SuperMethodInvocation node) {
-    return _emitSuperMethodInvocation(node.interfaceTarget, node.arguments);
+    return _emitSuperMethodInvocation(node.interfaceTarget!, node.arguments);
   }
 
   js_ast.Expression _emitSuperMethodInvocation(
@@ -5500,7 +5490,7 @@
         var params = [
           ..._emitTypeFormals(function.typeParameters),
           for (var param in function.positionalParameters)
-            _emitIdentifier(param.name),
+            _emitIdentifier(param.name!),
           if (function.namedParameters.isNotEmpty) namedArgumentTemp,
         ];
 
@@ -5536,7 +5526,7 @@
   /// the underlying [DartType], otherwise returns null.
   // TODO(sigmund,nshahan): remove all uses of type literals in the runtime
   // libraries, so that this pattern can be deleted.
-  DartType getTypeLiteralType(Expression e) {
+  DartType? getTypeLiteralType(Expression e) {
     if (e is TypeLiteral) return e.type;
     if (e is ConstantExpression) {
       var constant = e.constant;
@@ -5726,7 +5716,7 @@
   }
 
   List<js_ast.Expression> _emitArgumentList(Arguments node,
-      {bool types = true, Member target}) {
+      {bool types = true, Member? target}) {
     types = types && _reifyGenericFunction(target);
     final isJsInterop = target != null && isJsMember(target);
     return [
@@ -5799,7 +5789,7 @@
 
     // Add a check to make sure any JS() values from a native type are typed
     // properly in sound null-safety.
-    if (_isWebLibrary(_currentLibrary.importUri) && _options.soundNullSafety) {
+    if (_isWebLibrary(_currentLibrary!.importUri) && _options.soundNullSafety) {
       var type = node.getStaticType(_staticTypeContext);
       if (type.isPotentiallyNonNullable) {
         result = runtimeCall('checkNativeNonNull(#)', [result]);
@@ -5856,7 +5846,7 @@
   }
 
   String _enumValueName(Field field) {
-    var enumName = field.enclosingClass.name;
+    var enumName = field.enclosingClass!.name;
     var valueName = field.name.text;
     return '$enumName.$valueName';
   }
@@ -5868,7 +5858,6 @@
       .firstWhere((val) => val.toString() == _enumValueName(field));
 
   bool _isWebLibrary(Uri importUri) =>
-      importUri != null &&
       importUri.isScheme('dart') &&
       (importUri.path == 'html' ||
           importUri.path == 'svg' ||
@@ -5951,7 +5940,7 @@
   js_ast.Expression _emitFactoryInvocation(StaticInvocation node) {
     var args = node.arguments;
     var ctor = node.target;
-    var ctorClass = ctor.enclosingClass;
+    var ctorClass = ctor.enclosingClass!;
     if (ctor.isExternal && hasJSInteropAnnotation(ctorClass)) {
       return _emitJSInteropNew(ctor, args);
     }
@@ -5993,7 +5982,7 @@
           }
           break;
         case 'List':
-          if (ctor.name.text == '' && type is InterfaceType) {
+          if (ctor.name.text == '') {
             return _emitList(type.typeArguments[0], []);
           }
           break;
@@ -6007,14 +5996,14 @@
   }
 
   js_ast.Expression _emitJSInteropNew(Member ctor, Arguments args) {
-    var ctorClass = ctor.enclosingClass;
+    var ctorClass = ctor.enclosingClass!;
     if (isJSAnonymousType(ctorClass)) return _emitObjectLiteral(args, ctor);
     return js_ast.New(
         _emitConstructorName(_coreTypes.legacyRawType(ctorClass), ctor),
         _emitArgumentList(args, types: false, target: ctor));
   }
 
-  js_ast.Expression _emitMapImplType(InterfaceType type, {bool identity}) {
+  js_ast.Expression _emitMapImplType(InterfaceType type, {bool? identity}) {
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) {
       return _emitInterfaceType(type, emitNullability: false);
@@ -6025,7 +6014,7 @@
         emitNullability: false);
   }
 
-  js_ast.Expression _emitSetImplType(InterfaceType type, {bool identity}) {
+  js_ast.Expression _emitSetImplType(InterfaceType type, {bool? identity}) {
     var typeArgs = type.typeArguments;
     if (typeArgs.isEmpty) {
       return _emitInterfaceType(type, emitNullability: false);
@@ -6289,7 +6278,7 @@
 
   @override
   js_ast.Expression visitRethrow(Rethrow node) {
-    return runtimeCall('rethrow(#)', [_emitVariableRef(_rethrowParameter)]);
+    return runtimeCall('rethrow(#)', [_emitVariableRef(_rethrowParameter!)]);
   }
 
   @override
@@ -6396,14 +6385,14 @@
 
     // Simplify `=> { return e; }` to `=> e`
     if (body is js_ast.Block) {
-      var block = body as js_ast.Block;
+      var block = body;
       if (block.statements.length == 1) {
-        var s = block.statements[0];
+        var s = block.statements.single;
         if (s is js_ast.Block) {
-          block = s as js_ast.Block;
-          s = block.statements.length == 1 ? block.statements[0] : null;
+          block = s;
+          if (block.statements.length == 1) s = block.statements.single;
         }
-        if (s is js_ast.Return && s.value != null) body = s.value;
+        if (s is js_ast.Return && s.value != null) body = s.value!;
       }
     }
 
@@ -6433,13 +6422,13 @@
   @override
   js_ast.Expression visitLet(Let node) {
     var v = node.variable;
-    var init = _visitExpression(v.initializer);
+    var init = _visitExpression(v.initializer!);
     var body = _visitExpression(node.body);
     var temp = _tempVariables.remove(v);
     if (temp != null) {
       if (_letVariables != null) {
         init = js_ast.Assignment(temp, init);
-        _letVariables.add(temp);
+        _letVariables!.add(temp);
       } else {
         // TODO(jmesserly): make sure this doesn't happen on any performance
         // critical call path.
@@ -6488,7 +6477,7 @@
   js_ast.Expression visitLoadLibrary(LoadLibrary node) =>
       runtimeCall('loadLibrary(#, #)', [
         js.string(jsLibraryName(node.import.enclosingLibrary)),
-        js.string(node.import.name)
+        js.string(node.import.name!)
       ]);
 
   // TODO(jmesserly): DDC loads all libraries eagerly.
@@ -6499,11 +6488,11 @@
   js_ast.Expression visitCheckLibraryIsLoaded(CheckLibraryIsLoaded node) =>
       runtimeCall('checkDeferredIsLoaded(#, #)', [
         js.string(jsLibraryName(node.import.enclosingLibrary)),
-        js.string(node.import.name)
+        js.string(node.import.name!)
       ]);
 
   bool _reifyFunctionType(FunctionNode f) {
-    if (!_currentLibrary.importUri.isScheme('dart')) return true;
+    if (!_currentLibrary!.importUri.isScheme('dart')) return true;
     var parent = f.parent;
 
     // SDK libraries can skip reification if they request it.
@@ -6511,8 +6500,10 @@
         isBuiltinAnnotation(a, '_js_helper', 'ReifyFunctionTypes');
     while (parent != null) {
       var a = findAnnotation(parent, reifyFunctionTypes);
-      var value = _constants.getFieldValueFromAnnotation(a, 'value');
-      if (value is bool) return value;
+      if (a != null) {
+        var value = _constants.getFieldValueFromAnnotation(a, 'value');
+        if (value is bool) return value;
+      }
       parent = parent.parent;
     }
     return true;
@@ -6530,9 +6521,9 @@
   /// Returns the name value of the `JSExportName` annotation (when compiling
   /// the SDK), or `null` if there's none. This is used to control the name
   /// under which functions are compiled and exported.
-  String _jsExportName(NamedNode n) {
+  String? _jsExportName(NamedNode n) {
     var library = getLibrary(n);
-    if (library == null || !library.importUri.isScheme('dart')) return null;
+    if (!library.importUri.isScheme('dart')) return null;
 
     return _annotationName(n, isJSExportNameAnnotation);
   }
@@ -6541,14 +6532,16 @@
   /// string, this returns the string value.
   ///
   /// Calls [findAnnotation] followed by [getNameFromAnnotation].
-  String _annotationName(NamedNode node, bool Function(Expression) test) {
-    return _constants.getFieldValueFromAnnotation(
-        findAnnotation(node, test), 'name') as String;
+  String? _annotationName(NamedNode node, bool Function(Expression) test) {
+    var annotation = findAnnotation(node, test);
+    return annotation != null
+        ? _constants.getFieldValueFromAnnotation(annotation, 'name') as String
+        : null;
   }
 
   @override
   js_ast.Expression cacheConst(js_ast.Expression jsExpr) {
-    if (isSdkInternalRuntime(_currentLibrary)) {
+    if (isSdkInternalRuntime(_currentLibrary!)) {
       return super.cacheConst(jsExpr);
     }
     return jsExpr;
@@ -6586,8 +6579,8 @@
       }
       assert(!_isInForeignJS ||
           type.nullability == Nullability.nonNullable ||
-          // The types dynamic, void, and Null all instrinsicly have
-          // `Nullability.nullable` but are handled explicitly without emiting
+          // The types dynamic, void, and Null all intrinsically have
+          // `Nullability.nullable` but are handled explicitly without emitting
           // the nullable runtime wrapper. They are safe to allow through
           // unchanged.
           type == const DynamicType() ||
@@ -6595,7 +6588,7 @@
           type == const VoidType());
       return _emitTypeLiteral(type);
     }
-    if (isSdkInternalRuntime(_currentLibrary) || node is PrimitiveConstant) {
+    if (isSdkInternalRuntime(_currentLibrary!) || node is PrimitiveConstant) {
       return super.visitConstant(node);
     }
 
@@ -6703,7 +6696,7 @@
     js_ast.Property entryToProperty(MapEntry<Reference, Constant> entry) {
       var constant = visitConstant(entry.value);
       var member = entry.key.asField;
-      var cls = member.enclosingClass;
+      var cls = member.enclosingClass!;
       // Enums cannot be overridden, so we can safely use the field name
       // directly.  Otherwise, use a private symbol in case the field
       // was overridden.
@@ -6734,7 +6727,7 @@
   /// within the same library.
   js_ast.TemporaryId _emitClassPrivateNameSymbol(
       Library library, String className, Member member,
-      [js_ast.TemporaryId id]) {
+      [js_ast.TemporaryId? id]) {
     var name = '$className.${member.name.text}';
     // Wrap the name as a symbol here so it matches what you would find at
     // runtime when you get all properties and symbols from an instance.
@@ -6769,7 +6762,7 @@
   }
 }
 
-bool _isInlineJSFunction(Statement body) {
+bool _isInlineJSFunction(Statement? body) {
   var block = body;
   if (block is Block) {
     var statements = block.statements;
diff --git a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
index a41722c..7d5fb89 100644
--- a/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
+++ b/pkg/dev_compiler/lib/src/kernel/expression_compiler.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:async';
 
 import 'package:_fe_analyzer_shared/src/messages/codes.dart'
@@ -32,10 +30,10 @@
         VisitorNullMixin,
         VisitorVoidMixin;
 
-import '../../dev_compiler.dart';
 import '../compiler/js_names.dart' as js_ast;
 import '../compiler/module_builder.dart';
 import '../js_ast/js_ast.dart' as js_ast;
+import 'compiler.dart' show ProgramCompiler;
 
 DiagnosticMessage _createInternalError(Uri uri, int line, int col, String msg) {
   return Message(Code<String>('Expression Compiler Internal error'),
@@ -50,8 +48,8 @@
 /// Provides information about symbols available inside a dart scope.
 class DartScope {
   final Library library;
-  final Class cls;
-  final Member member;
+  final Class? cls;
+  final Member? member;
   final bool isStatic;
   final Map<String, DartType> definitions;
   final List<TypeParameter> typeParameters;
@@ -88,12 +86,12 @@
   final int _line;
   final int _column;
 
-  Library _library;
-  Class _cls;
-  Member _member;
-  int _offset;
+  Library? _library;
+  Class? _cls;
+  Member? _member;
+  int _offset = -1;
 
-  DiagnosticMessageHandler onDiagnostic;
+  DiagnosticMessageHandler? onDiagnostic;
 
   final List<FunctionNode> _functions = [];
   final Map<String, DartType> _definitions = {};
@@ -101,7 +99,7 @@
 
   DartScopeBuilder._(this._component, this._line, this._column);
 
-  static DartScope findScope(Component component, Library library, int line,
+  static DartScope? findScope(Component component, Library library, int line,
       int column, DiagnosticMessageHandler onDiagnostic) {
     var builder = DartScopeBuilder._(component, line, column)
       ..onDiagnostic = onDiagnostic;
@@ -109,10 +107,10 @@
     return builder.build();
   }
 
-  DartScope build() {
-    if (_offset == null || _library == null) return null;
+  DartScope? build() {
+    if (_offset < 0 || _library == null) return null;
 
-    return DartScope(_library, _cls, _member, _definitions, _typeParameters);
+    return DartScope(_library!, _cls, _member, _definitions, _typeParameters);
   }
 
   @override
@@ -125,7 +123,7 @@
     _library = library;
     _offset = 0;
     if (_line > 0) {
-      _offset = _component.getOffset(_library.fileUri, _line, _column);
+      _offset = _component.getOffset(_library!.fileUri, _line, _column);
     }
 
     // Exit early if the evaluation offset is not found.
@@ -171,7 +169,7 @@
     // make expression evaluation fail in too many cases.
     // Issue: https://github.com/dart-lang/sdk/issues/43966
     if (decl.fileOffset < 0 || decl.fileOffset < _offset) {
-      _definitions[decl.name] = decl.type;
+      _definitions[decl.name!] = decl.type;
     }
     super.visitVariableDeclaration(decl);
   }
@@ -198,7 +196,7 @@
 /// that do not have .fileEndOffset field.
 ///
 /// For example - [Block]
-class FileEndOffsetCalculator extends Visitor<int> with VisitorNullMixin<int> {
+class FileEndOffsetCalculator extends Visitor<int?> with VisitorNullMixin<int> {
   static const int noOffset = -1;
 
   final int _startOffset;
@@ -231,7 +229,7 @@
     for (var n = node.parent; n != null; n = n.parent) {
       var calculator = FileEndOffsetCalculator._(n, node.fileOffset);
       var offset = n.accept(calculator);
-      if (offset != noOffset) return offset;
+      if (offset != noOffset) return offset!;
     }
     return noOffset;
   }
@@ -286,7 +284,7 @@
     this._compiler,
     this._kernel2jsCompiler,
     this._component,
-  )   : onDiagnostic = _options.onDiagnostic,
+  )   : onDiagnostic = _options.onDiagnostic!,
         _context = _compiler.context;
 
   /// Compiles [expression] in [libraryUri] at [line]:[column] to JavaScript
@@ -303,7 +301,7 @@
   /// [jsFrameValues] is a map from js variable name to its primitive value
   /// or another variable name, for example
   /// { 'x': '1', 'y': 'y', 'o': 'null' }
-  Future<String> compileExpressionToJs(String libraryUri, int line, int column,
+  Future<String?> compileExpressionToJs(String libraryUri, int line, int column,
       Map<String, String> jsScope, String expression) async {
     try {
       // 1. find dart scope where debugger is paused
@@ -389,7 +387,7 @@
     }
   }
 
-  DartScope _findScopeAt(Uri libraryUri, int line, int column) {
+  DartScope? _findScopeAt(Uri libraryUri, int line, int column) {
     if (line < 0) {
       onDiagnostic(_createInternalError(
           libraryUri, line, column, 'Invalid source location'));
@@ -415,7 +413,7 @@
     return scope;
   }
 
-  Library _getLibrary(Uri libraryUri) {
+  Library? _getLibrary(Uri libraryUri) {
     return _compiler.lookupLibrary(libraryUri);
   }
 
@@ -423,7 +421,7 @@
   ///
   /// [scope] current dart scope information.
   /// [expression] expression to compile in given [scope].
-  Future<String> _compileExpression(DartScope scope, String expression) async {
+  Future<String?> _compileExpression(DartScope scope, String expression) async {
     var procedure = await _compiler.compileExpression(
         expression,
         scope.definitions,
@@ -443,7 +441,7 @@
 
     var imports = <js_ast.ModuleItem>[];
     var jsFun = _kernel2jsCompiler.emitFunctionIncremental(imports,
-        scope.library, scope.cls, procedure.function, debugProcedureName);
+        scope.library, scope.cls, procedure!.function, debugProcedureName);
 
     _log('Generated JavaScript for expression');
 
diff --git a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
index 0576c6f..0ddc092 100644
--- a/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
+++ b/pkg/dev_compiler/lib/src/kernel/kernel_helpers.dart
@@ -11,11 +11,11 @@
     c.constructors.firstWhereOrNull((c) => c.name.text == '');
 
 /// Returns the enclosing library for reference [node].
-Library? getLibrary(NamedNode node) {
+Library getLibrary(NamedNode node) {
   for (TreeNode? n = node; n != null; n = n.parent) {
     if (n is Library) return n;
   }
-  return null;
+  throw UnsupportedError('Could not find a containing library for $node');
 }
 
 final Pattern _syntheticTypeCharacters = RegExp('[&^#.|]');
@@ -44,14 +44,14 @@
 ///
 /// In the current encoding, generic classes are generated in a function scope
 /// which avoids name clashes of the escaped parameter name.
-String? getTypeParameterName(TypeParameter node) => escapeIdentifier(node.name);
+String getTypeParameterName(TypeParameter node) => escapeIdentifier(node.name)!;
 
-String? getTopLevelName(NamedNode n) {
+String getTopLevelName(NamedNode n) {
   if (n is Procedure) return n.name.text;
   if (n is Class) return n.name;
   if (n is Typedef) return n.name;
   if (n is Field) return n.name.text;
-  return n.reference.canonicalName?.name;
+  return n.reference.canonicalName!.name;
 }
 
 /// Given an annotated [node] and a [test] function, returns the first matching
diff --git a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
index c1ec743..85b1fd6 100644
--- a/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
+++ b/pkg/dev_compiler/lib/src/kernel/nullable_inference.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:collection';
 
 import 'package:kernel/core_types.dart';
@@ -46,7 +44,7 @@
   final bool _soundNullSafety;
 
   NullableInference(this.jsTypeRep, this._staticTypeContext,
-      {SharedCompilerOptions options})
+      {SharedCompilerOptions? options})
       : coreTypes = jsTypeRep.coreTypes,
         _soundNullSafety = options?.soundNullSafety ?? false {
     _variableInference._nullInference = this;
@@ -65,7 +63,7 @@
   }
 
   /// Returns true if [expr] can be null.
-  bool isNullable(Expression expr) => expr != null ? expr.accept(this) : false;
+  bool isNullable(Expression expr) => expr.accept(this);
 
   @override
   bool defaultExpression(Expression node) => true;
@@ -161,8 +159,8 @@
       _invocationIsNullable(node.interfaceTarget, node.name.text, node);
 
   bool _invocationIsNullable(
-      Member target, String name, InvocationExpression node,
-      [Expression receiver]) {
+      Member? target, String name, InvocationExpression node,
+      [Expression? receiver]) {
     // TODO(jmesserly): this is not a valid assumption for user-defined equality
     // but it is added to match the behavior of the Analyzer backend.
     // https://github.com/dart-lang/sdk/issues/31854
@@ -170,7 +168,8 @@
     if (_staticallyNonNullable(node.getStaticType(_staticTypeContext))) {
       return false;
     }
-    if (target == null) return true; // dynamic call
+    // Dynamic call.
+    if (target == null) return true;
     if (target.name.text == 'toString' &&
         receiver != null &&
         receiver.getStaticType(_staticTypeContext) ==
@@ -184,20 +183,19 @@
     return _returnValueIsNullable(target);
   }
 
-  bool _getterIsNullable(Member target, Expression node) {
+  bool _getterIsNullable(Member? target, Expression node) {
     if (_staticallyNonNullable(node.getStaticType(_staticTypeContext))) {
       return false;
     }
+    // Dynamic access.
     if (target == null) return true;
-    // tear-offs are not null
+    // Tear-offs are not null.
     if (target is Procedure && !target.isAccessor) return false;
     return _returnValueIsNullable(target);
   }
 
   bool _staticallyNonNullable(DartType type) =>
-      _soundNullSafety &&
-      type != null &&
-      type.nullability == Nullability.nonNullable;
+      _soundNullSafety && type.nullability == Nullability.nonNullable;
 
   bool _returnValueIsNullable(Member target) {
     var targetClass = target.enclosingClass;
@@ -359,7 +357,7 @@
 ///
 // TODO(jmesserly): Introduce flow analysis.
 class _NullableVariableInference extends RecursiveVisitor {
-  NullableInference _nullInference;
+  late NullableInference _nullInference;
 
   /// Variables that are currently believed to be not-null.
   final _notNullLocals = HashSet<VariableDeclaration>.identity();
@@ -378,7 +376,7 @@
 
   /// The current variable we are setting/initializing, so we can track if it
   /// is [_assignedTo] from another variable.
-  VariableDeclaration _variableAssignedTo;
+  VariableDeclaration? _variableAssignedTo;
 
   void enterFunction(FunctionNode node) {
     if (_functions.contains(node)) return; // local function already analyzed.
@@ -395,7 +393,7 @@
   @override
   void visitFunctionDeclaration(FunctionDeclaration node) {
     _notNullLocals.add(node.variable);
-    node.function?.accept(this);
+    node.function.accept(this);
   }
 
   @override
@@ -460,7 +458,7 @@
       _variableAssignedTo = variable;
 
       if (_nullInference.isNullable(node.value)) {
-        void markNullable(VariableDeclaration v) {
+        void markNullable(VariableDeclaration? v) {
           _notNullLocals.remove(v);
           _assignedTo.remove(v)?.forEach(markNullable);
         }
@@ -476,7 +474,7 @@
   bool variableIsNullable(VariableDeclaration variable) {
     if (_notNullLocals.contains(variable)) {
       if (_variableAssignedTo != null) {
-        _assignedTo.putIfAbsent(variable, () => []).add(_variableAssignedTo);
+        _assignedTo.putIfAbsent(variable, () => []).add(_variableAssignedTo!);
       }
       return false;
     }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_legacy_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_legacy_test.dart
index e124753..113c4d9 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_legacy_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_legacy_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-import 'package:dev_compiler/dev_compiler.dart' show ModuleFormat;
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    show ModuleFormat;
 import 'package:test/test.dart';
+
 import 'expression_compiler_e2e_shared.dart';
 import 'expression_compiler_e2e_suite.dart';
 
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_sound_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_sound_test.dart
index 24e6238..d1ac95c 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_sound_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_sound_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-import 'package:dev_compiler/dev_compiler.dart' show ModuleFormat;
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    show ModuleFormat;
 import 'package:test/test.dart';
+
 import 'expression_compiler_e2e_shared.dart';
 import 'expression_compiler_e2e_suite.dart';
 
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_unsound_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_unsound_test.dart
index e7a1804..8bbbff7 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_unsound_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_amd_unsound_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-import 'package:dev_compiler/dev_compiler.dart' show ModuleFormat;
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    show ModuleFormat;
 import 'package:test/test.dart';
+
 import 'expression_compiler_e2e_shared.dart';
 import 'expression_compiler_e2e_suite.dart';
 
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart
index 7efa925..7ba607e 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_dart_2_17_test.dart
@@ -1,10 +1,9 @@
-// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
+// Copyright (c) 2021, the Dart project authors.  Please see the AUTHORS file
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-import 'package:dev_compiler/dev_compiler.dart' show ModuleFormat;
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    show ModuleFormat;
 import 'package:test/test.dart';
 
 import 'expression_compiler_e2e_suite.dart';
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_legacy_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_legacy_test.dart
index 81952a8..289a07c 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_legacy_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_legacy_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-import 'package:dev_compiler/dev_compiler.dart' show ModuleFormat;
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    show ModuleFormat;
 import 'package:test/test.dart';
+
 import 'expression_compiler_e2e_shared.dart';
 import 'expression_compiler_e2e_suite.dart';
 
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_sound_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_sound_test.dart
index 6d40892..03a4998 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_sound_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_sound_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-import 'package:dev_compiler/dev_compiler.dart' show ModuleFormat;
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    show ModuleFormat;
 import 'package:test/test.dart';
+
 import 'expression_compiler_e2e_shared.dart';
 import 'expression_compiler_e2e_suite.dart';
 
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_unsound_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_unsound_test.dart
index aa231e2..1954b6b 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_unsound_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_ddc_unsound_test.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-import 'package:dev_compiler/dev_compiler.dart' show ModuleFormat;
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    show ModuleFormat;
 import 'package:test/test.dart';
+
 import 'expression_compiler_e2e_shared.dart';
 import 'expression_compiler_e2e_suite.dart';
 
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
index a1916b8..501a2de 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_shared.dart
@@ -2,9 +2,8 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'package:test/test.dart';
+
 import 'expression_compiler_e2e_suite.dart';
 
 const simpleClassSource = '''
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
index c578305..57466f1 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_e2e_suite.dart
@@ -2,17 +2,20 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:async';
 import 'dart:convert';
 import 'dart:io' show Directory, File, Platform;
 
 import 'package:browser_launcher/browser_launcher.dart' as browser;
-import 'package:dev_compiler/dev_compiler.dart';
 import 'package:dev_compiler/src/compiler/module_builder.dart';
+import 'package:dev_compiler/src/compiler/shared_command.dart'
+    show SharedCompilerOptions;
 import 'package:dev_compiler/src/kernel/command.dart';
+import 'package:dev_compiler/src/kernel/compiler.dart' show ProgramCompiler;
+import 'package:dev_compiler/src/kernel/expression_compiler.dart'
+    show ExpressionCompiler;
 import 'package:dev_compiler/src/kernel/module_metadata.dart';
+import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
 import 'package:front_end/src/api_unstable/ddc.dart' as fe;
 import 'package:front_end/src/compute_platform_binaries_location.dart' as fe;
 import 'package:front_end/src/fasta/incremental_serializer.dart' as fe;
@@ -28,9 +31,9 @@
   Uri entryPoint;
 
   DevelopmentIncrementalCompiler(fe.CompilerOptions options, this.entryPoint,
-      [Uri initializeFrom,
-      bool outlineOnly,
-      fe.IncrementalSerializer incrementalSerializer])
+      [Uri? initializeFrom,
+      bool? outlineOnly,
+      fe.IncrementalSerializer? incrementalSerializer])
       : super(
             fe.CompilerContext(
                 fe.ProcessedOptions(options: options, inputs: [entryPoint])),
@@ -40,7 +43,7 @@
 
   DevelopmentIncrementalCompiler.fromComponent(fe.CompilerOptions options,
       this.entryPoint, Component componentToInitializeFrom,
-      [bool outlineOnly, fe.IncrementalSerializer incrementalSerializer])
+      [bool? outlineOnly, fe.IncrementalSerializer? incrementalSerializer])
       : super.fromComponent(
             fe.CompilerContext(
                 fe.ProcessedOptions(options: options, inputs: [entryPoint])),
@@ -94,7 +97,7 @@
 }
 
 class TestCompilationResult {
-  final String result;
+  final String? result;
   final bool isSuccess;
 
   TestCompilationResult(this.result, this.isSuccess);
@@ -104,16 +107,16 @@
   final SetupCompilerOptions setup;
   final Component component;
   final ExpressionCompiler evaluator;
-  final ModuleMetadata metadata;
+  final ModuleMetadata? metadata;
   final source_maps.SingleMapping sourceMap;
 
   TestCompiler._(this.setup, this.component, this.evaluator, this.metadata,
       this.sourceMap);
 
   static Future<TestCompiler> init(SetupCompilerOptions setup,
-      {Uri input,
-      Uri output,
-      Uri packages,
+      {required Uri input,
+      required Uri output,
+      Uri? packages,
       Map<String, bool> experiments = const {}}) async {
     // Initialize the incremental compiler and module component.
     // TODO: extend this for multi-module compilations by storing separate
@@ -129,7 +132,7 @@
     // Initialize DDC.
     var moduleName = p.basenameWithoutExtension(output.toFilePath());
 
-    var classHierarchy = compilerResult.classHierarchy;
+    var classHierarchy = compilerResult.classHierarchy!;
     var compilerOptions = SharedCompilerOptions(
         replCompile: true,
         moduleName: moduleName,
@@ -184,17 +187,17 @@
     }
     setup.diagnosticMessages.clear();
 
-    var sourceMap = source_maps.SingleMapping.fromJson(code.sourceMap);
+    var sourceMap = source_maps.SingleMapping.fromJson(code.sourceMap!);
     return TestCompiler._(
         setup, component, evaluator, code.metadata, sourceMap);
   }
 
   Future<TestCompilationResult> compileExpression(
-      {Uri input,
-      int line,
-      int column,
-      Map<String, String> scope,
-      String expression}) async {
+      {required Uri input,
+      required int line,
+      required int column,
+      required Map<String, String> scope,
+      required String expression}) async {
     var libraryUri = metadataForLibraryUri(input);
     var jsExpression = await evaluator.compileExpressionToJs(
         libraryUri.importUri, line, column, scope, expression);
@@ -211,7 +214,7 @@
   }
 
   LibraryMetadata metadataForLibraryUri(Uri libraryUri) =>
-      metadata.libraries.entries
+      metadata!.libraries.entries
           .firstWhere((entry) => entry.value.fileUri == '$libraryUri')
           .value;
 }
@@ -221,16 +224,16 @@
   final Directory chromeDir;
   final wip.WipConnection connection;
   final wip.WipDebugger debugger;
-  TestCompiler compiler;
-  Uri htmlBootstrapper;
-  Uri input;
-  String moduleFormatString;
-  Uri output;
-  Uri packagesFile;
-  String preemptiveBp;
-  SetupCompilerOptions setup;
-  String source;
-  Directory testDir;
+  late TestCompiler compiler;
+  late Uri htmlBootstrapper;
+  late Uri input;
+  late String moduleFormatString;
+  late Uri output;
+  late Uri packagesFile;
+  late String preemptiveBp;
+  late SetupCompilerOptions setup;
+  late String source;
+  late Directory testDir;
 
   TestDriver._(this.chrome, this.chromeDir, this.connection, this.debugger);
 
@@ -242,8 +245,12 @@
     // Try to start Chrome on an empty page with a single empty tab.
     // TODO(#45713): Headless Chrome crashes the Windows bots, so run in
     // standard mode until it's fixed.
-    browser.Chrome chrome;
+    browser.Chrome? chrome;
     var retries = 3;
+    // It is possible for chrome to start and be ready while still printing
+    // messages to stderr which results in a Dart exception being thrown. For
+    // that reason, it is important to check `chrome == null` so we don't
+    // accidentally start multiple instances.
     while (chrome == null && retries-- > 0) {
       try {
         chrome = await browser.Chrome.startWithDebugPort(['about:blank'],
@@ -254,6 +261,9 @@
         await Future.delayed(Duration(seconds: 5));
       }
     }
+    if (chrome == null) {
+      throw Exception('Unable to launch Chrome.');
+    }
 
     // Connect to the first 'normal' tab.
     var tab = await chrome.chromeConnection
@@ -263,14 +273,14 @@
     }
 
     var connection = await tab.connect().timeout(Duration(seconds: 5),
-        onTimeout: () => throw Exception('Unable to connect to WIP tab'));
+        onTimeout: (() => throw Exception('Unable to connect to WIP tab')));
 
     await connection.page.enable().timeout(Duration(seconds: 5),
-        onTimeout: () => throw Exception('Unable to enable WIP tab page'));
+        onTimeout: (() => throw Exception('Unable to enable WIP tab page')));
 
     var debugger = connection.debugger;
     await debugger.enable().timeout(Duration(seconds: 5),
-        onTimeout: () => throw Exception('Unable to enable WIP debugger'));
+        onTimeout: (() => throw Exception('Unable to enable WIP debugger')));
     return TestDriver._(chrome, chromeDir, connection, debugger);
   }
 
@@ -279,9 +289,9 @@
   /// Depends on SDK artifacts (such as the sound and unsound dart_sdk.js
   /// files) generated from the 'dartdevc_test' target.
   Future<void> initSource(SetupCompilerOptions setup, String source,
-      {Map<String, bool> experiments}) async {
+      {Map<String, bool> experiments = const {}}) async {
     // Perform setup sanity checks.
-    var summaryPath = setup.options.sdkSummary.toFilePath();
+    var summaryPath = setup.options.sdkSummary!.toFilePath();
     if (!File(summaryPath).existsSync()) {
       throw StateError('Unable to find SDK summary at path: $summaryPath.');
     }
@@ -325,7 +335,7 @@
 
     htmlBootstrapper = testDir.uri.resolve('bootstrapper.html');
     var bootstrapFile = File(htmlBootstrapper.toFilePath())..createSync();
-    var moduleName = compiler.metadata.name;
+    var moduleName = compiler.metadata!.name;
     var mainLibraryName = compiler.metadataForLibraryUri(input).name;
 
     switch (setup.moduleFormat) {
@@ -405,8 +415,8 @@
 
         break;
       default:
-        throw Exception(
-            'Unsupported module format for SDK evaluation tests: ${setup.moduleFormat}');
+        throw Exception('Unsupported module format for SDK evaluation tests: '
+            '${setup.moduleFormat}');
     }
 
     await setBreakpointsActive(debugger, true);
@@ -422,10 +432,10 @@
   }
 
   Future<void> finish() async {
-    await chrome?.close();
+    await chrome.close();
     // Chrome takes a while to free its claim on chromeDir, so wait a bit.
     await Future.delayed(Duration(milliseconds: 500));
-    chromeDir?.deleteSync(recursive: true);
+    chromeDir.deleteSync(recursive: true);
   }
 
   Future<void> cleanupTest() async {
@@ -436,10 +446,10 @@
   }
 
   Future<void> check(
-      {String breakpointId,
-      String expression,
-      String expectedError,
-      String expectedResult}) async {
+      {required String breakpointId,
+      required String expression,
+      String? expectedError,
+      String? expectedResult}) async {
     assert(expectedError == null || expectedResult == null,
         'Cannot expect both an error and result.');
 
@@ -460,14 +470,15 @@
     // breakpoint.
     await connection.page.navigate('$htmlBootstrapper').timeout(
         Duration(seconds: 5),
-        onTimeout: () => throw Exception(
-            'Unable to navigate to page bootstrap script: $htmlBootstrapper'));
+        onTimeout: (() => throw Exception(
+            'Unable to navigate to page bootstrap script: $htmlBootstrapper')));
 
     // Poll until the script is found, or timeout after a few seconds.
     var script = (await scriptController.stream.first.timeout(
             Duration(seconds: 5),
-            onTimeout: () => throw Exception(
-                'Unable to find JS script corresponding to test file $output in ${debugger.scripts}.')))
+            onTimeout: (() => throw Exception(
+                'Unable to find JS script corresponding to test file '
+                '$output in ${debugger.scripts}.'))))
         .script;
     await scriptSub.cancel();
     await scriptController.close();
@@ -488,8 +499,9 @@
                 'Unable to find JS preemptive pause event in $output.'))
         .first
         .timeout(Duration(seconds: 5),
-            onTimeout: () => throw Exception(
-                'Unable to find JS pause event corresponding to line ($dartLine -> $location) in $output.'));
+            onTimeout: (() => throw Exception(
+                'Unable to find JS pause event corresponding to line '
+                '($dartLine -> $location) in $output.')));
     await pauseSub.cancel();
     await pauseController.close();
 
@@ -521,7 +533,7 @@
     }
 
     var evalResult = await debugger.evaluateOnCallFrame(
-        frame.callFrameId, result.result,
+        frame.callFrameId, result.result!,
         returnByValue: false);
 
     await debugger.removeBreakpoint(bp.breakpointId);
@@ -533,7 +545,7 @@
     expect(
         result,
         const TypeMatcher<TestCompilationResult>()
-            .having((_) => value, 'result', _matches(expectedResult)));
+            .having((_) => value, 'result', _matches(expectedResult!)));
   }
 
   /// Generate simple string representation of a RemoteObject that closely
@@ -548,7 +560,7 @@
     String str;
     switch (obj.type) {
       case 'function':
-        str = obj.description;
+        str = obj.description ?? '';
         break;
       case 'object':
         if (obj.subtype == 'null') {
@@ -556,10 +568,10 @@
         }
         var properties =
             await connection.runtime.getProperties(obj, ownProperties: true);
-        var filteredProps = <String, String>{};
+        var filteredProps = <String, String?>{};
         for (var prop in properties) {
           if (prop.value != null && prop.name != '__proto__') {
-            filteredProps[prop.name] = await stringifyRemoteObject(prop.value);
+            filteredProps[prop.name] = await stringifyRemoteObject(prop.value!);
           }
         }
         str = '${obj.description} $filteredProps';
@@ -583,8 +595,8 @@
           .getProperties(scope.object, ownProperties: true);
       for (var prop in response) {
         var propKey = prop.name;
-        var propValue = '${prop.value.value}';
-        if (prop.value.type == 'string') {
+        var propValue = '${prop.value!.value}';
+        if (prop.value!.type == 'string') {
           propValue = "'$propValue'";
         } else if (propValue == 'null') {
           propValue = propKey;
@@ -628,13 +640,14 @@
       for (var entry in lineEntry.entries) {
         if (entry.sourceUrlId != null &&
             entry.sourceLine == dartLine &&
-            compiler.sourceMap.urls[entry.sourceUrlId] == inputSourceUrl) {
+            compiler.sourceMap.urls[entry.sourceUrlId!] == inputSourceUrl) {
           return wip.WipLocation.fromValues(script.scriptId, lineEntry.line);
         }
       }
     }
     throw StateError(
-        'Unable to extract WIP Location from ${script.url} for Dart line $dartLine.');
+        'Unable to extract WIP Location from ${script.url} for Dart line '
+        '$dartLine.');
   }
 }
 
@@ -659,5 +672,5 @@
   await debugger.sendCommand('Debugger.setBreakpointsActive', params: {
     'active': active
   }).timeout(Duration(seconds: 5),
-      onTimeout: () => throw Exception('Unable to set breakpoint activity'));
+      onTimeout: (() => throw Exception('Unable to set breakpoint activity')));
 }
diff --git a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
index e5e91cc..4ee6424b 100644
--- a/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
+++ b/pkg/dev_compiler/test/expression_compiler/expression_compiler_test.dart
@@ -2,14 +2,16 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:io' show Directory, File;
 
-import 'package:dev_compiler/dev_compiler.dart';
 import 'package:dev_compiler/src/compiler/js_names.dart';
 import 'package:dev_compiler/src/compiler/module_builder.dart';
+import 'package:dev_compiler/src/compiler/shared_command.dart'
+    show SharedCompilerOptions;
 import 'package:dev_compiler/src/js_ast/js_ast.dart';
+import 'package:dev_compiler/src/kernel/compiler.dart' show ProgramCompiler;
+import 'package:dev_compiler/src/kernel/expression_compiler.dart'
+    show ExpressionCompiler;
 import 'package:kernel/ast.dart' show Component, Library;
 import 'package:test/test.dart';
 import 'package:vm/transformations/type_flow/utils.dart';
@@ -67,12 +69,12 @@
   TestCompiler(this.setup);
 
   Future<TestCompilationResult> compile(
-      {Uri input,
-      Uri packages,
-      int line,
-      int column,
-      Map<String, String> scope,
-      String expression}) async {
+      {required Uri input,
+      required Uri packages,
+      required int line,
+      required int column,
+      required Map<String, String> scope,
+      required String expression}) async {
     // initialize incremental compiler and create component
     setup.options.packagesFileUri = packages;
     var compiler = DevelopmentIncrementalCompiler(setup.options, input);
@@ -97,7 +99,7 @@
     }
     summaryToModule[component] = moduleName;
 
-    var kernel2jsCompiler = ProgramCompiler(component, classHierarchy,
+    var kernel2jsCompiler = ProgramCompiler(component, classHierarchy!,
         compilerOptions, importToSummary, summaryToModule,
         coreTypes: coreTypes);
     var moduleTree = kernel2jsCompiler.emitModule(component);
@@ -125,7 +127,7 @@
 
     // collect all module names and paths
     var moduleInfo = _collectModules(component);
-    var module = moduleInfo[input];
+    var module = moduleInfo[input]!;
 
     setup.errors.clear();
 
@@ -142,7 +144,7 @@
       return TestCompilationResult(jsExpression, false);
     }
 
-    return TestCompilationResult(jsExpression, true);
+    return TestCompilationResult(jsExpression!, true);
   }
 
   Map<Uri, Module> _collectModules(Component component) {
@@ -157,18 +159,17 @@
 
 class TestDriver {
   final SetupCompilerOptions options;
-  Directory tempDir;
+  late Directory tempDir;
   final String source;
-  Uri input;
-  Uri packages;
-  File file;
+  late Uri input;
+  late Uri packages;
+  late File file;
   int line;
 
-  TestDriver(this.options, this.source) {
+  TestDriver(this.options, this.source) : line = _getEvaluationLine(source) {
     var systemTempDir = Directory.systemTemp;
     tempDir = systemTempDir.createTempSync('foo bar');
 
-    line = _getEvaluationLine(source);
     input = tempDir.uri.resolve('foo.dart');
     file = File.fromUri(input)..createSync();
     file.writeAsStringSync(source);
@@ -194,10 +195,10 @@
   }
 
   Future<void> check(
-      {Map<String, String> scope,
-      String expression,
-      String expectedError,
-      String expectedResult}) async {
+      {required Map<String, String> scope,
+      required String expression,
+      String? expectedError,
+      String? expectedResult}) async {
     var result = await TestCompiler(options).compile(
         input: input,
         packages: packages,
@@ -207,7 +208,7 @@
         expression: expression);
 
     var success = expectedError == null;
-    var message = success ? expectedResult : expectedError;
+    var message = success ? expectedResult! : expectedError;
 
     expect(
         result,
@@ -227,7 +228,7 @@
     return matches(RegExp(unindented, multiLine: true));
   }
 
-  int _getEvaluationLine(String source) {
+  static int _getEvaluationLine(String source) {
     var placeholderRegExp = RegExp(r'/\* evaluation placeholder \*/');
 
     var lines = source.split('\n');
@@ -266,7 +267,7 @@
           }
           ''';
 
-          TestDriver driver;
+          late TestDriver driver;
 
           setUp(() {
             driver = TestDriver(options, source);
@@ -345,7 +346,7 @@
           void main() => foo();
           ''';
 
-          TestDriver driver;
+          late TestDriver driver;
           setUp(() {
             driver = TestDriver(options, source);
           });
@@ -465,7 +466,7 @@
           void main() => bar();
           ''';
 
-          TestDriver driver;
+          late TestDriver driver;
           setUp(() {
             driver = TestDriver(options, source);
           });
@@ -528,7 +529,7 @@
           }
           ''';
 
-          TestDriver driver;
+          late TestDriver driver;
 
           setUp(() {
             driver = TestDriver(options, source);
@@ -597,7 +598,7 @@
           void main() => bar();
           ''';
 
-          TestDriver driver;
+          late TestDriver driver;
           setUp(() {
             driver = TestDriver(options, source);
           });
diff --git a/pkg/dev_compiler/test/nullable_inference_test.dart b/pkg/dev_compiler/test/nullable_inference_test.dart
index 1c5d392..e8b30e9 100644
--- a/pkg/dev_compiler/test/nullable_inference_test.dart
+++ b/pkg/dev_compiler/test/nullable_inference_test.dart
@@ -2,12 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:async';
 import 'dart:io';
 
-import 'package:dev_compiler/src/kernel/command.dart';
+import 'package:dev_compiler/src/kernel/command.dart' show getSdkPath;
 import 'package:dev_compiler/src/kernel/js_typerep.dart';
 import 'package:dev_compiler/src/kernel/nullable_inference.dart';
 import 'package:dev_compiler/src/kernel/target.dart';
@@ -18,6 +16,7 @@
 import 'package:kernel/src/printer.dart';
 import 'package:kernel/target/targets.dart';
 import 'package:kernel/type_environment.dart';
+import 'package:path/path.dart' as p;
 import 'package:test/test.dart';
 
 const AstTextStrategy astTextStrategy = AstTextStrategy(
@@ -535,13 +534,13 @@
 }
 
 bool useAnnotations = false;
-NullableInference inference;
+NullableInference? inference;
 
 class _TestRecursiveVisitor extends RecursiveVisitor {
   final Set<Library> librariesFromDill;
   int _functionNesting = 0;
-  TypeEnvironment _typeEnvironment;
-  StatefulStaticTypeContext _staticTypeContext;
+  late TypeEnvironment _typeEnvironment;
+  late StatefulStaticTypeContext _staticTypeContext;
 
   _TestRecursiveVisitor(this.librariesFromDill);
 
@@ -558,8 +557,8 @@
     inference ??= NullableInference(jsTypeRep, _staticTypeContext);
 
     if (useAnnotations) {
-      inference.allowNotNullDeclarations = useAnnotations;
-      inference.allowPackageMetaAnnotations = useAnnotations;
+      inference!.allowNotNullDeclarations = useAnnotations;
+      inference!.allowPackageMetaAnnotations = useAnnotations;
     }
     super.visitComponent(node);
   }
@@ -601,10 +600,10 @@
   void visitFunctionNode(FunctionNode node) {
     _functionNesting++;
     if (_functionNesting == 1) {
-      inference.enterFunction(node);
+      inference!.enterFunction(node);
     }
     super.visitFunctionNode(node);
-    if (_functionNesting == 1) inference.exitFunction(node);
+    if (_functionNesting == 1) inference!.exitFunction(node);
     _functionNesting--;
   }
 }
@@ -616,7 +615,7 @@
 
   @override
   void defaultExpression(Expression node) {
-    if (!inference.isNullable(node)) {
+    if (!inference!.isNullable(node)) {
       notNullExpressions.add(node);
     }
     super.defaultExpression(node);
@@ -628,13 +627,13 @@
 
   @override
   void defaultExpression(Expression node) {
-    expect(inference.isNullable(node), false,
+    expect(inference!.isNullable(node), false,
         reason: 'expression `$node` should be inferred as not-null');
     super.defaultExpression(node);
   }
 }
 
-fe.InitializedCompilerState _compilerState;
+fe.InitializedCompilerState? _compilerState;
 final _fileSystem = fe.MemoryFileSystem(Uri.file('/memory/'));
 
 class CompileResult {
@@ -653,11 +652,18 @@
     fe.printDiagnosticMessage(message, print);
   }
 
+  var root = Uri.file('/memory');
   var sdkUri = Uri.file('/memory/dart_sdk.dill');
   var sdkFile = _fileSystem.entityForUri(sdkUri);
   if (!await sdkFile.exists()) {
-    sdkFile.writeAsBytesSync(
-        File(defaultSdkSummaryPath(soundNullSafety: false)).readAsBytesSync());
+    var outlineDill = p.join(getSdkPath(), 'lib', '_internal', 'ddc_sdk.dill');
+    sdkFile.writeAsBytesSync(File(outlineDill).readAsBytesSync());
+  }
+  var librariesUri = Uri.file('/memory/libraries.json');
+  var librariesFile = _fileSystem.entityForUri(librariesUri);
+  if (!await librariesFile.exists()) {
+    var librariesJson = p.join(getSdkPath(), 'lib', 'libraries.json');
+    librariesFile.writeAsBytesSync(File(librariesJson).readAsBytesSync());
   }
   var packagesUri = Uri.file('/memory/.packages');
   var packagesFile = _fileSystem.entityForUri(packagesUri);
@@ -676,17 +682,17 @@
   var mainUri = Uri.file('/memory/test.dart');
   _fileSystem.entityForUri(mainUri).writeAsStringSync(code);
   var oldCompilerState = _compilerState;
-  _compilerState = fe.initializeCompiler(oldCompilerState, false, null, sdkUri,
-      packagesUri, null, [], DevCompilerTarget(TargetFlags()),
+  _compilerState = fe.initializeCompiler(oldCompilerState, false, root, sdkUri,
+      packagesUri, librariesUri, [], DevCompilerTarget(TargetFlags()),
       fileSystem: _fileSystem,
       explicitExperimentalFlags: const {},
       environmentDefines: const {},
       nnbdMode: fe.NnbdMode.Weak);
   if (!identical(oldCompilerState, _compilerState)) inference = null;
   var result =
-      await fe.compile(_compilerState, [mainUri], diagnosticMessageHandler);
+      await (fe.compile(_compilerState!, [mainUri], diagnosticMessageHandler));
   expect(succeeded, true);
 
-  var librariesFromDill = result.computeLibrariesFromDill();
+  var librariesFromDill = result!.computeLibrariesFromDill();
   return CompileResult(result.component, librariesFromDill);
 }
diff --git a/pkg/dev_compiler/test/sdk_source_map_test.dart b/pkg/dev_compiler/test/sdk_source_map_test.dart
index 84e6038..799c1b1 100644
--- a/pkg/dev_compiler/test/sdk_source_map_test.dart
+++ b/pkg/dev_compiler/test/sdk_source_map_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:io';
 
 import 'package:expect/expect.dart';
diff --git a/pkg/dev_compiler/test/shared_test_options.dart b/pkg/dev_compiler/test/shared_test_options.dart
index 7edff24..7d4478e 100644
--- a/pkg/dev_compiler/test/shared_test_options.dart
+++ b/pkg/dev_compiler/test/shared_test_options.dart
@@ -2,10 +2,10 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
-import 'package:dev_compiler/dev_compiler.dart';
-import 'package:dev_compiler/src/kernel/command.dart';
+import 'package:dev_compiler/src/compiler/module_builder.dart'
+    show ModuleFormat;
+import 'package:dev_compiler/src/kernel/command.dart' show getSdkPath;
+import 'package:dev_compiler/src/kernel/target.dart' show DevCompilerTarget;
 import 'package:front_end/src/api_unstable/ddc.dart';
 import 'package:front_end/src/compute_platform_binaries_location.dart';
 import 'package:front_end/src/fasta/incremental_serializer.dart';
@@ -17,9 +17,9 @@
   Uri entryPoint;
 
   DevelopmentIncrementalCompiler(CompilerOptions options, this.entryPoint,
-      [Uri initializeFrom,
-      bool outlineOnly,
-      IncrementalSerializer incrementalSerializer])
+      [Uri? initializeFrom,
+      bool? outlineOnly,
+      IncrementalSerializer? incrementalSerializer])
       : super(
             CompilerContext(
                 ProcessedOptions(options: options, inputs: [entryPoint])),
@@ -29,7 +29,7 @@
 
   DevelopmentIncrementalCompiler.fromComponent(CompilerOptions options,
       this.entryPoint, Component componentToInitializeFrom,
-      [bool outlineOnly, IncrementalSerializer incrementalSerializer])
+      [bool? outlineOnly, IncrementalSerializer? incrementalSerializer])
       : super.fromComponent(
             CompilerContext(
                 ProcessedOptions(options: options, inputs: [entryPoint])),
@@ -43,6 +43,7 @@
   static final sdkUnsoundSummaryPath = p.join(sdkRoot.path, 'ddc_sdk.dill');
   static final sdkSoundSummaryPath =
       p.join(sdkRoot.path, 'ddc_outline_sound.dill');
+  // TODO(46617) Call getSdkPath() from command.dart instead.
   static final librariesSpecificationUri =
       p.join(p.dirname(p.dirname(getSdkPath())), 'libraries.json');
 
diff --git a/pkg/dev_compiler/test/sourcemap/common.dart b/pkg/dev_compiler/test/sourcemap/common.dart
index a443eec..d574968 100644
--- a/pkg/dev_compiler/test/sourcemap/common.dart
+++ b/pkg/dev_compiler/test/sourcemap/common.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:io';
 
 import 'package:_fe_analyzer_shared/src/testing/annotated_code_helper.dart';
@@ -13,10 +11,12 @@
 
 class Data {
   Uri uri;
-  Directory outDir;
-  String testFileName;
-  AnnotatedCode code;
-  List<String> d8Output;
+  late Directory outDir;
+  late String testFileName;
+  late AnnotatedCode code;
+  late List<String> d8Output;
+
+  Data(this.uri);
 }
 
 abstract class ChainContextWithCleanupHelper extends ChainContext {
@@ -26,12 +26,12 @@
   Future<void> cleanUp(TestDescription description, Result result) {
     if (debugging() && result.outcome != Expectation.Pass) {
       print('Not cleaning up: Running in debug-mode for non-passing test.');
-      return null;
+      return Future.value();
     }
 
     var data = cleanupHelper.remove(description);
-    data?.outDir?.deleteSync(recursive: true);
-    return null;
+    data?.outDir.deleteSync(recursive: true);
+    return Future.value();
   }
 
   bool debugging() => false;
@@ -45,7 +45,7 @@
 
   @override
   Future<Result<Data>> run(TestDescription input, ChainContext context) async {
-    var data = Data()..uri = input.uri;
+    var data = Data(input.uri);
     if (context is ChainContextWithCleanupHelper) {
       context.cleanupHelper[input] = data;
     }
@@ -99,7 +99,7 @@
 }
 
 File findInOutDir(String relative) {
-  var outerDir = sdkRoot.path;
+  var outerDir = sdkRoot!.path;
   for (var outDir in const [
     'out/ReleaseX64',
     'xcodebuild/ReleaseX64',
diff --git a/pkg/dev_compiler/test/sourcemap/ddc_common.dart b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
index 6653e57..8d27e08 100644
--- a/pkg/dev_compiler/test/sourcemap/ddc_common.dart
+++ b/pkg/dev_compiler/test/sourcemap/ddc_common.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 library dev_compiler.test.sourcemap.ddc_common;
 
 import 'dart:io';
@@ -23,7 +21,7 @@
 }
 
 abstract class WithCompilerState {
-  fe.InitializedCompilerState compilerState;
+  fe.InitializedCompilerState? compilerState;
 }
 
 class Compile extends Step<Data, Data, ChainContext> {
@@ -98,7 +96,7 @@
     return input.resolve('wrapper.js');
   }
 
-  String _convertName(String name) {
+  String? _convertName(String? name) {
     if (name == null) return null;
     // Hack for DDC naming scheme.
     var result = name;
@@ -112,7 +110,7 @@
   }
 }
 
-Directory _cachedDdcDir;
+Directory? _cachedDdcDir;
 Directory getDdcDir() {
   Directory search() {
     var dir = File.fromUri(Platform.script).parent;
@@ -165,7 +163,8 @@
 void createHtmlWrapper(File sdkJsFile, Uri outputFile, String jsContent,
     String outputFilename, Uri outDir) {
   // For debugging via HTML, Chrome and ./pkg/test_runner/bin/http_server.dart.
-  var sdkFile = File(p.relative(sdkJsFile.path, from: sdkRoot.path));
+  var sdkRootPath = sdkRoot!.path;
+  var sdkFile = File(p.relative(sdkJsFile.path, from: sdkRootPath));
   var jsRootDart = '/root_dart/${sdkFile.uri}';
   File.fromUri(outputFile.resolve('$outputFilename.html.js')).writeAsStringSync(
       jsContent.replaceFirst("from 'dart_sdk.js'", "from '$jsRootDart'"));
@@ -174,7 +173,7 @@
           jsRootDart, '/root_build/$outputFilename.html.js'));
 
   print('You should now be able to run\n\n'
-      'dart ${sdkRoot.path}/pkg/test_runner/bin/http_server.dart -p 39550 '
+      'dart $sdkRootPath/pkg/test_runner/bin/http_server.dart -p 39550 '
       '--network 127.0.0.1 '
       '--build-directory=${outDir.toFilePath()}'
       '\n\nand go to\n\n'
@@ -230,7 +229,7 @@
   if (name.isEmpty) return r'$';
 
   // Escape any invalid characters
-  StringBuffer buffer;
+  StringBuffer? buffer;
   for (var i = 0; i < name.length; i++) {
     var ch = name[i];
     var needsEscape = ch == r'$' || _invalidCharInIdentifier.hasMatch(ch);
diff --git a/pkg/dev_compiler/test/sourcemap/sourcemaps_ddk_suite.dart b/pkg/dev_compiler/test/sourcemap/sourcemaps_ddk_suite.dart
index a20cf67..94bf1f8 100644
--- a/pkg/dev_compiler/test/sourcemap/sourcemaps_ddk_suite.dart
+++ b/pkg/dev_compiler/test/sourcemap/sourcemaps_ddk_suite.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:io';
 
 import 'package:dev_compiler/src/compiler/shared_command.dart';
@@ -24,11 +22,11 @@
     implements WithCompilerState {
   final Map<String, String> environment;
   @override
-  fe.InitializedCompilerState compilerState;
+  fe.InitializedCompilerState? compilerState;
 
   SourceMapContext(this.environment);
 
-  List<Step> _steps;
+  List<Step>? _steps;
 
   @override
   List<Step> get steps {
@@ -61,7 +59,7 @@
     var ddcSdkSummary = findInOutDir('ddc_outline.dill');
 
     var packageConfigPath =
-        sdkRoot.uri.resolve('.dart_tool/package_config.json').toFilePath();
+        sdkRoot!.uri.resolve('.dart_tool/package_config.json').toFilePath();
     var args = <String>[
       '--batch',
       '--packages=$packageConfigPath',
@@ -77,7 +75,7 @@
       var result = await compile(ParsedArguments.from(args),
           compilerState: context.compilerState);
       context.compilerState =
-          result.compilerState as fe.InitializedCompilerState;
+          result.compilerState as fe.InitializedCompilerState?;
       succeeded = result.success;
     } catch (e, s) {
       print('Unhandled exception:');
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart
index e93433a..21a4cc1 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_ddk_suite.dart
@@ -1,4 +1,6 @@
-// @dart = 2.9
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
 
 import 'package:front_end/src/api_unstable/ddc.dart' as fe;
 import 'package:testing/testing.dart';
@@ -15,9 +17,9 @@
 class StackTraceContext extends ChainContextWithCleanupHelper
     implements WithCompilerState {
   @override
-  fe.InitializedCompilerState compilerState;
+  fe.InitializedCompilerState? compilerState;
 
-  List<Step> _steps;
+  List<Step>? _steps;
 
   @override
   List<Step> get steps {
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/null_instance_field.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/null_instance_field.dart
index d0ec237..2a36f88 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/null_instance_field.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/null_instance_field.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ test(Class());
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/null_interceptor_field.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/null_interceptor_field.dart
index a7bace6..d43b10b 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/null_interceptor_field.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/null_interceptor_field.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 class MyType {
   int get length => 3; // ensures we build an interceptor for `.length`
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/rethrow.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/rethrow.dart
index 3bff992..908eb8f 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/rethrow.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/rethrow.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ test();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_async.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_async.dart
index c2357bd..e1e10f8 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_async.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_async.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ test();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_awaited_async.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_awaited_async.dart
index 740a9e4..0458fc9 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_awaited_async.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_awaited_async.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ test1();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_constructor.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_constructor.dart
index b610f05..f57db8f 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_constructor.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_constructor.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   // ignore: UNUSED_LOCAL_VARIABLE
   var /*ddc.1:main*/ c = /*ddk.1:main*/ Class();
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_constructor_from_async.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_constructor_from_async.dart
index 62f002d..37467ae 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_constructor_from_async.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_constructor_from_async.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   // This call is no longer on the stack when the error is thrown.
   /*1:main*/ test();
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_instance_method.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_instance_method.dart
index ecdfe70..84dac4e3 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_instance_method.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_instance_method.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   var c = Class();
   c. /*1:main*/ test();
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_main.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_main.dart
index 8548403..c7043fe 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_main.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_main.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ throw '>ExceptionMarker<';
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_static_method.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_static_method.dart
index eaf057b..89a9033 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_static_method.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_static_method.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*ddc.1:main*/ Class. /*ddk.1:main*/ test();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_top_level_method.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_top_level_method.dart
index 125bc2d..799c9c0 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_top_level_method.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_top_level_method.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ test();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_top_level_method_from_async.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_top_level_method_from_async.dart
index 5dd30d1..06ec99f 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_top_level_method_from_async.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_top_level_method_from_async.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ test1();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
index 359b523..9ce488c 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_catch.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ test();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_finally.dart b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_finally.dart
index b92875b..211f9ed 100644
--- a/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_finally.dart
+++ b/pkg/dev_compiler/test/sourcemap/stacktrace_testfiles/throw_in_try_finally.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*1:main*/ test();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/breakpoint_on_function_line_breaks_in_body.dart b/pkg/dev_compiler/test/sourcemap/testfiles/breakpoint_on_function_line_breaks_in_body.dart
index 0748c25..b38f0821 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/breakpoint_on_function_line_breaks_in_body.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/breakpoint_on_function_line_breaks_in_body.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   foo();
 }
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/call_on_field_in_class.dart b/pkg/dev_compiler/test/sourcemap/testfiles/call_on_field_in_class.dart
index 51c0dcc..1d40779 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/call_on_field_in_class.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/call_on_field_in_class.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /* bl */ var foo = /*sl:1*/ Foo();
   foo.foo = foo. /*sl:2*/ fooMethod;
@@ -14,11 +12,11 @@
   // (back in dart.callMethod) -> dart._checkAndCall -> fooMethod
   // which seems unlikely to be something the user is going to step through.
   // As a "fix" here a breakpoint has been set on the line in fooMethod.
-  foo. /*sl:5*/ foo();
+  foo. /*sl:5*/ foo!();
 }
 
 class Foo {
-  void Function() foo;
+  void Function()? foo;
 
   void fooMethod() {
     /*bl*/ /*s:4*/ /*s:6*/ print('Hello from fooMethod');
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/hello_async.dart b/pkg/dev_compiler/test/sourcemap/testfiles/hello_async.dart
index 11023f4..62fba8c 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/hello_async.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/hello_async.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*bl*/
   /*s:1*/ foo();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/hello_call.dart b/pkg/dev_compiler/test/sourcemap/testfiles/hello_call.dart
index 6f93981..1f28925 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/hello_call.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/hello_call.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*bl*/
   /*s:1*/ foo();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/hello_class_call.dart b/pkg/dev_compiler/test/sourcemap/testfiles/hello_class_call.dart
index a1cc9fd..05bdd91 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/hello_class_call.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/hello_class_call.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*bl*/
   var foo = Foo();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/hello_sane_column_on_print_return_value.dart b/pkg/dev_compiler/test/sourcemap/testfiles/hello_sane_column_on_print_return_value.dart
index 54b020d..2f1663c 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/hello_sane_column_on_print_return_value.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/hello_sane_column_on_print_return_value.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*bc:3*/ print(/*bc:1*/ foo());
 }
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/hello_world.dart b/pkg/dev_compiler/test/sourcemap/testfiles/hello_world.dart
index a034e08..e8181f7 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/hello_world.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/hello_world.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /*nb*/ // no break on empty line
   /*bl*/ print('Hello, World!');
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/method_call_with_named_parameters.dart b/pkg/dev_compiler/test/sourcemap/testfiles/method_call_with_named_parameters.dart
index cbf1689..eea7830 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/method_call_with_named_parameters.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/method_call_with_named_parameters.dart
@@ -2,14 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   foo(/*bc:1*/ bar(), baz: /*bc:2*/ baz());
   /*nbb:0:4*/
 }
 
-void foo(int bar, {int /*bc:3*/ baz}) {
+void foo(int bar, {int? /*bc:3*/ baz}) {
   /*bc:4*/ print('foo!');
 }
 
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/method_call_with_named_parameters_no_given.dart b/pkg/dev_compiler/test/sourcemap/testfiles/method_call_with_named_parameters_no_given.dart
index a47263d..3122107 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/method_call_with_named_parameters_no_given.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/method_call_with_named_parameters_no_given.dart
@@ -2,14 +2,12 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   foo(/*bc:1*/ bar());
   /*nbb:0:3*/
 }
 
-void foo(int bar, {int /*bc:2*/ baz}) {
+void foo(int bar, {int? /*bc:2*/ baz}) {
   /*bc:3*/ print('foo!');
 }
 
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/multiple_debugger_calls.dart b/pkg/dev_compiler/test/sourcemap/testfiles/multiple_debugger_calls.dart
index 7ce45b4..8801ae9 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/multiple_debugger_calls.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/multiple_debugger_calls.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 import 'dart:developer';
 
 // Regression test: https://github.com/dart-lang/sdk/issues/45544
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assert.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assert.dart
index 478deef..eab2e71 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assert.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assert.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
 void main() {
   assert(/*bc:1*/ foo());
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assign_call_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assign_call_test.dart
index 5da999c..951e0a8 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assign_call_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assign_call_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
 void main() {
   /*nb*/ int a;
@@ -15,7 +13,7 @@
   /*bc:5*/ print(a);
   var d = /*bc:6*/ foo();
   /*bc:7*/ print(d);
-  int e = /*bc:8*/ foo(), f, g = /*bc:9*/ foo();
+  int? e = /*bc:8*/ foo(), f, g = /*bc:9*/ foo();
   /*bc:10*/ print(e);
   /*bc:11*/ print(f);
   /*bc:12*/ print(g);
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assign_int_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assign_int_test.dart
index d73151f..41cfb65 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assign_int_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_assign_int_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
 void main() {
   /*nb*/ int a;
@@ -16,7 +14,7 @@
   /*s:5*/ print(a);
   var d = /*s:6*/ 42;
   /*s:7*/ print(d);
-  int e = /*s:8*/ 41, f, g = /*s:9*/ 42;
+  int? e = /*s:8*/ 41, f, g = /*s:9*/ 42;
   /*s:10*/ print(e);
   /*s:11*/ print(f);
   /*s:12*/ print(g);
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_catch_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_catch_test.dart
index 93b9271..9a6f371 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_catch_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_catch_test.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   /*bl*/
   try {
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_for_each_loop_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_for_each_loop_test.dart
index d9a8a77..20c74c1 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_for_each_loop_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_for_each_loop_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
 void main() {
   /*bl*/ /*sl:1*/ var data = [1, 2, 3];
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_for_loop_with_break_and_continue_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_for_loop_with_break_and_continue_test.dart
index 962f8fc..a3e6148 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_for_loop_with_break_and_continue_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_for_loop_with_break_and_continue_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
 void main() {
   /*bl*/ /*sl:1*/ var count = 0;
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_is_and_as_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_is_and_as_test.dart
index d984c0d..20daab9 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_is_and_as_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_is_and_as_test.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   /*bl*/
   /*sl:1*/ var i = 42.42;
@@ -19,6 +16,7 @@
   /*bc:7*/ if (i is! int) {
     /*bc:8*/ print('i is not int');
   }
+  // ignore: unnecessary_type_check
   /*bc:9*/ if (hex is int) {
     /*bc:10*/ print('hex is int');
     // ignore: unnecessary_cast
@@ -29,6 +27,7 @@
       print("but it's not even even!");
     }
   }
+  // ignore: unnecessary_type_check
   /*bc:14*/ if (hex is! int) {
     print('hex is not int');
   }
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_map_creation.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_map_creation.dart
index 53eb14d..eac9eda 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_map_creation.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_map_creation.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   /*bl*/
   var x = {/*bc:1*/ foo(): /*bc:2*/ bar() };
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_multi_catch_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_multi_catch_test.dart
index 57e1ce9..44bc4dde 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_multi_catch_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_multi_catch_test.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   /*bl*/
   try {
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_super_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_super_test.dart
index bfd9266c..7a2bcca 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_super_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_super_test.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 class Class2 {
   dynamic operator [](index) => index;
 
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_this_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_this_test.dart
index 7fc64b2..2038431 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_this_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_on_this_test.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 class Class2 {
   dynamic operator [](index) => index;
 
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_test.dart
index 9351447..e9076fb 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_operator_bracket_test.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 class Class2 {
   dynamic operator [](index) => index;
 
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_static_set.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_static_set.dart
index e63b7ff..0f39f0b 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_static_set.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_static_set.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 var bar = 0;
 
 void main() {
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_concatenation.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_concatenation.dart
index 02d4137..35c4500 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_concatenation.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_concatenation.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   String qux;
   qux = '${/*bc:1*/ foo()} x ${/*bc:2*/ bar()} x ${/*bc:3*/ baz()}';
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_plus.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_plus.dart
index f395f55..be9ce11 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_plus.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_string_plus.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   String qux;
   qux = /*bc:1*/ foo() + /*bc:2*/ bar();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_throw.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_throw.dart
index bc00462c..fb23828 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_throw.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_throw.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   try {
     throw /*bc:1*/ foo();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_variable_set.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_variable_set.dart
index cce899b..0fad64b 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_variable_set.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_variable_set.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   /*bl*/
   /*sl:1*/ var x = 0;
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_yield.dart b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_yield.dart
index 62694a2..b3acab0 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/next_through_yield.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/next_through_yield.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   for (var i in naturalsTo(2)) {
     print(i);
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_constructor_line.dart b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_constructor_line.dart
index 8a143f8..b5d935b 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_constructor_line.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_constructor_line.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   // ignore: unused_local_variable
   var foo = Foo();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_function_line.dart b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_function_line.dart
index 5c2966b..8b3b281 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_function_line.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_function_line.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   var foo = Foo();
   foo.foo();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_line.dart b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_line.dart
index 92781ce..f7943d6 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_line.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_line.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   var foo = Foo();
   foo.foo();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_named_constructor_line.dart b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_named_constructor_line.dart
index 75e9030..9c71302 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_named_constructor_line.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_class_named_constructor_line.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   // ignore: unused_local_variable
   var foo = Foo.named();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_function_line.dart b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_function_line.dart
index eedeb22..4683e61 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_function_line.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/no_mapping_on_function_line.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*nm*/
 void main() {
   foo();
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/printing_class_fields.dart b/pkg/dev_compiler/test/sourcemap/testfiles/printing_class_fields.dart
index e1cd050..3594711 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/printing_class_fields.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/printing_class_fields.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
 void main() {
   /*bl*/
@@ -19,7 +17,7 @@
 }
 
 class Foo {
-  int x, y, z;
+  int? x, y, z;
 
   Foo(int a, int b)
       : x = a,
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/printing_class_fields_step_into.dart b/pkg/dev_compiler/test/sourcemap/testfiles/printing_class_fields_step_into.dart
index ab8d8a3..ea56b04 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/printing_class_fields_step_into.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/printing_class_fields_step_into.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*nb*/
 void main() {
   /*bl*/
@@ -14,7 +12,7 @@
 }
 
 class Foo {
-  int x, y, z;
+  int? x, y, z;
 
   Foo(int a, int b)
       : /*sl:2*/ x = a, // `s:2` fails, DDK is missing hover info
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_async_star_yield.dart b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_async_star_yield.dart
index ad18584..b9fd205 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_async_star_yield.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_async_star_yield.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() async {
   await for (var i in foobar() as Stream) {
     print(i);
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_await_for.dart b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_await_for.dart
index 1dd6548..20fc828 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_await_for.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_await_for.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() async {
   /* bl */
   /*sl:1 */ print('About to loop!');
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_conditional_expression.dart b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_conditional_expression.dart
index 45a661d..b8cfb71 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_conditional_expression.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_conditional_expression.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   print(/*bc:1*/ foo() ? bar() : /*bc:2*/ baz());
   print(! /*bc:3*/ foo() ? /*bc:4*/ bar() : baz());
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_if_and_identical.dart b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_if_and_identical.dart
index 0e57fda..6af41a9 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_if_and_identical.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_if_and_identical.dart
@@ -2,10 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 /*Debugger:stepOver*/
-
 void main() {
   if (/*bc:1*/ foo() == /*bc:2*/ bar()) {
     print('wat?!?');
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_property_get_test.dart b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_property_get_test.dart
index 2e5bcad..25fdc3e 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_property_get_test.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_property_get_test.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   var bar = Bar();
   bar.doStuff();
@@ -22,7 +20,7 @@
 
 class Bar extends Foo {
   final List<String> /*s:2*/ /*s:4*/ data2;
-  Foo data3;
+  Foo? data3;
 
   Bar() : data2 = ['d', 'e', 'f'] {
     data3 = this;
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_sync_star.dart b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_sync_star.dart
index 2aaec15..4ce057b 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/step_through_sync_star.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/step_through_sync_star.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   /* bl */
   /*sl:1*/ var iterator = naturalsTo(2);
diff --git a/pkg/dev_compiler/test/sourcemap/testfiles/stops_at_ending_brace.dart b/pkg/dev_compiler/test/sourcemap/testfiles/stops_at_ending_brace.dart
index 0e1347d..d322e4c 100644
--- a/pkg/dev_compiler/test/sourcemap/testfiles/stops_at_ending_brace.dart
+++ b/pkg/dev_compiler/test/sourcemap/testfiles/stops_at_ending_brace.dart
@@ -2,8 +2,6 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-// @dart = 2.9
-
 void main() {
   Foo();
   // Comment to push the ending brace back a bit.
diff --git a/pkg/dev_compiler/test/string_to_uri_test.dart b/pkg/dev_compiler/test/string_to_uri_test.dart
index bfd74be..9534711 100755
--- a/pkg/dev_compiler/test/string_to_uri_test.dart
+++ b/pkg/dev_compiler/test/string_to_uri_test.dart
@@ -1,11 +1,14 @@
-// @dart = 2.9
+// Copyright (c) 2017, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io';
+
 import 'package:dev_compiler/src/compiler/shared_command.dart';
 import 'package:test/test.dart';
 
 void main(List<String> args) {
-  String currentDir;
+  late String currentDir;
   setUpAll(() {
     currentDir = Directory.current.path.replaceAll(r'\', r'/');
     if (!currentDir.startsWith(r'/')) currentDir = '/$currentDir';
diff --git a/pkg/sourcemap_testing/lib/src/stepping_helper.dart b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
index 9392f77..cd4651e 100644
--- a/pkg/sourcemap_testing/lib/src/stepping_helper.dart
+++ b/pkg/sourcemap_testing/lib/src/stepping_helper.dart
@@ -89,7 +89,7 @@
       .map((entry) => '${entry.line}:${entry.column}')
       .toSet();
 
-  List<String> expectedStops = [];
+  List<String?> expectedStops = [];
   for (Annotation annotation in code.annotations.where((annotation) =>
       annotation.text.trim().startsWith('s:') ||
       annotation.text.trim().startsWith('sl:') ||
@@ -148,7 +148,7 @@
 
 void _checkRecordedStops(
     List<String> recordStops,
-    List<String> expectedStops,
+    List<String?> expectedStops,
     List<List<String>?> noBreaksStart,
     List<List<String>?> noBreaksEnd,
     bool debug) {
@@ -166,7 +166,8 @@
   for (String recorded in recordStops) {
     stopNumber++;
     if (expectedIndex == expectedStops.length) break;
-    if ('$recorded:'.contains(expectedStops[expectedIndex])) {
+    var expectedStop = expectedStops[expectedIndex];
+    if (expectedStop != null && '$recorded:'.contains(expectedStop)) {
       ++expectedIndex;
       if (noBreaksStart.length > expectedIndex &&
           noBreaksStart[expectedIndex] != null) {
diff --git a/runtime/vm/malloc_hooks_ia32.cc b/runtime/vm/malloc_hooks_ia32.cc
index 2b7a371..0572ac0 100644
--- a/runtime/vm/malloc_hooks_ia32.cc
+++ b/runtime/vm/malloc_hooks_ia32.cc
@@ -11,9 +11,9 @@
 namespace dart {
 
 #if defined(DEBUG)
-const intptr_t kSkipCount = 6;
+const intptr_t kSkipCount = 7;
 #elif !(defined(PRODUCT) || defined(DEBUG))
-const intptr_t kSkipCount = 5;
+const intptr_t kSkipCount = 6;
 #endif
 
 }  // namespace dart
diff --git a/tools/VERSION b/tools/VERSION
index 9764d09..ba74c8a 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 18
 PATCH 0
-PRERELEASE 220
+PRERELEASE 221
 PRERELEASE_PATCH 0
\ No newline at end of file