[dart2js] Migrate serialization.dart to nnbd and remove temp migration files.

Change-Id: I109c219fa0cc989ac1f3eea6b5d6de0b0cbb7d22
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/249746
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
diff --git a/pkg/compiler/lib/src/closure.dart b/pkg/compiler/lib/src/closure.dart
index 79f5e59..e3ba5f5 100644
--- a/pkg/compiler/lib/src/closure.dart
+++ b/pkg/compiler/lib/src/closure.dart
@@ -9,7 +9,7 @@
 import 'elements/entities.dart';
 import 'js_model/closure.dart';
 import 'js_model/element_map.dart';
-import 'serialization/serialization_interfaces.dart';
+import 'serialization/serialization.dart';
 
 export 'closure_migrated.dart'
     show
diff --git a/pkg/compiler/lib/src/common/codegen.dart b/pkg/compiler/lib/src/common/codegen.dart
index 67f0c30..1d64607 100644
--- a/pkg/compiler/lib/src/common/codegen.dart
+++ b/pkg/compiler/lib/src/common/codegen.dart
@@ -28,7 +28,7 @@
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../js_model/type_recipe.dart' show TypeRecipe;
 import '../native/behavior.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../ssa/ssa.dart';
 import '../universe/feature.dart';
 import '../universe/selector.dart';
diff --git a/pkg/compiler/lib/src/compiler.dart b/pkg/compiler/lib/src/compiler.dart
index b617621..5fdd14b 100644
--- a/pkg/compiler/lib/src/compiler.dart
+++ b/pkg/compiler/lib/src/compiler.dart
@@ -54,8 +54,8 @@
 import 'phase/load_kernel.dart' as load_kernel;
 import 'phase/modular_analysis.dart' as modular_analysis;
 import 'resolution/enqueuer.dart';
+import 'serialization/serialization.dart';
 import 'serialization/task.dart';
-import 'serialization/serialization_interfaces.dart' show DataSourceIndices;
 import 'serialization/strategies.dart';
 import 'universe/selector.dart' show Selector;
 import 'universe/codegen_world_builder.dart';
diff --git a/pkg/compiler/lib/src/deferred_load/output_unit.dart b/pkg/compiler/lib/src/deferred_load/output_unit.dart
index 360c64e..a116e6f 100644
--- a/pkg/compiler/lib/src/deferred_load/output_unit.dart
+++ b/pkg/compiler/lib/src/deferred_load/output_unit.dart
@@ -8,7 +8,7 @@
 import '../constants/values.dart'
     show ConstantValue, DeferredGlobalConstantValue;
 import '../elements/entities.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../options.dart';
 
 /// A "hunk" of the program that will be loaded whenever one of its [imports]
diff --git a/pkg/compiler/lib/src/elements/entities.dart b/pkg/compiler/lib/src/elements/entities.dart
index e55bd41..93a6851 100644
--- a/pkg/compiler/lib/src/elements/entities.dart
+++ b/pkg/compiler/lib/src/elements/entities.dart
@@ -8,7 +8,7 @@
 
 // TODO(48820): Spannable was imported from `../common.dart`.
 import '../diagnostics/spannable.dart' show Spannable;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/call_structure.dart' show CallStructure;
 import '../util/util.dart';
 import 'names.dart';
diff --git a/pkg/compiler/lib/src/elements/types.dart b/pkg/compiler/lib/src/elements/types.dart
index 47e94c1..3b9b9c6 100644
--- a/pkg/compiler/lib/src/elements/types.dart
+++ b/pkg/compiler/lib/src/elements/types.dart
@@ -5,7 +5,7 @@
 import '../common/elements.dart' show CommonElements;
 import '../common/names.dart';
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart' show equalElements, equalSets, identicalElements;
 import 'entities.dart';
 
diff --git a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
index 9856cc6..ed10dc8 100644
--- a/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
+++ b/pkg/compiler/lib/src/inferrer/abstract_value_domain.dart
@@ -9,7 +9,7 @@
 import '../elements/names.dart';
 import '../elements/types.dart' show DartType;
 import '../ir/class_relation.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 
 /// Enum-like values used for reporting known and unknown truth values.
diff --git a/pkg/compiler/lib/src/inferrer/engine.dart b/pkg/compiler/lib/src/inferrer/engine.dart
index 58d80d5..9e9a8d9 100644
--- a/pkg/compiler/lib/src/inferrer/engine.dart
+++ b/pkg/compiler/lib/src/inferrer/engine.dart
@@ -24,7 +24,7 @@
 import '../js_model/locals.dart';
 import '../native/behavior.dart';
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
 import '../universe/side_effects.dart';
diff --git a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
index b2fea8e..998b848 100644
--- a/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
+++ b/pkg/compiler/lib/src/inferrer/powersets/powersets.dart
@@ -9,7 +9,7 @@
 import '../../elements/names.dart';
 import '../../elements/types.dart' show DartType;
 import '../../ir/class_relation.dart';
-import '../../serialization/serialization_interfaces.dart';
+import '../../serialization/serialization.dart';
 import '../../universe/selector.dart';
 import '../../universe/world_builder.dart';
 import '../../universe/use.dart';
diff --git a/pkg/compiler/lib/src/inferrer/trivial.dart b/pkg/compiler/lib/src/inferrer/trivial.dart
index 2d9590b..fd2d10b 100644
--- a/pkg/compiler/lib/src/inferrer/trivial.dart
+++ b/pkg/compiler/lib/src/inferrer/trivial.dart
@@ -9,7 +9,7 @@
 import '../elements/names.dart';
 import '../elements/types.dart' show DartType;
 import '../ir/class_relation.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
 import '../universe/use.dart';
diff --git a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
index da421b9..cdccaa4 100644
--- a/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
+++ b/pkg/compiler/lib/src/inferrer/typemasks/masks.dart
@@ -15,7 +15,7 @@
 import '../../elements/names.dart';
 import '../../elements/types.dart';
 import '../../ir/class_relation.dart';
-import '../../serialization/serialization_interfaces.dart';
+import '../../serialization/serialization.dart';
 import '../../universe/class_hierarchy.dart';
 import '../../universe/selector.dart' show Selector;
 import '../../universe/use.dart' show DynamicUse;
diff --git a/pkg/compiler/lib/src/inferrer/types.dart b/pkg/compiler/lib/src/inferrer/types.dart
index c36483f..8705fb2 100644
--- a/pkg/compiler/lib/src/inferrer/types.dart
+++ b/pkg/compiler/lib/src/inferrer/types.dart
@@ -20,7 +20,7 @@
 import '../js_model/js_world.dart';
 import '../js_model/locals.dart';
 import '../serialization/deferrable.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/selector.dart' show Selector;
 import '../world.dart' show JClosedWorld;
 import 'abstract_value_domain.dart';
diff --git a/pkg/compiler/lib/src/inferrer/wrapped.dart b/pkg/compiler/lib/src/inferrer/wrapped.dart
index 21a7473..21717cb 100644
--- a/pkg/compiler/lib/src/inferrer/wrapped.dart
+++ b/pkg/compiler/lib/src/inferrer/wrapped.dart
@@ -9,7 +9,7 @@
 import '../elements/names.dart';
 import '../elements/types.dart' show DartType;
 import '../ir/class_relation.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 import '../universe/world_builder.dart';
 import '../universe/use.dart';
diff --git a/pkg/compiler/lib/src/io/position_information.dart b/pkg/compiler/lib/src/io/position_information.dart
index 08b07ae..1270cab 100644
--- a/pkg/compiler/lib/src/io/position_information.dart
+++ b/pkg/compiler/lib/src/io/position_information.dart
@@ -11,7 +11,7 @@
 import '../js/js.dart' as js;
 import '../js/js_debug.dart';
 import '../js/js_source_mapping.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart';
 import 'code_output.dart' show BufferedCodeOutput;
 import 'source_information.dart';
diff --git a/pkg/compiler/lib/src/io/source_information.dart b/pkg/compiler/lib/src/io/source_information.dart
index bbf7969..740d8298 100644
--- a/pkg/compiler/lib/src/io/source_information.dart
+++ b/pkg/compiler/lib/src/io/source_information.dart
@@ -8,7 +8,7 @@
 import '../common.dart';
 import '../elements/entities.dart';
 import '../js/js.dart' show JavaScriptNodeSourceInformation;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/call_structure.dart';
 import 'source_file.dart';
 import 'position_information.dart';
diff --git a/pkg/compiler/lib/src/ir/impact.dart b/pkg/compiler/lib/src/ir/impact.dart
index 102d6ac..e1e7473 100644
--- a/pkg/compiler/lib/src/ir/impact.dart
+++ b/pkg/compiler/lib/src/ir/impact.dart
@@ -5,7 +5,7 @@
 import 'package:kernel/ast.dart' as ir;
 import 'package:kernel/type_environment.dart' as ir;
 
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import 'class_relation.dart';
 import 'constants.dart';
 import 'impact_data.dart' show ImpactData;
diff --git a/pkg/compiler/lib/src/ir/impact_data.dart b/pkg/compiler/lib/src/ir/impact_data.dart
index 003a336..9df399e 100644
--- a/pkg/compiler/lib/src/ir/impact_data.dart
+++ b/pkg/compiler/lib/src/ir/impact_data.dart
@@ -14,7 +14,7 @@
 import '../kernel/element_map_interfaces.dart'
     show KernelToElementMapForImpactData;
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/enumset.dart';
 import 'class_relation.dart';
 import 'constants.dart';
diff --git a/pkg/compiler/lib/src/ir/modular.dart b/pkg/compiler/lib/src/ir/modular.dart
index 956a0e0..4713bbe 100644
--- a/pkg/compiler/lib/src/ir/modular.dart
+++ b/pkg/compiler/lib/src/ir/modular.dart
@@ -17,7 +17,7 @@
 import '../ir/static_type.dart';
 import '../js_backend/annotations.dart';
 import '../kernel/element_map.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/enumset.dart';
 import 'annotations.dart';
 import 'impact.dart';
diff --git a/pkg/compiler/lib/src/ir/static_type_cache.dart b/pkg/compiler/lib/src/ir/static_type_cache.dart
index 92e0023..3a4da89 100644
--- a/pkg/compiler/lib/src/ir/static_type_cache.dart
+++ b/pkg/compiler/lib/src/ir/static_type_cache.dart
@@ -4,7 +4,7 @@
 
 import 'package:kernel/ast.dart' as ir;
 
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 
 class StaticTypeCache {
   static const String tag = 'static-type-cache';
diff --git a/pkg/compiler/lib/src/js_backend/annotations.dart b/pkg/compiler/lib/src/js_backend/annotations.dart
index 1736e2a..8460a64 100644
--- a/pkg/compiler/lib/src/js_backend/annotations.dart
+++ b/pkg/compiler/lib/src/js_backend/annotations.dart
@@ -12,7 +12,7 @@
 import '../ir/util.dart';
 import '../kernel/dart2js_target.dart';
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/enumset.dart';
 
 class PragmaAnnotation {
diff --git a/pkg/compiler/lib/src/js_backend/backend_usage.dart b/pkg/compiler/lib/src/js_backend/backend_usage.dart
index 37662b2..1b408f8 100644
--- a/pkg/compiler/lib/src/js_backend/backend_usage.dart
+++ b/pkg/compiler/lib/src/js_backend/backend_usage.dart
@@ -9,7 +9,7 @@
 import '../ir/runtime_type_analysis.dart';
 import '../kernel/kernel_strategy_migrated.dart'
     show KernelFrontendStrategyForBackendUsage;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/feature.dart';
 import '../util/util.dart' show Setlet;
 import 'backend_impact.dart';
diff --git a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
index dc85fab..2e24fe1 100644
--- a/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
+++ b/pkg/compiler/lib/src/js_backend/deferred_holder_expression.dart
@@ -10,7 +10,7 @@
 import '../common/elements.dart' show JCommonElements;
 import '../elements/entities.dart';
 import '../js/js.dart' as js;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart';
 import '../js_emitter/model.dart';
 import '../constants/values.dart' show ConstantValue;
diff --git a/pkg/compiler/lib/src/js_backend/field_analysis.dart b/pkg/compiler/lib/src/js_backend/field_analysis.dart
index 976fbf3..5cc3a4b 100644
--- a/pkg/compiler/lib/src/js_backend/field_analysis.dart
+++ b/pkg/compiler/lib/src/js_backend/field_analysis.dart
@@ -19,7 +19,7 @@
 import '../kernel/kelements.dart' show KClass, KField, KConstructor;
 import '../kernel/kernel_world.dart';
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/member_usage.dart';
 
 /// AllocatorAnalysis
diff --git a/pkg/compiler/lib/src/js_backend/inferred_data.dart b/pkg/compiler/lib/src/js_backend/inferred_data.dart
index 6e96121..84a067a 100644
--- a/pkg/compiler/lib/src/js_backend/inferred_data.dart
+++ b/pkg/compiler/lib/src/js_backend/inferred_data.dart
@@ -9,7 +9,7 @@
 import '../common.dart';
 import '../elements/entities.dart';
 import '../inferrer/abstract_value_domain.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 import '../universe/side_effects.dart';
 import '../world.dart';
diff --git a/pkg/compiler/lib/src/js_backend/interceptor_data.dart b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
index 32cadd1..299dd02 100644
--- a/pkg/compiler/lib/src/js_backend/interceptor_data.dart
+++ b/pkg/compiler/lib/src/js_backend/interceptor_data.dart
@@ -13,7 +13,7 @@
 import '../elements/types.dart';
 import '../inferrer/abstract_value_domain.dart';
 import '../js/js.dart' as jsAst;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/class_set.dart';
 import '../universe/selector.dart';
 import '../world.dart' show JClosedWorld;
diff --git a/pkg/compiler/lib/src/js_backend/native_data.dart b/pkg/compiler/lib/src/js_backend/native_data.dart
index 6bfc3f0..56cabfd 100644
--- a/pkg/compiler/lib/src/js_backend/native_data.dart
+++ b/pkg/compiler/lib/src/js_backend/native_data.dart
@@ -15,7 +15,7 @@
 import '../js_model/js_to_frontend_map.dart' show identity, JsToFrontendMap;
 import '../kernel/element_map.dart';
 import '../native/behavior.dart' show NativeBehavior;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart';
 
 import 'native_data_interfaces.dart' as interfaces;
diff --git a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
index 8069eda..88afdee 100644
--- a/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
+++ b/pkg/compiler/lib/src/js_backend/no_such_method_registry.dart
@@ -10,7 +10,7 @@
 import '../elements/entities.dart';
 import '../inferrer/types.dart' show GlobalTypeInferenceResults;
 import '../kernel/no_such_method_resolver.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 
 /// [NoSuchMethodRegistry] and [NoSuchMethodData] categorizes `noSuchMethod`
 /// implementations.
diff --git a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
index 61c15b4..9791f4a 100644
--- a/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
+++ b/pkg/compiler/lib/src/js_backend/runtime_types_resolution.dart
@@ -16,7 +16,7 @@
 import '../kernel/kelements.dart';
 import '../kernel/kernel_world.dart';
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/class_hierarchy.dart';
 import '../universe/class_set.dart';
 import '../universe/feature.dart';
diff --git a/pkg/compiler/lib/src/js_backend/string_reference.dart b/pkg/compiler/lib/src/js_backend/string_reference.dart
index a07a756..949aec8 100644
--- a/pkg/compiler/lib/src/js_backend/string_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/string_reference.dart
@@ -62,7 +62,7 @@
 
 import '../constants/values.dart' show StringConstantValue;
 import '../js/js.dart' as js;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart' show Hashing;
 import 'frequency_assignment.dart';
 import 'name_sequence.dart';
diff --git a/pkg/compiler/lib/src/js_backend/type_reference.dart b/pkg/compiler/lib/src/js_backend/type_reference.dart
index 5bfc9ef..2f4bc25 100644
--- a/pkg/compiler/lib/src/js_backend/type_reference.dart
+++ b/pkg/compiler/lib/src/js_backend/type_reference.dart
@@ -76,7 +76,7 @@
         TypeExpressionRecipe,
         SingletonTypeEnvironmentRecipe,
         FullTypeEnvironmentRecipe;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart' show Hashing;
 import 'frequency_assignment.dart';
 import 'namer.dart';
diff --git a/pkg/compiler/lib/src/js_model/closure.dart b/pkg/compiler/lib/src/js_model/closure.dart
index 36372e51..5cd2856 100644
--- a/pkg/compiler/lib/src/js_model/closure.dart
+++ b/pkg/compiler/lib/src/js_model/closure.dart
@@ -19,7 +19,7 @@
 import '../js_model/env.dart';
 import '../ordered_typeset.dart';
 import '../serialization/deferrable.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/selector.dart';
 import 'elements.dart';
 import 'closure_migrated.dart' as migrated;
diff --git a/pkg/compiler/lib/src/js_model/closure_migrated.dart b/pkg/compiler/lib/src/js_model/closure_migrated.dart
index fc19dcb..ab35781 100644
--- a/pkg/compiler/lib/src/js_model/closure_migrated.dart
+++ b/pkg/compiler/lib/src/js_model/closure_migrated.dart
@@ -2,7 +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.
 
-import 'package:compiler/src/serialization/serialization_interfaces.dart';
+import 'package:compiler/src/serialization/serialization.dart';
 
 import 'package:kernel/ast.dart' as ir;
 
diff --git a/pkg/compiler/lib/src/js_model/element_map.dart b/pkg/compiler/lib/src/js_model/element_map.dart
index 1e0fdd8..7350f29 100644
--- a/pkg/compiler/lib/src/js_model/element_map.dart
+++ b/pkg/compiler/lib/src/js_model/element_map.dart
@@ -19,7 +19,7 @@
 import '../js_model/class_type_variable_access.dart';
 import '../js_model/elements.dart' show JGeneratorBody;
 import '../native/behavior.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/call_structure.dart';
 import '../universe/selector.dart';
 import '../world.dart';
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 80ff522..7836deb 100644
--- a/pkg/compiler/lib/src/js_model/element_map_impl.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_impl.dart
@@ -46,7 +46,7 @@
 import '../native/behavior.dart';
 import '../options.dart';
 import '../ordered_typeset.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/call_structure.dart';
 import '../universe/member_usage.dart';
 import '../universe/selector.dart';
diff --git a/pkg/compiler/lib/src/js_model/element_map_migrated.dart b/pkg/compiler/lib/src/js_model/element_map_migrated.dart
index b7328d8..fb5417f 100644
--- a/pkg/compiler/lib/src/js_model/element_map_migrated.dart
+++ b/pkg/compiler/lib/src/js_model/element_map_migrated.dart
@@ -10,7 +10,7 @@
 import '../elements/types.dart';
 import '../ir/util.dart';
 import '../serialization/deferrable.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import 'element_map_interfaces.dart';
 
 // TODO(48820): Merge back into element_map.dart when migration is done.
diff --git a/pkg/compiler/lib/src/js_model/elements.dart b/pkg/compiler/lib/src/js_model/elements.dart
index fd5644e..e5f8780 100644
--- a/pkg/compiler/lib/src/js_model/elements.dart
+++ b/pkg/compiler/lib/src/js_model/elements.dart
@@ -9,7 +9,7 @@
 import '../elements/indexed.dart';
 import '../elements/names.dart';
 import '../elements/types.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/class_set.dart' show ClassHierarchyNodesMapKey;
 import 'closure_migrated.dart';
 
diff --git a/pkg/compiler/lib/src/js_model/env.dart b/pkg/compiler/lib/src/js_model/env.dart
index e1e7e2d..0bf7e80 100644
--- a/pkg/compiler/lib/src/js_model/env.dart
+++ b/pkg/compiler/lib/src/js_model/env.dart
@@ -18,7 +18,7 @@
 import '../js_model/class_type_variable_access.dart';
 import '../ordered_typeset.dart';
 import '../serialization/deferrable.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import 'closure.dart';
 import 'element_map.dart';
 import 'element_map_impl.dart';
diff --git a/pkg/compiler/lib/src/js_model/js_strategy.dart b/pkg/compiler/lib/src/js_model/js_strategy.dart
index 7014261..54a43e6 100644
--- a/pkg/compiler/lib/src/js_model/js_strategy.dart
+++ b/pkg/compiler/lib/src/js_model/js_strategy.dart
@@ -47,10 +47,7 @@
 import '../native/behavior.dart';
 import '../native/enqueue.dart';
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart'
-    hide DataSinkWriter, DataSourceReader;
-import '../serialization/serialization.dart'
-    show DataSinkWriter, DataSourceReader;
+import '../serialization/serialization.dart';
 import '../ssa/builder.dart';
 import '../ssa/nodes.dart';
 import '../ssa/ssa.dart';
diff --git a/pkg/compiler/lib/src/js_model/js_world.dart b/pkg/compiler/lib/src/js_model/js_world.dart
index 92361b3..afdce46 100644
--- a/pkg/compiler/lib/src/js_model/js_world.dart
+++ b/pkg/compiler/lib/src/js_model/js_world.dart
@@ -30,7 +30,7 @@
 import '../js_backend/runtime_types_resolution.dart';
 import '../ordered_typeset.dart';
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/class_hierarchy.dart';
 import '../universe/class_set.dart';
 import '../universe/function_set.dart' show FunctionSet;
diff --git a/pkg/compiler/lib/src/js_model/locals.dart b/pkg/compiler/lib/src/js_model/locals.dart
index 70820da..bfa00b1 100644
--- a/pkg/compiler/lib/src/js_model/locals.dart
+++ b/pkg/compiler/lib/src/js_model/locals.dart
@@ -13,7 +13,7 @@
 import '../elements/jumps.dart';
 import '../elements/types.dart';
 import '../serialization/deferrable.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 
 import 'element_map_interfaces.dart';
 import 'element_map_migrated.dart';
diff --git a/pkg/compiler/lib/src/js_model/type_recipe.dart b/pkg/compiler/lib/src/js_model/type_recipe.dart
index ad26ddc..9214969 100644
--- a/pkg/compiler/lib/src/js_model/type_recipe.dart
+++ b/pkg/compiler/lib/src/js_model/type_recipe.dart
@@ -8,7 +8,7 @@
 import '../elements/types.dart';
 import '../diagnostics/invariant.dart';
 import '../diagnostics/spannable.dart' show CURRENT_ELEMENT_SPANNABLE;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart' show Hashing;
 
 abstract class TypeRecipeDomain {
diff --git a/pkg/compiler/lib/src/native/behavior.dart b/pkg/compiler/lib/src/native/behavior.dart
index 563f4a5..4832afb 100644
--- a/pkg/compiler/lib/src/native/behavior.dart
+++ b/pkg/compiler/lib/src/native/behavior.dart
@@ -11,7 +11,7 @@
 import '../js_backend/native_data_interfaces.dart' show NativeBasicData;
 import '../js_model/js_to_frontend_map.dart' show JsToFrontendMap;
 import '../options.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../universe/side_effects.dart' show SideEffects;
 import 'js.dart';
 
diff --git a/pkg/compiler/lib/src/ordered_typeset.dart b/pkg/compiler/lib/src/ordered_typeset.dart
index d8e8b07..ac2f4a7 100644
--- a/pkg/compiler/lib/src/ordered_typeset.dart
+++ b/pkg/compiler/lib/src/ordered_typeset.dart
@@ -10,7 +10,7 @@
 import 'common.dart';
 import 'elements/entities.dart';
 import 'elements/types.dart';
-import 'serialization/serialization_interfaces.dart';
+import 'serialization/serialization.dart';
 
 /// An ordered set of the supertypes of a class. The supertypes of a class are
 /// ordered by decreasing hierarchy depth and by the order they are extended,
diff --git a/pkg/compiler/lib/src/serialization/binary_source.dart b/pkg/compiler/lib/src/serialization/binary_source.dart
index 3d8ba61..f27ee1b 100644
--- a/pkg/compiler/lib/src/serialization/binary_source.dart
+++ b/pkg/compiler/lib/src/serialization/binary_source.dart
@@ -5,7 +5,7 @@
 import 'dart:convert';
 import 'dart:typed_data';
 import 'data_source.dart';
-import 'serialization_interfaces.dart' show StringInterner;
+import 'serialization.dart' show StringInterner;
 
 /// [DataSource] that reads data from a sequence of bytes.
 ///
diff --git a/pkg/compiler/lib/src/serialization/deferrable.dart b/pkg/compiler/lib/src/serialization/deferrable.dart
index a2074aa..50f220d 100644
--- a/pkg/compiler/lib/src/serialization/deferrable.dart
+++ b/pkg/compiler/lib/src/serialization/deferrable.dart
@@ -4,7 +4,7 @@
 
 import 'dart:collection';
 
-import 'package:compiler/src/serialization/serialization_interfaces.dart';
+import 'package:compiler/src/serialization/serialization.dart';
 
 /// Interface for data that may be deserialized lazily.
 ///
diff --git a/pkg/compiler/lib/src/serialization/helpers.dart b/pkg/compiler/lib/src/serialization/helpers.dart
index 2e395b7..a2e2a26 100644
--- a/pkg/compiler/lib/src/serialization/helpers.dart
+++ b/pkg/compiler/lib/src/serialization/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
-
 part of 'serialization.dart';
 
 /// Enum used for identifying [ir.TreeNode] subclasses in serialization.
@@ -119,7 +117,7 @@
       ..addAll(node.typeParameters);
     _sink.writeInt(node.typeParameters.length);
     for (ir.TypeParameter parameter in node.typeParameters) {
-      _sink.writeString(parameter.name);
+      _sink.writeString(parameter.name!);
       _sink._writeDartTypeNode(parameter.bound, functionTypeVariables);
       _sink._writeDartTypeNode(parameter.defaultType, functionTypeVariables);
     }
diff --git a/pkg/compiler/lib/src/serialization/indexed_sink_source.dart b/pkg/compiler/lib/src/serialization/indexed_sink_source.dart
index 0eedc2c..58d1849 100644
--- a/pkg/compiler/lib/src/serialization/indexed_sink_source.dart
+++ b/pkg/compiler/lib/src/serialization/indexed_sink_source.dart
@@ -4,7 +4,7 @@
 
 import 'data_sink.dart';
 import 'data_source.dart';
-import 'serialization_interfaces.dart';
+import 'serialization.dart';
 
 abstract class IndexedSource<E> {
   E? read(E readValue());
@@ -153,7 +153,7 @@
 /// so that the indices are maintained. Since the read order is assumed to be
 /// consistent, the actual data is written at the first occurrence of the
 /// indexable element.
-class OrderedIndexedSink<E extends Object> implements IndexedSink<E> {
+class OrderedIndexedSink<E> implements IndexedSink<E> {
   final DataSink _sink;
   final Map<E?, int> cache;
 
@@ -194,7 +194,7 @@
 /// discovered we assume the data is written immediately after. Subsequent
 /// occurrences of that index then refer to the same value. Indices will appear
 /// in ascending order.
-class OrderedIndexedSource<E extends Object> implements IndexedSource<E> {
+class OrderedIndexedSource<E> implements IndexedSource<E> {
   final DataSource _source;
   final List<E?> cache;
 
diff --git a/pkg/compiler/lib/src/serialization/serialization.dart b/pkg/compiler/lib/src/serialization/serialization.dart
index 71c758f..5e61e49 100644
--- a/pkg/compiler/lib/src/serialization/serialization.dart
+++ b/pkg/compiler/lib/src/serialization/serialization.dart
@@ -2,15 +2,14 @@
 // 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 'dart:collection';
 import 'dart:typed_data';
 import 'package:kernel/ast.dart' as ir;
-import '../closure.dart';
+import '../closure_migrated.dart';
+import '../common.dart';
 import '../constants/constant_system.dart' as constant_system;
 import '../constants/values.dart';
 import '../deferred_load/output_unit.dart' show OutputUnit;
-import '../diagnostics/source_span.dart';
 import '../elements/entities.dart';
 import '../elements/indexed.dart';
 import '../elements/types.dart';
@@ -18,7 +17,7 @@
 import '../ir/constants.dart';
 import '../ir/static_type_base.dart';
 import '../js/js.dart' as js;
-import '../js_model/closure.dart';
+import '../js_model/closure_migrated.dart';
 import '../js_model/locals.dart';
 import '../js_model/type_recipe.dart' show TypeRecipe;
 
@@ -27,19 +26,6 @@
 import 'data_source.dart';
 import 'deferrable.dart';
 import 'member_data.dart';
-import 'serialization_interfaces.dart' as migrated
-    show
-        CodegenReader,
-        CodegenWriter,
-        DataSourceReader,
-        DataSourceIndices,
-        DataSourceTypeIndices,
-        DataSinkWriter,
-        EntityLookup,
-        EntityReader,
-        EntityWriter,
-        LocalLookup,
-        ValueInterner;
 import 'indexed_sink_source.dart';
 import 'tags.dart';
 
@@ -49,9 +35,133 @@
 export 'object_sink.dart';
 export 'object_source.dart';
 export 'tags.dart';
-export 'serialization_interfaces.dart'
-    show CodegenReader, EntityLookup, EntityReader, EntityWriter;
 
 part 'sink.dart';
 part 'source.dart';
 part 'helpers.dart';
+
+abstract class StringInterner {
+  String internString(String string);
+}
+
+class ValueInterner {
+  final Map<DartType, DartType> _dartTypeMap = HashMap();
+  final Map<ir.DartType?, ir.DartType?> _dartTypeNodeMap = HashMap();
+
+  DartType internDartType(DartType dartType) {
+    return _dartTypeMap[dartType] ??= dartType;
+  }
+
+  ir.DartType? internDartTypeNode(ir.DartType? dartType) {
+    return _dartTypeNodeMap[dartType] ??= dartType;
+  }
+}
+
+/// Data class representing cache information for a given [T] which can be
+/// passed from a [DataSourceReader] to other [DataSourceReader]s and [DataSinkWriter]s.
+class DataSourceTypeIndices<E, T> {
+  Map<E, int> get cache => _cache ??= source.reshapeCacheAsMap(_getValue);
+
+  final E Function(T? value)? _getValue;
+  Map<E, int>? _cache;
+  final IndexedSource<T> source;
+
+  /// Uses the cache from the provided [source] and reshapes it if necessary
+  /// to create a lookup map of cached entities. If [_getValue] is provided,
+  /// the function will be used to map the cached entities into lookup keys.
+  DataSourceTypeIndices(this.source, [this._getValue]) {
+    assert(_getValue != null || T == E);
+  }
+}
+
+/// Data class representing the sum of all cache information for a given
+/// [DataSourceReader].
+class DataSourceIndices {
+  final Map<Type, DataSourceTypeIndices> caches = {};
+  final DataSourceReader? previousSourceReader;
+
+  DataSourceIndices(this.previousSourceReader);
+}
+
+/// Interface used for looking up locals by index during deserialization.
+abstract class LocalLookup {
+  Local getLocalByIndex(MemberEntity memberContext, int index);
+}
+
+/// Interface used for reading codegen only data during deserialization.
+abstract class CodegenReader {
+  AbstractValue readAbstractValue(DataSourceReader source);
+  OutputUnit readOutputUnitReference(DataSourceReader source);
+  js.Node readJsNode(DataSourceReader source);
+  TypeRecipe readTypeRecipe(DataSourceReader source);
+}
+
+/// Interface used for writing codegen only data during serialization.
+abstract class CodegenWriter {
+  void writeAbstractValue(DataSinkWriter sink, AbstractValue value);
+  void writeOutputUnitReference(DataSinkWriter sink, OutputUnit value);
+  void writeJsNode(DataSinkWriter sink, js.Node node);
+  void writeTypeRecipe(DataSinkWriter sink, TypeRecipe recipe);
+}
+
+/// Interface used for looking up entities by index during deserialization.
+abstract class EntityLookup {
+  /// Returns the indexed library corresponding to [index].
+  IndexedLibrary getLibraryByIndex(int index);
+
+  /// Returns the indexed class corresponding to [index].
+  IndexedClass getClassByIndex(int index);
+
+  /// Returns the indexed member corresponding to [index].
+  IndexedMember getMemberByIndex(int index);
+
+  /// Returns the indexed type variable corresponding to [index].
+  IndexedTypeVariable getTypeVariableByIndex(int index);
+}
+
+/// Decoding strategy for entity references.
+class EntityReader {
+  const EntityReader();
+
+  IndexedLibrary readLibraryFromDataSource(
+      DataSourceReader source, EntityLookup entityLookup) {
+    return entityLookup.getLibraryByIndex(source.readInt());
+  }
+
+  IndexedClass readClassFromDataSource(
+      DataSourceReader source, EntityLookup entityLookup) {
+    return entityLookup.getClassByIndex(source.readInt());
+  }
+
+  IndexedMember readMemberFromDataSource(
+      DataSourceReader source, EntityLookup entityLookup) {
+    return entityLookup.getMemberByIndex(source.readInt());
+  }
+
+  IndexedTypeVariable readTypeVariableFromDataSource(
+      DataSourceReader source, EntityLookup entityLookup) {
+    return entityLookup.getTypeVariableByIndex(source.readInt());
+  }
+}
+
+/// Encoding strategy for entity references.
+class EntityWriter {
+  const EntityWriter();
+
+  void writeLibraryToDataSink(DataSinkWriter sink, IndexedLibrary value) {
+    sink.writeInt(value.libraryIndex);
+  }
+
+  void writeClassToDataSink(DataSinkWriter sink, IndexedClass value) {
+    sink.writeInt(value.classIndex);
+  }
+
+  void writeMemberToDataSink(DataSinkWriter sink, IndexedMember value) {
+    sink.writeInt(value.memberIndex);
+  }
+
+  void writeTypeVariableToDataSink(
+      DataSinkWriter sink, IndexedTypeVariable value) {
+    sink.writeInt(value.typeVariableIndex);
+  }
+}
diff --git a/pkg/compiler/lib/src/serialization/serialization_interfaces.dart b/pkg/compiler/lib/src/serialization/serialization_interfaces.dart
deleted file mode 100644
index cbe1c3f..0000000
--- a/pkg/compiler/lib/src/serialization/serialization_interfaces.dart
+++ /dev/null
@@ -1,427 +0,0 @@
-// Copyright (c) 2022, the Dart project authors.  Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE file.
-
-import 'dart:collection';
-
-import 'package:kernel/ast.dart' as ir
-    show
-        Class,
-        DartType,
-        Library,
-        LibraryDependency,
-        Member,
-        Name,
-        TreeNode,
-        TypeParameter;
-
-import '../common.dart';
-import '../constants/values.dart' show ConstantValue;
-import '../deferred_load/output_unit.dart';
-import '../elements/entities.dart';
-import '../elements/indexed.dart';
-import '../elements/types.dart' show DartType;
-import '../inferrer/abstract_value_domain.dart' show AbstractValue;
-import '../js/js.dart' as js;
-import '../js_model/type_recipe.dart';
-import 'deferrable.dart';
-import 'indexed_sink_source.dart';
-import 'member_data.dart' show ComponentLookup;
-
-export 'binary_sink.dart';
-export 'binary_source.dart';
-export 'member_data.dart' show ComponentLookup;
-export 'object_sink.dart';
-export 'object_source.dart';
-export 'tags.dart';
-
-abstract class StringInterner {
-  String internString(String string);
-}
-
-class ValueInterner {
-  final Map<DartType, DartType> _dartTypeMap = HashMap();
-  final Map<ir.DartType, ir.DartType> _dartTypeNodeMap = HashMap();
-
-  DartType internDartType(DartType dartType) {
-    return _dartTypeMap[dartType] ??= dartType;
-  }
-
-  ir.DartType internDartTypeNode(ir.DartType dartType) {
-    return _dartTypeNodeMap[dartType] ??= dartType;
-  }
-}
-
-/// NNBD-migrated interface for methods of DataSinkWriter.
-///
-/// This is a pure interface or facade for DataSinkWriter.
-///
-/// This interface has the same name as the implementation class. Using the same
-/// name allows some libraries that use DataSinkWriter to be migrated before the
-/// serialization library by changing
-///
-///     import '../serialization/serialization.dart';
-///
-/// to:
-///
-///     import '../serialization/serialization_interfaces.dart';
-///
-/// Documentation of the methods can be found in source.dart.
-// TODO(sra): Copy documentation for methods?
-abstract class DataSinkWriter {
-  int get length;
-
-  void begin(String tag);
-  void end(Object tag);
-
-  void writeBool(bool value);
-  void writeInt(int value);
-  void writeIntOrNull(int? value);
-  void writeString(String value);
-  void writeStringOrNull(String? value);
-  void writeStringMap<V>(Map<String, V>? map, void f(V value),
-      {bool allowNull = false});
-  void writeStrings(Iterable<String>? values, {bool allowNull = false});
-  void writeEnum(dynamic value);
-  void writeUri(Uri value);
-
-  void writeMemberNode(ir.Member nvalue);
-  void writeMemberNodes(Iterable<ir.Member>? values, {bool allowNull = false});
-  void writeMemberNodeMap<V>(Map<ir.Member, V>? map, void f(V value),
-      {bool allowNull = false});
-
-  void writeName(ir.Name value);
-  void writeLibraryDependencyNode(ir.LibraryDependency value);
-  void writeLibraryDependencyNodeOrNull(ir.LibraryDependency? value);
-
-  void writeTreeNode(ir.TreeNode value);
-  void writeTreeNodeOrNull(ir.TreeNode value);
-  void writeTreeNodes(Iterable<ir.TreeNode>? values, {bool allowNull = false});
-  void writeTreeNodeMap<V>(Map<ir.TreeNode, V> map, void f(V value));
-
-  void writeClassNode(ir.Class value);
-
-  // TODO(48820): 'covariant ClassEntity' is used below because the
-  // implementation takes IndexedClass. What this means is that in pre-NNBD
-  // code, the call site to the implementation DataSinkWriter has an implicit
-  // downcast from ClassEntity to IndexedClass. With NNND, these casts become
-  // explicit and quite tedious. It is cleaner to move the cast into the method,
-  // which is what 'covariant' achieves.
-  //
-  // If we want to retire this facade interface, we will have to make the
-  // DataSinkWriter implementation accept ClassEntity and manually check for
-  // IndexedClass. This is not necessarily a bad thing, since it opens the way
-  // for being able to serialize some non-indexed entities.
-
-  void writeClass(covariant ClassEntity value); // IndexedClass
-  void writeClassOrNull(covariant ClassEntity? value); // IndexedClass
-  void writeClasses(Iterable<ClassEntity>? values, {bool allowNull = false});
-  void writeClassMap<V>(Map<ClassEntity, V>? map, void f(V value),
-      {bool allowNull = false});
-
-  void writeTypeVariable(
-      covariant TypeVariableEntity value); // IndexedTypeVariable
-
-  void writeMember(covariant MemberEntity member); // IndexMember
-  void writeMemberOrNull(covariant MemberEntity? member); // IndexMember
-  void writeMembers(Iterable<MemberEntity>? values, {bool allowNull = false});
-
-  void writeMemberMap<V>(
-      Map<MemberEntity, V>? map, void f(MemberEntity member, V value),
-      {bool allowNull = false});
-
-  void writeLibrary(covariant LibraryEntity value); // IndexedLibrary
-  void writeLibraryOrNull(covariant LibraryEntity? value); // IndexedLibrary
-  void writeLibraryMap<V>(Map<LibraryEntity, V>? map, void f(V value),
-      {bool allowNull = false});
-
-  void writeLibraryNode(ir.Library value);
-
-  void writeTypeRecipe(TypeRecipe value);
-
-  void writeDartTypeNode(ir.DartType value);
-  void writeDartTypeNodeOrNull(ir.DartType? value);
-  void writeDartTypeNodes(Iterable<ir.DartType>? values,
-      {bool allowNull = false});
-
-  void writeDartType(DartType value);
-  void writeDartTypeOrNull(DartType? value);
-  void writeDartTypesOrNull(Iterable<DartType>? values);
-  void writeDartTypes(Iterable<DartType> values);
-
-  void writeTypeParameterNode(ir.TypeParameter value);
-  void writeTypeParameterNodes(Iterable<ir.TypeParameter> values);
-
-  void writeTypeVariableMap<V>(
-      Map<IndexedTypeVariable, V> map, void f(V value));
-
-  void inMemberContext(ir.Member context, void f());
-  void writeTreeNodeMapInContext<V>(Map<ir.TreeNode, V>? map, void f(V value),
-      {bool allowNull = false});
-
-  void writeCached<E extends Object>(E? value, void f(E value));
-
-  void writeList<E extends Object>(Iterable<E>? values, void f(E value),
-      {bool allowNull = false});
-
-  void writeConstant(ConstantValue value);
-  void writeConstantOrNull(ConstantValue? value);
-  void writeConstantMap<V>(Map<ConstantValue, V>? map, void f(V value),
-      {bool allowNull = false});
-
-  void writeValueOrNull<E>(E? value, void f(E value));
-
-  void writeDoubleValue(double value);
-  void writeIntegerValue(int value);
-
-  void writeLocalOrNull(Local? local);
-  void writeLocalMap<V>(Map<Local, V> map, void f(V value));
-
-  void writeImport(ImportEntity import);
-  void writeImportOrNull(ImportEntity? import);
-  void writeImports(Iterable<ImportEntity>? values, {bool allowNull = false});
-  void writeImportMap<V>(Map<ImportEntity, V>? map, void f(V value),
-      {bool allowNull = false});
-
-  void writeAbstractValue(AbstractValue value);
-
-  void writeJsNodeOrNull(js.Node? value);
-
-  void writeSourceSpan(SourceSpan value);
-
-  void writeDeferrable(void f());
-}
-
-/// Migrated interface for methods of DataSourceReader.
-abstract class DataSourceReader {
-  int get length;
-  int get startOffset;
-  int get endOffset;
-
-  void registerComponentLookup(ComponentLookup componentLookup);
-  void registerLocalLookup(LocalLookup localLookup);
-  void registerEntityLookup(EntityLookup entityLookup);
-  void registerEntityReader(EntityReader reader);
-
-  void begin(String tag);
-  void end(String tag);
-
-  bool readBool();
-  int readInt();
-  int? readIntOrNull();
-  String readString();
-  String? readStringOrNull();
-  List<String>? readStrings({bool emptyAsNull = false});
-  Map<String, V>? readStringMap<V>(V f(), {bool emptyAsNull = false});
-  E readEnum<E>(List<E> values);
-  Uri readUri();
-
-  ir.Member readMemberNode();
-  List<E> readMemberNodes<E extends ir.Member>();
-  List<E>? readMemberNodesOrNull<E extends ir.Member>();
-  Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f());
-  Map<K, V>? readMemberNodeMapOrNull<K extends ir.Member, V>(V f());
-
-  ir.Name readName();
-  ir.LibraryDependency readLibraryDependencyNode();
-  ir.LibraryDependency readLibraryDependencyNodeOrNull();
-
-  ir.TreeNode readTreeNode();
-  ir.TreeNode? readTreeNodeOrNull();
-  List<E> readTreeNodes<E extends ir.TreeNode>();
-  List<E>? readTreeNodesOrNull<E extends ir.TreeNode>();
-  Map<K, V> readTreeNodeMap<K extends ir.TreeNode, V>(V f());
-  Map<K, V> readTreeNodeMapOrNull<K extends ir.TreeNode, V>(V f());
-
-  ir.Class readClassNode();
-
-  ClassEntity readClass(); // IndexedClass
-  ClassEntity? readClassOrNull(); // IndexedClass
-  List<E> readClasses<E extends ClassEntity>();
-  List<E>? readClassesOrNull<E extends ClassEntity>();
-  Map<K, V> readClassMap<K extends ClassEntity, V>(V f());
-  Map<K, V>? readClassMapOrNull<K extends ClassEntity, V>(V f());
-
-  TypeVariableEntity readTypeVariable(); // IndexedTypeVariable
-
-  MemberEntity readMember();
-  MemberEntity? readMemberOrNull();
-  List<E> readMembers<E extends MemberEntity>();
-  List<E>? readMembersOrNull<E extends MemberEntity>();
-  Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(MemberEntity member));
-  Map<K, V>? readMemberMapOrNull<K extends MemberEntity, V>(
-      V f(MemberEntity member));
-
-  LibraryEntity readLibrary(); // IndexedLibrary;
-  LibraryEntity? readLibraryOrNull(); // IndexedLibrary;
-  Map<K, V> readLibraryMap<K extends LibraryEntity, V>(V f());
-  Map<K, V>? readLibraryMapOrNull<K extends LibraryEntity, V>(V f());
-
-  ir.Library readLibraryNode();
-
-  TypeRecipe readTypeRecipe();
-
-  ir.DartType readDartTypeNode();
-  ir.DartType? readDartTypeNodeOrNull();
-  List<ir.DartType> readDartTypeNodes();
-  List<ir.DartType>? readDartTypeNodesOrNull();
-
-  DartType readDartType();
-  DartType? readDartTypeOrNull();
-  List<DartType> readDartTypes();
-  List<DartType>? readDartTypesOrNull();
-
-  Map<K, V> readTypeVariableMap<K extends IndexedTypeVariable, V>(V f());
-
-  ir.TypeParameter readTypeParameterNode();
-  List<ir.TypeParameter> readTypeParameterNodes();
-
-  T inMemberContext<T>(ir.Member context, T f());
-  Map<K, V> readTreeNodeMapInContext<K extends ir.TreeNode, V>(V f());
-  Map<K, V>? readTreeNodeMapInContextOrNull<K extends ir.TreeNode, V>(V f());
-
-  E readCached<E extends Object>(E f());
-  E? readCachedOrNull<E extends Object>(E f());
-
-  List<E> readList<E extends Object>(E f());
-  List<E>? readListOrNull<E extends Object>(E f());
-
-  ConstantValue readConstant();
-  ConstantValue? readConstantOrNull();
-  Map<K, V> readConstantMap<K extends ConstantValue, V>(V f());
-  Map<K, V>? readConstantMapOrNull<K extends ConstantValue, V>(V f());
-
-  E? readValueOrNull<E>(E f());
-
-  double readDoubleValue();
-  int readIntegerValue();
-
-  ImportEntity readImport();
-  ImportEntity? readImportOrNull();
-  List<ImportEntity> readImports();
-  List<ImportEntity>? readImportsOrNull();
-  Map<ImportEntity, V> readImportMap<V>(V f());
-  Map<ImportEntity, V>? readImportMapOrNull<V>(V f());
-
-  AbstractValue readAbstractValue();
-
-  js.Node? readJsNodeOrNull();
-
-  SourceSpan readSourceSpan();
-
-  Local? readLocalOrNull();
-  Map<K, V> readLocalMap<K extends Local, V>(V f());
-
-  E readWithSource<E>(DataSourceReader source, E f());
-  E readWithOffset<E>(int offset, E f());
-  Deferrable<E> readDeferrable<E>(E f(), {bool cacheData = true});
-}
-
-/// Data class representing cache information for a given [T] which can be
-/// passed from a [DataSourceReader] to other [DataSourceReader]s and [DataSinkWriter]s.
-class DataSourceTypeIndices<E, T> {
-  Map<E, int> get cache => _cache ??= source.reshapeCacheAsMap(_getValue);
-
-  final E Function(T? value)? _getValue;
-  Map<E, int>? _cache;
-  final IndexedSource<T> source;
-
-  /// Uses the cache from the provided [source] and reshapes it if necessary
-  /// to create a lookup map of cached entities. If [_getValue] is provided,
-  /// the function will be used to map the cached entities into lookup keys.
-  DataSourceTypeIndices(this.source, [this._getValue]) {
-    assert(_getValue != null || T == E);
-  }
-}
-
-/// Data class representing the sum of all cache information for a given
-/// [DataSourceReader].
-class DataSourceIndices {
-  final Map<Type, DataSourceTypeIndices> caches = {};
-  final DataSourceReader? previousSourceReader;
-
-  DataSourceIndices(this.previousSourceReader);
-}
-
-/// Interface used for looking up locals by index during deserialization.
-abstract class LocalLookup {
-  Local getLocalByIndex(MemberEntity memberContext, int index);
-}
-
-/// Interface used for reading codegen only data during deserialization.
-abstract class CodegenReader {
-  AbstractValue readAbstractValue(DataSourceReader source);
-  OutputUnit readOutputUnitReference(DataSourceReader source);
-  js.Node readJsNode(DataSourceReader source);
-  TypeRecipe readTypeRecipe(DataSourceReader source);
-}
-
-/// Interface used for writing codegen only data during serialization.
-abstract class CodegenWriter {
-  void writeAbstractValue(DataSinkWriter sink, AbstractValue value);
-  void writeOutputUnitReference(DataSinkWriter sink, OutputUnit value);
-  void writeJsNode(DataSinkWriter sink, js.Node node);
-  void writeTypeRecipe(DataSinkWriter sink, TypeRecipe recipe);
-}
-
-/// Interface used for looking up entities by index during deserialization.
-abstract class EntityLookup {
-  /// Returns the indexed library corresponding to [index].
-  IndexedLibrary getLibraryByIndex(int index);
-
-  /// Returns the indexed class corresponding to [index].
-  IndexedClass getClassByIndex(int index);
-
-  /// Returns the indexed member corresponding to [index].
-  IndexedMember getMemberByIndex(int index);
-
-  /// Returns the indexed type variable corresponding to [index].
-  IndexedTypeVariable getTypeVariableByIndex(int index);
-}
-
-/// Decoding strategy for entity references.
-class EntityReader {
-  const EntityReader();
-
-  IndexedLibrary readLibraryFromDataSource(
-      DataSourceReader source, EntityLookup entityLookup) {
-    return entityLookup.getLibraryByIndex(source.readInt());
-  }
-
-  IndexedClass readClassFromDataSource(
-      DataSourceReader source, EntityLookup entityLookup) {
-    return entityLookup.getClassByIndex(source.readInt());
-  }
-
-  IndexedMember readMemberFromDataSource(
-      DataSourceReader source, EntityLookup entityLookup) {
-    return entityLookup.getMemberByIndex(source.readInt());
-  }
-
-  IndexedTypeVariable readTypeVariableFromDataSource(
-      DataSourceReader source, EntityLookup entityLookup) {
-    return entityLookup.getTypeVariableByIndex(source.readInt());
-  }
-}
-
-/// Encoding strategy for entity references.
-class EntityWriter {
-  const EntityWriter();
-
-  void writeLibraryToDataSink(DataSinkWriter sink, IndexedLibrary value) {
-    sink.writeInt(value.libraryIndex);
-  }
-
-  void writeClassToDataSink(DataSinkWriter sink, IndexedClass value) {
-    sink.writeInt(value.classIndex);
-  }
-
-  void writeMemberToDataSink(DataSinkWriter sink, IndexedMember value) {
-    sink.writeInt(value.memberIndex);
-  }
-
-  void writeTypeVariableToDataSink(
-      DataSinkWriter sink, IndexedTypeVariable value) {
-    sink.writeInt(value.typeVariableIndex);
-  }
-}
diff --git a/pkg/compiler/lib/src/serialization/sink.dart b/pkg/compiler/lib/src/serialization/sink.dart
index 7fc2611..5aad4b2 100644
--- a/pkg/compiler/lib/src/serialization/sink.dart
+++ b/pkg/compiler/lib/src/serialization/sink.dart
@@ -2,15 +2,13 @@
 // 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
-
 part of 'serialization.dart';
 
 /// Serialization writer
 ///
 /// To be used with [DataSourceReader] to read and write serialized data.
 /// Serialization format is deferred to provided [DataSink].
-class DataSinkWriter implements migrated.DataSinkWriter {
+class DataSinkWriter {
   final DataSink _sinkWriter;
 
   final bool enableDeferredStrategy;
@@ -22,52 +20,53 @@
   /// and deserialization.
   final bool useDataKinds;
 
-  migrated.DataSourceIndices importedIndices;
+  DataSourceIndices? importedIndices;
 
   /// Visitor used for serializing [ir.DartType]s.
-  DartTypeNodeWriter _dartTypeNodeWriter;
+  late final DartTypeNodeWriter _dartTypeNodeWriter;
 
   /// Stack of tags used when [useDataKinds] is `true` to help debugging section
   /// inconsistencies between serialization and deserialization.
-  List<String> _tags;
+  List<String>? _tags;
 
   /// Map of [MemberData] object for serialized kernel member nodes.
   final Map<ir.Member, MemberData> _memberData = {};
 
-  IndexedSink<String> _stringIndex;
-  IndexedSink<Uri> _uriIndex;
-  IndexedSink<ir.Member> _memberNodeIndex;
-  IndexedSink<ImportEntity> _importIndex;
-  IndexedSink<ConstantValue> _constantIndex;
+  late final IndexedSink<String> _stringIndex;
+  late final IndexedSink<Uri> _uriIndex;
+  late final IndexedSink<ir.Member> _memberNodeIndex;
+  late final IndexedSink<ImportEntity> _importIndex;
+  late final IndexedSink<ConstantValue> _constantIndex;
 
   final Map<Type, IndexedSink> _generalCaches = {};
 
-  migrated.EntityWriter _entityWriter = const migrated.EntityWriter();
-  migrated.CodegenWriter _codegenWriter;
+  EntityWriter _entityWriter = const EntityWriter();
+  late final CodegenWriter _codegenWriter;
 
-  final Map<String, int> tagFrequencyMap;
+  final Map<String, int>? tagFrequencyMap;
 
-  ir.Member _currentMemberContext;
-  MemberData _currentMemberData;
+  ir.Member? _currentMemberContext;
+  MemberData? _currentMemberData;
 
   IndexedSink<T> _createUnorderedSink<T>() {
-    if (importedIndices == null) return UnorderedIndexedSink<T>(this);
-    final sourceInfo = importedIndices.caches[T];
+    final indices = importedIndices;
+    if (indices == null) return UnorderedIndexedSink<T>(this);
+    final sourceInfo = indices.caches[T];
     if (sourceInfo == null) {
       return UnorderedIndexedSink<T>(this,
-          startOffset: importedIndices.previousSourceReader.endOffset);
+          startOffset: indices.previousSourceReader?.endOffset);
     }
     Map<T, int> cacheCopy = Map.from(sourceInfo.cache);
     return UnorderedIndexedSink<T>(this,
-        cache: cacheCopy,
-        startOffset: importedIndices.previousSourceReader.endOffset);
+        cache: cacheCopy, startOffset: indices.previousSourceReader?.endOffset);
   }
 
   IndexedSink<T> _createSink<T>() {
-    if (importedIndices == null || !importedIndices.caches.containsKey(T)) {
+    final indices = importedIndices;
+    if (indices == null || !indices.caches.containsKey(T)) {
       return OrderedIndexedSink<T>(_sinkWriter);
     } else {
-      Map<T, int> cacheCopy = Map.from(importedIndices.caches[T].cache);
+      Map<T, int> cacheCopy = Map.from(indices.caches[T]!.cache);
       return OrderedIndexedSink<T>(_sinkWriter, cache: cacheCopy);
     }
   }
@@ -75,7 +74,7 @@
   DataSinkWriter(this._sinkWriter, CompilerOptions options,
       {this.useDataKinds = false, this.tagFrequencyMap, this.importedIndices})
       : enableDeferredStrategy =
-            (options?.features?.deferredSerialization?.isEnabled ?? false) {
+            options.features.deferredSerialization.isEnabled {
     _dartTypeNodeWriter = DartTypeNodeWriter(this);
     if (!enableDeferredStrategy) {
       _stringIndex = _createSink<String>();
@@ -95,7 +94,7 @@
   /// The amount of data written to this data sink.
   ///
   /// The units is based on the underlying data structure for this data sink.
-  @override
+
   int get length => _sinkWriter.length;
 
   /// Flushes any pending data and closes this data sink.
@@ -109,15 +108,10 @@
   ///
   /// This is used for debugging to verify that sections are correctly aligned
   /// between serialization and deserialization.
-  @override
   void begin(String tag) {
-    if (tagFrequencyMap != null) {
-      tagFrequencyMap[tag] ??= 0;
-      tagFrequencyMap[tag]++;
-    }
+    tagFrequencyMap?.update(tag, (count) => count + 1, ifAbsent: () => 1);
     if (useDataKinds) {
-      _tags ??= <String>[];
-      _tags.add(tag);
+      (_tags ??= <String>[]).add(tag);
       _sinkWriter.beginTag(tag);
     }
   }
@@ -126,18 +120,16 @@
   ///
   /// This is used for debugging to verify that sections are correctly aligned
   /// between serialization and deserialization.
-  @override
-  void end(Object tag) {
+  void end(String tag) {
     if (useDataKinds) {
       _sinkWriter.endTag(tag);
 
-      String existingTag = _tags.removeLast();
+      String existingTag = _tags!.removeLast();
       assert(existingTag == tag,
           "Unexpected tag end. Expected $existingTag, found $tag.");
     }
   }
 
-  @override
   void writeDeferrable(void f()) {
     if (enableDeferredStrategy) {
       _sinkWriter.writeDeferred(f);
@@ -148,8 +140,7 @@
 
   /// Writes a reference to [value] to this data sink. If [value] has not yet
   /// been serialized, [f] is called to serialize the value itself.
-  @override
-  void writeCached<E>(E /*?*/ value, void f(E value)) {
+  void writeCached<E>(E? value, void f(E value)) {
     IndexedSink sink = _generalCaches[E] ??=
         (enableDeferredStrategy ? _createUnorderedSink<E>() : _createSink<E>());
     sink.write(value, (v) => f(v));
@@ -160,8 +151,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readValueOrNull].
-  @override
-  void writeValueOrNull<E>(E value, void f(E value)) {
+  void writeValueOrNull<E>(E? value, void f(E value)) {
     writeBool(value != null);
     if (value != null) {
       f(value);
@@ -173,8 +163,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readList].
-  @override
-  void writeList<E>(Iterable<E> values, void f(E value),
+  void writeList<E>(Iterable<E>? values, void f(E value),
       {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
@@ -186,9 +175,8 @@
   }
 
   /// Writes the boolean [value] to this data sink.
-  @override
   void writeBool(bool value) {
-    assert(value != null);
+    assert((value as dynamic) != null); // TODO(48820): Remove when sound.
     _writeDataKind(DataKind.bool);
     _writeBool(value);
   }
@@ -198,9 +186,8 @@
   }
 
   /// Writes the non-negative 30 bit integer [value] to this data sink.
-  @override
   void writeInt(int value) {
-    assert(value != null);
+    assert((value as dynamic) != null); // TODO(48820): Remove when sound.
     assert(value >= 0 && value >> 30 == 0);
     _writeDataKind(DataKind.uint30);
     _sinkWriter.writeInt(value);
@@ -210,8 +197,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readIntOrNull].
-  @override
-  void writeIntOrNull(int value) {
+  void writeIntOrNull(int? value) {
     writeBool(value != null);
     if (value != null) {
       writeInt(value);
@@ -219,9 +205,8 @@
   }
 
   /// Writes the string [value] to this data sink.
-  @override
   void writeString(String value) {
-    assert(value != null);
+    assert((value as dynamic) != null); // TODO(48820): Remove when sound.
     _writeDataKind(DataKind.string);
     _writeString(value);
   }
@@ -234,8 +219,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readStringOrNull].
-  @override
-  void writeStringOrNull(String value) {
+  void writeStringOrNull(String? value) {
     writeBool(value != null);
     if (value != null) {
       writeString(value);
@@ -248,8 +232,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readStringMap].
-  @override
-  void writeStringMap<V>(Map<String, V> map, void f(V value),
+  void writeStringMap<V>(Map<String, V>? map, void f(V value),
       {bool allowNull = false}) {
     if (map == null) {
       assert(allowNull);
@@ -268,8 +251,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readStrings].
-  @override
-  void writeStrings(Iterable<String> values, {bool allowNull = false}) {
+  void writeStrings(Iterable<String>? values, {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
       writeInt(0);
@@ -285,16 +267,15 @@
   // TODO(johnniwinther): Change the signature to
   // `void writeEnum<E extends Enum<E>>(E value);` when an interface for enums
   // is added to the language.
-  @override
+
   void writeEnum(dynamic value) {
     _writeDataKind(DataKind.enumValue);
     _sinkWriter.writeEnum(value);
   }
 
   /// Writes the URI [value] to this data sink.
-  @override
   void writeUri(Uri value) {
-    assert(value != null);
+    assert((value as dynamic) != null); // TODO(48820): Remove when sound.
     _writeDataKind(DataKind.uri);
     _writeUri(value);
   }
@@ -308,7 +289,6 @@
   }
 
   /// Writes a reference to the kernel library node [value] to this data sink.
-  @override
   void writeLibraryNode(ir.Library value) {
     _writeDataKind(DataKind.libraryNode);
     _writeLibraryNode(value);
@@ -319,7 +299,6 @@
   }
 
   /// Writes a reference to the kernel class node [value] to this data sink.
-  @override
   void writeClassNode(ir.Class value) {
     _writeDataKind(DataKind.classNode);
     _writeClassNode(value);
@@ -342,7 +321,6 @@
   }
 
   /// Writes a reference to the kernel member node [value] to this data sink.
-  @override
   void writeMemberNode(ir.Member value) {
     _writeDataKind(DataKind.memberNode);
     _writeMemberNode(value);
@@ -353,7 +331,7 @@
   }
 
   void _writeMemberNodeInternal(ir.Member value) {
-    ir.Class cls = value.enclosingClass;
+    ir.Class? cls = value.enclosingClass;
     if (cls != null) {
       _sinkWriter.writeEnum(MemberContextKind.cls);
       _writeClassNode(cls);
@@ -370,8 +348,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readMemberNodes].
-  @override
-  void writeMemberNodes(Iterable<ir.Member> values, {bool allowNull = false}) {
+  void writeMemberNodes(Iterable<ir.Member>? values, {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
       writeInt(0);
@@ -389,8 +366,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readMemberNodeMap].
-  @override
-  void writeMemberNodeMap<V>(Map<ir.Member, V> map, void f(V value),
+  void writeMemberNodeMap<V>(Map<ir.Member, V>? map, void f(V value),
       {bool allowNull = false}) {
     if (map == null) {
       assert(allowNull);
@@ -405,35 +381,31 @@
   }
 
   /// Writes a kernel name node to this data sink.
-  @override
   void writeName(ir.Name value) {
     writeString(value.text);
     writeValueOrNull(value.library, writeLibraryNode);
   }
 
   /// Writes a kernel library dependency node [value] to this data sink.
-  @override
   void writeLibraryDependencyNode(ir.LibraryDependency value) {
-    ir.Library library = value.parent;
+    final library = value.parent as ir.Library;
     writeLibraryNode(library);
     writeInt(library.dependencies.indexOf(value));
   }
 
   /// Writes a potentially `null` kernel library dependency node [value] to
   /// this data sink.
-  @override
-  void writeLibraryDependencyNodeOrNull(ir.LibraryDependency value) {
+  void writeLibraryDependencyNodeOrNull(ir.LibraryDependency? value) {
     writeValueOrNull(value, writeLibraryDependencyNode);
   }
 
   /// Writes a reference to the kernel tree node [value] to this data sink.
-  @override
   void writeTreeNode(ir.TreeNode value) {
     _writeDataKind(DataKind.treeNode);
     _writeTreeNode(value, null);
   }
 
-  void _writeTreeNode(ir.TreeNode value, MemberData memberData) {
+  void _writeTreeNode(ir.TreeNode value, MemberData? memberData) {
     if (value is ir.Class) {
       _sinkWriter.writeEnum(_TreeNodeKind.cls);
       _writeClassNode(value);
@@ -443,7 +415,7 @@
     } else if (value is ir.VariableDeclaration &&
         value.parent is ir.FunctionDeclaration) {
       _sinkWriter.writeEnum(_TreeNodeKind.functionDeclarationVariable);
-      _writeTreeNode(value.parent, memberData);
+      _writeTreeNode(value.parent!, memberData);
     } else if (value is ir.FunctionNode) {
       _sinkWriter.writeEnum(_TreeNodeKind.functionNode);
       _writeFunctionNode(value, memberData);
@@ -461,10 +433,6 @@
       _sinkWriter.writeEnum(_TreeNodeKind.node);
       memberData ??= _getMemberData(value);
       int index = memberData.getIndexByTreeNode(value);
-      assert(
-          index != null,
-          "No TreeNode index found for ${value.runtimeType} "
-          "found in ${memberData}.");
       _sinkWriter.writeInt(index);
     }
   }
@@ -474,8 +442,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readTreeNodeOrNull].
-  @override
-  void writeTreeNodeOrNull(ir.TreeNode value) {
+  void writeTreeNodeOrNull(ir.TreeNode? value) {
     writeBool(value != null);
     if (value != null) {
       writeTreeNode(value);
@@ -487,8 +454,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readTreeNodes].
-  @override
-  void writeTreeNodes(Iterable<ir.TreeNode> values, {bool allowNull = false}) {
+  void writeTreeNodes(Iterable<ir.TreeNode>? values, {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
       writeInt(0);
@@ -506,7 +472,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readTreeNodeMap].
-  @override
   void writeTreeNodeMap<V>(Map<ir.TreeNode, V> map, void f(V value)) {
     writeInt(map.length);
     map.forEach((ir.TreeNode key, V value) {
@@ -532,7 +497,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readTreeNodeOrNullInContext].
-  void writeTreeNodeOrNullInContext(ir.TreeNode value) {
+  void writeTreeNodeOrNullInContext(ir.TreeNode? value) {
     writeBool(value != null);
     if (value != null) {
       writeTreeNodeInContextInternal(value, currentMemberData);
@@ -545,7 +510,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readTreeNodesInContext].
-  void writeTreeNodesInContext(Iterable<ir.TreeNode> values,
+  void writeTreeNodesInContext(Iterable<ir.TreeNode>? values,
       {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
@@ -564,9 +529,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readTreeNodeMapInContext].
-  @override
-  void writeTreeNodeMapInContext<V>(
-      Map<ir.TreeNode, V> /*?*/ map, void f(V value),
+  void writeTreeNodeMapInContext<V>(Map<ir.TreeNode, V>? map, void f(V value),
       {bool allowNull = false}) {
     if (map == null) {
       assert(allowNull);
@@ -582,14 +545,13 @@
 
   /// Writes a reference to the kernel type parameter node [value] to this data
   /// sink.
-  @override
   void writeTypeParameterNode(ir.TypeParameter value) {
     _writeDataKind(DataKind.typeParameterNode);
     _writeTypeParameter(value, null);
   }
 
-  void _writeTypeParameter(ir.TypeParameter value, MemberData memberData) {
-    ir.TreeNode parent = value.parent;
+  void _writeTypeParameter(ir.TypeParameter value, MemberData? memberData) {
+    ir.TreeNode parent = value.parent!;
     if (parent is ir.Class) {
       _sinkWriter.writeEnum(_TypeParameterKind.cls);
       _writeClassNode(parent);
@@ -610,7 +572,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readTypeParameterNodes].
-  @override
   void writeTypeParameterNodes(Iterable<ir.TypeParameter> values) {
     writeInt(values.length);
     for (ir.TypeParameter value in values) {
@@ -619,15 +580,13 @@
   }
 
   /// Writes the type [value] to this data sink.
-  @override
   void writeDartType(DartType value) {
     _writeDataKind(DataKind.dartType);
     value.writeToDataSink(this, []);
   }
 
   /// Writes the optional type [value] to this data sink.
-  @override
-  void writeDartTypeOrNull(DartType /*?*/ value) {
+  void writeDartTypeOrNull(DartType? value) {
     _writeDataKind(DataKind.dartType);
     if (value == null) {
       writeEnum(DartTypeKind.none);
@@ -641,8 +600,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readDartTypesOrNull].
-  @override
-  void writeDartTypesOrNull(Iterable<DartType> /*?*/ values) {
+  void writeDartTypesOrNull(Iterable<DartType>? values) {
     if (values == null) {
       writeInt(0);
     } else {
@@ -654,7 +612,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readDartTypes].
-  @override
   void writeDartTypes(Iterable<DartType> values) {
     writeInt(values.length);
     for (DartType value in values) {
@@ -663,21 +620,19 @@
   }
 
   /// Writes the kernel type node [value] to this data sink.
-  @override
   void writeDartTypeNode(ir.DartType /*!*/ value) {
     _writeDataKind(DataKind.dartTypeNode);
     _writeDartTypeNode(value, [], allowNull: false);
   }
 
   /// Writes the kernel type node [value] to this data sink, `null` permitted.
-  @override
-  void writeDartTypeNodeOrNull(ir.DartType /*?*/ value) {
+  void writeDartTypeNodeOrNull(ir.DartType? value) {
     _writeDataKind(DataKind.dartTypeNode);
     _writeDartTypeNode(value, [], allowNull: true);
   }
 
   void _writeDartTypeNode(
-      ir.DartType value, List<ir.TypeParameter> functionTypeVariables,
+      ir.DartType? value, List<ir.TypeParameter> functionTypeVariables,
       {bool allowNull = false}) {
     if (value == null) {
       if (!allowNull) {
@@ -694,8 +649,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readDartTypeNodes].
-  @override
-  void writeDartTypeNodes(Iterable<ir.DartType> values,
+  void writeDartTypeNodes(Iterable<ir.DartType>? values,
       {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
@@ -709,7 +663,6 @@
   }
 
   /// Writes the source span [value] to this data sink.
-  @override
   void writeSourceSpan(SourceSpan value) {
     _writeDataKind(DataKind.sourceSpan);
     _writeUri(value.uri);
@@ -717,33 +670,34 @@
     _sinkWriter.writeInt(value.end);
   }
 
-  /// Writes a reference to the indexed library [value] to this data sink.
-  @override
-  void writeLibrary(IndexedLibrary value) {
-    _entityWriter.writeLibraryToDataSink(this, value);
+  /// Writes a reference to the library entity [value] to this data sink.
+  void writeLibrary(LibraryEntity value) {
+    if (value is IndexedLibrary) {
+      _entityWriter.writeLibraryToDataSink(this, value);
+    } else {
+      failedAt(value, 'Unexpected library entity type ${value.runtimeType}');
+    }
   }
 
-  /// Writes a reference to the potentially `null` indexed library [value]
+  /// Writes a reference to the potentially `null` library entities [value]
   /// to this data sink.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readLibraryOrNull].
-  @override
-  void writeLibraryOrNull(IndexedLibrary value) {
+  void writeLibraryOrNull(LibraryEntity? value) {
     writeBool(value != null);
     if (value != null) {
       writeLibrary(value);
     }
   }
 
-  /// Writes the [map] from references to indexed libraries to [V] values to
+  /// Writes the [map] from references to library entities to [V] values to
   /// this data sink, calling [f] to write each value to the data sink. If
   /// [allowNull] is `true`, [map] is allowed to be `null`.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readLibraryMap].
-  @override
-  void writeLibraryMap<V>(Map<LibraryEntity, V> map, void f(V value),
+  void writeLibraryMap<V>(Map<LibraryEntity, V>? map, void f(V value),
       {bool allowNull = false}) {
     if (map == null) {
       assert(allowNull);
@@ -757,51 +711,51 @@
     }
   }
 
-  /// Writes a reference to the indexed class [value] to this data sink.
-  @override
-  void writeClass(IndexedClass value) {
-    _entityWriter.writeClassToDataSink(this, value);
+  /// Writes a reference to the class entity [value] to this data sink.
+  void writeClass(ClassEntity value) {
+    if (value is IndexedClass) {
+      _entityWriter.writeClassToDataSink(this, value);
+    } else {
+      failedAt(value, 'Unexpected class entity type ${value.runtimeType}');
+    }
   }
 
-  /// Writes a reference to the potentially `null` indexed class [value]
+  /// Writes a reference to the potentially `null` class entity [value]
   /// to this data sink.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readClassOrNull].
-  @override
-  void writeClassOrNull(IndexedClass value) {
+  void writeClassOrNull(ClassEntity? value) {
     writeBool(value != null);
     if (value != null) {
       writeClass(value);
     }
   }
 
-  /// Writes references to the indexed class [values] to this data sink. If
+  /// Writes references to the class entity [values] to this data sink. If
   /// [allowNull] is `true`, [values] is allowed to be `null`.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readClasses].
-  @override
-  void writeClasses(Iterable<ClassEntity> values, {bool allowNull = false}) {
+  void writeClasses(Iterable<ClassEntity>? values, {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
       writeInt(0);
     } else {
       writeInt(values.length);
-      for (IndexedClass value in values) {
+      for (ClassEntity value in values) {
         writeClass(value);
       }
     }
   }
 
-  /// Writes the [map] from references to indexed classes to [V] values to this
+  /// Writes the [map] from references to class entities to [V] values to this
   /// data sink, calling [f] to write each value to the data sink. If
   /// [allowNull] is `true`, [map] is allowed to be `null`.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readClassMap].
-  @override
-  void writeClassMap<V>(Map<ClassEntity, V> map, void f(V value),
+  void writeClassMap<V>(Map<ClassEntity, V>? map, void f(V value),
       {bool allowNull = false}) {
     if (map == null) {
       assert(allowNull);
@@ -815,52 +769,52 @@
     }
   }
 
-  /// Writes a reference to the indexed member [value] to this data sink.
-  @override
-  void writeMember(IndexedMember value) {
-    _entityWriter.writeMemberToDataSink(this, value);
+  /// Writes a reference to the member entity [value] to this data sink.
+  void writeMember(MemberEntity value) {
+    if (value is IndexedMember) {
+      _entityWriter.writeMemberToDataSink(this, value);
+    } else {
+      failedAt(value, 'Unexpected member entity type ${value.runtimeType}');
+    }
   }
 
-  /// Writes a reference to the potentially `null` indexed member [value]
+  /// Writes a reference to the potentially `null` member entities [value]
   /// to this data sink.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readMemberOrNull].
-  @override
-  void writeMemberOrNull(IndexedMember value) {
+  void writeMemberOrNull(MemberEntity? value) {
     writeBool(value != null);
     if (value != null) {
       writeMember(value);
     }
   }
 
-  /// Writes references to the indexed member [values] to this data sink. If
+  /// Writes references to the member entities [values] to this data sink. If
   /// [allowNull] is `true`, [values] is allowed to be `null`.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readMembers].
-  @override
-  void writeMembers(Iterable<MemberEntity> values, {bool allowNull = false}) {
+  void writeMembers(Iterable<MemberEntity>? values, {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
       writeInt(0);
     } else {
       writeInt(values.length);
-      for (IndexedMember value in values) {
+      for (MemberEntity value in values) {
         writeMember(value);
       }
     }
   }
 
-  /// Writes the [map] from references to indexed members to [V] values to this
+  /// Writes the [map] from references to member entities to [V] values to this
   /// data sink, calling [f] to write each value to the data sink. If
   /// [allowNull] is `true`, [map] is allowed to be `null`.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readMemberMap].
-  @override
   void writeMemberMap<V>(
-      Map<MemberEntity, V> map, void f(MemberEntity member, V value),
+      Map<MemberEntity, V>? map, void f(MemberEntity member, V value),
       {bool allowNull = false}) {
     if (map == null) {
       assert(allowNull);
@@ -874,23 +828,26 @@
     }
   }
 
-  /// Writes a reference to the indexed type variable [value] to this data sink.
-  @override
-  void writeTypeVariable(IndexedTypeVariable value) {
-    _entityWriter.writeTypeVariableToDataSink(this, value);
+  /// Writes a reference to the type variable entity [value] to this data sink.
+  void writeTypeVariable(TypeVariableEntity value) {
+    if (value is IndexedTypeVariable) {
+      _entityWriter.writeTypeVariableToDataSink(this, value);
+    } else {
+      failedAt(
+          value, 'Unexpected type variable entity type ${value.runtimeType}');
+    }
   }
 
-  /// Writes the [map] from references to indexed type variables to [V] values
+  /// Writes the [map] from references to type variable entites to [V] values
   /// to this data sink, calling [f] to write each value to the data sink. If
   /// [allowNull] is `true`, [map] is allowed to be `null`.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readTypeVariableMap].
-  @override
   void writeTypeVariableMap<V>(
-      Map<IndexedTypeVariable, V> map, void f(V value)) {
+      Map<TypeVariableEntity, V> map, void f(V value)) {
     writeInt(map.length);
-    map.forEach((IndexedTypeVariable key, V value) {
+    map.forEach((TypeVariableEntity key, V value) {
       writeTypeVariable(key);
       f(value);
     });
@@ -924,38 +881,19 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readLocalOrNull].
-  @override
-  void writeLocalOrNull(Local value) {
+  void writeLocalOrNull(Local? value) {
     writeBool(value != null);
     if (value != null) {
       writeLocal(value);
     }
   }
 
-  /// Writes references to the local [values] to this data sink. If [allowNull]
-  /// is `true`, [values] is allowed to be `null`.
-  ///
-  /// This is a convenience method to be used together with
-  /// [DataSourceReader.readLocals].
-  void writeLocals(Iterable<Local> values, {bool allowNull = false}) {
-    if (values == null) {
-      assert(allowNull);
-      writeInt(0);
-    } else {
-      writeInt(values.length);
-      for (Local value in values) {
-        writeLocal(value);
-      }
-    }
-  }
-
   /// Writes the [map] from references to locals to [V] values to this data
   /// sink, calling [f] to write each value to the data sink. If [allowNull] is
   /// `true`, [map] is allowed to be `null`.
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readLocalMap].
-  @override
   void writeLocalMap<V>(Map<Local, V> map, void f(V value)) {
     writeInt(map.length);
     map.forEach((Local key, V value) {
@@ -965,7 +903,6 @@
   }
 
   /// Writes the constant [value] to this data sink.
-  @override
   void writeConstant(ConstantValue value) {
     _writeDataKind(DataKind.constant);
     _writeConstant(value);
@@ -979,70 +916,69 @@
     _sinkWriter.writeEnum(value.kind);
     switch (value.kind) {
       case ConstantValueKind.BOOL:
-        BoolConstantValue constant = value;
+        final constant = value as BoolConstantValue;
         writeBool(constant.boolValue);
         break;
       case ConstantValueKind.INT:
-        IntConstantValue constant = value;
+        final constant = value as IntConstantValue;
         _writeBigInt(constant.intValue);
         break;
       case ConstantValueKind.DOUBLE:
-        DoubleConstantValue constant = value;
+        final constant = value as DoubleConstantValue;
         _writeDoubleValue(constant.doubleValue);
         break;
       case ConstantValueKind.STRING:
-        StringConstantValue constant = value;
+        final constant = value as StringConstantValue;
         writeString(constant.stringValue);
         break;
       case ConstantValueKind.NULL:
         break;
       case ConstantValueKind.FUNCTION:
-        FunctionConstantValue constant = value;
-        IndexedFunction function = constant.element;
-        writeMember(function);
+        final constant = value as FunctionConstantValue;
+        writeMember(constant.element);
         writeDartType(constant.type);
         break;
       case ConstantValueKind.LIST:
-        ListConstantValue constant = value;
+        final constant = value as ListConstantValue;
         writeDartType(constant.type);
         writeConstants(constant.entries);
         break;
       case ConstantValueKind.SET:
-        constant_system.JavaScriptSetConstant constant = value;
+        final constant = value as constant_system.JavaScriptSetConstant;
         writeDartType(constant.type);
         writeConstant(constant.entries);
         break;
       case ConstantValueKind.MAP:
-        constant_system.JavaScriptMapConstant constant = value;
+        final constant = value as constant_system.JavaScriptMapConstant;
         writeDartType(constant.type);
         writeConstant(constant.keyList);
         writeConstants(constant.values);
         writeBool(constant.onlyStringKeys);
         break;
       case ConstantValueKind.CONSTRUCTED:
-        ConstructedConstantValue constant = value;
+        final constant = value as ConstructedConstantValue;
         writeDartType(constant.type);
         writeMemberMap(constant.fields,
             (MemberEntity member, ConstantValue value) => writeConstant(value));
         break;
       case ConstantValueKind.TYPE:
-        TypeConstantValue constant = value;
+        final constant = value as TypeConstantValue;
         writeDartType(constant.representedType);
         writeDartType(constant.type);
         break;
       case ConstantValueKind.INSTANTIATION:
-        InstantiationConstantValue constant = value;
+        final constant = value as InstantiationConstantValue;
         writeDartTypes(constant.typeArguments);
         writeConstant(constant.function);
         break;
       case ConstantValueKind.NON_CONSTANT:
         break;
       case ConstantValueKind.INTERCEPTOR:
-        InterceptorConstantValue constant = value;
+        final constant = value as InterceptorConstantValue;
         writeClass(constant.cls);
         break;
       case ConstantValueKind.DEFERRED_GLOBAL:
-        DeferredGlobalConstantValue constant = value;
+        final constant = value as DeferredGlobalConstantValue;
         writeConstant(constant.referenced);
         writeOutputUnitReference(constant.unit);
         break;
@@ -1053,15 +989,14 @@
       case ConstantValueKind.UNREACHABLE:
         break;
       case ConstantValueKind.JS_NAME:
-        JsNameConstantValue constant = value;
+        final constant = value as JsNameConstantValue;
         writeJsNode(constant.name);
         break;
     }
   }
 
   /// Writes the potentially `null` constant [value] to this data sink.
-  @override
-  void writeConstantOrNull(ConstantValue value) {
+  void writeConstantOrNull(ConstantValue? value) {
     writeBool(value != null);
     if (value != null) {
       writeConstant(value);
@@ -1073,7 +1008,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readConstants].
-  void writeConstants(Iterable<ConstantValue> values,
+  void writeConstants(Iterable<ConstantValue>? values,
       {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
@@ -1092,8 +1027,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readConstantMap].
-  @override
-  void writeConstantMap<V>(Map<ConstantValue, V> map, void f(V value),
+  void writeConstantMap<V>(Map<ConstantValue, V>? map, void f(V value),
       {bool allowNull = false}) {
     if (map == null) {
       assert(allowNull);
@@ -1108,7 +1042,6 @@
   }
 
   /// Writes a double value to this data sink.
-  @override
   void writeDoubleValue(double value) {
     _writeDataKind(DataKind.double);
     _writeDoubleValue(value);
@@ -1127,7 +1060,6 @@
   ///
   /// This is should only when the value is not known to be a non-negative
   /// 30 bit integer. Otherwise [writeInt] should be used.
-  @override
   void writeIntegerValue(int value) {
     _writeDataKind(DataKind.int);
     _writeBigInt(BigInt.from(value));
@@ -1138,7 +1070,6 @@
   }
 
   /// Writes the import [value] to this data sink.
-  @override
   void writeImport(ImportEntity value) {
     _writeDataKind(DataKind.import);
     _writeImport(value);
@@ -1157,8 +1088,7 @@
   }
 
   /// Writes the potentially `null` import [value] to this data sink.
-  @override
-  void writeImportOrNull(ImportEntity value) {
+  void writeImportOrNull(ImportEntity? value) {
     writeBool(value != null);
     if (value != null) {
       writeImport(value);
@@ -1170,8 +1100,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readImports].
-  @override
-  void writeImports(Iterable<ImportEntity> values, {bool allowNull = false}) {
+  void writeImports(Iterable<ImportEntity>? values, {bool allowNull = false}) {
     if (values == null) {
       assert(allowNull);
       writeInt(0);
@@ -1189,8 +1118,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSourceReader.readImportMap].
-  @override
-  void writeImportMap<V>(Map<ImportEntity, V> /*?*/ map, void f(V value),
+  void writeImportMap<V>(Map<ImportEntity, V>? map, void f(V value),
       {bool allowNull = false}) {
     if (map == null) {
       assert(allowNull);
@@ -1207,10 +1135,7 @@
   /// Writes an abstract [value] to this data sink.
   ///
   /// This feature is only available a [CodegenWriter] has been registered.
-  @override
   void writeAbstractValue(AbstractValue value) {
-    assert(_codegenWriter != null,
-        "Can not serialize an AbstractValue without a registered codegen writer.");
     _codegenWriter.writeAbstractValue(this, value);
   }
 
@@ -1218,10 +1143,6 @@
   ///
   /// This feature is only available a [CodegenWriter] has been registered.
   void writeOutputUnitReference(OutputUnit value) {
-    assert(
-        _codegenWriter != null,
-        "Can not serialize an OutputUnit reference "
-        "without a registered codegen writer.");
     _codegenWriter.writeOutputUnitReference(this, value);
   }
 
@@ -1229,16 +1150,13 @@
   ///
   /// This feature is only available a [CodegenWriter] has been registered.
   void writeJsNode(js.Node value) {
-    assert(_codegenWriter != null,
-        "Can not serialize a JS node without a registered codegen writer.");
     _codegenWriter.writeJsNode(this, value);
   }
 
   /// Writes a potentially `null` js node [value] to this data sink.
   ///
   /// This feature is only available a [CodegenWriter] has been registered.
-  @override
-  void writeJsNodeOrNull(js.Node value) {
+  void writeJsNodeOrNull(js.Node? value) {
     writeBool(value != null);
     if (value != null) {
       writeJsNode(value);
@@ -1248,35 +1166,30 @@
   /// Writes TypeRecipe [value] to this data sink.
   ///
   /// This feature is only available a [CodegenWriter] has been registered.
-  @override
   void writeTypeRecipe(TypeRecipe value) {
-    assert(_codegenWriter != null,
-        "Can not serialize a TypeRecipe without a registered codegen writer.");
     _codegenWriter.writeTypeRecipe(this, value);
   }
 
   /// Register an [EntityWriter] with this data sink for non-default encoding
   /// of entity references.
-  void registerEntityWriter(migrated.EntityWriter writer) {
-    assert(writer != null);
+  void registerEntityWriter(EntityWriter writer) {
+    assert((writer as dynamic) != null); // TODO(48820): Remove when sound.
     _entityWriter = writer;
   }
 
   /// Register a [CodegenWriter] with this data sink to support serialization
   /// of codegen only data.
-  void registerCodegenWriter(migrated.CodegenWriter writer) {
-    assert(writer != null);
-    assert(_codegenWriter == null);
+  void registerCodegenWriter(CodegenWriter writer) {
+    assert((writer as dynamic) != null); // TODO(48820): Remove when sound.
     _codegenWriter = writer;
   }
 
   /// Invoke [f] in the context of [member]. This sets up support for
   /// serialization of `ir.TreeNode`s using the `writeTreeNode*InContext`
   /// methods.
-  @override
   void inMemberContext(ir.Member context, void f()) {
-    ir.Member oldMemberContext = _currentMemberContext;
-    MemberData oldMemberData = _currentMemberData;
+    ir.Member? oldMemberContext = _currentMemberContext;
+    MemberData? oldMemberData = _currentMemberData;
     _currentMemberContext = context;
     _currentMemberData = null;
     f();
@@ -1285,14 +1198,13 @@
   }
 
   MemberData get currentMemberData {
-    assert(_currentMemberContext != null,
-        "DataSink has no current member context.");
-    return _currentMemberData ??= _memberData[_currentMemberContext] ??=
-        MemberData(_currentMemberContext);
+    final currentMemberContext = _currentMemberContext!;
+    return _currentMemberData ??=
+        _memberData[currentMemberContext] ??= MemberData(currentMemberContext);
   }
 
   MemberData _getMemberData(ir.TreeNode node) {
-    ir.TreeNode member = node;
+    ir.TreeNode? member = node;
     while (member is! ir.Member) {
       if (member == null) {
         throw UnsupportedError("No enclosing member of TreeNode "
@@ -1304,8 +1216,8 @@
     return _memberData[member] ??= MemberData(member);
   }
 
-  void _writeFunctionNode(ir.FunctionNode value, MemberData memberData) {
-    ir.TreeNode parent = value.parent;
+  void _writeFunctionNode(ir.FunctionNode value, MemberData? memberData) {
+    ir.TreeNode parent = value.parent!;
     if (parent is ir.Procedure) {
       _sinkWriter.writeEnum(_FunctionNodeKind.procedure);
       _writeMemberNode(parent);
diff --git a/pkg/compiler/lib/src/serialization/source.dart b/pkg/compiler/lib/src/serialization/source.dart
index 0ea2edc..7fab209 100644
--- a/pkg/compiler/lib/src/serialization/source.dart
+++ b/pkg/compiler/lib/src/serialization/source.dart
@@ -2,15 +2,13 @@
 // 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
-
 part of 'serialization.dart';
 
 /// Deserialization reader
 ///
 /// To be used with [DataSinkWriter] to read and write serialized data.
 /// Deserialization format is deferred to provided [DataSource].
-class DataSourceReader implements migrated.DataSourceReader {
+class DataSourceReader {
   // The active [DataSource] to read data from. This can be the base DataSource
   // for this reader or can be set to access data in a different serialized
   // input in the case of deferred indexed data.
@@ -22,26 +20,25 @@
   final bool enableDeferredStrategy;
   final bool useDeferredStrategy;
   final bool useDataKinds;
-  final migrated.ValueInterner /*?*/ interner;
-  migrated.DataSourceIndices importedIndices;
-  migrated.EntityReader _entityReader = const migrated.EntityReader();
-  ComponentLookup _componentLookup;
-  migrated.EntityLookup _entityLookup;
-  migrated.LocalLookup _localLookup;
-  migrated.CodegenReader _codegenReader;
+  final ValueInterner? interner;
+  DataSourceIndices? importedIndices;
+  EntityReader _entityReader = const EntityReader();
+  ComponentLookup? _componentLookup;
+  EntityLookup? _entityLookup;
+  LocalLookup? _localLookup;
+  CodegenReader? _codegenReader;
 
-  IndexedSource<String> _stringIndex;
-  IndexedSource<Uri> _uriIndex;
-  IndexedSource<MemberData> _memberNodeIndex;
-  IndexedSource<ImportEntity> _importIndex;
-  IndexedSource<ConstantValue> _constantIndex;
+  late final IndexedSource<String> _stringIndex;
+  late final IndexedSource<Uri> _uriIndex;
+  late final IndexedSource<MemberData> _memberNodeIndex;
+  late final IndexedSource<ImportEntity> _importIndex;
+  late final IndexedSource<ConstantValue> _constantIndex;
 
   final Map<Type, IndexedSource> _generalCaches = {};
 
-  ir.Member _currentMemberContext;
-  MemberData _currentMemberData;
+  ir.Member? _currentMemberContext;
+  MemberData? _currentMemberData;
 
-  @override
   int get length => _sourceReader.length;
 
   /// Defines the beginning of this block in the address space created by all
@@ -51,8 +48,7 @@
   /// shifted. That is the length of all the sources read before this one.
   ///
   /// See [UnorderedIndexedSource] for more info.
-  @override
-  int get startOffset => importedIndices.previousSourceReader.endOffset;
+  int get startOffset => importedIndices?.previousSourceReader?.endOffset ?? 0;
 
   /// Defines the end of this block in the address space created by all
   /// instances of [DataSourceReader].
@@ -61,32 +57,33 @@
   /// value.
   ///
   /// See [UnorderedIndexedSource] for more info.
-  @override
   final int endOffset;
 
   IndexedSource<T> _createSource<T>() {
-    if (importedIndices == null || !importedIndices.caches.containsKey(T)) {
+    final indices = importedIndices;
+    if (indices == null || !indices.caches.containsKey(T)) {
       return OrderedIndexedSource<T>(this._sourceReader);
     } else {
-      final source = importedIndices.caches[T].source as OrderedIndexedSource;
-      List<T> cacheCopy = source.cache.toList();
+      final source = indices.caches[T]!.source as OrderedIndexedSource<T>;
+      List<T?> cacheCopy = source.cache.toList();
       return OrderedIndexedSource<T>(this._sourceReader, cache: cacheCopy);
     }
   }
 
-  UnorderedIndexedSource<T> /*?*/ _getPreviousUncreatedSource<T>() {
+  UnorderedIndexedSource<T>? _getPreviousUncreatedSource<T>() {
     final previousSourceReader = importedIndices?.previousSourceReader;
     if (previousSourceReader == null) return null;
     return UnorderedIndexedSource<T>(previousSourceReader,
-        previousSource: (previousSourceReader as DataSourceReader)
-            ._getPreviousUncreatedSource<T>());
+        previousSource: previousSourceReader._getPreviousUncreatedSource<T>());
   }
 
   IndexedSource<T> _createUnorderedSource<T>() {
-    if (importedIndices != null) {
-      if (importedIndices.caches.containsKey(T)) {
-        final index = importedIndices.caches.remove(T);
-        return UnorderedIndexedSource<T>(this, previousSource: index.source);
+    final indices = importedIndices;
+    if (indices != null) {
+      if (indices.caches.containsKey(T)) {
+        final index = indices.caches.remove(T);
+        return UnorderedIndexedSource<T>(this,
+            previousSource: index!.source as UnorderedIndexedSource<T>);
       }
       final newPreviousSource = _getPreviousUncreatedSource<T>();
       if (newPreviousSource != null) {
@@ -103,7 +100,7 @@
       this.interner,
       this.useDeferredStrategy = false})
       : enableDeferredStrategy =
-            (options?.features?.deferredSerialization?.isEnabled ?? false),
+            (options.features.deferredSerialization.isEnabled),
         endOffset = (importedIndices?.previousSourceReader?.endOffset ?? 0) +
             _sourceReader.length {
     if (!enableDeferredStrategy) {
@@ -123,22 +120,19 @@
 
   /// Exports [DataSourceIndices] for use in other [DataSourceReader]s and
   /// [DataSinkWriter]s.
-  migrated.DataSourceIndices exportIndices() {
-    final indices = migrated.DataSourceIndices(this);
-    indices.caches[String] = migrated.DataSourceTypeIndices(_stringIndex);
-    indices.caches[Uri] = migrated.DataSourceTypeIndices(_uriIndex);
-    indices.caches[ImportEntity] = migrated.DataSourceTypeIndices(_importIndex);
+  DataSourceIndices exportIndices() {
+    final indices = DataSourceIndices(this);
+    indices.caches[String] = DataSourceTypeIndices(_stringIndex);
+    indices.caches[Uri] = DataSourceTypeIndices(_uriIndex);
+    indices.caches[ImportEntity] = DataSourceTypeIndices(_importIndex);
     // _memberNodeIndex needs two entries depending on if the indices will be
     // consumed by a [DataSource] or [DataSink].
-    indices.caches[MemberData] =
-        migrated.DataSourceTypeIndices(_memberNodeIndex);
-    indices.caches[ir.Member] =
-        migrated.DataSourceTypeIndices<ir.Member, MemberData>(
-            _memberNodeIndex, (MemberData data) => data?.node);
-    indices.caches[ConstantValue] =
-        migrated.DataSourceTypeIndices(_constantIndex);
+    indices.caches[MemberData] = DataSourceTypeIndices(_memberNodeIndex);
+    indices.caches[ir.Member] = DataSourceTypeIndices<ir.Member?, MemberData>(
+        _memberNodeIndex, (MemberData? data) => data?.node);
+    indices.caches[ConstantValue] = DataSourceTypeIndices(_constantIndex);
     _generalCaches.forEach((type, indexedSource) {
-      indices.caches[type] = migrated.DataSourceTypeIndices(indexedSource);
+      indices.caches[type] = DataSourceTypeIndices(indexedSource);
     });
     return indices;
   }
@@ -147,7 +141,6 @@
   ///
   /// This is used for debugging to verify that sections are correctly aligned
   /// between serialization and deserialization.
-  @override
   void begin(String tag) {
     if (useDataKinds) _sourceReader.begin(tag);
   }
@@ -156,68 +149,61 @@
   ///
   /// This is used for debugging to verify that sections are correctly aligned
   /// between serialization and deserialization.
-  @override
   void end(String tag) {
     if (useDataKinds) _sourceReader.end(tag);
   }
 
   /// Registers a [ComponentLookup] object with this data source to support
   /// deserialization of references to kernel nodes.
-  @override
   void registerComponentLookup(ComponentLookup componentLookup) {
     assert(_componentLookup == null);
     _componentLookup = componentLookup;
   }
 
   ComponentLookup get componentLookup {
-    assert(_componentLookup != null);
-    return _componentLookup /*!*/;
+    return _componentLookup!;
   }
 
   /// Registers an [EntityLookup] object with this data source to support
-  /// deserialization of references to indexed entities.
-  @override
-  void registerEntityLookup(migrated.EntityLookup entityLookup) {
+  /// deserialization of references to entities.
+  void registerEntityLookup(EntityLookup entityLookup) {
     assert(_entityLookup == null);
     _entityLookup = entityLookup;
   }
 
-  migrated.EntityLookup get entityLookup {
-    assert(_entityLookup != null);
-    return _entityLookup /*!*/;
+  EntityLookup get entityLookup {
+    return _entityLookup!;
   }
 
   /// Registers an [EntityReader] with this data source for non-default encoding
   /// of entity references.
-  @override
-  void registerEntityReader(migrated.EntityReader reader) {
-    assert(reader != null);
+  void registerEntityReader(EntityReader reader) {
+    assert((reader as dynamic) != null); // TODO(48820): Remove when sound.
     _entityReader = reader;
   }
 
   /// Registers a [LocalLookup] object with this data source to support
-  @override
-  void registerLocalLookup(migrated.LocalLookup localLookup) {
-    assert(_localLookup == null);
+
+  void registerLocalLookup(LocalLookup localLookup) {
+    assert((localLookup as dynamic) != null); // TODO(48820): Remove when sound.
     _localLookup = localLookup;
   }
 
-  migrated.LocalLookup get localLookup {
-    assert(_localLookup != null);
-    return _localLookup /*!*/;
+  LocalLookup get localLookup {
+    return _localLookup!;
   }
 
-  /// Registers a [migrated.CodegenReader] with this data source to support
+  /// Registers a [CodegenReader] with this data source to support
   /// deserialization of codegen only data.
-  void registerCodegenReader(migrated.CodegenReader reader) {
-    assert(reader != null);
+  void registerCodegenReader(CodegenReader reader) {
+    assert((reader as dynamic) != null); // TODO(48820): Remove when sound.
     assert(_codegenReader == null);
     _codegenReader = reader;
   }
 
-  /// Unregisters the [migrated.CodegenReader] from this data source to remove support
+  /// Unregisters the [CodegenReader] from this data source to remove support
   /// for deserialization of codegen only data.
-  void deregisterCodegenReader(migrated.CodegenReader reader) {
+  void deregisterCodegenReader(CodegenReader reader) {
     assert(_codegenReader == reader);
     _codegenReader = null;
   }
@@ -225,9 +211,7 @@
   /// Evaluates [f] with [DataSource] for the provided [source] as the
   /// temporary [DataSource] for this object. Allows deferred data to be read
   /// from a file other than the one currently being read from.
-  // TODO(48820): Remove covariant when sound.
-  @override
-  E readWithSource<E>(covariant DataSourceReader source, E f()) {
+  E readWithSource<E>(DataSourceReader source, E f()) {
     final lastSource = _sourceReader;
     _sourceReader = source._sourceReader;
     final value = f();
@@ -235,12 +219,10 @@
     return value;
   }
 
-  @override
   E readWithOffset<E>(int offset, E f()) {
     return _sourceReader.readAtOffset(offset, f);
   }
 
-  @override
   Deferrable<E> readDeferrable<E>(E f(), {bool cacheData = true}) {
     return enableDeferredStrategy
         ? (useDeferredStrategy
@@ -253,10 +235,9 @@
   /// Invoke [f] in the context of [member]. This sets up support for
   /// deserialization of `ir.TreeNode`s using the `readTreeNode*InContext`
   /// methods.
-  @override
   T inMemberContext<T>(ir.Member context, T f()) {
-    ir.Member oldMemberContext = _currentMemberContext;
-    MemberData oldMemberData = _currentMemberData;
+    ir.Member? oldMemberContext = _currentMemberContext;
+    MemberData? oldMemberData = _currentMemberData;
     _currentMemberContext = context;
     _currentMemberData = null;
     T result = f();
@@ -268,25 +249,23 @@
   MemberData get currentMemberData {
     assert(_currentMemberContext != null,
         "DataSink has no current member context.");
-    return _currentMemberData ??= _getMemberData(_currentMemberContext);
+    return _currentMemberData ??= _getMemberData(_currentMemberContext!);
   }
 
   /// Reads a reference to an [E] value from this data source. If the value has
   /// not yet been deserialized, [f] is called to deserialize the value itself.
-  @override
   E readCached<E>(E f()) {
-    E /*?*/ value = readCachedOrNull(f);
+    E? value = readCachedOrNull(f);
     if (value == null) throw StateError("Unexpected 'null' for $E");
     return value;
   }
 
   /// Reads a reference to an [E] value from this data source. If the value has
   /// not yet been deserialized, [f] is called to deserialize the value itself.
-  @override
-  E /*?*/ readCachedOrNull<E>(E f()) {
-    IndexedSource<E> source = _generalCaches[E] ??= (enableDeferredStrategy
+  E? readCachedOrNull<E>(E f()) {
+    IndexedSource<E> source = (_generalCaches[E] ??= (enableDeferredStrategy
         ? _createUnorderedSource<E>()
-        : _createSource<E>());
+        : _createSource<E>())) as IndexedSource<E>;
     return source.read(f);
   }
 
@@ -295,8 +274,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeValueOrNull].
-  @override
-  E readValueOrNull<E>(E f()) {
+  E? readValueOrNull<E>(E f()) {
     bool hasValue = readBool();
     if (hasValue) {
       return f();
@@ -308,7 +286,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeList].
-  @override
   List<E> readList<E>(E f()) {
     return readListOrNull<E>(f) ?? List<E>.empty();
   }
@@ -318,8 +295,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeList].
-  @override
-  List<E> /*?*/ readListOrNull<E>(E f()) {
+  List<E>? readListOrNull<E>(E f()) {
     int count = readInt();
     if (count == 0) return null;
     final first = f();
@@ -330,7 +306,6 @@
     return list;
   }
 
-  @override
   bool readBool() {
     _checkDataKind(DataKind.bool);
     return _readBool();
@@ -344,7 +319,6 @@
   }
 
   /// Reads a non-negative 30 bit integer value from this data source.
-  @override
   int readInt() {
     _checkDataKind(DataKind.uint30);
     return _sourceReader.readInt();
@@ -355,8 +329,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeIntOrNull].
-  @override
-  int readIntOrNull() {
+  int? readIntOrNull() {
     bool hasValue = readBool();
     if (hasValue) {
       return readInt();
@@ -365,22 +338,20 @@
   }
 
   /// Reads a string value from this data source.
-  @override
   String readString() {
     _checkDataKind(DataKind.string);
     return _readString();
   }
 
-  String /*!*/ _readString() {
-    return _stringIndex.read(() => _sourceReader.readString());
+  String _readString() {
+    return _stringIndex.read(() => _sourceReader.readString())!;
   }
 
   /// Reads a potentially `null` string value from this data source.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeStringOrNull].
-  @override
-  String readStringOrNull() {
+  String? readStringOrNull() {
     bool hasValue = readBool();
     if (hasValue) {
       return readString();
@@ -393,8 +364,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeStrings].
-  @override
-  List<String> readStrings({bool emptyAsNull = false}) {
+  List<String>? readStrings({bool emptyAsNull = false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
     List<String> list = List<String>.filled(count, '');
@@ -410,8 +380,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeStringMap].
-  @override
-  Map<String, V> readStringMap<V>(V f(), {bool emptyAsNull = false}) {
+  Map<String, V>? readStringMap<V>(V f(), {bool emptyAsNull = false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
     Map<String, V> map = {};
@@ -432,21 +401,19 @@
   ///    ...
   ///    Foo foo = source.readEnum(Foo.values);
   ///
-  @override
   E readEnum<E>(List<E> values) {
     _checkDataKind(DataKind.enumValue);
     return _sourceReader.readEnum(values);
   }
 
   /// Reads a URI value from this data source.
-  @override
   Uri readUri() {
     _checkDataKind(DataKind.uri);
     return _readUri();
   }
 
   Uri _readUri() {
-    return _uriIndex.read(_doReadUri);
+    return _uriIndex.read(_doReadUri)!;
   }
 
   Uri _doReadUri() {
@@ -454,7 +421,6 @@
   }
 
   /// Reads a reference to a kernel library node from this data source.
-  @override
   ir.Library readLibraryNode() {
     _checkDataKind(DataKind.libraryNode);
     return _readLibraryData().node;
@@ -466,7 +432,6 @@
   }
 
   /// Reads a reference to a kernel class node from this data source.
-  @override
   ir.Class readClassNode() {
     _checkDataKind(DataKind.classNode);
     return _readClassData().node;
@@ -475,7 +440,7 @@
   ClassData _readClassData() {
     LibraryData library = _readLibraryData();
     String name = _readString();
-    return library.lookupClassByName(name);
+    return library.lookupClassByName(name)!;
   }
 
   /// Reads a reference to a kernel class node from this data source.
@@ -487,18 +452,17 @@
   ir.Typedef _readTypedefNode() {
     LibraryData library = _readLibraryData();
     String name = _readString();
-    return library.lookupTypedef(name);
+    return library.lookupTypedef(name)!;
   }
 
   /// Reads a reference to a kernel member node from this data source.
-  @override
   ir.Member readMemberNode() {
     _checkDataKind(DataKind.memberNode);
     return _readMemberData().node;
   }
 
   MemberData _readMemberData() {
-    return _memberNodeIndex.read(_readMemberDataInternal);
+    return _memberNodeIndex.read(_readMemberDataInternal)!;
   }
 
   MemberData _readMemberDataInternal() {
@@ -507,20 +471,18 @@
       case MemberContextKind.cls:
         ClassData cls = _readClassData();
         String name = _readString();
-        return cls.lookupMemberDataByName(name);
+        return cls.lookupMemberDataByName(name)!;
       case MemberContextKind.library:
         LibraryData library = _readLibraryData();
         String name = _readString();
-        return library.lookupMemberDataByName(name);
+        return library.lookupMemberDataByName(name)!;
     }
-    throw UnsupportedError("Unsupported _MemberKind $kind");
   }
 
   /// Reads a list of references to kernel member nodes from this data source.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeMemberNodes].
-  @override
   List<E> readMemberNodes<E extends ir.Member>() {
     return readMemberNodesOrNull<E>() ?? List.empty();
   }
@@ -530,8 +492,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeMemberNodes].
-  @override
-  List<E> readMemberNodesOrNull<E extends ir.Member>() {
+  List<E>? readMemberNodesOrNull<E extends ir.Member>() {
     int count = readInt();
     if (count == 0) return null;
     return List<E>.generate(count, (_) => readMemberNode() as E,
@@ -543,7 +504,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeMemberNodeMap].
-  @override
   Map<K, V> readMemberNodeMap<K extends ir.Member, V>(V f()) {
     return readMemberNodeMapOrNull<K, V>(f) ?? {};
   }
@@ -554,13 +514,12 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeMemberNodeMap].
-  @override
-  Map<K, V> /*?*/ readMemberNodeMapOrNull<K extends ir.Member, V>(V f()) {
+  Map<K, V>? readMemberNodeMapOrNull<K extends ir.Member, V>(V f()) {
     int count = readInt();
     if (count == 0) return null;
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      ir.Member node = readMemberNode();
+      final node = readMemberNode() as K;
       V value = f();
       map[node] = value;
     }
@@ -568,15 +527,13 @@
   }
 
   /// Reads a kernel name node from this data source.
-  @override
   ir.Name readName() {
     String text = readString();
-    ir.Library library = readValueOrNull(readLibraryNode);
+    ir.Library? library = readValueOrNull(readLibraryNode);
     return ir.Name(text, library);
   }
 
   /// Reads a kernel library dependency node from this data source.
-  @override
   ir.LibraryDependency readLibraryDependencyNode() {
     ir.Library library = readLibraryNode();
     int index = readInt();
@@ -585,19 +542,17 @@
 
   /// Reads a potentially `null` kernel library dependency node from this data
   /// source.
-  @override
-  ir.LibraryDependency readLibraryDependencyNodeOrNull() {
+  ir.LibraryDependency? readLibraryDependencyNodeOrNull() {
     return readValueOrNull(readLibraryDependencyNode);
   }
 
   /// Reads a reference to a kernel tree node from this data source.
-  @override
   ir.TreeNode readTreeNode() {
     _checkDataKind(DataKind.treeNode);
     return _readTreeNode(null);
   }
 
-  ir.TreeNode _readTreeNode(MemberData memberData) {
+  ir.TreeNode _readTreeNode(MemberData? memberData) {
     _TreeNodeKind kind = _sourceReader.readEnum(_TreeNodeKind.values);
     switch (kind) {
       case _TreeNodeKind.cls:
@@ -605,7 +560,8 @@
       case _TreeNodeKind.member:
         return _readMemberData().node;
       case _TreeNodeKind.functionDeclarationVariable:
-        ir.FunctionDeclaration functionDeclaration = _readTreeNode(memberData);
+        final functionDeclaration =
+            _readTreeNode(memberData) as ir.FunctionDeclaration;
         return functionDeclaration.variable;
       case _TreeNodeKind.functionNode:
         return _readFunctionNode(memberData);
@@ -613,7 +569,7 @@
         return _readTypeParameter(memberData);
       case _TreeNodeKind.constant:
         memberData ??= _readMemberData();
-        ir.ConstantExpression expression = _readTreeNode(memberData);
+        final expression = _readTreeNode(memberData) as ir.ConstantExpression;
         ir.Constant constant =
             memberData.getConstantByIndex(expression, _sourceReader.readInt());
         return ConstantReference(expression, constant);
@@ -621,19 +577,13 @@
         memberData ??= _readMemberData();
         int index = _sourceReader.readInt();
         ir.TreeNode treeNode = memberData.getTreeNodeByIndex(index);
-        assert(
-            treeNode != null,
-            "No TreeNode found for index $index in "
-            "${memberData.node}.${_sourceReader.errorContext}");
         return treeNode;
     }
-    throw UnsupportedError("Unexpected _TreeNodeKind $kind");
   }
 
   /// Reads a reference to a potentially `null` kernel tree node from this data
   /// source.
-  @override
-  ir.TreeNode readTreeNodeOrNull() {
+  ir.TreeNode? readTreeNodeOrNull() {
     bool hasValue = readBool();
     if (hasValue) {
       return readTreeNode();
@@ -645,7 +595,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeTreeNodes].
-  @override
   List<E> readTreeNodes<E extends ir.TreeNode>() {
     return readTreeNodesOrNull<E>() ?? List.empty();
   }
@@ -655,8 +604,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeTreeNodes].
-  @override
-  List<E> readTreeNodesOrNull<E extends ir.TreeNode>() {
+  List<E>? readTreeNodesOrNull<E extends ir.TreeNode>() {
     int count = readInt();
     if (count == 0) return null;
     return List<E>.generate(count, (i) => readTreeNode() as E, growable: false);
@@ -668,18 +616,16 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeTreeNodeMap].
-  @override
   Map<K, V> readTreeNodeMap<K extends ir.TreeNode, V>(V f()) {
     return readTreeNodeMapOrNull(f) ?? <K, V>{};
   }
 
-  @override
-  Map<K, V> readTreeNodeMapOrNull<K extends ir.TreeNode, V>(V f()) {
+  Map<K, V>? readTreeNodeMapOrNull<K extends ir.TreeNode, V>(V f()) {
     int count = readInt();
     if (count == 0) return null;
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      ir.TreeNode node = readTreeNode();
+      final node = readTreeNode() as K;
       V value = f();
       map[node] = value;
     }
@@ -699,7 +645,7 @@
 
   /// Reads a reference to a potentially `null` kernel tree node in the known
   /// [context] from this data source.
-  ir.TreeNode readTreeNodeOrNullInContext() {
+  ir.TreeNode? readTreeNodeOrNullInContext() {
     bool hasValue = readBool();
     if (hasValue) {
       return readTreeNodeInContextInternal(currentMemberData);
@@ -713,16 +659,13 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeTreeNodesInContext].
-  List<E> readTreeNodesInContext<E extends ir.TreeNode>(
+  List<E>? readTreeNodesInContext<E extends ir.TreeNode>(
       {bool emptyAsNull = false}) {
     int count = readInt();
     if (count == 0 && emptyAsNull) return null;
-    List<E> list = List<E>.filled(count, null);
-    for (int i = 0; i < count; i++) {
-      ir.TreeNode node = readTreeNodeInContextInternal(currentMemberData);
-      list[i] = node;
-    }
-    return list;
+    return List<E>.generate(
+        count, (index) => readTreeNodeInContextInternal(currentMemberData) as E,
+        growable: false);
   }
 
   /// Reads a map from kernel tree nodes to [V] values in the known [context]
@@ -731,7 +674,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeTreeNodeMapInContext].
-  @override
   Map<K, V> readTreeNodeMapInContext<K extends ir.TreeNode, V>(V f()) {
     return readTreeNodeMapInContextOrNull<K, V>(f) ?? {};
   }
@@ -742,14 +684,12 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeTreeNodeMapInContext].
-  @override
-  Map<K, V> /*?*/ readTreeNodeMapInContextOrNull<K extends ir.TreeNode, V>(
-      V f()) {
+  Map<K, V>? readTreeNodeMapInContextOrNull<K extends ir.TreeNode, V>(V f()) {
     int count = readInt();
     if (count == 0) return null;
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      ir.TreeNode node = readTreeNodeInContextInternal(currentMemberData);
+      final node = readTreeNodeInContextInternal(currentMemberData) as K;
       V value = f();
       map[node] = value;
     }
@@ -757,13 +697,12 @@
   }
 
   /// Reads a reference to a kernel type parameter node from this data source.
-  @override
   ir.TypeParameter readTypeParameterNode() {
     _checkDataKind(DataKind.typeParameterNode);
     return _readTypeParameter(null);
   }
 
-  ir.TypeParameter _readTypeParameter(MemberData memberData) {
+  ir.TypeParameter _readTypeParameter(MemberData? memberData) {
     _TypeParameterKind kind = _sourceReader.readEnum(_TypeParameterKind.values);
     switch (kind) {
       case _TypeParameterKind.cls:
@@ -773,7 +712,6 @@
         ir.FunctionNode functionNode = _readFunctionNode(memberData);
         return functionNode.typeParameters[_sourceReader.readInt()];
     }
-    throw UnsupportedError("Unexpected _TypeParameterKind kind $kind");
   }
 
   /// Reads a list of references to kernel type parameter nodes from this data
@@ -782,27 +720,22 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeTypeParameterNodes].
-  @override
   List<ir.TypeParameter> readTypeParameterNodes() {
     int count = readInt();
-    List<ir.TypeParameter> list = List<ir.TypeParameter>.filled(count, null);
-    for (int i = 0; i < count; i++) {
-      list[i] = readTypeParameterNode();
-    }
-    return list;
+    return List<ir.TypeParameter>.generate(
+        count, (index) => readTypeParameterNode(),
+        growable: false);
   }
 
   /// Reads a type from this data source.
-  @override
-  DartType /*!*/ readDartType() {
+  DartType readDartType() {
     _checkDataKind(DataKind.dartType);
     final type = DartType.readFromDataSource(this, []);
     return interner?.internDartType(type) ?? type;
   }
 
   /// Reads a nullable type from this data source.
-  @override
-  DartType /*?*/ readDartTypeOrNull() {
+  DartType? readDartTypeOrNull() {
     _checkDataKind(DataKind.dartType);
     return DartType.readFromDataSourceOrNull(this, []);
   }
@@ -811,7 +744,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeDartTypes].
-  @override
   List<DartType> readDartTypes() {
     // Share the list when empty.
     return readDartTypesOrNull() ?? const [];
@@ -822,8 +754,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeDartTypes].
-  @override
-  List<DartType> /*?*/ readDartTypesOrNull() {
+  List<DartType>? readDartTypesOrNull() {
     int count = readInt();
     if (count == 0) return null;
     return List.generate(count, (_) => readDartType(), growable: false);
@@ -831,24 +762,22 @@
 
   /// Reads a kernel type node from this data source. If [allowNull], the
   /// returned type is allowed to be `null`.
-  @override
-  ir.DartType /*!*/ readDartTypeNode() {
+  ir.DartType readDartTypeNode() {
     _checkDataKind(DataKind.dartTypeNode);
-    ir.DartType type = readDartTypeNodeOrNull();
+    ir.DartType? type = readDartTypeNodeOrNull();
     if (type == null) throw UnsupportedError('Unexpected `null` DartTypeNode');
     return type;
   }
 
   /// Reads a kernel type node from this data source. The returned type is
   /// allowed to be `null`.
-  @override
-  ir.DartType /*?*/ readDartTypeNodeOrNull() {
+  ir.DartType? readDartTypeNodeOrNull() {
     _checkDataKind(DataKind.dartTypeNode);
     final type = _readDartTypeNode([]);
     return interner?.internDartTypeNode(type) ?? type;
   }
 
-  ir.DartType _readDartTypeNode(List<ir.TypeParameter> functionTypeVariables) {
+  ir.DartType? _readDartTypeNode(List<ir.TypeParameter> functionTypeVariables) {
     DartTypeNodeKind kind = readEnum(DartTypeNodeKind.values);
     switch (kind) {
       case DartTypeNodeKind.none:
@@ -866,7 +795,7 @@
         ir.TypeParameter typeParameter = readTypeParameterNode();
         ir.Nullability typeParameterTypeNullability =
             readEnum(ir.Nullability.values);
-        ir.DartType promotedBound = _readDartTypeNode(functionTypeVariables);
+        ir.DartType? promotedBound = _readDartTypeNode(functionTypeVariables);
         return ir.TypeParameterType(
             typeParameter, typeParameterTypeNullability, promotedBound);
       case DartTypeNodeKind.functionTypeVariable:
@@ -874,39 +803,38 @@
         assert(0 <= index && index < functionTypeVariables.length);
         ir.Nullability typeParameterTypeNullability =
             readEnum(ir.Nullability.values);
-        ir.DartType promotedBound = _readDartTypeNode(functionTypeVariables);
+        ir.DartType? promotedBound = _readDartTypeNode(functionTypeVariables);
         return ir.TypeParameterType(functionTypeVariables[index],
             typeParameterTypeNullability, promotedBound);
       case DartTypeNodeKind.functionType:
         begin(functionTypeNodeTag);
         int typeParameterCount = readInt();
         List<ir.TypeParameter> typeParameters = List<ir.TypeParameter>.generate(
-            typeParameterCount, (int index) => ir.TypeParameter());
+            typeParameterCount, (int index) => ir.TypeParameter(),
+            growable: false);
         functionTypeVariables =
             List<ir.TypeParameter>.from(functionTypeVariables)
               ..addAll(typeParameters);
         for (int index = 0; index < typeParameterCount; index++) {
           typeParameters[index].name = readString();
           typeParameters[index].bound =
-              _readDartTypeNode(functionTypeVariables);
+              _readDartTypeNode(functionTypeVariables)!;
           typeParameters[index].defaultType =
-              _readDartTypeNode(functionTypeVariables);
+              _readDartTypeNode(functionTypeVariables)!;
         }
-        ir.DartType returnType = _readDartTypeNode(functionTypeVariables);
+        ir.DartType returnType = _readDartTypeNode(functionTypeVariables)!;
         ir.Nullability nullability = readEnum(ir.Nullability.values);
         int requiredParameterCount = readInt();
         List<ir.DartType> positionalParameters =
             _readDartTypeNodes(functionTypeVariables);
         int namedParameterCount = readInt();
-        List<ir.NamedType> namedParameters =
-            List<ir.NamedType>.filled(namedParameterCount, null);
-        for (int index = 0; index < namedParameterCount; index++) {
+        final namedParameters =
+            List<ir.NamedType>.generate(namedParameterCount, (index) {
           String name = readString();
           bool isRequired = readBool();
-          ir.DartType type = _readDartTypeNode(functionTypeVariables);
-          namedParameters[index] =
-              ir.NamedType(name, type, isRequired: isRequired);
-        }
+          ir.DartType type = _readDartTypeNode(functionTypeVariables)!;
+          return ir.NamedType(name, type, isRequired: isRequired);
+        }, growable: false);
         end(functionTypeNodeTag);
         return ir.FunctionType(positionalParameters, returnType, nullability,
             namedParameters: namedParameters,
@@ -941,19 +869,17 @@
         return const ir.DynamicType();
       case DartTypeNodeKind.futureOrType:
         ir.Nullability nullability = readEnum(ir.Nullability.values);
-        ir.DartType typeArgument = _readDartTypeNode(functionTypeVariables);
+        ir.DartType typeArgument = _readDartTypeNode(functionTypeVariables)!;
         return ir.FutureOrType(typeArgument, nullability);
       case DartTypeNodeKind.nullType:
         return const ir.NullType();
     }
-    throw UnsupportedError("Unexpected DartTypeKind $kind");
   }
 
   /// Reads a list of kernel type nodes from this data source.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeDartTypeNodes].
-  @override
   List<ir.DartType> readDartTypeNodes() {
     return readDartTypeNodesOrNull() ?? const [];
   }
@@ -963,31 +889,23 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeDartTypeNodes].
-  @override
-  List<ir.DartType> readDartTypeNodesOrNull() {
+  List<ir.DartType>? readDartTypeNodesOrNull() {
     int count = readInt();
     if (count == 0) return null;
-    List<ir.DartType> list = List<ir.DartType>.filled(count, null);
-    for (int i = 0; i < count; i++) {
-      list[i] = readDartTypeNode();
-    }
-    return list;
+    return List<ir.DartType>.generate(count, (index) => readDartTypeNode(),
+        growable: false);
   }
 
   List<ir.DartType> _readDartTypeNodes(
       List<ir.TypeParameter> functionTypeVariables) {
     int count = readInt();
     if (count == 0) return emptyListOfDartTypes;
-    List<ir.DartType> types =
-        List<ir.DartType>.filled(count, const ir.InvalidType());
-    for (int index = 0; index < count; index++) {
-      types[index] = _readDartTypeNode(functionTypeVariables);
-    }
-    return types;
+    return List<ir.DartType>.generate(
+        count, (index) => _readDartTypeNode(functionTypeVariables)!,
+        growable: false);
   }
 
   /// Reads a source span from this data source.
-  @override
   SourceSpan readSourceSpan() {
     _checkDataKind(DataKind.sourceSpan);
     Uri uri = _readUri();
@@ -996,16 +914,14 @@
     return SourceSpan(uri, begin, end);
   }
 
-  /// Reads a reference to an indexed library from this data source.
-  @override
-  IndexedLibrary readLibrary() {
+  /// Reads a reference to a library entity from this data source.
+  LibraryEntity readLibrary() {
     return _entityReader.readLibraryFromDataSource(this, entityLookup);
   }
 
-  /// Reads a reference to a potentially `null` indexed library from this data
+  /// Reads a reference to a potentially `null` library entity from this data
   /// source.
-  @override
-  IndexedLibrary readLibraryOrNull() {
+  LibraryEntity? readLibraryOrNull() {
     bool hasValue = readBool();
     if (hasValue) {
       return readLibrary();
@@ -1018,7 +934,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeLibraryMap].
-  @override
   Map<K, V> readLibraryMap<K extends LibraryEntity, V>(V f()) {
     return readLibraryMapOrNull<K, V>(f) ?? {};
   }
@@ -1029,29 +944,26 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeLibraryMap].
-  @override
-  Map<K, V> /*?*/ readLibraryMapOrNull<K extends LibraryEntity, V>(V f()) {
+  Map<K, V>? readLibraryMapOrNull<K extends LibraryEntity, V>(V f()) {
     int count = readInt();
     if (count == 0) return null;
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      LibraryEntity library = readLibrary();
+      final library = readLibrary() as K;
       V value = f();
       map[library] = value;
     }
     return map;
   }
 
-  /// Reads a reference to an indexed class from this data source.
-  @override
-  IndexedClass readClass() {
+  /// Reads a reference to an class entity from this data source.
+  ClassEntity readClass() {
     return _entityReader.readClassFromDataSource(this, entityLookup);
   }
 
-  /// Reads a reference to a potentially `null` indexed class from this data
+  /// Reads a reference to a potentially `null` class entity from this data
   /// source.
-  @override
-  IndexedClass readClassOrNull() {
+  ClassEntity? readClassOrNull() {
     bool hasClass = readBool();
     if (hasClass) {
       return readClass();
@@ -1059,71 +971,61 @@
     return null;
   }
 
-  /// Reads a list of references to indexed classes from this data source.
+  /// Reads a list of references to class entities from this data source.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeClasses].
-  @override
   List<E> readClasses<E extends ClassEntity>() {
     return readClassesOrNull<E>() ?? List.empty();
   }
 
-  /// Reads a list of references to indexed classes from this data source.
+  /// Reads a list of references to class entities from this data source.
   /// `null` is returned instead of an empty list.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeClasses].
-  @override
-  List<E> readClassesOrNull<E extends ClassEntity>() {
+  List<E>? readClassesOrNull<E extends ClassEntity>() {
     int count = readInt();
     if (count == 0) return null;
-    List<E> list = List<E>.filled(count, null);
-    for (int i = 0; i < count; i++) {
-      ClassEntity cls = readClass();
-      list[i] = cls;
-    }
-    return list;
+    return List<E>.generate(count, (index) => readClass() as E,
+        growable: false);
   }
 
-  /// Reads a map from indexed classes to [V] values from this data source,
+  /// Reads a map from class entities to [V] values from this data source,
   /// calling [f] to read each value from the data source.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeClassMap].
-  @override
   Map<K, V> readClassMap<K extends ClassEntity, V>(V f()) {
     return readClassMapOrNull<K, V>(f) ?? {};
   }
 
-  /// Reads a map from indexed classes to [V] values from this data source,
+  /// Reads a map from class entities to [V] values from this data source,
   /// calling [f] to read each value from the data source. `null` is returned if
   /// the map is empty.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeClassMap].
-  @override
-  Map<K, V> /*?*/ readClassMapOrNull<K extends ClassEntity, V>(V f()) {
+  Map<K, V>? readClassMapOrNull<K extends ClassEntity, V>(V f()) {
     int count = readInt();
     if (count == 0) return null;
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      ClassEntity cls = readClass();
+      final cls = readClass() as K;
       V value = f();
       map[cls] = value;
     }
     return map;
   }
 
-  /// Reads a reference to an indexed member from this data source.
-  @override
-  IndexedMember /*!*/ readMember() {
+  /// Reads a reference to an member entity from this data source.
+  MemberEntity readMember() {
     return _entityReader.readMemberFromDataSource(this, entityLookup);
   }
 
-  /// Reads a reference to a potentially `null` indexed member from this data
+  /// Reads a reference to a potentially `null` member entity from this data
   /// source.
-  @override
-  IndexedMember readMemberOrNull() {
+  MemberEntity? readMemberOrNull() {
     bool hasValue = readBool();
     if (hasValue) {
       return readMember();
@@ -1131,81 +1033,70 @@
     return null;
   }
 
-  /// Reads a list of references to indexed members from this data source.
+  /// Reads a list of references to member entities from this data source.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeMembers].
-  @override
-  List<E /*!*/ > readMembers<E extends MemberEntity /*!*/ >() {
+  List<E> readMembers<E extends MemberEntity>() {
     return readMembersOrNull() ?? List.empty();
   }
 
-  /// Reads a list of references to indexed members from this data source.
+  /// Reads a list of references to member entities from this data source.
   /// `null` is returned instead of an empty list.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeMembers].
-  @override
-  List<E /*!*/ > readMembersOrNull<E extends MemberEntity /*!*/ >() {
+  List<E>? readMembersOrNull<E extends MemberEntity>() {
     int count = readInt();
     if (count == 0) return null;
-    MemberEntity firstMember = readMember();
-    List<E> list = List<E>.filled(count, firstMember);
-    for (int i = 1; i < count; i++) {
-      MemberEntity member = readMember();
-      list[i] = member;
-    }
-    return list;
+    return List<E>.generate(count, (index) => readMember() as E,
+        growable: false);
   }
 
-  /// Reads a map from indexed members to [V] values from this data source,
+  /// Reads a map from member entities to [V] values from this data source,
   /// calling [f] to read each value from the data source.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeMemberMap].
-  @override
   Map<K, V> readMemberMap<K extends MemberEntity, V>(V f(MemberEntity member)) {
     return readMemberMapOrNull<K, V>(f) ?? {};
   }
 
-  /// Reads a map from indexed members to [V] values from this data source,
+  /// Reads a map from member entities to [V] values from this data source,
   /// calling [f] to read each value from the data source.
   /// `null` is returned instead of an empty map.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeMemberMap].
-  @override
-  Map<K, V> readMemberMapOrNull<K extends MemberEntity, V>(
+  Map<K, V>? readMemberMapOrNull<K extends MemberEntity, V>(
       V f(MemberEntity member)) {
     int count = readInt();
     if (count == 0) return null;
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      MemberEntity member = readMember();
+      final member = readMember() as K;
       V value = f(member);
       map[member] = value;
     }
     return map;
   }
 
-  /// Reads a reference to an indexed type variable from this data source.
-  @override
-  IndexedTypeVariable readTypeVariable() {
+  /// Reads a reference to an type variable entity from this data source.
+  TypeVariableEntity readTypeVariable() {
     return _entityReader.readTypeVariableFromDataSource(this, entityLookup);
   }
 
-  /// Reads a map from indexed type variable to [V] values from this data
+  /// Reads a map from type variable entities to [V] values from this data
   /// source, calling [f] to read each value from the data source. If
   /// [emptyAsNull] is `true`, `null` is returned instead of an empty map.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeTypeVariableMap].
-  @override
-  Map<K, V> readTypeVariableMap<K extends IndexedTypeVariable, V>(V f()) {
+  Map<K, V> readTypeVariableMap<K extends TypeVariableEntity, V>(V f()) {
     int count = readInt();
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      IndexedTypeVariable node = readTypeVariable();
+      final node = readTypeVariable() as K;
       V value = f();
       map[node] = value;
     }
@@ -1227,18 +1118,16 @@
         ClassEntity cls = readClass();
         return BoxLocal(cls);
       case LocalKind.anonymousClosureLocal:
-        ClassEntity cls = readClass();
+        final cls = readClass() as JClosureClass;
         return AnonymousClosureLocal(cls);
       case LocalKind.typeVariableLocal:
         TypeVariableEntity typeVariable = readTypeVariable();
         return TypeVariableLocal(typeVariable);
     }
-    throw UnsupportedError("Unexpected local kind $kind");
   }
 
   /// Reads a reference to a potentially `null` local from this data source.
-  @override
-  Local readLocalOrNull() {
+  Local? readLocalOrNull() {
     bool hasValue = readBool();
     if (hasValue) {
       return readLocal();
@@ -1246,34 +1135,17 @@
     return null;
   }
 
-  /// Reads a list of references to locals from this data source. If
-  /// [emptyAsNull] is `true`, `null` is returned instead of an empty list.
-  ///
-  /// This is a convenience method to be used together with
-  /// [DataSinkWriter.writeLocals].
-  List<E> readLocals<E extends Local>({bool emptyAsNull = false}) {
-    int count = readInt();
-    if (count == 0 && emptyAsNull) return null;
-    List<E> list = List<E>.filled(count, null);
-    for (int i = 0; i < count; i++) {
-      Local local = readLocal();
-      list[i] = local;
-    }
-    return list;
-  }
-
   /// Reads a map from locals to [V] values from this data source, calling [f]
   /// to read each value from the data source. If [emptyAsNull] is `true`,
   /// `null` is returned instead of an empty map.
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeLocalMap].
-  @override
   Map<K, V> readLocalMap<K extends Local, V>(V f()) {
     int count = readInt();
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      Local local = readLocal();
+      final local = readLocal() as K;
       V value = f();
       map[local] = value;
     }
@@ -1281,14 +1153,13 @@
   }
 
   /// Reads a constant value from this data source.
-  @override
   ConstantValue readConstant() {
     _checkDataKind(DataKind.constant);
     return _readConstant();
   }
 
   ConstantValue _readConstant() {
-    return _constantIndex.read(_readConstantInternal);
+    return _constantIndex.read(_readConstantInternal)!;
   }
 
   ConstantValue _readConstantInternal() {
@@ -1309,37 +1180,37 @@
       case ConstantValueKind.NULL:
         return const NullConstantValue();
       case ConstantValueKind.FUNCTION:
-        IndexedFunction function = readMember();
-        DartType type = readDartType();
+        final function = readMember() as FunctionEntity;
+        final type = readDartType() as FunctionType;
         return FunctionConstantValue(function, type);
       case ConstantValueKind.LIST:
-        DartType type = readDartType();
-        List<ConstantValue> entries = readConstants();
+        final type = readDartType() as InterfaceType;
+        final entries = readConstants();
         return ListConstantValue(type, entries);
       case ConstantValueKind.SET:
-        DartType type = readDartType();
-        MapConstantValue entries = readConstant();
+        final type = readDartType() as InterfaceType;
+        final entries = readConstant() as MapConstantValue;
         return constant_system.JavaScriptSetConstant(type, entries);
       case ConstantValueKind.MAP:
-        DartType type = readDartType();
-        ListConstantValue keyList = readConstant();
+        final type = readDartType() as InterfaceType;
+        final keyList = readConstant() as ListConstantValue;
         List<ConstantValue> values = readConstants();
         bool onlyStringKeys = readBool();
         return constant_system.JavaScriptMapConstant(
             type, keyList, values, onlyStringKeys);
       case ConstantValueKind.CONSTRUCTED:
-        InterfaceType type = readDartType();
+        final type = readDartType() as InterfaceType;
         Map<FieldEntity, ConstantValue> fields =
             readMemberMap<FieldEntity, ConstantValue>(
                 (MemberEntity member) => readConstant());
         return ConstructedConstantValue(type, fields);
       case ConstantValueKind.TYPE:
-        DartType representedType = readDartType();
-        DartType type = readDartType();
+        final representedType = readDartType();
+        final type = readDartType() as InterfaceType;
         return TypeConstantValue(representedType, type);
       case ConstantValueKind.INSTANTIATION:
         List<DartType> typeArguments = readDartTypes();
-        ConstantValue function = readConstant();
+        final function = readConstant() as FunctionConstantValue;
         return InstantiationConstantValue(typeArguments, function);
       case ConstantValueKind.NON_CONSTANT:
         return NonConstantValue();
@@ -1357,15 +1228,13 @@
       case ConstantValueKind.UNREACHABLE:
         return UnreachableConstantValue();
       case ConstantValueKind.JS_NAME:
-        js.LiteralString name = readJsNode();
+        final name = readJsNode() as js.LiteralString;
         return JsNameConstantValue(name);
     }
-    throw UnsupportedError("Unexpected constant value kind ${kind}.");
   }
 
   /// Reads a potentially `null` constant value from this data source.
-  @override
-  ConstantValue readConstantOrNull() {
+  ConstantValue? readConstantOrNull() {
     bool hasClass = readBool();
     if (hasClass) {
       return readConstant();
@@ -1378,15 +1247,10 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeConstants].
-  List<E> readConstants<E extends ConstantValue>({bool emptyAsNull = false}) {
+  List<E> readConstants<E extends ConstantValue>() {
     int count = readInt();
-    if (count == 0 && emptyAsNull) return null;
-    List<E> list = List<E>.filled(count, null);
-    for (int i = 0; i < count; i++) {
-      ConstantValue value = readConstant();
-      list[i] = value;
-    }
-    return list;
+    return List<E>.generate(count, (index) => readConstant() as E,
+        growable: false);
   }
 
   /// Reads a map from constant values to [V] values from this data source,
@@ -1394,7 +1258,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeConstantMap].
-  @override
   Map<K, V> readConstantMap<K extends ConstantValue, V>(V f()) {
     return readConstantMapOrNull<K, V>(f) ?? {};
   }
@@ -1405,13 +1268,12 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeConstantMap].
-  @override
-  Map<K, V> /*?*/ readConstantMapOrNull<K extends ConstantValue, V>(V f()) {
+  Map<K, V>? readConstantMapOrNull<K extends ConstantValue, V>(V f()) {
     int count = readInt();
     if (count == 0) return null;
     Map<K, V> map = {};
     for (int i = 0; i < count; i++) {
-      ConstantValue key = readConstant();
+      final key = readConstant() as K;
       V value = f();
       map[key] = value;
     }
@@ -1419,7 +1281,6 @@
   }
 
   /// Reads a double value from this data source.
-  @override
   double readDoubleValue() {
     _checkDataKind(DataKind.double);
     return _readDoubleValue();
@@ -1438,7 +1299,6 @@
   ///
   /// This is should only when the value is not known to be a non-negative
   /// 30 bit integer. Otherwise [readInt] should be used.
-  @override
   int readIntegerValue() {
     _checkDataKind(DataKind.int);
     return _readBigInt().toInt();
@@ -1448,7 +1308,6 @@
     return BigInt.parse(readString());
   }
 
-  @override
   ImportEntity readImport() {
     _checkDataKind(DataKind.import);
     return _readImport();
@@ -1456,11 +1315,11 @@
 
   /// Reads a import from this data source.
   ImportEntity _readImport() {
-    return _importIndex.read(_readImportInternal);
+    return _importIndex.read(_readImportInternal)!;
   }
 
   ImportEntity _readImportInternal() {
-    String name = readStringOrNull();
+    String? name = readStringOrNull();
     Uri uri = _readUri();
     Uri enclosingLibraryUri = _readUri();
     bool isDeferred = _readBool();
@@ -1468,8 +1327,7 @@
   }
 
   /// Reads a potentially `null` import from this data source.
-  @override
-  ImportEntity readImportOrNull() {
+  ImportEntity? readImportOrNull() {
     bool hasClass = readBool();
     if (hasClass) {
       return readImport();
@@ -1481,7 +1339,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeImports].
-  @override
   List<ImportEntity> readImports() {
     return readImportsOrNull() ?? const [];
   }
@@ -1491,15 +1348,11 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeImports].
-  @override
-  List<ImportEntity> /*?*/ readImportsOrNull() {
+  List<ImportEntity>? readImportsOrNull() {
     int count = readInt();
     if (count == 0) return null;
-    List<ImportEntity> list = List<ImportEntity>.filled(count, null);
-    for (int i = 0; i < count; i++) {
-      list[i] = readImport();
-    }
-    return list;
+    return List<ImportEntity>.generate(count, (index) => readImport(),
+        growable: false);
   }
 
   /// Reads a map from imports to [V] values from this data source,
@@ -1507,7 +1360,6 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeImportMap].
-  @override
   Map<ImportEntity, V> readImportMap<V>(V f()) {
     return readImportMapOrNull<V>(f) ?? {};
   }
@@ -1518,8 +1370,7 @@
   ///
   /// This is a convenience method to be used together with
   /// [DataSinkWriter.writeImportMap].
-  @override
-  Map<ImportEntity, V> /*?*/ readImportMapOrNull<V>(V f()) {
+  Map<ImportEntity, V>? readImportMapOrNull<V>(V f()) {
     int count = readInt();
     if (count == 0) return null;
     Map<ImportEntity, V> map = {};
@@ -1534,13 +1385,12 @@
   /// Reads an [AbstractValue] from this data source.
   ///
   /// This feature is only available a [CodegenReader] has been registered.
-  @override
   AbstractValue readAbstractValue() {
     assert(
         _codegenReader != null,
         "Can not deserialize an AbstractValue "
         "without a registered codegen reader.");
-    return _codegenReader.readAbstractValue(this);
+    return _codegenReader!.readAbstractValue(this);
   }
 
   /// Reads a reference to an [OutputUnit] from this data source.
@@ -1551,7 +1401,7 @@
         _codegenReader != null,
         "Can not deserialize an OutputUnit reference "
         "without a registered codegen reader.");
-    return _codegenReader.readOutputUnitReference(this);
+    return _codegenReader!.readOutputUnitReference(this);
   }
 
   /// Reads a [js.Node] value from this data source.
@@ -1560,14 +1410,13 @@
   js.Node readJsNode() {
     assert(_codegenReader != null,
         "Can not deserialize a JS node without a registered codegen reader.");
-    return _codegenReader.readJsNode(this);
+    return _codegenReader!.readJsNode(this);
   }
 
   /// Reads a potentially `null` [js.Node] value from this data source.
   ///
   /// This feature is only available a [CodegenReader] has been registered.
-  @override
-  js.Node readJsNodeOrNull() {
+  js.Node? readJsNodeOrNull() {
     bool hasValue = readBool();
     if (hasValue) {
       return readJsNode();
@@ -1578,41 +1427,41 @@
   /// Reads a [TypeRecipe] value from this data source.
   ///
   /// This feature is only available a [CodegenReader] has been registered.
-  @override
   TypeRecipe readTypeRecipe() {
     assert(_codegenReader != null,
         "Can not deserialize a TypeRecipe without a registered codegen reader.");
-    return _codegenReader.readTypeRecipe(this);
+    return _codegenReader!.readTypeRecipe(this);
   }
 
   MemberData _getMemberData(ir.Member node) {
     LibraryData libraryData =
         componentLookup.getLibraryDataByUri(node.enclosingLibrary.importUri);
     if (node.enclosingClass != null) {
-      ClassData classData = libraryData.lookupClassByNode(node.enclosingClass);
-      return classData.lookupMemberDataByNode(node);
+      final classData = libraryData.lookupClassByNode(node.enclosingClass!)!;
+      return classData.lookupMemberDataByNode(node)!;
     } else {
-      return libraryData.lookupMemberDataByNode(node);
+      return libraryData.lookupMemberDataByNode(node)!;
     }
   }
 
-  ir.FunctionNode _readFunctionNode(MemberData memberData) {
+  ir.FunctionNode _readFunctionNode(MemberData? memberData) {
     _FunctionNodeKind kind = _sourceReader.readEnum(_FunctionNodeKind.values);
     switch (kind) {
       case _FunctionNodeKind.procedure:
-        ir.Procedure procedure = _readMemberData().node;
+        final procedure = _readMemberData().node as ir.Procedure;
         return procedure.function;
       case _FunctionNodeKind.constructor:
-        ir.Constructor constructor = _readMemberData().node;
+        final constructor = _readMemberData().node as ir.Constructor;
         return constructor.function;
       case _FunctionNodeKind.functionExpression:
-        ir.FunctionExpression functionExpression = _readTreeNode(memberData);
+        final functionExpression =
+            _readTreeNode(memberData) as ir.FunctionExpression;
         return functionExpression.function;
       case _FunctionNodeKind.functionDeclaration:
-        ir.FunctionDeclaration functionDeclaration = _readTreeNode(memberData);
+        final functionDeclaration =
+            _readTreeNode(memberData) as ir.FunctionDeclaration;
         return functionDeclaration.function;
     }
-    throw UnsupportedError("Unexpected _FunctionNodeKind $kind");
   }
 
   void _checkDataKind(DataKind expectedKind) {
diff --git a/pkg/compiler/lib/src/serialization/strategies.dart b/pkg/compiler/lib/src/serialization/strategies.dart
index 02bd576..6cbe9d2 100644
--- a/pkg/compiler/lib/src/serialization/strategies.dart
+++ b/pkg/compiler/lib/src/serialization/strategies.dart
@@ -20,8 +20,7 @@
 import '../options.dart';
 import '../source_file_provider.dart';
 import '../util/sink_adapter.dart';
-import 'serialization.dart' show DataSinkWriter, DataSourceReader;
-import 'serialization_interfaces.dart' hide DataSinkWriter, DataSourceReader;
+import 'serialization.dart';
 import 'task.dart';
 
 abstract class SerializationStrategy<T> {
diff --git a/pkg/compiler/lib/src/serialization/task.dart b/pkg/compiler/lib/src/serialization/task.dart
index 04fa396..e225449 100644
--- a/pkg/compiler/lib/src/serialization/task.dart
+++ b/pkg/compiler/lib/src/serialization/task.dart
@@ -28,8 +28,7 @@
 import '../options.dart';
 import '../util/sink_adapter.dart';
 import '../world.dart';
-import 'serialization.dart' show DataSinkWriter, DataSourceReader;
-import 'serialization_interfaces.dart' hide DataSinkWriter, DataSourceReader;
+import 'serialization.dart';
 
 /// A data class holding some data [T] and the associated [DataSourceIndices].
 class DataAndIndices<T> {
diff --git a/pkg/compiler/lib/src/universe/call_structure.dart b/pkg/compiler/lib/src/universe/call_structure.dart
index 448ad06..427b165 100644
--- a/pkg/compiler/lib/src/universe/call_structure.dart
+++ b/pkg/compiler/lib/src/universe/call_structure.dart
@@ -6,7 +6,7 @@
 
 import '../common/names.dart' show Names;
 import '../elements/entities.dart' show ParameterStructure;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart';
 import 'selector.dart' show Selector;
 
diff --git a/pkg/compiler/lib/src/universe/class_hierarchy.dart b/pkg/compiler/lib/src/universe/class_hierarchy.dart
index 8634d09..d70a7bc 100644
--- a/pkg/compiler/lib/src/universe/class_hierarchy.dart
+++ b/pkg/compiler/lib/src/universe/class_hierarchy.dart
@@ -9,7 +9,7 @@
 import '../elements/types.dart' show InterfaceType;
 import '../kernel/element_map_interfaces.dart'
     show KernelToElementMapForClassHierarchy;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import 'class_set.dart';
 
 // TODO(johnniwinther): Move more methods from `JClosedWorld` to
diff --git a/pkg/compiler/lib/src/universe/class_set.dart b/pkg/compiler/lib/src/universe/class_set.dart
index e5ccc33..f10d690 100644
--- a/pkg/compiler/lib/src/universe/class_set.dart
+++ b/pkg/compiler/lib/src/universe/class_set.dart
@@ -8,7 +8,7 @@
 
 import '../elements/entities.dart' show ClassEntity;
 import '../elements/indexed.dart' show IndexedClass;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/enumset.dart' show EnumSet;
 
 /// Enum for the different kinds of instantiation of a class.
@@ -215,9 +215,9 @@
   factory ClassHierarchyNode.readFromDataSource(
       DataSourceReader source, Map<ClassEntity, ClassHierarchyNode> nodeMap) {
     source.begin(tag);
-    IndexedClass cls = source.readClass() as IndexedClass;
+    final cls = source.readClass();
     ClassHierarchyNode? parentNode;
-    final superclass = source.readClassOrNull() as IndexedClass?;
+    final superclass = source.readClassOrNull();
     if (superclass != null) {
       parentNode = nodeMap[superclass]!;
     }
@@ -225,7 +225,7 @@
     int hierarchyDepth = source.readInt();
     int instantiatedSubclassCount = source.readInt();
     source.end(tag);
-    return ClassHierarchyNode(parentNode, cls, hierarchyDepth)
+    return ClassHierarchyNode(parentNode, cls as IndexedClass, hierarchyDepth)
       .._instantiatedSubclassCount = instantiatedSubclassCount
       .._mask.value = maskValue;
   }
diff --git a/pkg/compiler/lib/src/universe/feature.dart b/pkg/compiler/lib/src/universe/feature.dart
index 8dac144..755014d 100644
--- a/pkg/compiler/lib/src/universe/feature.dart
+++ b/pkg/compiler/lib/src/universe/feature.dart
@@ -14,7 +14,7 @@
 
 import '../elements/types.dart';
 import '../ir/runtime_type_analysis.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart';
 
 /// A language feature that may be seen in the program.
diff --git a/pkg/compiler/lib/src/universe/member_usage.dart b/pkg/compiler/lib/src/universe/member_usage.dart
index 84df30c..558f8ac 100644
--- a/pkg/compiler/lib/src/universe/member_usage.dart
+++ b/pkg/compiler/lib/src/universe/member_usage.dart
@@ -8,7 +8,7 @@
 import '../constants/values.dart';
 import '../elements/entities.dart';
 import '../js_model/jrecord_field_interface.dart' show JRecordFieldInterface;
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/enumset.dart';
 import 'call_structure.dart';
 
diff --git a/pkg/compiler/lib/src/universe/selector.dart b/pkg/compiler/lib/src/universe/selector.dart
index fa927f4..c32eff0 100644
--- a/pkg/compiler/lib/src/universe/selector.dart
+++ b/pkg/compiler/lib/src/universe/selector.dart
@@ -11,7 +11,7 @@
 import '../elements/names.dart';
 import '../elements/operators.dart';
 import '../kernel/invocation_mirror_constants.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../util/util.dart' show Hashing;
 import 'call_structure.dart' show CallStructure;
 
diff --git a/pkg/compiler/lib/src/universe/side_effects.dart b/pkg/compiler/lib/src/universe/side_effects.dart
index a269f63..091cc56 100644
--- a/pkg/compiler/lib/src/universe/side_effects.dart
+++ b/pkg/compiler/lib/src/universe/side_effects.dart
@@ -5,7 +5,7 @@
 library universe.side_effects;
 
 import '../elements/entities.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 
 class SideEffects {
   /// Tag used for identifying serialized [SideEffects] objects in a debugging
diff --git a/pkg/compiler/lib/src/universe/use.dart b/pkg/compiler/lib/src/universe/use.dart
index ed7a7c3..b4ebace 100644
--- a/pkg/compiler/lib/src/universe/use.dart
+++ b/pkg/compiler/lib/src/universe/use.dart
@@ -21,7 +21,7 @@
 import '../elements/types.dart';
 import '../elements/entities.dart';
 import '../inferrer/abstract_value_domain.dart';
-import '../serialization/serialization_interfaces.dart';
+import '../serialization/serialization.dart';
 import '../js_model/jrecord_field_interface.dart' show JRecordFieldInterface;
 import '../util/util.dart' show equalElements, Hashing;
 import 'call_structure.dart' show CallStructure;
diff --git a/pkg/compiler/test/serialization/serialization_test_helper.dart b/pkg/compiler/test/serialization/serialization_test_helper.dart
index f126bfd..f50d65b 100644
--- a/pkg/compiler/test/serialization/serialization_test_helper.dart
+++ b/pkg/compiler/test/serialization/serialization_test_helper.dart
@@ -12,7 +12,7 @@
 import 'package:compiler/src/compiler.dart';
 import 'package:compiler/src/js_model/js_world.dart';
 import 'package:compiler/src/inferrer/types.dart';
-import 'package:compiler/src/serialization/serialization_interfaces.dart';
+import 'package:compiler/src/serialization/serialization.dart';
 import 'package:compiler/src/serialization/strategies.dart';
 import 'package:compiler/src/serialization/task.dart';
 import 'package:expect/expect.dart';