diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 70eeca3..69e68ff 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -22,47 +22,31 @@
         TreeNode,
         TypeParameter,
         getAsTypeArguments;
-
 import 'package:kernel/class_hierarchy.dart'
     show ClassHierarchy, ClassHierarchyMembers;
-
 import 'package:kernel/core_types.dart' show CoreTypes;
-
+import 'package:kernel/src/legacy_erasure.dart';
 import 'package:kernel/text/text_serialization_verifier.dart';
-
 import 'package:kernel/type_algebra.dart' show Substitution, substitute;
-
 import 'package:kernel/type_environment.dart'
     show SubtypeCheckMode, TypeEnvironment;
 
-import 'package:kernel/src/legacy_erasure.dart';
-
 import '../dill/dill_member_builder.dart';
-
 import '../fasta_codes.dart';
-
 import '../kernel/kernel_helper.dart';
-
 import '../kernel/redirecting_factory_body.dart' show RedirectingFactoryBody;
-
 import '../loader.dart';
-
 import '../modifier.dart';
-
 import '../names.dart' show noSuchMethodName;
-
 import '../problems.dart' show internalProblem, unhandled;
-
 import '../scope.dart';
-
+import '../source/source_constructor_builder.dart';
+import '../source/source_factory_builder.dart';
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
 import '../source/source_loader.dart';
-
+import '../source/source_member_builder.dart';
 import '../type_inference/type_schema.dart' show UnknownType;
-
 import '../util/helpers.dart' show DelayedActionPerformer;
-
 import 'builder.dart';
 import 'constructor_builder.dart';
 import 'constructor_reference_builder.dart';
@@ -75,7 +59,6 @@
 import 'named_type_builder.dart';
 import 'never_type_declaration_builder.dart';
 import 'nullability_builder.dart';
-import 'factory_builder.dart';
 import 'type_alias_builder.dart';
 import 'type_builder.dart';
 import 'type_declaration_builder.dart';
diff --git a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
index c2e155b..960410b 100644
--- a/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/constructor_builder.dart
@@ -2,757 +2,11 @@
 // 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:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
 import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
-import 'package:kernel/type_algebra.dart';
 
-import '../builder/library_builder.dart';
-
-import '../constant_context.dart' show ConstantContext;
-
-import '../dill/dill_member_builder.dart';
-
-import '../kernel/body_builder.dart' show BodyBuilder;
-import '../kernel/constructor_tearoff_lowering.dart';
-import '../kernel/expression_generator_helper.dart'
-    show ExpressionGeneratorHelper;
-import '../kernel/hierarchy/class_member.dart' show ClassMember;
-import '../kernel/utils.dart'
-    show isRedirectingGenerativeConstructorImplementation;
-import '../kernel/kernel_helper.dart' show SynthesizedFunctionNode;
-
-import '../source/source_loader.dart' show SourceLoader;
-
-import '../messages.dart'
-    show
-        Message,
-        messageMoreThanOneSuperInitializer,
-        messageRedirectingConstructorWithAnotherInitializer,
-        messageRedirectingConstructorWithMultipleRedirectInitializers,
-        messageRedirectingConstructorWithSuperInitializer,
-        messageSuperInitializerNotLast,
-        noLength;
-
-import '../source/source_class_builder.dart';
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-import '../type_inference/type_schema.dart';
-import '../type_inference/type_inferrer.dart';
-import '../util/helpers.dart' show DelayedActionPerformer;
-
-import 'builder.dart';
-import 'class_builder.dart';
-import 'field_builder.dart';
-import 'formal_parameter_builder.dart';
 import 'function_builder.dart';
-import 'member_builder.dart';
-import 'metadata_builder.dart';
-import 'named_type_builder.dart';
-import 'type_alias_builder.dart';
-import 'type_builder.dart';
-import 'type_declaration_builder.dart';
-import 'type_variable_builder.dart';
 
 abstract class ConstructorBuilder implements FunctionBuilder {
   /// The [Constructor] built by this builder.
   Constructor get constructor;
 }
-
-class SourceConstructorBuilder extends FunctionBuilderImpl
-    implements ConstructorBuilder {
-  final Constructor _constructor;
-  final Procedure? _constructorTearOff;
-
-  Set<FieldBuilder>? _initializedFields;
-
-  final int charOpenParenOffset;
-
-  bool hasMovedSuperInitializer = false;
-
-  SuperInitializer? superInitializer;
-
-  RedirectingInitializer? redirectingInitializer;
-
-  Token? beginInitializers;
-
-  SourceConstructorBuilder? actualOrigin;
-
-  Constructor get actualConstructor => _constructor;
-
-  bool _hasFormalsInferred = false;
-
-  final bool _hasSuperInitializingFormals;
-
-  final List<SynthesizedFunctionNode> _superParameterDefaultValueCloners =
-      <SynthesizedFunctionNode>[];
-
-  SourceConstructorBuilder(
-      List<MetadataBuilder>? metadata,
-      int modifiers,
-      TypeBuilder? returnType,
-      String name,
-      List<TypeVariableBuilder>? typeVariables,
-      List<FormalParameterBuilder>? formals,
-      SourceLibraryBuilder compilationUnit,
-      int startCharOffset,
-      int charOffset,
-      this.charOpenParenOffset,
-      int charEndOffset,
-      Reference? constructorReference,
-      Reference? tearOffReference,
-      {String? nativeMethodName,
-      required bool forAbstractClassOrEnum})
-      : _constructor = new Constructor(new FunctionNode(null),
-            name: new Name(name, compilationUnit.library),
-            fileUri: compilationUnit.fileUri,
-            reference: constructorReference)
-          ..startFileOffset = startCharOffset
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset
-          ..isNonNullableByDefault = compilationUnit.isNonNullableByDefault,
-        _constructorTearOff = createConstructorTearOffProcedure(
-            name,
-            compilationUnit,
-            compilationUnit.fileUri,
-            charOffset,
-            tearOffReference,
-            forAbstractClassOrEnum: forAbstractClassOrEnum),
-        _hasSuperInitializingFormals =
-            formals?.any((formal) => formal.isSuperInitializingFormal) ?? false,
-        super(metadata, modifiers, returnType, name, typeVariables, formals,
-            compilationUnit, charOffset, nativeMethodName);
-
-  @override
-  SourceLibraryBuilder get library => super.library as SourceLibraryBuilder;
-
-  @override
-  SourceClassBuilder get classBuilder =>
-      super.classBuilder as SourceClassBuilder;
-
-  @override
-  Member? get readTarget => _constructorTearOff ?? _constructor;
-
-  @override
-  Member? get writeTarget => null;
-
-  @override
-  Member get invokeTarget => constructor;
-
-  @override
-  FunctionNode get function => _constructor.function;
-
-  @override
-  Iterable<Member> get exportedMembers => [constructor];
-
-  @override
-  SourceConstructorBuilder get origin => actualOrigin ?? this;
-
-  ConstructorBuilder? get patchForTesting =>
-      dataForTesting?.patchForTesting as ConstructorBuilder?;
-
-  @override
-  bool get isDeclarationInstanceMember => false;
-
-  @override
-  bool get isClassInstanceMember => false;
-
-  @override
-  bool get isConstructor => true;
-
-  @override
-  AsyncMarker get asyncModifier => AsyncMarker.Sync;
-
-  @override
-  ProcedureKind? get kind => null;
-
-  @override
-  bool get isRedirectingGenerativeConstructor {
-    return isRedirectingGenerativeConstructorImplementation(_constructor);
-  }
-
-  @override
-  void buildMembers(
-      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
-    Member member = build(library);
-    f(member, BuiltMemberKind.Constructor);
-    if (_constructorTearOff != null) {
-      f(_constructorTearOff!, BuiltMemberKind.Method);
-    }
-  }
-
-  bool _hasBeenBuilt = false;
-
-  @override
-  Constructor build(SourceLibraryBuilder libraryBuilder) {
-    if (!_hasBeenBuilt) {
-      buildFunction(libraryBuilder);
-      _constructor.function.fileOffset = charOpenParenOffset;
-      _constructor.function.fileEndOffset = _constructor.fileEndOffset;
-      _constructor.function.typeParameters = const <TypeParameter>[];
-      _constructor.isConst = isConst;
-      _constructor.isExternal = isExternal;
-      updatePrivateMemberName(_constructor, libraryBuilder);
-
-      if (_constructorTearOff != null) {
-        buildConstructorTearOffProcedure(_constructorTearOff!, _constructor,
-            classBuilder.cls, libraryBuilder);
-      }
-
-      _hasBeenBuilt = true;
-    }
-    if (formals != null) {
-      bool needsInference = false;
-      for (FormalParameterBuilder formal in formals!) {
-        if (formal.type == null &&
-            (formal.isInitializingFormal || formal.isSuperInitializingFormal)) {
-          formal.variable!.type = const UnknownType();
-          needsInference = true;
-        }
-      }
-      if (needsInference) {
-        assert(
-            library == libraryBuilder,
-            "Unexpected library builder ${libraryBuilder} for"
-            " constructor $this in ${library}.");
-        libraryBuilder.loader
-            .registerConstructorToBeInferred(_constructor, this);
-      }
-    }
-    return _constructor;
-  }
-
-  /// Infers the types of any untyped initializing formals.
-  void inferFormalTypes(ClassHierarchy classHierarchy) {
-    if (_hasFormalsInferred) return;
-    if (formals != null) {
-      for (FormalParameterBuilder formal in formals!) {
-        if (formal.type == null) {
-          if (formal.isInitializingFormal) {
-            formal.finalizeInitializingFormal(classBuilder);
-          }
-        }
-      }
-
-      if (_hasSuperInitializingFormals) {
-        if (beginInitializers != null) {
-          BodyBuilder bodyBuilder = library.loader
-              .createBodyBuilderForOutlineExpression(
-                  library, classBuilder, this, classBuilder.scope, fileUri);
-          bodyBuilder.constantContext = ConstantContext.required;
-          bodyBuilder.parseInitializers(beginInitializers!,
-              doFinishConstructor: false);
-        }
-        finalizeSuperInitializingFormals(
-            classHierarchy, _superParameterDefaultValueCloners);
-      }
-    }
-    _hasFormalsInferred = true;
-  }
-
-  /* ConstructorBuilder | DillConstructorBuilder */
-  Object? _computeSuperTargetBuilder() {
-    Constructor superTarget;
-    ClassBuilder superclassBuilder;
-
-    TypeBuilder? supertype = classBuilder.supertypeBuilder;
-    if (supertype is NamedTypeBuilder) {
-      TypeDeclarationBuilder? declaration = supertype.declaration;
-      if (declaration is ClassBuilder) {
-        superclassBuilder = declaration;
-      } else if (declaration is TypeAliasBuilder) {
-        declaration = declaration.unaliasDeclaration(supertype.arguments);
-        if (declaration is ClassBuilder) {
-          superclassBuilder = declaration;
-        } else {
-          // The error in this case should be reported elsewhere.
-          return null;
-        }
-      } else {
-        // The error in this case should be reported elsewhere.
-        return null;
-      }
-    } else {
-      // The error in this case should be reported elsewhere.
-      return null;
-    }
-
-    if (constructor.initializers.isNotEmpty &&
-        constructor.initializers.last is SuperInitializer) {
-      superTarget = (constructor.initializers.last as SuperInitializer).target;
-    } else {
-      MemberBuilder? memberBuilder = superclassBuilder.constructors
-          .lookup("", charOffset, library.fileUri);
-      if (memberBuilder is ConstructorBuilder) {
-        superTarget = memberBuilder.constructor;
-      } else if (memberBuilder is DillConstructorBuilder) {
-        superTarget = memberBuilder.constructor;
-      } else {
-        // The error in this case should be reported elsewhere.
-        return null;
-      }
-    }
-
-    MemberBuilder? constructorBuilder =
-        superclassBuilder.findConstructorOrFactory(
-            superTarget.name.text, charOffset, library.fileUri, library);
-    return constructorBuilder is ConstructorBuilder ||
-            constructorBuilder is DillConstructorBuilder
-        ? constructorBuilder
-        : null;
-  }
-
-  void finalizeSuperInitializingFormals(ClassHierarchy classHierarchy,
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
-    if (formals == null) return;
-    if (!_hasSuperInitializingFormals) return;
-
-    void performRecoveryForErroneousCase() {
-      for (FormalParameterBuilder formal in formals!) {
-        if (formal.isSuperInitializingFormal) {
-          formal.variable!.type = const DynamicType();
-        }
-      }
-    }
-
-    Object? superTargetBuilder = _computeSuperTargetBuilder();
-    Constructor superTarget;
-    List<FormalParameterBuilder>? superFormals;
-    if (superTargetBuilder is SourceConstructorBuilder) {
-      superTarget = superTargetBuilder.constructor;
-      superFormals = superTargetBuilder.formals!;
-    } else if (superTargetBuilder is DillConstructorBuilder) {
-      superTarget = superTargetBuilder.constructor;
-      if (superTargetBuilder is SyntheticConstructorBuilder) {
-        superFormals = superTargetBuilder.formals;
-      } else {
-        // The error in this case should be reported elsewhere. Here we perform
-        // a simple recovery.
-        return performRecoveryForErroneousCase();
-      }
-    } else {
-      // The error in this case should be reported elsewhere. Here we perform a
-      // simple recovery.
-      return performRecoveryForErroneousCase();
-    }
-
-    if (superFormals == null) {
-      // The error in this case should be reported elsewhere. Here we perform a
-      // simple recovery.
-      return performRecoveryForErroneousCase();
-    }
-
-    if (superTargetBuilder is SourceConstructorBuilder) {
-      superTargetBuilder.inferFormalTypes(classHierarchy);
-    } else if (superTargetBuilder is SyntheticConstructorBuilder) {
-      MemberBuilder? superTargetOriginBuilder = superTargetBuilder.actualOrigin;
-      if (superTargetOriginBuilder is SourceConstructorBuilder) {
-        superTargetOriginBuilder.inferFormalTypes(classHierarchy);
-      }
-    }
-
-    int superInitializingFormalIndex = -1;
-    List<int>? positionalSuperParameters;
-    List<String>? namedSuperParameters;
-
-    Supertype? supertype = classHierarchy.getClassAsInstanceOf(
-        classBuilder.cls, superTarget.enclosingClass);
-    assert(supertype != null);
-    Map<TypeParameter, DartType> substitution =
-        new Map<TypeParameter, DartType>.fromIterables(
-            supertype!.classNode.typeParameters, supertype.typeArguments);
-
-    for (int formalIndex = 0; formalIndex < formals!.length; formalIndex++) {
-      FormalParameterBuilder formal = formals![formalIndex];
-      if (formal.isSuperInitializingFormal) {
-        superInitializingFormalIndex++;
-        bool hasImmediatelyDeclaredInitializer = formal.hasDeclaredInitializer;
-        if (formal.type == null) {
-          DartType? type;
-
-          if (formal.isPositional) {
-            if (superInitializingFormalIndex < superFormals.length) {
-              FormalParameterBuilder correspondingSuperFormal =
-                  superFormals[superInitializingFormalIndex];
-              formal.hasDeclaredInitializer =
-                  hasImmediatelyDeclaredInitializer ||
-                      correspondingSuperFormal.hasDeclaredInitializer;
-              if (!hasImmediatelyDeclaredInitializer) {
-                (positionalSuperParameters ??= <int>[]).add(formalIndex);
-              }
-              type = correspondingSuperFormal.variable!.type;
-            } else {
-              // TODO(cstefantsova): Report an error.
-            }
-          } else {
-            FormalParameterBuilder? correspondingSuperFormal;
-            for (FormalParameterBuilder superFormal in superFormals) {
-              if (superFormal.isNamed && superFormal.name == formal.name) {
-                correspondingSuperFormal = superFormal;
-                break;
-              }
-            }
-
-            if (correspondingSuperFormal != null) {
-              formal.hasDeclaredInitializer =
-                  hasImmediatelyDeclaredInitializer ||
-                      correspondingSuperFormal.hasDeclaredInitializer;
-              if (!hasImmediatelyDeclaredInitializer) {
-                (namedSuperParameters ??= <String>[]).add(formal.name);
-              }
-              type = correspondingSuperFormal.variable!.type;
-            } else {
-              // TODO(cstefantsova): Report an error.
-            }
-          }
-
-          if (substitution.isNotEmpty && type != null) {
-            type = substitute(type, substitution);
-          }
-          formal.variable!.type = type ?? const DynamicType();
-        } else {
-          formal.variable!.type = const DynamicType();
-        }
-      }
-    }
-
-    if (positionalSuperParameters != null || namedSuperParameters != null) {
-      synthesizedFunctionNodes.add(new SynthesizedFunctionNode(
-          substitution, superTarget.function, constructor.function,
-          positionalSuperParameters: positionalSuperParameters ?? const <int>[],
-          namedSuperParameters: namedSuperParameters ?? const <String>[],
-          isOutlineNode: true));
-    }
-  }
-
-  bool _hasBuiltOutlines = false;
-
-  @override
-  void buildOutlineExpressions(
-      SourceLibraryBuilder library,
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
-    if (_hasBuiltOutlines) return;
-    if (isConst && isPatch) {
-      origin.buildOutlineExpressions(library, classHierarchy,
-          delayedActionPerformers, synthesizedFunctionNodes);
-    }
-    super.buildOutlineExpressions(library, classHierarchy,
-        delayedActionPerformers, synthesizedFunctionNodes);
-
-    // For modular compilation purposes we need to include initializers
-    // for const constructors into the outline. We also need to parse
-    // initializers to infer types of the super-initializing parameters.
-    if ((isConst || _hasSuperInitializingFormals) &&
-        beginInitializers != null) {
-      BodyBuilder bodyBuilder = library.loader
-          .createBodyBuilderForOutlineExpression(
-              library, classBuilder, this, classBuilder.scope, fileUri);
-      bodyBuilder.constantContext = ConstantContext.required;
-      bodyBuilder.parseInitializers(beginInitializers!,
-          doFinishConstructor: isConst);
-      bodyBuilder.performBacklogComputations(delayedActionPerformers);
-    }
-    beginInitializers = null;
-    addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
-    if (isConst && isPatch) {
-      _finishPatch();
-    }
-    _hasBuiltOutlines = true;
-  }
-
-  void addSuperParameterDefaultValueCloners(
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
-    Object? superTargetBuilder = _computeSuperTargetBuilder();
-    if (superTargetBuilder is SourceConstructorBuilder) {
-      superTargetBuilder
-          .addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
-    } else if (superTargetBuilder is SyntheticConstructorBuilder) {
-      superTargetBuilder
-          .addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
-    }
-    synthesizedFunctionNodes.addAll(_superParameterDefaultValueCloners);
-    _superParameterDefaultValueCloners.clear();
-  }
-
-  @override
-  void buildFunction(SourceLibraryBuilder library) {
-    // According to the specification §9.3 the return type of a constructor
-    // function is its enclosing class.
-    super.buildFunction(library);
-    Class enclosingClass = classBuilder.cls;
-    List<DartType> typeParameterTypes = <DartType>[];
-    for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
-      TypeParameter typeParameter = enclosingClass.typeParameters[i];
-      typeParameterTypes.add(
-          new TypeParameterType.withDefaultNullabilityForLibrary(
-              typeParameter, library.library));
-    }
-    function.returnType = new InterfaceType(
-        enclosingClass, library.nonNullable, typeParameterTypes);
-  }
-
-  @override
-  Constructor get constructor => isPatch ? origin.constructor : _constructor;
-
-  @override
-  Member get member => constructor;
-
-  void injectInvalidInitializer(Message message, int charOffset, int length,
-      ExpressionGeneratorHelper helper) {
-    List<Initializer> initializers = _constructor.initializers;
-    Initializer lastInitializer = initializers.removeLast();
-    assert(lastInitializer == superInitializer ||
-        lastInitializer == redirectingInitializer);
-    Initializer error = helper.buildInvalidInitializer(
-        helper.buildProblem(message, charOffset, length));
-    initializers.add(error..parent = _constructor);
-    initializers.add(lastInitializer);
-  }
-
-  void addInitializer(Initializer initializer, ExpressionGeneratorHelper helper,
-      {required InitializerInferenceResult? inferenceResult}) {
-    List<Initializer> initializers = _constructor.initializers;
-    if (initializer is SuperInitializer) {
-      if (superInitializer != null) {
-        injectInvalidInitializer(messageMoreThanOneSuperInitializer,
-            initializer.fileOffset, "super".length, helper);
-      } else if (redirectingInitializer != null) {
-        injectInvalidInitializer(
-            messageRedirectingConstructorWithSuperInitializer,
-            initializer.fileOffset,
-            "super".length,
-            helper);
-      } else {
-        inferenceResult?.applyResult(initializers, _constructor);
-        initializers.add(initializer..parent = _constructor);
-        superInitializer = initializer;
-      }
-    } else if (initializer is RedirectingInitializer) {
-      if (superInitializer != null) {
-        // Point to the existing super initializer.
-        injectInvalidInitializer(
-            messageRedirectingConstructorWithSuperInitializer,
-            superInitializer!.fileOffset,
-            "super".length,
-            helper);
-      } else if (redirectingInitializer != null) {
-        injectInvalidInitializer(
-            messageRedirectingConstructorWithMultipleRedirectInitializers,
-            initializer.fileOffset,
-            noLength,
-            helper);
-      } else if (initializers.isNotEmpty) {
-        // Error on all previous ones.
-        for (int i = 0; i < initializers.length; i++) {
-          Initializer initializer = initializers[i];
-          int length = noLength;
-          if (initializer is AssertInitializer) length = "assert".length;
-          Initializer error = helper.buildInvalidInitializer(
-              helper.buildProblem(
-                  messageRedirectingConstructorWithAnotherInitializer,
-                  initializer.fileOffset,
-                  length));
-          error.parent = _constructor;
-          initializers[i] = error;
-        }
-        inferenceResult?.applyResult(initializers, _constructor);
-        initializers.add(initializer..parent = _constructor);
-        redirectingInitializer = initializer;
-      } else {
-        inferenceResult?.applyResult(initializers, _constructor);
-        initializers.add(initializer..parent = _constructor);
-        redirectingInitializer = initializer;
-      }
-    } else if (redirectingInitializer != null) {
-      int length = noLength;
-      if (initializer is AssertInitializer) length = "assert".length;
-      injectInvalidInitializer(
-          messageRedirectingConstructorWithAnotherInitializer,
-          initializer.fileOffset,
-          length,
-          helper);
-    } else if (superInitializer != null) {
-      injectInvalidInitializer(messageSuperInitializerNotLast,
-          initializer.fileOffset, noLength, helper);
-    } else {
-      inferenceResult?.applyResult(initializers, _constructor);
-      initializers.add(initializer..parent = _constructor);
-    }
-  }
-
-  @override
-  VariableDeclaration? getTearOffParameter(int index) {
-    if (_constructorTearOff != null) {
-      if (index < _constructorTearOff!.function.positionalParameters.length) {
-        return _constructorTearOff!.function.positionalParameters[index];
-      } else {
-        index -= _constructorTearOff!.function.positionalParameters.length;
-        if (index < _constructorTearOff!.function.namedParameters.length) {
-          return _constructorTearOff!.function.namedParameters[index];
-        }
-      }
-    }
-    return null;
-  }
-
-  void _finishPatch() {
-    // TODO(ahe): restore file-offset once we track both origin and patch file
-    // URIs. See https://github.com/dart-lang/sdk/issues/31579
-    origin.constructor.fileUri = fileUri;
-    origin.constructor.startFileOffset = _constructor.startFileOffset;
-    origin.constructor.fileOffset = _constructor.fileOffset;
-    origin.constructor.fileEndOffset = _constructor.fileEndOffset;
-    origin.constructor.annotations
-        .forEach((m) => m.fileOffset = _constructor.fileOffset);
-
-    origin.constructor.isExternal = _constructor.isExternal;
-    origin.constructor.function = _constructor.function;
-    origin.constructor.function.parent = origin.constructor;
-    origin.constructor.initializers = _constructor.initializers;
-    setParents(origin.constructor.initializers, origin.constructor);
-  }
-
-  @override
-  int finishPatch() {
-    if (!isPatch) return 0;
-    _finishPatch();
-    return 1;
-  }
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    _constructor.isExternal = true;
-    super.becomeNative(loader);
-  }
-
-  @override
-  void applyPatch(Builder patch) {
-    if (patch is SourceConstructorBuilder) {
-      if (checkPatch(patch)) {
-        patch.actualOrigin = this;
-        dataForTesting?.patchForTesting = patch;
-      }
-    } else {
-      reportPatchMismatch(patch);
-    }
-  }
-
-  void prepareInitializers() {
-    // For const constructors we parse initializers already at the outlining
-    // stage, there is no easy way to make body building stage skip initializer
-    // parsing, so we simply clear parsed initializers and rebuild them
-    // again.
-    // For when doing an experimental incremental compilation they are also
-    // potentially done more than once (because it rebuilds the bodies of an old
-    // compile), and so we also clear them.
-    // Note: this method clears both initializers from the target Kernel node
-    // and internal state associated with parsing initializers.
-    _constructor.initializers = [];
-    redirectingInitializer = null;
-    superInitializer = null;
-    hasMovedSuperInitializer = false;
-  }
-
-  @override
-  List<ClassMember> get localMembers =>
-      throw new UnsupportedError('${runtimeType}.localMembers');
-
-  @override
-  List<ClassMember> get localSetters =>
-      throw new UnsupportedError('${runtimeType}.localSetters');
-
-  /// Registers field as being initialized by this constructor.
-  ///
-  /// The field can be initialized either via an initializing formal or via an
-  /// entry in the constructor initializer list.
-  void registerInitializedField(FieldBuilder fieldBuilder) {
-    (_initializedFields ??= {}).add(fieldBuilder);
-  }
-
-  /// Returns the fields registered as initialized by this constructor.
-  ///
-  /// Returns the set of fields previously registered via
-  /// [registerInitializedField] and passes on the ownership of the collection
-  /// to the caller.
-  Set<FieldBuilder>? takeInitializedFields() {
-    Set<FieldBuilder>? result = _initializedFields;
-    _initializedFields = null;
-    return result;
-  }
-}
-
-class SyntheticConstructorBuilder extends DillConstructorBuilder
-    with SourceMemberBuilderMixin {
-  // TODO(johnniwinther,cstefantsova): Rename [_origin] to avoid the confusion
-  // with patches.
-  // TODO(johnniwinther): Change the type of [_origin] to SourceMemberBuilder
-  // when it's the supertype for both old SourceMemberBuilder and
-  // SyntheticConstructorBuilder.
-  MemberBuilder? _origin;
-  SynthesizedFunctionNode? _synthesizedFunctionNode;
-
-  SyntheticConstructorBuilder(SourceClassBuilder parent,
-      Constructor constructor, Procedure? constructorTearOff,
-      {MemberBuilder? origin, SynthesizedFunctionNode? synthesizedFunctionNode})
-      : _origin = origin,
-        _synthesizedFunctionNode = synthesizedFunctionNode,
-        super(constructor, constructorTearOff, parent);
-
-  // TODO(johnniwinther,cstefantsova): Rename [actualOrigin] to avoid the
-  //  confusion with patches.
-  MemberBuilder? get actualOrigin {
-    MemberBuilder? origin = _origin;
-    while (origin is SyntheticConstructorBuilder) {
-      origin = origin._origin;
-    }
-    return origin;
-  }
-
-  List<FormalParameterBuilder>? get formals {
-    MemberBuilder? origin = actualOrigin;
-    return origin is SourceConstructorBuilder ? origin.formals : null;
-  }
-
-  @override
-  void buildOutlineExpressions(
-      SourceLibraryBuilder libraryBuilder,
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
-    if (_origin != null) {
-      // Ensure that default value expressions have been created for [_origin].
-      LibraryBuilder originLibraryBuilder = _origin!.library;
-      if (originLibraryBuilder is SourceLibraryBuilder) {
-        // If [_origin] is from a source library, we need to build the default
-        // values and initializers first.
-        MemberBuilder origin = _origin!;
-        if (origin is SourceConstructorBuilder) {
-          origin.buildOutlineExpressions(originLibraryBuilder, classHierarchy,
-              delayedActionPerformers, synthesizedFunctionNodes);
-        } else if (origin is SyntheticConstructorBuilder) {
-          origin.buildOutlineExpressions(originLibraryBuilder, classHierarchy,
-              delayedActionPerformers, synthesizedFunctionNodes);
-        }
-      }
-      addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
-      _origin = null;
-    }
-  }
-
-  void addSuperParameterDefaultValueCloners(
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
-    MemberBuilder? origin = _origin;
-    if (origin is SourceConstructorBuilder) {
-      origin.addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
-    } else if (origin is SyntheticConstructorBuilder) {
-      origin.addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
-    }
-    if (_synthesizedFunctionNode != null) {
-      synthesizedFunctionNodes
-          .add(_synthesizedFunctionNode!..isOutlineNode = true);
-      _synthesizedFunctionNode = null;
-    }
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/builder/field_builder.dart b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
index 251ad96..725b34c 100644
--- a/pkg/front_end/lib/src/fasta/builder/field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/field_builder.dart
@@ -4,43 +4,9 @@
 
 library fasta.field_builder;
 
-import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
-
 import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/core_types.dart';
-import 'package:kernel/src/legacy_erasure.dart';
-import 'package:kernel/type_algebra.dart';
 
-import '../constant_context.dart' show ConstantContext;
-
-import '../fasta_codes.dart' show messageInternalProblemAlreadyInitialized;
-
-import '../kernel/body_builder.dart' show BodyBuilder;
-import '../kernel/hierarchy/class_member.dart';
-import '../kernel/hierarchy/members_builder.dart';
-import '../kernel/implicit_field_type.dart';
-import '../kernel/kernel_helper.dart';
-import '../kernel/late_lowering.dart' as late_lowering;
-import '../kernel/member_covariance.dart';
-
-import '../modifier.dart' show covariantMask, hasInitializerMask, lateMask;
-
-import '../problems.dart' show internalProblem;
-
-import '../scope.dart' show Scope;
-
-import '../source/name_scheme.dart';
-import '../source/source_extension_builder.dart';
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-import '../source/source_loader.dart' show SourceLoader;
-
-import '../type_inference/type_inference_engine.dart'
-    show IncludesTypeParametersNonCovariantly;
-
-import '../util/helpers.dart' show DelayedActionPerformer;
-
-import 'class_builder.dart';
 import 'member_builder.dart';
 import 'metadata_builder.dart';
 import 'type_builder.dart';
@@ -82,1776 +48,3 @@
 
   DartType get fieldType;
 }
-
-class SourceFieldBuilder extends SourceMemberBuilderImpl
-    implements FieldBuilder {
-  @override
-  final String name;
-
-  @override
-  final int modifiers;
-
-  late FieldEncoding _fieldEncoding;
-
-  @override
-  final List<MetadataBuilder>? metadata;
-
-  @override
-  final TypeBuilder? type;
-
-  Token? _constInitializerToken;
-
-  bool hadTypesInferred = false;
-
-  @override
-  bool hasBodyBeenBuilt = false;
-
-  // TODO(johnniwinther): [parent] is not trust-worthy for determining
-  //  properties since it is changed after the creation of the builder. For now
-  //  we require it has an argument here. A follow-up should clean up the
-  //  misuse of parent.
-  @override
-  final bool isTopLevel;
-
-  SourceFieldBuilder(
-      this.metadata,
-      this.type,
-      this.name,
-      this.modifiers,
-      this.isTopLevel,
-      SourceLibraryBuilder libraryBuilder,
-      int charOffset,
-      int charEndOffset,
-      NameScheme fieldNameScheme,
-      {Reference? fieldReference,
-      Reference? fieldGetterReference,
-      Reference? fieldSetterReference,
-      Reference? lateIsSetFieldReference,
-      Reference? lateIsSetGetterReference,
-      Reference? lateIsSetSetterReference,
-      Reference? lateGetterReference,
-      Reference? lateSetterReference,
-      Token? constInitializerToken})
-      : _constInitializerToken = constInitializerToken,
-        super(libraryBuilder, charOffset) {
-    bool isInstanceMember = fieldNameScheme.isInstanceMember;
-
-    Uri fileUri = libraryBuilder.fileUri;
-    // If in mixed mode, late lowerings cannot use `null` as a sentinel on
-    // non-nullable fields since they can be assigned from legacy code.
-    late_lowering.IsSetStrategy isSetStrategy =
-        late_lowering.computeIsSetStrategy(libraryBuilder);
-
-    if (isAbstract || isExternal) {
-      assert(fieldReference == null);
-      assert(lateIsSetFieldReference == null);
-      assert(lateIsSetGetterReference == null);
-      assert(lateIsSetSetterReference == null);
-      assert(lateGetterReference == null);
-      assert(lateSetterReference == null);
-      _fieldEncoding = new AbstractOrExternalFieldEncoding(
-          this,
-          name,
-          fieldNameScheme,
-          fileUri,
-          charOffset,
-          charEndOffset,
-          fieldGetterReference,
-          fieldSetterReference,
-          isAbstract: isAbstract,
-          isExternal: isExternal,
-          isFinal: isFinal,
-          isCovariantByDeclaration: isCovariantByDeclaration,
-          isNonNullableByDefault: library.isNonNullableByDefault);
-    } else if (isLate &&
-        libraryBuilder.loader.target.backendTarget.isLateFieldLoweringEnabled(
-            hasInitializer: hasInitializer,
-            isFinal: isFinal,
-            isStatic: !isInstanceMember)) {
-      if (hasInitializer) {
-        if (isFinal) {
-          _fieldEncoding = new LateFinalFieldWithInitializerEncoding(
-              name,
-              fieldNameScheme,
-              fileUri,
-              charOffset,
-              charEndOffset,
-              fieldReference,
-              fieldGetterReference,
-              fieldSetterReference,
-              lateIsSetFieldReference,
-              lateIsSetGetterReference,
-              lateIsSetSetterReference,
-              lateGetterReference,
-              lateSetterReference,
-              isCovariantByDeclaration,
-              isSetStrategy);
-        } else {
-          _fieldEncoding = new LateFieldWithInitializerEncoding(
-              name,
-              fieldNameScheme,
-              fileUri,
-              charOffset,
-              charEndOffset,
-              fieldReference,
-              fieldGetterReference,
-              fieldSetterReference,
-              lateIsSetFieldReference,
-              lateIsSetGetterReference,
-              lateIsSetSetterReference,
-              lateGetterReference,
-              lateSetterReference,
-              isCovariantByDeclaration,
-              isSetStrategy);
-        }
-      } else {
-        if (isFinal) {
-          _fieldEncoding = new LateFinalFieldWithoutInitializerEncoding(
-              name,
-              fieldNameScheme,
-              fileUri,
-              charOffset,
-              charEndOffset,
-              fieldReference,
-              fieldGetterReference,
-              fieldSetterReference,
-              lateIsSetFieldReference,
-              lateIsSetGetterReference,
-              lateIsSetSetterReference,
-              lateGetterReference,
-              lateSetterReference,
-              isCovariantByDeclaration,
-              isSetStrategy);
-        } else {
-          _fieldEncoding = new LateFieldWithoutInitializerEncoding(
-              name,
-              fieldNameScheme,
-              fileUri,
-              charOffset,
-              charEndOffset,
-              fieldReference,
-              fieldGetterReference,
-              fieldSetterReference,
-              lateIsSetFieldReference,
-              lateIsSetGetterReference,
-              lateIsSetSetterReference,
-              lateGetterReference,
-              lateSetterReference,
-              isCovariantByDeclaration,
-              isSetStrategy);
-        }
-      }
-    } else if (libraryBuilder.isNonNullableByDefault &&
-        libraryBuilder.loader.target.backendTarget.useStaticFieldLowering &&
-        !isInstanceMember &&
-        !isConst &&
-        hasInitializer) {
-      if (isFinal) {
-        _fieldEncoding = new LateFinalFieldWithInitializerEncoding(
-            name,
-            fieldNameScheme,
-            fileUri,
-            charOffset,
-            charEndOffset,
-            fieldReference,
-            fieldGetterReference,
-            fieldSetterReference,
-            lateIsSetFieldReference,
-            lateIsSetGetterReference,
-            lateIsSetSetterReference,
-            lateGetterReference,
-            lateSetterReference,
-            isCovariantByDeclaration,
-            isSetStrategy);
-      } else {
-        _fieldEncoding = new LateFieldWithInitializerEncoding(
-            name,
-            fieldNameScheme,
-            fileUri,
-            charOffset,
-            charEndOffset,
-            fieldReference,
-            fieldGetterReference,
-            fieldSetterReference,
-            lateIsSetFieldReference,
-            lateIsSetGetterReference,
-            lateIsSetSetterReference,
-            lateGetterReference,
-            lateSetterReference,
-            isCovariantByDeclaration,
-            isSetStrategy);
-      }
-    } else {
-      assert(lateIsSetFieldReference == null);
-      assert(lateIsSetGetterReference == null);
-      assert(lateIsSetSetterReference == null);
-      assert(lateGetterReference == null);
-      assert(lateSetterReference == null);
-      _fieldEncoding = new RegularFieldEncoding(
-          name, fieldNameScheme, fileUri, charOffset, charEndOffset,
-          isFinal: isFinal,
-          isConst: isConst,
-          isLate: isLate,
-          hasInitializer: hasInitializer,
-          isNonNullableByDefault: library.isNonNullableByDefault,
-          fieldReference: fieldReference,
-          getterReference: fieldGetterReference,
-          setterReference: fieldSetterReference);
-    }
-  }
-
-  bool get isLateLowered => _fieldEncoding.isLateLowering;
-
-  bool _typeEnsured = false;
-  Set<ClassMember>? _overrideDependencies;
-
-  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
-    assert(
-        overriddenMembers.every((overriddenMember) =>
-            overriddenMember.classBuilder != classBuilder),
-        "Unexpected override dependencies for $this: $overriddenMembers");
-    _overrideDependencies ??= {};
-    _overrideDependencies!.addAll(overriddenMembers);
-  }
-
-  void _ensureType(ClassMembersBuilder membersBuilder) {
-    if (_typeEnsured) return;
-    if (_overrideDependencies != null) {
-      membersBuilder.inferFieldType(this, _overrideDependencies!);
-      _overrideDependencies = null;
-    } else {
-      inferType();
-    }
-    _typeEnsured = true;
-  }
-
-  @override
-  SourceLibraryBuilder get library => super.library as SourceLibraryBuilder;
-
-  @override
-  Member get member => _fieldEncoding.field;
-
-  @override
-  String get debugName => "FieldBuilder";
-
-  @override
-  bool get isField => true;
-
-  @override
-  bool get isLate => (modifiers & lateMask) != 0;
-
-  @override
-  bool get isCovariantByDeclaration => (modifiers & covariantMask) != 0;
-
-  @override
-  bool get hasInitializer => (modifiers & hasInitializerMask) != 0;
-
-  @override
-  void buildBody(CoreTypes coreTypes, Expression? initializer) {
-    assert(!hasBodyBeenBuilt);
-    hasBodyBeenBuilt = true;
-    if (!hasInitializer &&
-        initializer != null &&
-        initializer is! NullLiteral &&
-        !isConst &&
-        !isFinal) {
-      internalProblem(
-          messageInternalProblemAlreadyInitialized, charOffset, fileUri);
-    }
-    _fieldEncoding.createBodies(coreTypes, initializer);
-  }
-
-  @override
-  List<Initializer> buildInitializer(int fileOffset, Expression value,
-      {required bool isSynthetic}) {
-    return _fieldEncoding.createInitializer(fileOffset, value,
-        isSynthetic: isSynthetic);
-  }
-
-  @override
-  bool get isEligibleForInference {
-    return type == null && (hasInitializer || isClassInstanceMember);
-  }
-
-  @override
-  bool get isAssignable {
-    if (isConst) return false;
-    if (isFinal) {
-      if (isLate) {
-        return !hasInitializer;
-      }
-      return false;
-    }
-    return true;
-  }
-
-  @override
-  Field get field => _fieldEncoding.field;
-
-  @override
-  Member get readTarget => _fieldEncoding.readTarget;
-
-  @override
-  Member? get writeTarget {
-    return isAssignable ? _fieldEncoding.writeTarget : null;
-  }
-
-  @override
-  Member get invokeTarget => readTarget;
-
-  @override
-  Iterable<Member> get exportedMembers => _fieldEncoding.exportedMembers;
-
-  @override
-  void buildMembers(
-      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
-    build(library);
-    _fieldEncoding.registerMembers(library, this, f);
-  }
-
-  /// Builds the core AST structures for this field as needed for the outline.
-  void build(SourceLibraryBuilder libraryBuilder) {
-    if (type != null) {
-      fieldType = type!.build(libraryBuilder);
-    }
-    _fieldEncoding.build(libraryBuilder, this);
-  }
-
-  @override
-  void buildOutlineExpressions(
-      SourceLibraryBuilder library,
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
-    _fieldEncoding.completeSignature(classHierarchy.coreTypes);
-
-    for (Annotatable annotatable in _fieldEncoding.annotatables) {
-      MetadataBuilder.buildAnnotations(
-          annotatable,
-          metadata,
-          library,
-          declarationBuilder,
-          this,
-          fileUri,
-          declarationBuilder?.scope ?? library.scope);
-    }
-
-    // For modular compilation we need to include initializers of all const
-    // fields and all non-static final fields in classes with const constructors
-    // into the outline.
-    if ((isConst ||
-            (isFinal &&
-                !isStatic &&
-                isClassMember &&
-                classBuilder!.declaresConstConstructor)) &&
-        _constInitializerToken != null) {
-      Scope scope = declarationBuilder?.scope ?? library.scope;
-      BodyBuilder bodyBuilder = library.loader
-          .createBodyBuilderForOutlineExpression(
-              library, declarationBuilder, this, scope, fileUri);
-      bodyBuilder.constantContext =
-          isConst ? ConstantContext.inferred : ConstantContext.required;
-      Expression initializer = bodyBuilder.typeInferrer.inferFieldInitializer(
-          bodyBuilder,
-          fieldType,
-          bodyBuilder.parseFieldInitializer(_constInitializerToken!));
-      if (bodyBuilder.transformSetLiterals ||
-          bodyBuilder.transformCollections) {
-        // Wrap the initializer in a temporary parent expression; the
-        // transformations need a parent relation.
-        Not wrapper = new Not(initializer);
-        SourceLoader loader = library.loader;
-        loader.transformPostInference(wrapper, bodyBuilder.transformSetLiterals,
-            bodyBuilder.transformCollections, library.library);
-        initializer = wrapper.operand;
-      }
-      buildBody(classHierarchy.coreTypes, initializer);
-      bodyBuilder.performBacklogComputations(delayedActionPerformers);
-    }
-    _constInitializerToken = null;
-  }
-
-  @override
-  DartType get fieldType => _fieldEncoding.type;
-
-  void set fieldType(DartType value) {
-    _fieldEncoding.type = value;
-    if (!isFinal && !isConst && parent is ClassBuilder) {
-      Class enclosingClass = classBuilder!.cls;
-      if (enclosingClass.typeParameters.isNotEmpty) {
-        IncludesTypeParametersNonCovariantly needsCheckVisitor =
-            new IncludesTypeParametersNonCovariantly(
-                enclosingClass.typeParameters,
-                // We are checking the field type as if it is the type of the
-                // parameter of the implicit setter and this is a contravariant
-                // position.
-                initialVariance: Variance.contravariant);
-        if (value.accept(needsCheckVisitor)) {
-          _fieldEncoding.setGenericCovariantImpl();
-        }
-      }
-    }
-  }
-
-  @override
-  DartType inferType() {
-    SourceLibraryBuilder library = this.library;
-    if (fieldType is! ImplicitFieldType) {
-      // We have already inferred a type.
-      return fieldType;
-    }
-
-    ImplicitFieldType implicitFieldType = fieldType as ImplicitFieldType;
-    DartType inferredType = implicitFieldType.computeType();
-    if (fieldType is ImplicitFieldType) {
-      // `fieldType` may have changed if a circularity was detected when
-      // [inferredType] was computed.
-      if (!library.isNonNullableByDefault) {
-        inferredType = legacyErasure(inferredType);
-      }
-      fieldType = implicitFieldType.checkInferred(inferredType);
-
-      IncludesTypeParametersNonCovariantly? needsCheckVisitor;
-      if (parent is ClassBuilder) {
-        Class enclosingClass = classBuilder!.cls;
-        if (enclosingClass.typeParameters.isNotEmpty) {
-          needsCheckVisitor = new IncludesTypeParametersNonCovariantly(
-              enclosingClass.typeParameters,
-              // We are checking the field type as if it is the type of the
-              // parameter of the implicit setter and this is a contravariant
-              // position.
-              initialVariance: Variance.contravariant);
-        }
-      }
-      if (needsCheckVisitor != null) {
-        if (fieldType.accept(needsCheckVisitor)) {
-          _fieldEncoding.setGenericCovariantImpl();
-        }
-      }
-    }
-    return fieldType;
-  }
-
-  @override
-  DartType get builtType => fieldType;
-
-  List<ClassMember>? _localMembers;
-  List<ClassMember>? _localSetters;
-
-  @override
-  List<ClassMember> get localMembers =>
-      _localMembers ??= _fieldEncoding.getLocalMembers(this);
-
-  @override
-  List<ClassMember> get localSetters =>
-      _localSetters ??= _fieldEncoding.getLocalSetters(this);
-}
-
-/// Strategy pattern for creating different encodings of a declared field.
-///
-/// This is used to provide lowerings for late fields using synthesized getters
-/// and setters.
-abstract class FieldEncoding {
-  /// The type of the declared field.
-  abstract DartType type;
-
-  /// Creates the bodies needed for the field encoding using [initializer] as
-  /// the declared initializer expression.
-  ///
-  /// This method is not called for fields in outlines unless their are constant
-  /// or part of a const constructor.
-  void createBodies(CoreTypes coreTypes, Expression? initializer);
-
-  List<Initializer> createInitializer(int fileOffset, Expression value,
-      {required bool isSynthetic});
-
-  /// Registers that the (implicit) setter associated with this field needs to
-  /// contain a runtime type check to deal with generic covariance.
-  void setGenericCovariantImpl();
-
-  /// Returns the field that holds the field value at runtime.
-  Field get field;
-
-  /// Returns the members that holds the field annotations.
-  Iterable<Annotatable> get annotatables;
-
-  /// Returns the member used to read the field value.
-  Member get readTarget;
-
-  /// Returns the member used to write to the field.
-  Member? get writeTarget;
-
-  /// Returns the generated members that are visible through exports.
-  Iterable<Member> get exportedMembers;
-
-  /// Creates the members necessary for this field encoding.
-  ///
-  /// This method is called for both outline and full compilation so the created
-  /// members should be without body. The member bodies are created through
-  /// [createBodies].
-  void build(
-      SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder);
-
-  /// Calls [f] for each member needed for this field encoding.
-  void registerMembers(
-      SourceLibraryBuilder library,
-      SourceFieldBuilder fieldBuilder,
-      void Function(Member, BuiltMemberKind) f);
-
-  /// Returns a list of the field, getters and methods created by this field
-  /// encoding.
-  List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder);
-
-  /// Returns a list of the setters created by this field encoding.
-  List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder);
-
-  /// Ensures that the signatures all members created by this field encoding
-  /// are fully typed.
-  void completeSignature(CoreTypes coreTypes);
-
-  /// Returns `true` if this encoding is a late lowering.
-  bool get isLateLowering;
-}
-
-class RegularFieldEncoding implements FieldEncoding {
-  late final Field _field;
-
-  RegularFieldEncoding(String name, NameScheme nameScheme, Uri fileUri,
-      int charOffset, int charEndOffset,
-      {required bool isFinal,
-      required bool isConst,
-      required bool isLate,
-      required bool hasInitializer,
-      required bool isNonNullableByDefault,
-      required Reference? fieldReference,
-      required Reference? getterReference,
-      required Reference? setterReference}) {
-    // ignore: unnecessary_null_comparison
-    assert(isFinal != null);
-    // ignore: unnecessary_null_comparison
-    assert(isConst != null);
-    // ignore: unnecessary_null_comparison
-    assert(isLate != null);
-    // ignore: unnecessary_null_comparison
-    assert(hasInitializer != null);
-    bool isImmutable =
-        isLate ? (isFinal && hasInitializer) : (isFinal || isConst);
-    _field = isImmutable
-        ? new Field.immutable(
-            nameScheme.getFieldName(FieldNameType.Field, name,
-                isSynthesized: false),
-            isFinal: isFinal,
-            isConst: isConst,
-            isLate: isLate,
-            fileUri: fileUri,
-            fieldReference: fieldReference,
-            getterReference: getterReference)
-        : new Field.mutable(
-            nameScheme.getFieldName(FieldNameType.Field, name,
-                isSynthesized: false),
-            isFinal: isFinal,
-            isLate: isLate,
-            fileUri: fileUri,
-            fieldReference: fieldReference,
-            getterReference: getterReference,
-            setterReference: setterReference);
-    _field
-      ..fileOffset = charOffset
-      ..fileEndOffset = charEndOffset
-      ..isNonNullableByDefault = isNonNullableByDefault;
-  }
-
-  @override
-  DartType get type => _field.type;
-
-  @override
-  void set type(DartType value) {
-    _field.type = value;
-  }
-
-  @override
-  void completeSignature(CoreTypes coreTypes) {}
-
-  @override
-  void createBodies(CoreTypes coreTypes, Expression? initializer) {
-    if (initializer != null) {
-      _field.initializer = initializer..parent = _field;
-    }
-  }
-
-  @override
-  List<Initializer> createInitializer(int fileOffset, Expression value,
-      {required bool isSynthetic}) {
-    return <Initializer>[
-      new FieldInitializer(_field, value)
-        ..fileOffset = fileOffset
-        ..isSynthetic = isSynthetic
-    ];
-  }
-
-  @override
-  void build(
-      SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder) {
-    _field..isCovariantByDeclaration = fieldBuilder.isCovariantByDeclaration;
-    if (fieldBuilder.isExtensionMember) {
-      _field
-        ..isStatic = true
-        ..isExtensionMember = true;
-    } else {
-      bool isInstanceMember =
-          !fieldBuilder.isStatic && !fieldBuilder.isTopLevel;
-      _field
-        ..isStatic = !isInstanceMember
-        ..isExtensionMember = false;
-    }
-    _field.isLate = fieldBuilder.isLate;
-    updatePrivateMemberName(_field, libraryBuilder);
-  }
-
-  @override
-  void registerMembers(
-      SourceLibraryBuilder library,
-      SourceFieldBuilder fieldBuilder,
-      void Function(Member, BuiltMemberKind) f) {
-    f(
-        _field,
-        fieldBuilder.isExtensionMember
-            ? BuiltMemberKind.ExtensionField
-            : BuiltMemberKind.Field);
-  }
-
-  @override
-  void setGenericCovariantImpl() {
-    _field.isCovariantByClass = true;
-  }
-
-  @override
-  Field get field => _field;
-
-  @override
-  Iterable<Annotatable> get annotatables => [_field];
-
-  @override
-  Member get readTarget => _field;
-
-  @override
-  Member get writeTarget => _field;
-
-  @override
-  Iterable<Member> get exportedMembers => [_field];
-
-  @override
-  List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) =>
-      <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: false)];
-
-  @override
-  List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) =>
-      fieldBuilder.isAssignable
-          ? <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: true)]
-          : const <ClassMember>[];
-
-  @override
-  bool get isLateLowering => false;
-}
-
-class SourceFieldMember extends BuilderClassMember {
-  @override
-  final SourceFieldBuilder memberBuilder;
-
-  Covariance? _covariance;
-
-  @override
-  final bool forSetter;
-
-  SourceFieldMember(this.memberBuilder, {required this.forSetter})
-      // ignore: unnecessary_null_comparison
-      : assert(forSetter != null);
-
-  @override
-  void inferType(ClassMembersBuilder membersBuilder) {
-    memberBuilder._ensureType(membersBuilder);
-  }
-
-  @override
-  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
-    memberBuilder.registerOverrideDependency(overriddenMembers);
-  }
-
-  @override
-  Member getMember(ClassMembersBuilder membersBuilder) {
-    memberBuilder._ensureType(membersBuilder);
-    return memberBuilder.field;
-  }
-
-  @override
-  Covariance getCovariance(ClassMembersBuilder membersBuilder) {
-    return _covariance ??= forSetter
-        ? new Covariance.fromMember(getMember(membersBuilder),
-            forSetter: forSetter)
-        : const Covariance.empty();
-  }
-
-  @override
-  bool get isSourceDeclaration => true;
-
-  @override
-  bool get isProperty => true;
-
-  @override
-  bool isSameDeclaration(ClassMember other) {
-    return other is SourceFieldMember && memberBuilder == other.memberBuilder;
-  }
-}
-
-abstract class AbstractLateFieldEncoding implements FieldEncoding {
-  final String name;
-  final int fileOffset;
-  final int fileEndOffset;
-  DartType? _type;
-  late final Field _field;
-  Field? _lateIsSetField;
-  late Procedure _lateGetter;
-  Procedure? _lateSetter;
-
-  // If `true`, an isSet field is used even when the type of the field is
-  // not potentially nullable.
-  //
-  // This is used to force use isSet fields in mixed mode encoding since
-  // we cannot trust non-nullable fields to be initialized with non-null values.
-  final late_lowering.IsSetStrategy _isSetStrategy;
-  late_lowering.IsSetEncoding? _isSetEncoding;
-
-  // If `true`, the is-set field was register before the type was known to be
-  // nullable or non-nullable. In this case we do not try to remove it from
-  // the generated AST to avoid inconsistency between the class hierarchy used
-  // during and after inference.
-  //
-  // This is also used to force use isSet fields in mixed mode encoding since
-  // we cannot trust non-nullable fields to be initialized with non-null values.
-  bool _forceIncludeIsSetField;
-
-  AbstractLateFieldEncoding(
-      this.name,
-      NameScheme nameScheme,
-      Uri fileUri,
-      int charOffset,
-      int charEndOffset,
-      Reference? fieldReference,
-      Reference? fieldGetterReference,
-      Reference? fieldSetterReference,
-      Reference? lateIsSetFieldReference,
-      Reference? lateIsSetGetterReference,
-      Reference? lateIsSetSetterReference,
-      Reference? lateGetterReference,
-      Reference? lateSetterReference,
-      bool isCovariantByDeclaration,
-      late_lowering.IsSetStrategy isSetStrategy)
-      : fileOffset = charOffset,
-        fileEndOffset = charEndOffset,
-        _isSetStrategy = isSetStrategy,
-        _forceIncludeIsSetField =
-            isSetStrategy == late_lowering.IsSetStrategy.forceUseIsSetField {
-    _field = new Field.mutable(
-        nameScheme.getFieldName(FieldNameType.Field, name, isSynthesized: true),
-        fileUri: fileUri,
-        fieldReference: fieldReference,
-        getterReference: fieldGetterReference,
-        setterReference: fieldSetterReference)
-      ..fileOffset = charOffset
-      ..fileEndOffset = charEndOffset
-      ..isNonNullableByDefault = true
-      ..isInternalImplementation = true;
-    switch (_isSetStrategy) {
-      case late_lowering.IsSetStrategy.useSentinelOrNull:
-      case late_lowering.IsSetStrategy.forceUseSentinel:
-        // [_lateIsSetField] is never needed.
-        break;
-      case late_lowering.IsSetStrategy.forceUseIsSetField:
-      case late_lowering.IsSetStrategy.useIsSetFieldOrNull:
-        _lateIsSetField = new Field.mutable(
-            nameScheme.getFieldName(FieldNameType.IsSetField, name,
-                isSynthesized: true),
-            fileUri: fileUri,
-            fieldReference: lateIsSetFieldReference,
-            getterReference: lateIsSetGetterReference,
-            setterReference: lateIsSetSetterReference)
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset
-          ..isNonNullableByDefault = true
-          ..isInternalImplementation = true;
-        break;
-    }
-    _lateGetter = new Procedure(
-        nameScheme.getFieldName(FieldNameType.Getter, name,
-            isSynthesized: true),
-        ProcedureKind.Getter,
-        new FunctionNode(null)
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset,
-        fileUri: fileUri,
-        reference: lateGetterReference)
-      ..fileOffset = charOffset
-      ..fileEndOffset = charEndOffset
-      ..isNonNullableByDefault = true;
-    _lateSetter = _createSetter(
-        nameScheme.getFieldName(FieldNameType.Setter, name,
-            isSynthesized: true),
-        fileUri,
-        charOffset,
-        lateSetterReference,
-        isCovariantByDeclaration: isCovariantByDeclaration);
-  }
-
-  late_lowering.IsSetEncoding get isSetEncoding {
-    assert(_type != null, "Type has not been computed for field $name.");
-    return _isSetEncoding ??=
-        late_lowering.computeIsSetEncoding(_type!, _isSetStrategy);
-  }
-
-  @override
-  void completeSignature(CoreTypes coreTypes) {
-    _lateIsSetField?.type = coreTypes.boolRawType(Nullability.nonNullable);
-  }
-
-  @override
-  void createBodies(CoreTypes coreTypes, Expression? initializer) {
-    assert(_type != null, "Type has not been computed for field $name.");
-    if (isSetEncoding == late_lowering.IsSetEncoding.useSentinel) {
-      _field.initializer = new StaticInvocation(coreTypes.createSentinelMethod,
-          new Arguments([], types: [_type!])..fileOffset = fileOffset)
-        ..fileOffset = fileOffset
-        ..parent = _field;
-    } else {
-      _field.initializer = new NullLiteral()
-        ..fileOffset = fileOffset
-        ..parent = _field;
-    }
-    if (_lateIsSetField != null) {
-      _lateIsSetField!.initializer = new BoolLiteral(false)
-        ..fileOffset = fileOffset
-        ..parent = _lateIsSetField;
-    }
-    _lateGetter.function.body = _createGetterBody(coreTypes, name, initializer)
-      ..parent = _lateGetter.function;
-    if (_lateSetter != null) {
-      _lateSetter!.function.body = _createSetterBody(
-          coreTypes, name, _lateSetter!.function.positionalParameters.first)
-        ..parent = _lateSetter!.function;
-    }
-  }
-
-  @override
-  List<Initializer> createInitializer(int fileOffset, Expression value,
-      {required bool isSynthetic}) {
-    List<Initializer> initializers = <Initializer>[];
-    if (_lateIsSetField != null) {
-      initializers.add(new FieldInitializer(
-          _lateIsSetField!, new BoolLiteral(true)..fileOffset = fileOffset)
-        ..fileOffset = fileOffset
-        ..isSynthetic = isSynthetic);
-    }
-    initializers.add(new FieldInitializer(_field, value)
-      ..fileOffset = fileOffset
-      ..isSynthetic = isSynthetic);
-    return initializers;
-  }
-
-  /// Creates an [Expression] that reads [_field].
-  ///
-  /// If [needsPromotion] is `true`, the field will be read through a `let`
-  /// expression that promotes the expression to [_type]. This is needed for a
-  /// sound encoding of fields with type variable type of undetermined
-  /// nullability.
-  Expression _createFieldRead({bool needsPromotion: false}) {
-    assert(_type != null, "Type has not been computed for field $name.");
-    if (needsPromotion) {
-      VariableDeclaration variable = new VariableDeclaration.forValue(
-          _createFieldGet(_field),
-          type: _type!.withDeclaredNullability(Nullability.nullable))
-        ..fileOffset = fileOffset;
-      return new Let(
-          variable, new VariableGet(variable, _type)..fileOffset = fileOffset);
-    } else {
-      return _createFieldGet(_field);
-    }
-  }
-
-  /// Creates an [Expression] that reads [field].
-  Expression _createFieldGet(Field field) {
-    if (field.isStatic) {
-      return new StaticGet(field)..fileOffset = fileOffset;
-    } else {
-      // No substitution needed for the result type, since any type variables
-      // in there are also in scope at the access site.
-      return new InstanceGet(InstanceAccessKind.Instance,
-          new ThisExpression()..fileOffset = fileOffset, field.name,
-          interfaceTarget: field, resultType: field.type)
-        ..fileOffset = fileOffset;
-    }
-  }
-
-  /// Creates an [Expression] that writes [value] to [field].
-  Expression _createFieldSet(Field field, Expression value) {
-    if (field.isStatic) {
-      return new StaticSet(field, value)..fileOffset = fileOffset;
-    } else {
-      return new InstanceSet(InstanceAccessKind.Instance,
-          new ThisExpression()..fileOffset = fileOffset, field.name, value,
-          interfaceTarget: field)
-        ..fileOffset = fileOffset;
-    }
-  }
-
-  Statement _createGetterBody(
-      CoreTypes coreTypes, String name, Expression? initializer);
-
-  Procedure? _createSetter(
-      Name name, Uri fileUri, int charOffset, Reference? reference,
-      {required bool isCovariantByDeclaration}) {
-    // ignore: unnecessary_null_comparison
-    assert(isCovariantByDeclaration != null);
-    VariableDeclaration parameter = new VariableDeclaration(null)
-      ..isCovariantByDeclaration = isCovariantByDeclaration
-      ..fileOffset = fileOffset;
-    return new Procedure(
-        name,
-        ProcedureKind.Setter,
-        new FunctionNode(null,
-            positionalParameters: [parameter], returnType: const VoidType())
-          ..fileOffset = charOffset
-          ..fileEndOffset = fileEndOffset,
-        fileUri: fileUri,
-        reference: reference)
-      ..fileOffset = charOffset
-      ..fileEndOffset = fileEndOffset
-      ..isNonNullableByDefault = true;
-  }
-
-  Statement _createSetterBody(
-      CoreTypes coreTypes, String name, VariableDeclaration parameter);
-
-  @override
-  DartType get type {
-    assert(_type != null, "Type has not been computed for field $name.");
-    return _type!;
-  }
-
-  @override
-  void set type(DartType value) {
-    assert(_type == null || _type is ImplicitFieldType,
-        "Type has already been computed for field $name.");
-    _type = value;
-    if (value is! ImplicitFieldType) {
-      _field.type = value.withDeclaredNullability(Nullability.nullable);
-      _lateGetter.function.returnType = value;
-      if (_lateSetter != null) {
-        _lateSetter!.function.positionalParameters.single.type = value;
-      }
-      if (!_type!.isPotentiallyNullable && !_forceIncludeIsSetField) {
-        // We only need the is-set field if the field is potentially nullable.
-        //  Otherwise we use `null` to signal that the field is uninitialized.
-        _lateIsSetField = null;
-      }
-    }
-  }
-
-  @override
-  void setGenericCovariantImpl() {
-    _field.isCovariantByClass = true;
-    _lateSetter?.function.positionalParameters.single.isCovariantByClass = true;
-  }
-
-  @override
-  Field get field => _field;
-
-  @override
-  Iterable<Annotatable> get annotatables {
-    List<Annotatable> list = [_lateGetter];
-    if (_lateSetter != null) {
-      list.add(_lateSetter!);
-    }
-    return list;
-  }
-
-  @override
-  Member get readTarget => _lateGetter;
-
-  @override
-  Member? get writeTarget => _lateSetter;
-
-  @override
-  Iterable<Member> get exportedMembers {
-    if (_lateSetter != null) {
-      return [_lateGetter, _lateSetter!];
-    }
-    return [_lateGetter];
-  }
-
-  @override
-  void build(
-      SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder) {
-    bool isInstanceMember;
-    bool isExtensionMember = fieldBuilder.isExtensionMember;
-    if (isExtensionMember) {
-      _field
-        ..isStatic = true
-        ..isExtensionMember = isExtensionMember;
-      isInstanceMember = false;
-    } else {
-      isInstanceMember = !fieldBuilder.isStatic && !fieldBuilder.isTopLevel;
-      _field
-        ..isStatic = !isInstanceMember
-        ..isExtensionMember = false;
-    }
-    updatePrivateMemberName(_field, libraryBuilder);
-    if (_lateIsSetField != null) {
-      _lateIsSetField!
-        ..isStatic = !isInstanceMember
-        ..isStatic = _field.isStatic
-        ..isExtensionMember = isExtensionMember;
-      updatePrivateMemberName(_lateIsSetField!, libraryBuilder);
-    }
-    _lateGetter
-      ..isStatic = !isInstanceMember
-      ..isExtensionMember = isExtensionMember;
-    updatePrivateMemberName(_lateGetter, libraryBuilder);
-    if (_lateSetter != null) {
-      _lateSetter!
-        ..isStatic = !isInstanceMember
-        ..isExtensionMember = isExtensionMember;
-      updatePrivateMemberName(_lateSetter!, libraryBuilder);
-    }
-  }
-
-  @override
-  void registerMembers(
-      SourceLibraryBuilder library,
-      SourceFieldBuilder fieldBuilder,
-      void Function(Member, BuiltMemberKind) f) {
-    f(
-        _field,
-        fieldBuilder.isExtensionMember
-            ? BuiltMemberKind.ExtensionField
-            : BuiltMemberKind.Field);
-    if (_lateIsSetField != null) {
-      _forceIncludeIsSetField = true;
-      f(_lateIsSetField!, BuiltMemberKind.LateIsSetField);
-    }
-    f(_lateGetter, BuiltMemberKind.LateGetter);
-    if (_lateSetter != null) {
-      f(_lateSetter!, BuiltMemberKind.LateSetter);
-    }
-  }
-
-  @override
-  List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) {
-    List<ClassMember> list = <ClassMember>[
-      new _SynthesizedFieldClassMember(
-          fieldBuilder, field, _SynthesizedFieldMemberKind.LateField,
-          isInternalImplementation: true),
-      new _SynthesizedFieldClassMember(fieldBuilder, _lateGetter,
-          _SynthesizedFieldMemberKind.LateGetterSetter,
-          isInternalImplementation: false)
-    ];
-    if (_lateIsSetField != null) {
-      list.add(new _SynthesizedFieldClassMember(
-          fieldBuilder, _lateIsSetField!, _SynthesizedFieldMemberKind.LateIsSet,
-          isInternalImplementation: true));
-    }
-    return list;
-  }
-
-  @override
-  List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) {
-    List<ClassMember> list = <ClassMember>[
-      new _SynthesizedFieldClassMember(
-          fieldBuilder, field, _SynthesizedFieldMemberKind.LateField,
-          forSetter: true, isInternalImplementation: true),
-    ];
-    if (_lateIsSetField != null) {
-      list.add(new _SynthesizedFieldClassMember(
-          fieldBuilder, _lateIsSetField!, _SynthesizedFieldMemberKind.LateIsSet,
-          forSetter: true, isInternalImplementation: true));
-    }
-    if (_lateSetter != null) {
-      list.add(new _SynthesizedFieldClassMember(fieldBuilder, _lateSetter!,
-          _SynthesizedFieldMemberKind.LateGetterSetter,
-          forSetter: true, isInternalImplementation: false));
-    }
-    return list;
-  }
-
-  @override
-  bool get isLateLowering => true;
-}
-
-mixin NonFinalLate on AbstractLateFieldEncoding {
-  @override
-  Statement _createSetterBody(
-      CoreTypes coreTypes, String name, VariableDeclaration parameter) {
-    assert(_type != null, "Type has not been computed for field $name.");
-    return late_lowering.createSetterBody(
-        coreTypes, fileOffset, name, parameter, _type!,
-        shouldReturnValue: false,
-        createVariableWrite: (Expression value) =>
-            _createFieldSet(_field, value),
-        createIsSetWrite: (Expression value) =>
-            _createFieldSet(_lateIsSetField!, value),
-        isSetEncoding: isSetEncoding);
-  }
-}
-
-mixin LateWithoutInitializer on AbstractLateFieldEncoding {
-  @override
-  Statement _createGetterBody(
-      CoreTypes coreTypes, String name, Expression? initializer) {
-    assert(_type != null, "Type has not been computed for field $name.");
-    return late_lowering.createGetterBodyWithoutInitializer(
-        coreTypes, fileOffset, name, type,
-        createVariableRead: _createFieldRead,
-        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
-        isSetEncoding: isSetEncoding,
-        forField: true);
-  }
-}
-
-class LateFieldWithoutInitializerEncoding extends AbstractLateFieldEncoding
-    with NonFinalLate, LateWithoutInitializer {
-  LateFieldWithoutInitializerEncoding(
-      String name,
-      NameScheme nameScheme,
-      Uri fileUri,
-      int charOffset,
-      int charEndOffset,
-      Reference? fieldReference,
-      Reference? fieldGetterReference,
-      Reference? fieldSetterReference,
-      Reference? lateIsSetFieldReference,
-      Reference? lateIsSetGetterReference,
-      Reference? lateIsSetSetterReference,
-      Reference? lateGetterReference,
-      Reference? lateSetterReference,
-      bool isCovariantByDeclaration,
-      late_lowering.IsSetStrategy isSetStrategy)
-      : super(
-            name,
-            nameScheme,
-            fileUri,
-            charOffset,
-            charEndOffset,
-            fieldReference,
-            fieldGetterReference,
-            fieldSetterReference,
-            lateIsSetFieldReference,
-            lateIsSetGetterReference,
-            lateIsSetSetterReference,
-            lateGetterReference,
-            lateSetterReference,
-            isCovariantByDeclaration,
-            isSetStrategy);
-}
-
-class LateFieldWithInitializerEncoding extends AbstractLateFieldEncoding
-    with NonFinalLate {
-  LateFieldWithInitializerEncoding(
-      String name,
-      NameScheme nameScheme,
-      Uri fileUri,
-      int charOffset,
-      int charEndOffset,
-      Reference? fieldReference,
-      Reference? fieldGetterReference,
-      Reference? fieldSetterReference,
-      Reference? lateIsSetFieldReference,
-      Reference? lateIsSetGetterReference,
-      Reference? lateIsSetSetterReference,
-      Reference? lateGetterReference,
-      Reference? lateSetterReference,
-      bool isCovariantByDeclaration,
-      late_lowering.IsSetStrategy isSetStrategy)
-      : super(
-            name,
-            nameScheme,
-            fileUri,
-            charOffset,
-            charEndOffset,
-            fieldReference,
-            fieldGetterReference,
-            fieldSetterReference,
-            lateIsSetFieldReference,
-            lateIsSetGetterReference,
-            lateIsSetSetterReference,
-            lateGetterReference,
-            lateSetterReference,
-            isCovariantByDeclaration,
-            isSetStrategy);
-
-  @override
-  Statement _createGetterBody(
-      CoreTypes coreTypes, String name, Expression? initializer) {
-    assert(_type != null, "Type has not been computed for field $name.");
-    return late_lowering.createGetterWithInitializer(
-        coreTypes, fileOffset, name, _type!, initializer!,
-        createVariableRead: _createFieldRead,
-        createVariableWrite: (Expression value) =>
-            _createFieldSet(_field, value),
-        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
-        createIsSetWrite: (Expression value) =>
-            _createFieldSet(_lateIsSetField!, value),
-        isSetEncoding: isSetEncoding);
-  }
-}
-
-class LateFinalFieldWithoutInitializerEncoding extends AbstractLateFieldEncoding
-    with LateWithoutInitializer {
-  LateFinalFieldWithoutInitializerEncoding(
-      String name,
-      NameScheme nameScheme,
-      Uri fileUri,
-      int charOffset,
-      int charEndOffset,
-      Reference? fieldReference,
-      Reference? fieldGetterReference,
-      Reference? fieldSetterReference,
-      Reference? lateIsSetFieldReference,
-      Reference? lateIsSetGetterReference,
-      Reference? lateIsSetSetterReference,
-      Reference? lateGetterReference,
-      Reference? lateSetterReference,
-      bool isCovariantByDeclaration,
-      late_lowering.IsSetStrategy isSetStrategy)
-      : super(
-            name,
-            nameScheme,
-            fileUri,
-            charOffset,
-            charEndOffset,
-            fieldReference,
-            fieldGetterReference,
-            fieldSetterReference,
-            lateIsSetFieldReference,
-            lateIsSetGetterReference,
-            lateIsSetSetterReference,
-            lateGetterReference,
-            lateSetterReference,
-            isCovariantByDeclaration,
-            isSetStrategy);
-
-  @override
-  Statement _createSetterBody(
-      CoreTypes coreTypes, String name, VariableDeclaration parameter) {
-    assert(_type != null, "Type has not been computed for field $name.");
-    return late_lowering.createSetterBodyFinal(
-        coreTypes, fileOffset, name, parameter, type,
-        shouldReturnValue: false,
-        createVariableRead: () => _createFieldGet(_field),
-        createVariableWrite: (Expression value) =>
-            _createFieldSet(_field, value),
-        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
-        createIsSetWrite: (Expression value) =>
-            _createFieldSet(_lateIsSetField!, value),
-        isSetEncoding: isSetEncoding,
-        forField: true);
-  }
-}
-
-class LateFinalFieldWithInitializerEncoding extends AbstractLateFieldEncoding {
-  LateFinalFieldWithInitializerEncoding(
-      String name,
-      NameScheme nameScheme,
-      Uri fileUri,
-      int charOffset,
-      int charEndOffset,
-      Reference? fieldReference,
-      Reference? fieldGetterReference,
-      Reference? fieldSetterReference,
-      Reference? lateIsSetFieldReference,
-      Reference? lateIsSetGetterReference,
-      Reference? lateIsSetSetterReference,
-      Reference? lateGetterReference,
-      Reference? lateSetterReference,
-      bool isCovariantByDeclaration,
-      late_lowering.IsSetStrategy isSetStrategy)
-      : super(
-            name,
-            nameScheme,
-            fileUri,
-            charOffset,
-            charEndOffset,
-            fieldReference,
-            fieldGetterReference,
-            fieldSetterReference,
-            lateIsSetFieldReference,
-            lateIsSetGetterReference,
-            lateIsSetSetterReference,
-            lateGetterReference,
-            lateSetterReference,
-            isCovariantByDeclaration,
-            isSetStrategy);
-  @override
-  Statement _createGetterBody(
-      CoreTypes coreTypes, String name, Expression? initializer) {
-    assert(_type != null, "Type has not been computed for field $name.");
-    return late_lowering.createGetterWithInitializerWithRecheck(
-        coreTypes, fileOffset, name, _type!, initializer!,
-        createVariableRead: _createFieldRead,
-        createVariableWrite: (Expression value) =>
-            _createFieldSet(_field, value),
-        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
-        createIsSetWrite: (Expression value) =>
-            _createFieldSet(_lateIsSetField!, value),
-        isSetEncoding: isSetEncoding,
-        forField: true);
-  }
-
-  @override
-  Procedure? _createSetter(
-          Name name, Uri fileUri, int charOffset, Reference? reference,
-          {required bool isCovariantByDeclaration}) =>
-      null;
-
-  @override
-  Statement _createSetterBody(
-          CoreTypes coreTypes, String name, VariableDeclaration parameter) =>
-      throw new UnsupportedError(
-          '$runtimeType._createSetterBody is not supported.');
-}
-
-class _SynthesizedFieldClassMember implements ClassMember {
-  final SourceFieldBuilder fieldBuilder;
-  final _SynthesizedFieldMemberKind _kind;
-
-  final Member _member;
-
-  Covariance? _covariance;
-
-  @override
-  final bool forSetter;
-
-  @override
-  final bool isInternalImplementation;
-
-  _SynthesizedFieldClassMember(this.fieldBuilder, this._member, this._kind,
-      {this.forSetter: false, required this.isInternalImplementation})
-      // ignore: unnecessary_null_comparison
-      : assert(isInternalImplementation != null);
-
-  @override
-  Member getMember(ClassMembersBuilder membersBuilder) {
-    fieldBuilder._ensureType(membersBuilder);
-    return _member;
-  }
-
-  @override
-  Covariance getCovariance(ClassMembersBuilder membersBuilder) {
-    return _covariance ??= new Covariance.fromMember(getMember(membersBuilder),
-        forSetter: forSetter);
-  }
-
-  @override
-  void inferType(ClassMembersBuilder membersBuilder) {
-    fieldBuilder._ensureType(membersBuilder);
-  }
-
-  @override
-  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
-    fieldBuilder.registerOverrideDependency(overriddenMembers);
-  }
-
-  @override
-  bool get isSourceDeclaration => true;
-
-  @override
-  bool get isProperty => isField || isGetter || isSetter;
-
-  @override
-  ClassBuilder get classBuilder => fieldBuilder.classBuilder!;
-
-  @override
-  bool isObjectMember(ClassBuilder objectClass) {
-    return classBuilder == objectClass;
-  }
-
-  @override
-  bool get isDuplicate => fieldBuilder.isDuplicate;
-
-  @override
-  bool get isStatic => fieldBuilder.isStatic;
-
-  @override
-  bool get isField => _member is Field;
-
-  @override
-  bool get isAssignable {
-    Member field = _member;
-    return field is Field && field.hasSetter;
-  }
-
-  @override
-  bool get isSetter {
-    Member procedure = _member;
-    return procedure is Procedure && procedure.kind == ProcedureKind.Setter;
-  }
-
-  @override
-  bool get isGetter {
-    Member procedure = _member;
-    return procedure is Procedure && procedure.kind == ProcedureKind.Getter;
-  }
-
-  @override
-  bool get isFinal {
-    Member field = _member;
-    return field is Field && field.isFinal;
-  }
-
-  @override
-  bool get isConst {
-    Member field = _member;
-    return field is Field && field.isConst;
-  }
-
-  @override
-  Name get name => _member.name;
-
-  @override
-  String get fullName {
-    String suffix = isSetter ? "=" : "";
-    String className = classBuilder.fullNameForErrors;
-    // ignore: unnecessary_null_comparison
-    return className == null
-        ? "${fullNameForErrors}$suffix"
-        : "${className}.${fullNameForErrors}$suffix";
-  }
-
-  @override
-  String get fullNameForErrors => fieldBuilder.fullNameForErrors;
-
-  @override
-  Uri get fileUri => fieldBuilder.fileUri;
-
-  @override
-  int get charOffset => fieldBuilder.charOffset;
-
-  @override
-  bool get isAbstract => _member.isAbstract;
-
-  @override
-  bool get isSynthesized => false;
-
-  @override
-  bool get hasDeclarations => false;
-
-  @override
-  List<ClassMember> get declarations =>
-      throw new UnsupportedError("$runtimeType.declarations");
-
-  @override
-  ClassMember get interfaceMember => this;
-
-  @override
-  bool isSameDeclaration(ClassMember other) {
-    if (identical(this, other)) return true;
-    return other is _SynthesizedFieldClassMember &&
-        fieldBuilder == other.fieldBuilder &&
-        _kind == other._kind;
-  }
-
-  @override
-  String toString() => '_SynthesizedFieldClassMember('
-      '$fieldBuilder,$_member,$_kind,forSetter=${forSetter})';
-}
-
-class AbstractOrExternalFieldEncoding implements FieldEncoding {
-  final SourceFieldBuilder _fieldBuilder;
-  final bool isAbstract;
-  final bool isExternal;
-  final bool _isExtensionInstanceMember;
-
-  late Procedure _getter;
-  Procedure? _setter;
-  DartType? _type;
-
-  AbstractOrExternalFieldEncoding(
-      this._fieldBuilder,
-      String name,
-      NameScheme nameScheme,
-      Uri fileUri,
-      int charOffset,
-      int charEndOffset,
-      Reference? getterReference,
-      Reference? setterReference,
-      {required this.isAbstract,
-      required this.isExternal,
-      required bool isFinal,
-      required bool isCovariantByDeclaration,
-      required bool isNonNullableByDefault})
-      // ignore: unnecessary_null_comparison
-      : assert(isAbstract != null),
-        // ignore: unnecessary_null_comparison
-        assert(isExternal != null),
-        // ignore: unnecessary_null_comparison
-        assert(isFinal != null),
-        // ignore: unnecessary_null_comparison
-        assert(isCovariantByDeclaration != null),
-        // ignore: unnecessary_null_comparison
-        assert(isNonNullableByDefault != null),
-        _isExtensionInstanceMember = isExternal &&
-            nameScheme.isExtensionMember &&
-            nameScheme.isInstanceMember {
-    if (_isExtensionInstanceMember) {
-      _getter = new Procedure(
-          nameScheme.getProcedureName(ProcedureKind.Getter, name),
-          ProcedureKind.Method,
-          new FunctionNode(null, positionalParameters: [
-            new VariableDeclaration(extensionThisName)..fileOffset
-          ]),
-          fileUri: fileUri,
-          reference: getterReference)
-        ..fileOffset = charOffset
-        ..fileEndOffset = charEndOffset
-        ..isNonNullableByDefault = isNonNullableByDefault;
-      if (!isFinal) {
-        VariableDeclaration parameter =
-            new VariableDeclaration("#externalFieldValue")
-              ..isCovariantByDeclaration = isCovariantByDeclaration
-              ..fileOffset = charOffset;
-        _setter = new Procedure(
-            nameScheme.getProcedureName(ProcedureKind.Setter, name),
-            ProcedureKind.Method,
-            new FunctionNode(null,
-                positionalParameters: [
-                  new VariableDeclaration(extensionThisName)..fileOffset,
-                  parameter
-                ],
-                returnType: const VoidType())
-              ..fileOffset = charOffset
-              ..fileEndOffset = charEndOffset,
-            fileUri: fileUri,
-            reference: setterReference)
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset
-          ..isNonNullableByDefault = isNonNullableByDefault;
-      }
-    } else {
-      _getter = new Procedure(
-          nameScheme.getFieldName(FieldNameType.Getter, name,
-              isSynthesized: true),
-          ProcedureKind.Getter,
-          new FunctionNode(null),
-          fileUri: fileUri,
-          reference: getterReference)
-        ..fileOffset = charOffset
-        ..fileEndOffset = charEndOffset
-        ..isNonNullableByDefault = isNonNullableByDefault;
-      if (!isFinal) {
-        VariableDeclaration parameter =
-            new VariableDeclaration("#externalFieldValue")
-              ..isCovariantByDeclaration = isCovariantByDeclaration
-              ..fileOffset = charOffset;
-        _setter = new Procedure(
-            nameScheme.getFieldName(FieldNameType.Setter, name,
-                isSynthesized: true),
-            ProcedureKind.Setter,
-            new FunctionNode(null,
-                positionalParameters: [parameter], returnType: const VoidType())
-              ..fileOffset = charOffset
-              ..fileEndOffset = charEndOffset,
-            fileUri: fileUri,
-            reference: setterReference)
-          ..fileOffset = charOffset
-          ..fileEndOffset = charEndOffset
-          ..isNonNullableByDefault = isNonNullableByDefault;
-      }
-    }
-  }
-
-  @override
-  DartType get type {
-    assert(_type != null,
-        "Type has not been computed for field ${_fieldBuilder.name}.");
-    return _type!;
-  }
-
-  @override
-  void set type(DartType value) {
-    assert(_type == null || _type is ImplicitFieldType,
-        "Type has already been computed for field ${_fieldBuilder.name}.");
-    _type = value;
-    if (value is! ImplicitFieldType) {
-      if (_isExtensionInstanceMember) {
-        SourceExtensionBuilder extensionBuilder =
-            _fieldBuilder.parent as SourceExtensionBuilder;
-        DartType onType = extensionBuilder.extension.onType;
-        List<TypeParameter> typeParameters =
-            extensionBuilder.extension.typeParameters;
-        if (typeParameters.isNotEmpty) {
-          FreshTypeParameters getterTypeParameters =
-              getFreshTypeParameters(typeParameters);
-          _getter.function.positionalParameters.first.type =
-              getterTypeParameters.substitute(onType);
-          _getter.function.returnType = getterTypeParameters.substitute(value);
-          _getter.function.typeParameters =
-              getterTypeParameters.freshTypeParameters;
-          setParents(
-              getterTypeParameters.freshTypeParameters, _getter.function);
-
-          Procedure? setter = _setter;
-          if (setter != null) {
-            FreshTypeParameters setterTypeParameters =
-                getFreshTypeParameters(typeParameters);
-            setter.function.positionalParameters.first.type =
-                setterTypeParameters.substitute(onType);
-            setter.function.positionalParameters[1].type =
-                setterTypeParameters.substitute(value);
-            setter.function.typeParameters =
-                setterTypeParameters.freshTypeParameters;
-            setParents(
-                setterTypeParameters.freshTypeParameters, setter.function);
-          }
-        } else {
-          _getter.function.returnType = value;
-          _setter?.function.positionalParameters[1].type = value;
-          _getter.function.positionalParameters.first.type = onType;
-          _setter?.function.positionalParameters.first.type = onType;
-        }
-      } else {
-        _getter.function.returnType = value;
-        Procedure? setter = _setter;
-        if (setter != null) {
-          if (setter.kind == ProcedureKind.Method) {
-            setter.function.positionalParameters[1].type = value;
-          } else {
-            setter.function.positionalParameters.first.type = value;
-          }
-        }
-      }
-    }
-  }
-
-  @override
-  void completeSignature(CoreTypes coreTypes) {}
-
-  @override
-  void createBodies(CoreTypes coreTypes, Expression? initializer) {
-    //assert(initializer != null);
-  }
-
-  @override
-  List<Initializer> createInitializer(int fileOffset, Expression value,
-      {required bool isSynthetic}) {
-    throw new UnsupportedError('ExternalFieldEncoding.createInitializer');
-  }
-
-  @override
-  void build(
-      SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder) {
-    bool isExtensionMember = fieldBuilder.isExtensionMember;
-    bool isInstanceMember = !fieldBuilder.isExtensionMember &&
-        !fieldBuilder.isStatic &&
-        !fieldBuilder.isTopLevel;
-    _getter..isConst = fieldBuilder.isConst;
-    _getter
-      ..isStatic = !isInstanceMember
-      ..isExtensionMember = isExtensionMember
-      ..isAbstract = isAbstract && !isExternal
-      ..isExternal = isExternal;
-    updatePrivateMemberName(_getter, libraryBuilder);
-
-    if (_setter != null) {
-      _setter!
-        ..isStatic = !isInstanceMember
-        ..isExtensionMember = isExtensionMember
-        ..isAbstract = isAbstract && !isExternal
-        ..isExternal = isExternal;
-      updatePrivateMemberName(_setter!, libraryBuilder);
-    }
-  }
-
-  @override
-  void registerMembers(
-      SourceLibraryBuilder library,
-      SourceFieldBuilder fieldBuilder,
-      void Function(Member, BuiltMemberKind) f) {
-    f(
-        _getter,
-        fieldBuilder.isExtensionMember
-            ? BuiltMemberKind.ExtensionGetter
-            : BuiltMemberKind.Method);
-    if (_setter != null) {
-      f(
-          _setter!,
-          fieldBuilder.isExtensionMember
-              ? BuiltMemberKind.ExtensionSetter
-              : BuiltMemberKind.Method);
-    }
-  }
-
-  @override
-  void setGenericCovariantImpl() {
-    _setter!.function.positionalParameters.first.isCovariantByClass = true;
-  }
-
-  @override
-  Field get field {
-    throw new UnsupportedError("ExternalFieldEncoding.field");
-  }
-
-  @override
-  Iterable<Annotatable> get annotatables {
-    List<Annotatable> list = [_getter];
-    if (_setter != null) {
-      list.add(_setter!);
-    }
-    return list;
-  }
-
-  @override
-  Member get readTarget => _getter;
-
-  @override
-  Member? get writeTarget => _setter;
-
-  @override
-  Iterable<Member> get exportedMembers {
-    if (_setter != null) {
-      return [_getter, _setter!];
-    }
-    return [_getter];
-  }
-
-  @override
-  List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) =>
-      <ClassMember>[
-        new _SynthesizedFieldClassMember(fieldBuilder, _getter,
-            _SynthesizedFieldMemberKind.AbstractExternalGetterSetter,
-            forSetter: false, isInternalImplementation: false)
-      ];
-
-  @override
-  List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) =>
-      _setter != null
-          ? <ClassMember>[
-              new _SynthesizedFieldClassMember(fieldBuilder, _setter!,
-                  _SynthesizedFieldMemberKind.AbstractExternalGetterSetter,
-                  forSetter: true, isInternalImplementation: false)
-            ]
-          : const <ClassMember>[];
-
-  @override
-  bool get isLateLowering => false;
-}
-
-enum _SynthesizedFieldMemberKind {
-  /// A `isSet` field used for late lowering.
-  LateIsSet,
-
-  /// A field used for the value of a late lowered field.
-  LateField,
-
-  /// A getter or setter used for late lowering.
-  LateGetterSetter,
-
-  /// A getter or setter used for abstract or external fields.
-  AbstractExternalGetterSetter,
-}
diff --git a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
index 5c954d0..1503956 100644
--- a/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/formal_parameter_builder.dart
@@ -9,35 +9,24 @@
         isMandatoryFormalParameterKind,
         isOptionalNamedFormalParameterKind,
         isOptionalPositionalFormalParameterKind;
-
 import 'package:_fe_analyzer_shared/src/parser/parser.dart'
     show FormalParameterKind;
-
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
-
 import 'package:kernel/ast.dart'
     show DartType, DynamicType, Expression, VariableDeclaration;
-
 import 'package:kernel/src/legacy_erasure.dart';
 
 import '../constant_context.dart' show ConstantContext;
-
-import '../modifier.dart';
-
-import '../scope.dart' show Scope;
-
-import '../source/source_library_builder.dart';
-
 import '../kernel/body_builder.dart' show BodyBuilder;
-
 import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
-
+import '../modifier.dart';
+import '../scope.dart' show Scope;
+import '../source/source_factory_builder.dart';
+import '../source/source_library_builder.dart';
 import '../util/helpers.dart' show DelayedActionPerformer;
-
 import 'builder.dart';
 import 'class_builder.dart';
 import 'constructor_builder.dart';
-import 'factory_builder.dart';
 import 'field_builder.dart';
 import 'library_builder.dart';
 import 'metadata_builder.dart';
diff --git a/pkg/front_end/lib/src/fasta/builder/function_builder.dart b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
index 1390968..820d4bb 100644
--- a/pkg/front_end/lib/src/fasta/builder/function_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/function_builder.dart
@@ -5,522 +5,10 @@
 library fasta.procedure_builder;
 
 import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
 
-import '../identifiers.dart';
-import '../scope.dart';
-
-import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
-import '../kernel/kernel_helper.dart';
-
-import '../source/source_loader.dart' show SourceLoader;
-
-import '../messages.dart'
-    show
-        messagePatchDeclarationMismatch,
-        messagePatchDeclarationOrigin,
-        messagePatchNonExternal,
-        noLength,
-        templateRequiredNamedParameterHasDefaultValueError;
-
-import '../modifier.dart';
-
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
-import '../type_inference/type_inference_engine.dart'
-    show IncludesTypeParametersNonCovariantly;
-
-import '../util/helpers.dart' show DelayedActionPerformer;
-
-import 'builder.dart';
-import 'class_builder.dart';
-import 'declaration_builder.dart';
-import 'extension_builder.dart';
-import 'formal_parameter_builder.dart';
-import 'library_builder.dart';
 import 'member_builder.dart';
-import 'metadata_builder.dart';
-import 'type_builder.dart';
-import 'type_variable_builder.dart';
 
 /// Common base class for constructor and procedure builders.
 abstract class FunctionBuilder implements MemberBuilder {
   FunctionNode get function;
 }
-
-abstract class SourceFunctionBuilder
-    implements FunctionBuilder, SourceMemberBuilder {
-  List<MetadataBuilder>? get metadata;
-
-  TypeBuilder? get returnType;
-
-  List<TypeVariableBuilder>? get typeVariables;
-
-  List<FormalParameterBuilder>? get formals;
-
-  AsyncMarker get asyncModifier;
-
-  @override
-  ProcedureKind? get kind;
-
-  @override
-  bool get isAbstract;
-
-  @override
-  bool get isConstructor;
-
-  @override
-  bool get isRegularMethod;
-
-  @override
-  bool get isGetter;
-
-  @override
-  bool get isSetter;
-
-  @override
-  bool get isOperator;
-
-  @override
-  bool get isFactory;
-
-  /// This is the formal parameter scope as specified in the Dart Programming
-  /// Language Specification, 4th ed, section 9.2.
-  Scope computeFormalParameterScope(Scope parent);
-
-  Scope computeFormalParameterInitializerScope(Scope parent);
-
-  /// This scope doesn't correspond to any scope specified in the Dart
-  /// Programming Language Specification, 4th ed. It's an unspecified extension
-  /// to support generic methods.
-  Scope computeTypeParameterScope(Scope parent);
-
-  FormalParameterBuilder? getFormal(Identifier identifier);
-
-  String? get nativeMethodName;
-
-  Statement? get body;
-
-  void set body(Statement? newBody);
-
-  @override
-  bool get isNative;
-
-  /// Returns the [index]th parameter of this function.
-  ///
-  /// The index is the syntactical index, including both positional and named
-  /// parameter in the order they are declared, and excluding the synthesized
-  /// this parameter on extension instance members.
-  VariableDeclaration getFormalParameter(int index);
-
-  /// If this is an extension instance method or constructor with lowering
-  /// enabled, the tear off parameter corresponding to the [index]th parameter
-  /// on the instance method or constructor is returned.
-  ///
-  /// This is used to update the default value for the closure parameter when
-  /// it has been computed for the original parameter.
-  VariableDeclaration? getTearOffParameter(int index);
-
-  /// Returns the parameter for 'this' synthetically added to extension
-  /// instance members.
-  VariableDeclaration? get extensionThis;
-
-  /// Returns a list of synthetic type parameters added to extension instance
-  /// members.
-  List<TypeParameter>? get extensionTypeParameters;
-
-  void becomeNative(SourceLoader loader);
-
-  bool checkPatch(FunctionBuilder patch);
-
-  void reportPatchMismatch(Builder patch);
-}
-
-/// Common base class for constructor and procedure builders.
-abstract class FunctionBuilderImpl extends SourceMemberBuilderImpl
-    implements SourceFunctionBuilder {
-  @override
-  final List<MetadataBuilder>? metadata;
-
-  @override
-  final int modifiers;
-
-  @override
-  final TypeBuilder? returnType;
-
-  @override
-  final String name;
-
-  @override
-  final List<TypeVariableBuilder>? typeVariables;
-
-  @override
-  final List<FormalParameterBuilder>? formals;
-
-  /// If this procedure is an extension instance member, [_extensionThis] holds
-  /// the synthetically added `this` parameter.
-  VariableDeclaration? _extensionThis;
-
-  /// If this procedure is an extension instance member,
-  /// [_extensionTypeParameters] holds the type parameters copied from the
-  /// extension declaration.
-  List<TypeParameter>? _extensionTypeParameters;
-
-  FunctionBuilderImpl(
-      this.metadata,
-      this.modifiers,
-      this.returnType,
-      this.name,
-      this.typeVariables,
-      this.formals,
-      LibraryBuilder compilationUnit,
-      int charOffset,
-      this.nativeMethodName)
-      : super(compilationUnit, charOffset) {
-    if (formals != null) {
-      for (int i = 0; i < formals!.length; i++) {
-        formals![i].parent = this;
-      }
-    }
-  }
-
-  @override
-  String get debugName => "FunctionBuilder";
-
-  @override
-  AsyncMarker get asyncModifier;
-
-  @override
-  bool get isConstructor => false;
-
-  @override
-  bool get isAbstract => (modifiers & abstractMask) != 0;
-
-  @override
-  bool get isRegularMethod => identical(ProcedureKind.Method, kind);
-
-  @override
-  bool get isGetter => identical(ProcedureKind.Getter, kind);
-
-  @override
-  bool get isSetter => identical(ProcedureKind.Setter, kind);
-
-  @override
-  bool get isOperator => identical(ProcedureKind.Operator, kind);
-
-  @override
-  bool get isFactory => identical(ProcedureKind.Factory, kind);
-
-  @override
-  bool get isExternal => (modifiers & externalMask) != 0;
-
-  @override
-  bool get isAssignable => false;
-
-  @override
-  Scope computeFormalParameterScope(Scope parent) {
-    if (formals == null) return parent;
-    Map<String, Builder> local = <String, Builder>{};
-    for (FormalParameterBuilder formal in formals!) {
-      if (!isConstructor ||
-          !formal.isInitializingFormal && !formal.isSuperInitializingFormal) {
-        local[formal.name] = formal;
-      }
-    }
-    return new Scope(
-        local: local,
-        parent: parent,
-        debugName: "formal parameter",
-        isModifiable: false);
-  }
-
-  @override
-  Scope computeFormalParameterInitializerScope(Scope parent) {
-    // From
-    // [dartLangSpec.tex](../../../../../../docs/language/dartLangSpec.tex) at
-    // revision 94b23d3b125e9d246e07a2b43b61740759a0dace:
-    //
-    // When the formal parameter list of a non-redirecting generative
-    // constructor contains any initializing formals, a new scope is
-    // introduced, the _formal parameter initializer scope_, which is the
-    // current scope of the initializer list of the constructor, and which is
-    // enclosed in the scope where the constructor is declared.  Each
-    // initializing formal in the formal parameter list introduces a final
-    // local variable into the formal parameter initializer scope, but not into
-    // the formal parameter scope; every other formal parameter introduces a
-    // local variable into both the formal parameter scope and the formal
-    // parameter initializer scope.
-
-    if (formals == null) return parent;
-    Map<String, Builder> local = <String, Builder>{};
-    for (FormalParameterBuilder formal in formals!) {
-      local[formal.name] = formal.forFormalParameterInitializerScope();
-    }
-    return new Scope(
-        local: local,
-        parent: parent,
-        debugName: "formal parameter initializer",
-        isModifiable: false);
-  }
-
-  @override
-  Scope computeTypeParameterScope(Scope parent) {
-    if (typeVariables == null) return parent;
-    Map<String, Builder> local = <String, Builder>{};
-    for (TypeVariableBuilder variable in typeVariables!) {
-      local[variable.name] = variable;
-    }
-    return new Scope(
-        local: local,
-        parent: parent,
-        debugName: "type parameter",
-        isModifiable: false);
-  }
-
-  @override
-  FormalParameterBuilder? getFormal(Identifier identifier) {
-    if (formals != null) {
-      for (FormalParameterBuilder formal in formals!) {
-        if (formal.name == identifier.name &&
-            formal.charOffset == identifier.charOffset) {
-          return formal;
-        }
-      }
-      // If we have any formals we should find the one we're looking for.
-      assert(false, "$identifier not found in $formals");
-    }
-    return null;
-  }
-
-  @override
-  final String? nativeMethodName;
-
-  Statement? bodyInternal;
-
-  @override
-  void set body(Statement? newBody) {
-//    if (newBody != null) {
-//      if (isAbstract) {
-//        // TODO(danrubel): Is this check needed?
-//        return internalProblem(messageInternalProblemBodyOnAbstractMethod,
-//            newBody.fileOffset, fileUri);
-//      }
-//    }
-    bodyInternal = newBody;
-    // A forwarding semi-stub is a method that is abstract in the source code,
-    // but which needs to have a forwarding stub body in order to ensure that
-    // covariance checks occur.  We don't want to replace the forwarding stub
-    // body with null.
-    TreeNode? parent = function.parent;
-    if (!(newBody == null &&
-        parent is Procedure &&
-        parent.isForwardingSemiStub)) {
-      function.body = newBody;
-      newBody?.parent = function;
-    }
-  }
-
-  @override
-  Statement? get body => bodyInternal ??= new EmptyStatement();
-
-  @override
-  bool get isNative => nativeMethodName != null;
-
-  void buildFunction(SourceLibraryBuilder library) {
-    function.asyncMarker = asyncModifier;
-    function.body = body;
-    body?.parent = function;
-    IncludesTypeParametersNonCovariantly? needsCheckVisitor;
-    if (!isConstructor && !isFactory && parent is ClassBuilder) {
-      Class enclosingClass = classBuilder!.cls;
-      if (enclosingClass.typeParameters.isNotEmpty) {
-        needsCheckVisitor = new IncludesTypeParametersNonCovariantly(
-            enclosingClass.typeParameters,
-            // We are checking the parameter types which are in a
-            // contravariant position.
-            initialVariance: Variance.contravariant);
-      }
-    }
-    if (typeVariables != null) {
-      for (TypeVariableBuilder t in typeVariables!) {
-        TypeParameter parameter = t.parameter;
-        function.typeParameters.add(parameter);
-        if (needsCheckVisitor != null) {
-          if (parameter.bound.accept(needsCheckVisitor)) {
-            parameter.isCovariantByClass = true;
-          }
-        }
-      }
-      setParents(function.typeParameters, function);
-    }
-    if (formals != null) {
-      for (FormalParameterBuilder formal in formals!) {
-        VariableDeclaration parameter = formal.build(library, 0);
-        if (needsCheckVisitor != null) {
-          if (parameter.type.accept(needsCheckVisitor)) {
-            parameter.isCovariantByClass = true;
-          }
-        }
-        if (formal.isNamed) {
-          function.namedParameters.add(parameter);
-        } else {
-          function.positionalParameters.add(parameter);
-        }
-        parameter.parent = function;
-        if (formal.isRequired) {
-          function.requiredParameterCount++;
-        }
-
-        if (library.isNonNullableByDefault) {
-          // Required named parameters can't have default values.
-          if (formal.isNamedRequired && formal.initializerToken != null) {
-            library.addProblem(
-                templateRequiredNamedParameterHasDefaultValueError
-                    .withArguments(formal.name),
-                formal.charOffset,
-                formal.name.length,
-                formal.fileUri);
-          }
-        }
-      }
-    }
-    if (!isExtensionInstanceMember &&
-        isSetter &&
-        (formals?.length != 1 || formals![0].isOptional)) {
-      // Replace illegal parameters by single dummy parameter.
-      // Do this after building the parameters, since the diet listener
-      // assumes that parameters are built, even if illegal in number.
-      VariableDeclaration parameter =
-          new VariableDeclarationImpl("#synthetic", 0);
-      function.positionalParameters.clear();
-      function.positionalParameters.add(parameter);
-      parameter.parent = function;
-      function.namedParameters.clear();
-      function.requiredParameterCount = 1;
-    }
-    if (returnType != null) {
-      function.returnType = returnType!.build(library);
-    }
-    if (isExtensionInstanceMember) {
-      ExtensionBuilder extensionBuilder = parent as ExtensionBuilder;
-      _extensionThis = function.positionalParameters.first;
-      if (extensionBuilder.typeParameters != null) {
-        int count = extensionBuilder.typeParameters!.length;
-        _extensionTypeParameters = new List<TypeParameter>.generate(
-            count, (int index) => function.typeParameters[index],
-            growable: false);
-      }
-    }
-  }
-
-  @override
-  VariableDeclaration getFormalParameter(int index) {
-    if (isExtensionInstanceMember) {
-      return formals![index + 1].variable!;
-    } else {
-      return formals![index].variable!;
-    }
-  }
-
-  @override
-  VariableDeclaration? getTearOffParameter(int index) => null;
-
-  @override
-  VariableDeclaration? get extensionThis {
-    assert(_extensionThis != null || !isExtensionInstanceMember,
-        "ProcedureBuilder.extensionThis has not been set.");
-    return _extensionThis;
-  }
-
-  @override
-  List<TypeParameter>? get extensionTypeParameters {
-    // Use [_extensionThis] as marker for whether extension type parameters have
-    // been computed.
-    assert(_extensionThis != null || !isExtensionInstanceMember,
-        "ProcedureBuilder.extensionTypeParameters has not been set.");
-    return _extensionTypeParameters;
-  }
-
-  bool _hasBuiltOutlineExpressions = false;
-
-  @override
-  void buildOutlineExpressions(
-      SourceLibraryBuilder library,
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
-    if (!_hasBuiltOutlineExpressions) {
-      DeclarationBuilder? classOrExtensionBuilder =
-          isClassMember || isExtensionMember
-              ? parent as DeclarationBuilder
-              : null;
-      Scope parentScope = classOrExtensionBuilder?.scope ?? library.scope;
-      MetadataBuilder.buildAnnotations(member, metadata, library,
-          classOrExtensionBuilder, this, fileUri, parentScope);
-      if (typeVariables != null) {
-        for (int i = 0; i < typeVariables!.length; i++) {
-          typeVariables![i].buildOutlineExpressions(
-              library,
-              classOrExtensionBuilder,
-              this,
-              classHierarchy,
-              delayedActionPerformers,
-              computeTypeParameterScope(parentScope));
-        }
-      }
-
-      if (formals != null) {
-        // For const constructors we need to include default parameter values
-        // into the outline. For all other formals we need to call
-        // buildOutlineExpressions to clear initializerToken to prevent
-        // consuming too much memory.
-        for (FormalParameterBuilder formal in formals!) {
-          formal.buildOutlineExpressions(library, delayedActionPerformers);
-        }
-      }
-      _hasBuiltOutlineExpressions = true;
-    }
-  }
-
-  Member build(SourceLibraryBuilder library);
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    MemberBuilder constructor = loader.getNativeAnnotation();
-    Arguments arguments =
-        new Arguments(<Expression>[new StringLiteral(nativeMethodName!)]);
-    Expression annotation;
-    if (constructor.isConstructor) {
-      annotation = new ConstructorInvocation(
-          constructor.member as Constructor, arguments)
-        ..isConst = true;
-    } else {
-      annotation =
-          new StaticInvocation(constructor.member as Procedure, arguments)
-            ..isConst = true;
-    }
-    member.addAnnotation(annotation);
-  }
-
-  @override
-  bool checkPatch(FunctionBuilder patch) {
-    if (!isExternal) {
-      patch.library.addProblem(
-          messagePatchNonExternal, patch.charOffset, noLength, patch.fileUri!,
-          context: [
-            messagePatchDeclarationOrigin.withLocation(
-                fileUri, charOffset, noLength)
-          ]);
-      return false;
-    }
-    return true;
-  }
-
-  @override
-  void reportPatchMismatch(Builder patch) {
-    library.addProblem(messagePatchDeclarationMismatch, patch.charOffset,
-        noLength, patch.fileUri!, context: [
-      messagePatchDeclarationOrigin.withLocation(fileUri, charOffset, noLength)
-    ]);
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index 954097a..719b64d 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -5,19 +5,9 @@
 library fasta.member_builder;
 
 import 'package:kernel/ast.dart';
-import 'package:kernel/class_hierarchy.dart';
-
-import '../../base/common.dart';
 
 import '../kernel/hierarchy/class_member.dart';
-import '../kernel/kernel_helper.dart';
 import '../modifier.dart';
-import '../problems.dart' show unsupported;
-import '../source/source_library_builder.dart';
-import '../type_inference/type_inference_engine.dart'
-    show InferenceDataForTesting;
-import '../util/helpers.dart' show DelayedActionPerformer;
-
 import 'builder.dart';
 import 'class_builder.dart';
 import 'declaration_builder.dart';
@@ -165,105 +155,6 @@
   String get fullNameForErrors => name;
 }
 
-abstract class SourceMemberBuilder implements MemberBuilder {
-  MemberDataForTesting? get dataForTesting;
-
-  /// Builds the core AST structures for this member as needed for the outline.
-  void buildMembers(
-      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f);
-
-  void buildOutlineExpressions(
-      SourceLibraryBuilder library,
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes);
-}
-
-mixin SourceMemberBuilderMixin implements SourceMemberBuilder {
-  @override
-  MemberDataForTesting? dataForTesting =
-      retainDataForTesting ? new MemberDataForTesting() : null;
-
-  @override
-  void buildMembers(
-      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
-    assert(false, "Unexpected call to $runtimeType.buildMembers.");
-  }
-}
-
-abstract class SourceMemberBuilderImpl extends MemberBuilderImpl
-    implements SourceMemberBuilder {
-  @override
-  MemberDataForTesting? dataForTesting;
-
-  SourceMemberBuilderImpl(Builder parent, int charOffset, [Uri? fileUri])
-      : dataForTesting =
-            retainDataForTesting ? new MemberDataForTesting() : null,
-        super(parent, charOffset, fileUri);
-
-  bool get isRedirectingGenerativeConstructor => false;
-
-  bool? _isConflictingSetter;
-
-  @override
-  bool get isConflictingSetter {
-    return _isConflictingSetter ??= false;
-  }
-
-  void set isConflictingSetter(bool value) {
-    assert(_isConflictingSetter == null,
-        '$this.isConflictingSetter has already been fixed.');
-    _isConflictingSetter = value;
-  }
-
-  // TODO(johnniwinther): Remove this and create a [ProcedureBuilder] interface.
-  @override
-  ProcedureKind? get kind => unsupported("kind", charOffset, fileUri);
-
-  @override
-  void buildOutlineExpressions(
-      SourceLibraryBuilder library,
-      ClassHierarchy classHierarchy,
-      List<DelayedActionPerformer> delayedActionPerformers,
-      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {}
-
-  @override
-  StringBuffer printOn(StringBuffer buffer) {
-    if (isClassMember) {
-      buffer.write(classBuilder!.name);
-      buffer.write('.');
-    }
-    buffer.write(name);
-    return buffer;
-  }
-
-  /// The builder for the enclosing class or extension, if any.
-  DeclarationBuilder? get declarationBuilder =>
-      parent is DeclarationBuilder ? parent as DeclarationBuilder : null;
-}
-
-enum BuiltMemberKind {
-  Constructor,
-  RedirectingFactory,
-  Field,
-  Method,
-  ExtensionField,
-  ExtensionMethod,
-  ExtensionGetter,
-  ExtensionSetter,
-  ExtensionOperator,
-  ExtensionTearOff,
-  LateIsSetField,
-  LateGetter,
-  LateSetter,
-}
-
-class MemberDataForTesting {
-  final InferenceDataForTesting inferenceData = new InferenceDataForTesting();
-
-  MemberBuilder? patchForTesting;
-}
-
 /// Base class for implementing [ClassMember] for a [MemberBuilder].
 abstract class BuilderClassMember implements ClassMember {
   MemberBuilderImpl get memberBuilder;
@@ -344,13 +235,3 @@
   @override
   String toString() => '$runtimeType($fullName,forSetter=${forSetter})';
 }
-
-/// If the name of [member] is private, update it to use the library reference
-/// of [libraryBuilder].
-// TODO(johnniwinther): Avoid having to update private names by setting
-// the correct library reference when creating parts.
-void updatePrivateMemberName(Member member, LibraryBuilder libraryBuilder) {
-  if (member.name.isPrivate) {
-    member.name = new Name(member.name.text, libraryBuilder.library);
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
index f09dc0d..71ca0c2 100644
--- a/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/procedure_builder.dart
@@ -3,24 +3,8 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:kernel/ast.dart';
-import 'package:kernel/type_algebra.dart';
 
-import '../kernel/hierarchy/class_member.dart';
-import '../kernel/hierarchy/members_builder.dart';
-import '../kernel/member_covariance.dart';
-
-import '../source/name_scheme.dart';
-import '../source/source_loader.dart' show SourceLoader;
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
-import 'builder.dart';
-import 'extension_builder.dart';
-import 'formal_parameter_builder.dart';
 import 'function_builder.dart';
-import 'member_builder.dart';
-import 'metadata_builder.dart';
-import 'type_builder.dart';
-import 'type_variable_builder.dart';
 
 abstract class ProcedureBuilder implements FunctionBuilder {
   int get charOpenParenOffset;
@@ -46,521 +30,3 @@
   /// Returns `true` if this procedure is declared in an extension declaration.
   bool get isExtensionMethod;
 }
-
-class SourceProcedureBuilder extends FunctionBuilderImpl
-    implements ProcedureBuilder {
-  @override
-  final int charOpenParenOffset;
-
-  @override
-  AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
-
-  @override
-  final bool isExtensionInstanceMember;
-
-  late Procedure _procedure;
-
-  final Reference? _tearOffReference;
-
-  /// If this is an extension instance method then [_extensionTearOff] holds
-  /// the synthetically created tear off function.
-  Procedure? _extensionTearOff;
-
-  /// If this is an extension instance method then
-  /// [_extensionTearOffParameterMap] holds a map from the parameters of
-  /// the methods to the parameter of the closure returned in the tear-off.
-  ///
-  /// This map is used to set the default values on the closure parameters when
-  /// these have been built.
-  Map<VariableDeclaration, VariableDeclaration>? _extensionTearOffParameterMap;
-
-  @override
-  final ProcedureKind kind;
-
-  SourceProcedureBuilder? actualOrigin;
-
-  SourceProcedureBuilder(
-      List<MetadataBuilder>? metadata,
-      int modifiers,
-      TypeBuilder? returnType,
-      String name,
-      List<TypeVariableBuilder>? typeVariables,
-      List<FormalParameterBuilder>? formals,
-      this.kind,
-      SourceLibraryBuilder libraryBuilder,
-      int startCharOffset,
-      int charOffset,
-      this.charOpenParenOffset,
-      int charEndOffset,
-      Reference? procedureReference,
-      this._tearOffReference,
-      AsyncMarker asyncModifier,
-      NameScheme nameScheme,
-      {required bool isExtensionMember,
-      required bool isInstanceMember,
-      String? nativeMethodName})
-      // ignore: unnecessary_null_comparison
-      : assert(isExtensionMember != null),
-        // ignore: unnecessary_null_comparison
-        assert(isInstanceMember != null),
-        assert(kind != ProcedureKind.Factory),
-        this.isExtensionInstanceMember = isInstanceMember && isExtensionMember,
-        super(metadata, modifiers, returnType, name, typeVariables, formals,
-            libraryBuilder, charOffset, nativeMethodName) {
-    _procedure = new Procedure(
-        nameScheme.getProcedureName(kind, name),
-        isExtensionInstanceMember ? ProcedureKind.Method : kind,
-        new FunctionNode(null),
-        fileUri: libraryBuilder.fileUri,
-        reference: procedureReference)
-      ..startFileOffset = startCharOffset
-      ..fileOffset = charOffset
-      ..fileEndOffset = charEndOffset
-      ..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault;
-    this.asyncModifier = asyncModifier;
-    if (isExtensionMember && isInstanceMember && kind == ProcedureKind.Method) {
-      _extensionTearOff ??= new Procedure(
-          nameScheme.getProcedureName(ProcedureKind.Getter, name),
-          ProcedureKind.Method,
-          new FunctionNode(null),
-          isStatic: true,
-          isExtensionMember: true,
-          reference: _tearOffReference,
-          fileUri: fileUri)
-        ..isNonNullableByDefault = library.isNonNullableByDefault;
-    }
-  }
-
-  @override
-  ProcedureBuilder? get patchForTesting =>
-      dataForTesting?.patchForTesting as ProcedureBuilder?;
-
-  @override
-  AsyncMarker get asyncModifier => actualAsyncModifier;
-
-  @override
-  Statement? get body {
-    if (bodyInternal == null && !isAbstract && !isExternal) {
-      bodyInternal = new EmptyStatement();
-    }
-    return bodyInternal;
-  }
-
-  @override
-  void set asyncModifier(AsyncMarker newModifier) {
-    actualAsyncModifier = newModifier;
-    function.asyncMarker = actualAsyncModifier;
-    function.dartAsyncMarker = actualAsyncModifier;
-  }
-
-  @override
-  bool get isEligibleForTopLevelInference {
-    if (isDeclarationInstanceMember) {
-      if (returnType == null) return true;
-      if (formals != null) {
-        for (FormalParameterBuilder formal in formals!) {
-          if (formal.type == null) return true;
-        }
-      }
-    }
-    return false;
-  }
-
-  @override
-  bool get isExtensionMethod {
-    return parent is ExtensionBuilder;
-  }
-
-  @override
-  Member get member => procedure;
-
-  @override
-  SourceProcedureBuilder get origin => actualOrigin ?? this;
-
-  @override
-  Procedure get procedure => isPatch ? origin.procedure : _procedure;
-
-  @override
-  Procedure get actualProcedure => _procedure;
-
-  @override
-  FunctionNode get function => _procedure.function;
-
-  bool _typeEnsured = false;
-  Set<ClassMember>? _overrideDependencies;
-
-  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
-    assert(
-        overriddenMembers.every((overriddenMember) =>
-            overriddenMember.classBuilder != classBuilder),
-        "Unexpected override dependencies for $this: $overriddenMembers");
-    _overrideDependencies ??= {};
-    _overrideDependencies!.addAll(overriddenMembers);
-  }
-
-  void _ensureTypes(ClassMembersBuilder membersBuilder) {
-    if (_typeEnsured) return;
-    if (_overrideDependencies != null) {
-      if (isGetter) {
-        membersBuilder.inferGetterType(this, _overrideDependencies!);
-      } else if (isSetter) {
-        membersBuilder.inferSetterType(this, _overrideDependencies!);
-      } else {
-        membersBuilder.inferMethodType(this, _overrideDependencies!);
-      }
-      _overrideDependencies = null;
-    }
-    _typeEnsured = true;
-  }
-
-  @override
-  Member? get readTarget {
-    switch (kind) {
-      case ProcedureKind.Method:
-        return extensionTearOff ?? procedure;
-      case ProcedureKind.Getter:
-        return procedure;
-      case ProcedureKind.Factory:
-        return procedure;
-      case ProcedureKind.Operator:
-      case ProcedureKind.Setter:
-        return null;
-    }
-  }
-
-  @override
-  Member? get writeTarget {
-    switch (kind) {
-      case ProcedureKind.Setter:
-        return procedure;
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Operator:
-      case ProcedureKind.Factory:
-        return null;
-    }
-  }
-
-  @override
-  Member? get invokeTarget {
-    switch (kind) {
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Operator:
-      case ProcedureKind.Factory:
-        return procedure;
-      case ProcedureKind.Setter:
-        return null;
-    }
-  }
-
-  @override
-  Iterable<Member> get exportedMembers => [procedure];
-
-  @override
-  void buildMembers(
-      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
-    Member member = build(library);
-    if (isExtensionMethod) {
-      switch (kind) {
-        case ProcedureKind.Method:
-          f(member, BuiltMemberKind.ExtensionMethod);
-          break;
-        case ProcedureKind.Getter:
-          f(member, BuiltMemberKind.ExtensionGetter);
-          break;
-        case ProcedureKind.Setter:
-          f(member, BuiltMemberKind.ExtensionSetter);
-          break;
-        case ProcedureKind.Operator:
-          f(member, BuiltMemberKind.ExtensionOperator);
-          break;
-        case ProcedureKind.Factory:
-          throw new UnsupportedError(
-              'Unexpected extension method kind ${kind}');
-      }
-      if (extensionTearOff != null) {
-        f(extensionTearOff!, BuiltMemberKind.ExtensionTearOff);
-      }
-    } else {
-      f(member, BuiltMemberKind.Method);
-    }
-  }
-
-  @override
-  Procedure build(SourceLibraryBuilder libraryBuilder) {
-    buildFunction(libraryBuilder);
-    _procedure.function.fileOffset = charOpenParenOffset;
-    _procedure.function.fileEndOffset = _procedure.fileEndOffset;
-    _procedure.isAbstract = isAbstract;
-    _procedure.isExternal = isExternal;
-    _procedure.isConst = isConst;
-    updatePrivateMemberName(_procedure, libraryBuilder);
-    if (isExtensionMethod) {
-      _procedure.isExtensionMember = true;
-      _procedure.isStatic = true;
-      if (isExtensionInstanceMember) {
-        assert(_procedure.kind == ProcedureKind.Method);
-      }
-    } else {
-      _procedure.isStatic = isStatic;
-    }
-    if (extensionTearOff != null) {
-      _buildExtensionTearOff(libraryBuilder, parent as ExtensionBuilder);
-      updatePrivateMemberName(extensionTearOff!, libraryBuilder);
-    }
-    return _procedure;
-  }
-
-  /// Creates a top level function that creates a tear off of an extension
-  /// instance method.
-  ///
-  /// For this declaration
-  ///
-  ///     extension E<T> on A<T> {
-  ///       X method<S>(S s, Y y) {}
-  ///     }
-  ///
-  /// we create the top level function
-  ///
-  ///     X E|method<T, S>(A<T> #this, S s, Y y) {}
-  ///
-  /// and the tear off function
-  ///
-  ///     X Function<S>(S, Y) E|get#method<T>(A<T> #this) {
-  ///       return (S s, Y y) => E|method<T, S>(#this, s, y);
-  ///     }
-  ///
-  void _buildExtensionTearOff(
-      SourceLibraryBuilder libraryBuilder, ExtensionBuilder extensionBuilder) {
-    assert(
-        _extensionTearOff != null, "No extension tear off created for $this.");
-
-    _extensionTearOffParameterMap = {};
-
-    int fileOffset = _procedure.fileOffset;
-    int fileEndOffset = _procedure.fileEndOffset;
-
-    int extensionTypeParameterCount =
-        extensionBuilder.typeParameters?.length ?? 0;
-
-    List<TypeParameter> typeParameters = <TypeParameter>[];
-
-    Map<TypeParameter, DartType> substitutionMap = {};
-    List<DartType> typeArguments = <DartType>[];
-    for (TypeParameter typeParameter in function.typeParameters) {
-      TypeParameter newTypeParameter = new TypeParameter(typeParameter.name);
-      typeParameters.add(newTypeParameter);
-      typeArguments.add(substitutionMap[typeParameter] =
-          new TypeParameterType.forAlphaRenaming(
-              typeParameter, newTypeParameter));
-    }
-
-    List<TypeParameter> tearOffTypeParameters = <TypeParameter>[];
-    List<TypeParameter> closureTypeParameters = <TypeParameter>[];
-    Substitution substitution = Substitution.fromMap(substitutionMap);
-    for (int index = 0; index < typeParameters.length; index++) {
-      TypeParameter newTypeParameter = typeParameters[index];
-      newTypeParameter.bound =
-          substitution.substituteType(function.typeParameters[index].bound);
-      newTypeParameter.defaultType = function.typeParameters[index].defaultType;
-      if (index < extensionTypeParameterCount) {
-        tearOffTypeParameters.add(newTypeParameter);
-      } else {
-        closureTypeParameters.add(newTypeParameter);
-      }
-    }
-
-    VariableDeclaration copyParameter(
-        VariableDeclaration parameter, DartType type,
-        {required bool isOptional}) {
-      VariableDeclaration newParameter = new VariableDeclaration(parameter.name,
-          type: type,
-          isFinal: parameter.isFinal,
-          isLowered: parameter.isLowered)
-        ..fileOffset = parameter.fileOffset;
-      _extensionTearOffParameterMap![parameter] = newParameter;
-      return newParameter;
-    }
-
-    VariableDeclaration extensionThis = copyParameter(
-        function.positionalParameters.first,
-        substitution.substituteType(function.positionalParameters.first.type),
-        isOptional: false);
-
-    DartType closureReturnType =
-        substitution.substituteType(function.returnType);
-    List<VariableDeclaration> closurePositionalParameters = [];
-    List<Expression> closurePositionalArguments = [];
-
-    for (int position = 0;
-        position < function.positionalParameters.length;
-        position++) {
-      VariableDeclaration parameter = function.positionalParameters[position];
-      if (position == 0) {
-        /// Pass `this` as a captured variable.
-        closurePositionalArguments
-            .add(new VariableGet(extensionThis)..fileOffset = fileOffset);
-      } else {
-        DartType type = substitution.substituteType(parameter.type);
-        VariableDeclaration newParameter = copyParameter(parameter, type,
-            isOptional: position >= function.requiredParameterCount);
-        closurePositionalParameters.add(newParameter);
-        closurePositionalArguments
-            .add(new VariableGet(newParameter)..fileOffset = fileOffset);
-      }
-    }
-    List<VariableDeclaration> closureNamedParameters = [];
-    List<NamedExpression> closureNamedArguments = [];
-    for (VariableDeclaration parameter in function.namedParameters) {
-      DartType type = substitution.substituteType(parameter.type);
-      VariableDeclaration newParameter =
-          copyParameter(parameter, type, isOptional: true);
-      closureNamedParameters.add(newParameter);
-      closureNamedArguments.add(new NamedExpression(parameter.name!,
-          new VariableGet(newParameter)..fileOffset = fileOffset));
-    }
-
-    Statement closureBody = new ReturnStatement(
-        new StaticInvocation(
-            _procedure,
-            new Arguments(closurePositionalArguments,
-                types: typeArguments, named: closureNamedArguments))
-          ..fileOffset = fileOffset)
-      ..fileOffset = fileOffset;
-
-    FunctionExpression closure = new FunctionExpression(
-        new FunctionNode(closureBody,
-            typeParameters: closureTypeParameters,
-            positionalParameters: closurePositionalParameters,
-            namedParameters: closureNamedParameters,
-            requiredParameterCount:
-                _procedure.function.requiredParameterCount - 1,
-            returnType: closureReturnType)
-          ..fileOffset = fileOffset
-          ..fileEndOffset = fileEndOffset)
-      ..fileOffset = fileOffset;
-
-    _extensionTearOff!
-      ..function = (new FunctionNode(
-          new ReturnStatement(closure)..fileOffset = fileOffset,
-          typeParameters: tearOffTypeParameters,
-          positionalParameters: [extensionThis],
-          requiredParameterCount: 1,
-          returnType: closure.function.computeFunctionType(library.nonNullable))
-        ..fileOffset = fileOffset
-        ..fileEndOffset = fileEndOffset)
-      ..fileUri = fileUri
-      ..fileOffset = fileOffset
-      ..fileEndOffset = fileEndOffset;
-    _extensionTearOff!.function.parent = _extensionTearOff;
-  }
-
-  Procedure? get extensionTearOff => _extensionTearOff;
-
-  @override
-  VariableDeclaration? getTearOffParameter(int index) {
-    return _extensionTearOffParameterMap?[getFormalParameter(index)];
-  }
-
-  List<ClassMember>? _localMembers;
-  List<ClassMember>? _localSetters;
-
-  @override
-  List<ClassMember> get localMembers => _localMembers ??= isSetter
-      ? const <ClassMember>[]
-      : <ClassMember>[new SourceProcedureMember(this)];
-
-  @override
-  List<ClassMember> get localSetters =>
-      _localSetters ??= isSetter && !isConflictingSetter
-          ? <ClassMember>[new SourceProcedureMember(this)]
-          : const <ClassMember>[];
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    _procedure.isExternal = true;
-    super.becomeNative(loader);
-  }
-
-  @override
-  void applyPatch(Builder patch) {
-    if (patch is SourceProcedureBuilder) {
-      if (checkPatch(patch)) {
-        patch.actualOrigin = this;
-        dataForTesting?.patchForTesting = patch;
-      }
-    } else {
-      reportPatchMismatch(patch);
-    }
-  }
-
-  @override
-  int finishPatch() {
-    if (!isPatch) return 0;
-
-    // TODO(ahe): restore file-offset once we track both origin and patch file
-    // URIs. See https://github.com/dart-lang/sdk/issues/31579
-    origin.procedure.fileUri = fileUri;
-    origin.procedure.startFileOffset = _procedure.startFileOffset;
-    origin.procedure.fileOffset = _procedure.fileOffset;
-    origin.procedure.fileEndOffset = _procedure.fileEndOffset;
-    origin.procedure.annotations
-        .forEach((m) => m.fileOffset = _procedure.fileOffset);
-
-    origin.procedure.isAbstract = _procedure.isAbstract;
-    origin.procedure.isExternal = _procedure.isExternal;
-    origin.procedure.function = _procedure.function;
-    origin.procedure.function.parent = origin.procedure;
-    origin.procedure.isRedirectingFactory = _procedure.isRedirectingFactory;
-    return 1;
-  }
-}
-
-class SourceProcedureMember extends BuilderClassMember {
-  @override
-  final SourceProcedureBuilder memberBuilder;
-
-  Covariance? _covariance;
-
-  SourceProcedureMember(this.memberBuilder);
-
-  @override
-  bool get isSourceDeclaration => true;
-
-  @override
-  void inferType(ClassMembersBuilder membersBuilder) {
-    memberBuilder._ensureTypes(membersBuilder);
-  }
-
-  @override
-  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
-    memberBuilder.registerOverrideDependency(overriddenMembers);
-  }
-
-  @override
-  Member getMember(ClassMembersBuilder membersBuilder) {
-    memberBuilder._ensureTypes(membersBuilder);
-    return memberBuilder.member;
-  }
-
-  @override
-  Covariance getCovariance(ClassMembersBuilder membersBuilder) {
-    return _covariance ??= new Covariance.fromMember(getMember(membersBuilder),
-        forSetter: forSetter);
-  }
-
-  @override
-  bool get forSetter => isSetter;
-
-  @override
-  bool get isProperty =>
-      memberBuilder.kind == ProcedureKind.Getter ||
-      memberBuilder.kind == ProcedureKind.Setter;
-
-  @override
-  bool isSameDeclaration(ClassMember other) {
-    return other is SourceProcedureMember &&
-        memberBuilder == other.memberBuilder;
-  }
-}
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 3c7b280..847a435 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -5,9 +5,7 @@
 library fasta.body_builder;
 
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
-
 import 'package:_fe_analyzer_shared/src/messages/severity.dart' show Severity;
-
 import 'package:_fe_analyzer_shared/src/parser/parser.dart'
     show
         Assert,
@@ -20,7 +18,6 @@
         lengthForToken,
         lengthOfSpan,
         optional;
-
 import 'package:_fe_analyzer_shared/src/parser/quote.dart'
     show
         Quote,
@@ -32,13 +29,10 @@
 import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart'
     show FixedNullableList, GrowableList, NullValue, ParserRecovery;
 import 'package:_fe_analyzer_shared/src/parser/value_kind.dart';
-
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
 import 'package:_fe_analyzer_shared/src/scanner/token_impl.dart'
     show isBinaryOperator, isMinusOperator, isUserDefinableOperator;
-
 import 'package:_fe_analyzer_shared/src/util/link.dart';
-
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/clone.dart';
@@ -52,12 +46,9 @@
 import '../builder/class_builder.dart';
 import '../builder/constructor_builder.dart';
 import '../builder/declaration_builder.dart';
-import '../builder/enum_builder.dart';
 import '../builder/extension_builder.dart';
-import '../builder/factory_builder.dart';
 import '../builder/field_builder.dart';
 import '../builder/formal_parameter_builder.dart';
-import '../builder/function_builder.dart';
 import '../builder/function_type_builder.dart';
 import '../builder/invalid_type_declaration_builder.dart';
 import '../builder/library_builder.dart';
@@ -66,20 +57,15 @@
 import '../builder/named_type_builder.dart';
 import '../builder/nullability_builder.dart';
 import '../builder/prefix_builder.dart';
-import '../builder/procedure_builder.dart';
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
 import '../builder/type_declaration_builder.dart';
 import '../builder/type_variable_builder.dart';
 import '../builder/variable_builder.dart';
 import '../builder/void_type_declaration_builder.dart';
-
 import '../constant_context.dart' show ConstantContext;
-
 import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
-
 import '../fasta_codes.dart' as fasta;
-
 import '../fasta_codes.dart'
     show
         LocatedMessage,
@@ -87,36 +73,30 @@
         Template,
         noLength,
         templateExperimentNotEnabled;
-
 import '../identifiers.dart'
     show Identifier, InitializedIdentifier, QualifiedName, flattenName;
-
 import '../kernel/utils.dart';
-
 import '../messages.dart' as messages show getLocationFromUri;
-
 import '../modifier.dart'
     show Modifier, constMask, covariantMask, finalMask, lateMask, requiredMask;
-
 import '../names.dart' show emptyName, minusName, plusName;
-
 import '../problems.dart'
     show internalProblem, unexpected, unhandled, unsupported;
-
 import '../scope.dart';
-
 import '../source/diet_parser.dart';
 import '../source/scope_listener.dart' show JumpTargetKind, ScopeListener;
+import '../source/source_constructor_builder.dart';
+import '../source/source_enum_builder.dart';
+import '../source/source_factory_builder.dart';
+import '../source/source_function_builder.dart';
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_procedure_builder.dart';
 import '../source/stack_listener_impl.dart' show offsetForToken;
 import '../source/value_kinds.dart';
-
 import '../type_inference/type_inferrer.dart'
     show TypeInferrer, InferredFunctionBody, InitializerInferenceResult;
 import '../type_inference/type_schema.dart' show UnknownType;
-
 import '../util/helpers.dart' show DelayedActionPerformer;
-
 import 'collections.dart';
 import 'constness.dart' show Constness;
 import 'constructor_tearoff_lowering.dart';
diff --git a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
index 244a71d..0cbb45a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constructor_tearoff_lowering.dart
@@ -4,8 +4,9 @@
 
 import 'package:kernel/ast.dart';
 import 'package:kernel/type_algebra.dart';
-import '../builder/member_builder.dart';
+
 import '../source/source_library_builder.dart';
+import '../source/source_member_builder.dart';
 import 'kernel_helper.dart';
 
 const String _tearOffNamePrefix = '_#';
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart
index f50343a..6a0c047 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart
@@ -8,10 +8,10 @@
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchyMembers;
 
 import '../../builder/class_builder.dart';
-import '../../builder/field_builder.dart';
-import '../../builder/procedure_builder.dart';
 import '../../builder/type_builder.dart';
 import '../../source/source_class_builder.dart';
+import '../../source/source_field_builder.dart';
+import '../../source/source_procedure_builder.dart';
 import 'class_member.dart';
 import 'delayed.dart';
 import 'hierarchy_builder.dart';
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
index b2fc124..81fd945 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
@@ -14,12 +14,10 @@
 import '../../../base/common.dart';
 import '../../builder/builder.dart';
 import '../../builder/class_builder.dart';
-import '../../builder/field_builder.dart';
 import '../../builder/formal_parameter_builder.dart';
 import '../../builder/library_builder.dart';
 import '../../builder/member_builder.dart';
 import '../../builder/named_type_builder.dart';
-import '../../builder/procedure_builder.dart';
 import '../../builder/type_alias_builder.dart';
 import '../../builder/type_builder.dart';
 import '../../builder/type_declaration_builder.dart';
@@ -44,6 +42,8 @@
 import '../../names.dart' show noSuchMethodName;
 import '../../scope.dart' show Scope;
 import '../../source/source_class_builder.dart';
+import '../../source/source_field_builder.dart';
+import '../../source/source_procedure_builder.dart';
 import '../combined_member_signature.dart';
 import '../member_covariance.dart';
 import 'class_member.dart';
diff --git a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
index c4f1db7..792c92f 100644
--- a/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/implicit_field_type.dart
@@ -5,17 +5,15 @@
 library fasta.implicit_type;
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
 import 'package:kernel/ast.dart';
-
 import 'package:kernel/src/assumptions.dart';
 import 'package:kernel/src/legacy_erasure.dart';
 import 'package:kernel/src/printer.dart';
 
-import '../builder/field_builder.dart';
 import '../constant_context.dart';
 import '../fasta_codes.dart';
 import '../problems.dart' show unsupported;
+import '../source/source_field_builder.dart';
 import '../type_inference/type_inferrer.dart';
 import '../type_inference/type_schema.dart';
 import 'body_builder.dart';
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 4167fe9..ad571bc 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -66,6 +66,8 @@
 import '../scope.dart' show AmbiguousBuilder;
 import '../source/name_scheme.dart';
 import '../source/source_class_builder.dart' show SourceClassBuilder;
+import '../source/source_constructor_builder.dart';
+import '../source/source_field_builder.dart';
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
 import '../source/source_loader.dart' show SourceLoader;
 import '../target_implementation.dart' show TargetImplementation;
diff --git a/pkg/front_end/lib/src/fasta/scope.dart b/pkg/front_end/lib/src/fasta/scope.dart
index 840e400..cc9eb28 100644
--- a/pkg/front_end/lib/src/fasta/scope.dart
+++ b/pkg/front_end/lib/src/fasta/scope.dart
@@ -13,12 +13,6 @@
 import 'builder/member_builder.dart';
 import 'builder/name_iterator.dart';
 import 'builder/type_variable_builder.dart';
-import 'kernel/body_builder.dart' show JumpTarget;
-import 'kernel/hierarchy/class_member.dart' show ClassMember;
-import 'kernel/kernel_helper.dart';
-import 'source/source_library_builder.dart';
-import 'util/helpers.dart' show DelayedActionPerformer;
-
 import 'fasta_codes.dart'
     show
         LocatedMessage,
@@ -27,8 +21,13 @@
         templateAccessError,
         templateDuplicatedDeclarationUse,
         templateDuplicatedNamePreviouslyUsedCause;
-
+import 'kernel/body_builder.dart' show JumpTarget;
+import 'kernel/hierarchy/class_member.dart' show ClassMember;
+import 'kernel/kernel_helper.dart';
 import 'problems.dart' show internalProblem, unsupported;
+import 'source/source_library_builder.dart';
+import 'source/source_member_builder.dart';
+import 'util/helpers.dart' show DelayedActionPerformer;
 
 class MutableScope {
   /// Names declared in this scope.
diff --git a/pkg/front_end/lib/src/fasta/source/diet_listener.dart b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
index ae3196c..ab8d175 100644
--- a/pkg/front_end/lib/src/fasta/source/diet_listener.dart
+++ b/pkg/front_end/lib/src/fasta/source/diet_listener.dart
@@ -12,40 +12,26 @@
         MemberKind,
         Parser,
         optional;
-
 import 'package:_fe_analyzer_shared/src/parser/quote.dart' show unescapeString;
-
 import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart'
     show FixedNullableList, NullValue, ParserRecovery;
-
 import 'package:_fe_analyzer_shared/src/parser/value_kind.dart';
-
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
 import 'package:kernel/ast.dart';
-
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
 import 'package:kernel/core_types.dart' show CoreTypes;
 
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
 import '../builder/declaration_builder.dart';
-import '../builder/field_builder.dart';
 import '../builder/formal_parameter_builder.dart';
-import '../builder/function_builder.dart';
 import '../builder/function_type_builder.dart';
 import '../builder/metadata_builder.dart';
 import '../builder/modifier_builder.dart';
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
-
-import '../identifiers.dart' show QualifiedName;
-
 import '../constant_context.dart' show ConstantContext;
-
 import '../crash.dart' show Crash;
-
 import '../fasta_codes.dart'
     show
         Code,
@@ -53,27 +39,20 @@
         Message,
         messageExpectedBlockToSkip,
         templateInternalProblemNotFound;
-
+import '../identifiers.dart' show QualifiedName;
 import '../ignored_parser_errors.dart' show isIgnoredParserError;
-
 import '../kernel/body_builder.dart' show BodyBuilder, FormalParameters;
-
 import '../problems.dart'
     show DebugAbort, internalProblem, unexpected, unhandled;
-
 import '../scope.dart';
-
 import '../source/value_kinds.dart';
-
 import '../type_inference/type_inference_engine.dart'
     show InferenceDataForTesting, TypeInferenceEngine;
-
 import '../type_inference/type_inferrer.dart' show TypeInferrer;
-
 import 'diet_parser.dart';
-
+import 'source_field_builder.dart';
+import 'source_function_builder.dart';
 import 'source_library_builder.dart' show SourceLibraryBuilder;
-
 import 'stack_listener_impl.dart';
 
 class DietListener extends StackListenerImpl {
diff --git a/pkg/front_end/lib/src/fasta/source/outline_builder.dart b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
index c4e44e2..7f34cfd 100644
--- a/pkg/front_end/lib/src/fasta/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/outline_builder.dart
@@ -14,23 +14,16 @@
         lengthOfSpan,
         MemberKind,
         optional;
-
 import 'package:_fe_analyzer_shared/src/parser/quote.dart' show unescapeString;
-
 import 'package:_fe_analyzer_shared/src/parser/stack_listener.dart'
     show FixedNullableList, NullValue, ParserRecovery;
-
 import 'package:_fe_analyzer_shared/src/parser/value_kind.dart';
-
 import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
-
 import 'package:_fe_analyzer_shared/src/util/link.dart';
-
 import 'package:kernel/ast.dart'
     show AsyncMarker, InvalidType, Nullability, ProcedureKind, Variance;
 
 import '../builder/constructor_reference_builder.dart';
-import '../builder/enum_builder.dart';
 import '../builder/fixed_type_builder.dart';
 import '../builder/formal_parameter_builder.dart';
 import '../builder/function_type_builder.dart';
@@ -41,20 +34,13 @@
 import '../builder/nullability_builder.dart';
 import '../builder/type_builder.dart';
 import '../builder/type_variable_builder.dart';
-
 import '../combinator.dart' show CombinatorBuilder;
-
 import '../configuration.dart' show Configuration;
-
 import '../fasta_codes.dart';
-
 import '../identifiers.dart' show QualifiedName, flattenName;
-
 import '../ignored_parser_errors.dart' show isIgnoredParserError;
-
 import '../kernel/type_algorithms.dart';
 import '../kernel/utils.dart';
-
 import '../modifier.dart'
     show
         Const,
@@ -73,27 +59,22 @@
         mixinDeclarationMask,
         requiredMask,
         staticMask;
-
 import '../operator.dart'
     show
         Operator,
         operatorFromString,
         operatorToString,
         operatorRequiredArgumentCount;
-
 import '../problems.dart' show unhandled;
-
+import 'source_enum_builder.dart';
 import 'source_extension_builder.dart';
-
 import 'source_library_builder.dart'
     show
         TypeParameterScopeBuilder,
         TypeParameterScopeKind,
         FieldInfo,
         SourceLibraryBuilder;
-
 import 'stack_listener_impl.dart';
-
 import 'value_kinds.dart';
 
 enum MethodBody {
diff --git a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
index f60505d..b623395 100644
--- a/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_class_builder.dart
@@ -21,10 +21,7 @@
 
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
-import '../builder/constructor_builder.dart';
 import '../builder/constructor_reference_builder.dart';
-import '../builder/factory_builder.dart';
-import '../builder/field_builder.dart';
 import '../builder/function_builder.dart';
 import '../builder/invalid_type_declaration_builder.dart';
 import '../builder/library_builder.dart';
@@ -32,34 +29,29 @@
 import '../builder/metadata_builder.dart';
 import '../builder/named_type_builder.dart';
 import '../builder/nullability_builder.dart';
-import '../builder/procedure_builder.dart';
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
 import '../builder/type_declaration_builder.dart';
 import '../builder/type_variable_builder.dart';
-
 import '../dill/dill_member_builder.dart';
-
 import '../fasta_codes.dart';
-
 import '../kernel/combined_member_signature.dart';
 import '../kernel/kernel_helper.dart';
 import '../kernel/kernel_target.dart' show KernelTarget;
 import '../kernel/redirecting_factory_body.dart' show redirectingName;
 import '../kernel/type_algorithms.dart' show computeTypeVariableBuilderVariance;
 import '../kernel/utils.dart' show compareProcedures;
-
 import '../names.dart' show equalsName, noSuchMethodName;
-
 import '../problems.dart' show unexpected, unhandled, unimplemented;
-
 import '../scope.dart';
-
 import '../type_inference/type_schema.dart';
-
 import '../util/helpers.dart';
-
+import 'source_constructor_builder.dart';
+import 'source_factory_builder.dart';
+import 'source_field_builder.dart';
 import 'source_library_builder.dart' show SourceLibraryBuilder;
+import 'source_member_builder.dart';
+import 'source_procedure_builder.dart';
 
 Class initializeClass(
     Class? cls,
diff --git a/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
new file mode 100644
index 0000000..ed633a7
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/source/source_constructor_builder.dart
@@ -0,0 +1,747 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/type_algebra.dart';
+
+import '../builder/builder.dart';
+import '../builder/class_builder.dart';
+import '../builder/constructor_builder.dart';
+import '../builder/field_builder.dart';
+import '../builder/formal_parameter_builder.dart';
+import '../builder/library_builder.dart';
+import '../builder/member_builder.dart';
+import '../builder/metadata_builder.dart';
+import '../builder/named_type_builder.dart';
+import '../builder/type_alias_builder.dart';
+import '../builder/type_builder.dart';
+import '../builder/type_declaration_builder.dart';
+import '../builder/type_variable_builder.dart';
+import '../constant_context.dart' show ConstantContext;
+import '../dill/dill_member_builder.dart';
+import '../kernel/body_builder.dart' show BodyBuilder;
+import '../kernel/constructor_tearoff_lowering.dart';
+import '../kernel/expression_generator_helper.dart'
+    show ExpressionGeneratorHelper;
+import '../kernel/hierarchy/class_member.dart' show ClassMember;
+import '../kernel/kernel_helper.dart' show SynthesizedFunctionNode;
+import '../kernel/utils.dart'
+    show isRedirectingGenerativeConstructorImplementation;
+import '../messages.dart'
+    show
+        Message,
+        messageMoreThanOneSuperInitializer,
+        messageRedirectingConstructorWithAnotherInitializer,
+        messageRedirectingConstructorWithMultipleRedirectInitializers,
+        messageRedirectingConstructorWithSuperInitializer,
+        messageSuperInitializerNotLast,
+        noLength;
+import '../source/source_class_builder.dart';
+import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_loader.dart' show SourceLoader;
+import '../source/source_member_builder.dart';
+import '../type_inference/type_inferrer.dart';
+import '../type_inference/type_schema.dart';
+import '../util/helpers.dart' show DelayedActionPerformer;
+import 'source_function_builder.dart';
+
+class SourceConstructorBuilder extends FunctionBuilderImpl
+    implements ConstructorBuilder {
+  final Constructor _constructor;
+  final Procedure? _constructorTearOff;
+
+  Set<FieldBuilder>? _initializedFields;
+
+  final int charOpenParenOffset;
+
+  bool hasMovedSuperInitializer = false;
+
+  SuperInitializer? superInitializer;
+
+  RedirectingInitializer? redirectingInitializer;
+
+  Token? beginInitializers;
+
+  SourceConstructorBuilder? actualOrigin;
+
+  Constructor get actualConstructor => _constructor;
+
+  bool _hasFormalsInferred = false;
+
+  final bool _hasSuperInitializingFormals;
+
+  final List<SynthesizedFunctionNode> _superParameterDefaultValueCloners =
+      <SynthesizedFunctionNode>[];
+
+  SourceConstructorBuilder(
+      List<MetadataBuilder>? metadata,
+      int modifiers,
+      TypeBuilder? returnType,
+      String name,
+      List<TypeVariableBuilder>? typeVariables,
+      List<FormalParameterBuilder>? formals,
+      SourceLibraryBuilder compilationUnit,
+      int startCharOffset,
+      int charOffset,
+      this.charOpenParenOffset,
+      int charEndOffset,
+      Reference? constructorReference,
+      Reference? tearOffReference,
+      {String? nativeMethodName,
+      required bool forAbstractClassOrEnum})
+      : _constructor = new Constructor(new FunctionNode(null),
+            name: new Name(name, compilationUnit.library),
+            fileUri: compilationUnit.fileUri,
+            reference: constructorReference)
+          ..startFileOffset = startCharOffset
+          ..fileOffset = charOffset
+          ..fileEndOffset = charEndOffset
+          ..isNonNullableByDefault = compilationUnit.isNonNullableByDefault,
+        _constructorTearOff = createConstructorTearOffProcedure(
+            name,
+            compilationUnit,
+            compilationUnit.fileUri,
+            charOffset,
+            tearOffReference,
+            forAbstractClassOrEnum: forAbstractClassOrEnum),
+        _hasSuperInitializingFormals =
+            formals?.any((formal) => formal.isSuperInitializingFormal) ?? false,
+        super(metadata, modifiers, returnType, name, typeVariables, formals,
+            compilationUnit, charOffset, nativeMethodName);
+
+  @override
+  SourceLibraryBuilder get library => super.library as SourceLibraryBuilder;
+
+  @override
+  SourceClassBuilder get classBuilder =>
+      super.classBuilder as SourceClassBuilder;
+
+  @override
+  Member? get readTarget => _constructorTearOff ?? _constructor;
+
+  @override
+  Member? get writeTarget => null;
+
+  @override
+  Member get invokeTarget => constructor;
+
+  @override
+  FunctionNode get function => _constructor.function;
+
+  @override
+  Iterable<Member> get exportedMembers => [constructor];
+
+  @override
+  SourceConstructorBuilder get origin => actualOrigin ?? this;
+
+  ConstructorBuilder? get patchForTesting =>
+      dataForTesting?.patchForTesting as ConstructorBuilder?;
+
+  @override
+  bool get isDeclarationInstanceMember => false;
+
+  @override
+  bool get isClassInstanceMember => false;
+
+  @override
+  bool get isConstructor => true;
+
+  @override
+  AsyncMarker get asyncModifier => AsyncMarker.Sync;
+
+  @override
+  ProcedureKind? get kind => null;
+
+  @override
+  bool get isRedirectingGenerativeConstructor {
+    return isRedirectingGenerativeConstructorImplementation(_constructor);
+  }
+
+  @override
+  void buildMembers(
+      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
+    Member member = build(library);
+    f(member, BuiltMemberKind.Constructor);
+    if (_constructorTearOff != null) {
+      f(_constructorTearOff!, BuiltMemberKind.Method);
+    }
+  }
+
+  bool _hasBeenBuilt = false;
+
+  @override
+  Constructor build(SourceLibraryBuilder libraryBuilder) {
+    if (!_hasBeenBuilt) {
+      buildFunction(libraryBuilder);
+      _constructor.function.fileOffset = charOpenParenOffset;
+      _constructor.function.fileEndOffset = _constructor.fileEndOffset;
+      _constructor.function.typeParameters = const <TypeParameter>[];
+      _constructor.isConst = isConst;
+      _constructor.isExternal = isExternal;
+      updatePrivateMemberName(_constructor, libraryBuilder);
+
+      if (_constructorTearOff != null) {
+        buildConstructorTearOffProcedure(_constructorTearOff!, _constructor,
+            classBuilder.cls, libraryBuilder);
+      }
+
+      _hasBeenBuilt = true;
+    }
+    if (formals != null) {
+      bool needsInference = false;
+      for (FormalParameterBuilder formal in formals!) {
+        if (formal.type == null &&
+            (formal.isInitializingFormal || formal.isSuperInitializingFormal)) {
+          formal.variable!.type = const UnknownType();
+          needsInference = true;
+        }
+      }
+      if (needsInference) {
+        assert(
+            library == libraryBuilder,
+            "Unexpected library builder ${libraryBuilder} for"
+            " constructor $this in ${library}.");
+        libraryBuilder.loader
+            .registerConstructorToBeInferred(_constructor, this);
+      }
+    }
+    return _constructor;
+  }
+
+  /// Infers the types of any untyped initializing formals.
+  void inferFormalTypes(ClassHierarchy classHierarchy) {
+    if (_hasFormalsInferred) return;
+    if (formals != null) {
+      for (FormalParameterBuilder formal in formals!) {
+        if (formal.type == null) {
+          if (formal.isInitializingFormal) {
+            formal.finalizeInitializingFormal(classBuilder);
+          }
+        }
+      }
+
+      if (_hasSuperInitializingFormals) {
+        if (beginInitializers != null) {
+          BodyBuilder bodyBuilder = library.loader
+              .createBodyBuilderForOutlineExpression(
+                  library, classBuilder, this, classBuilder.scope, fileUri);
+          bodyBuilder.constantContext = ConstantContext.required;
+          bodyBuilder.parseInitializers(beginInitializers!,
+              doFinishConstructor: false);
+        }
+        finalizeSuperInitializingFormals(
+            classHierarchy, _superParameterDefaultValueCloners);
+      }
+    }
+    _hasFormalsInferred = true;
+  }
+
+  /* ConstructorBuilder | DillConstructorBuilder */
+  Object? _computeSuperTargetBuilder() {
+    Constructor superTarget;
+    ClassBuilder superclassBuilder;
+
+    TypeBuilder? supertype = classBuilder.supertypeBuilder;
+    if (supertype is NamedTypeBuilder) {
+      TypeDeclarationBuilder? declaration = supertype.declaration;
+      if (declaration is ClassBuilder) {
+        superclassBuilder = declaration;
+      } else if (declaration is TypeAliasBuilder) {
+        declaration = declaration.unaliasDeclaration(supertype.arguments);
+        if (declaration is ClassBuilder) {
+          superclassBuilder = declaration;
+        } else {
+          // The error in this case should be reported elsewhere.
+          return null;
+        }
+      } else {
+        // The error in this case should be reported elsewhere.
+        return null;
+      }
+    } else {
+      // The error in this case should be reported elsewhere.
+      return null;
+    }
+
+    if (constructor.initializers.isNotEmpty &&
+        constructor.initializers.last is SuperInitializer) {
+      superTarget = (constructor.initializers.last as SuperInitializer).target;
+    } else {
+      MemberBuilder? memberBuilder = superclassBuilder.constructors
+          .lookup("", charOffset, library.fileUri);
+      if (memberBuilder is ConstructorBuilder) {
+        superTarget = memberBuilder.constructor;
+      } else if (memberBuilder is DillConstructorBuilder) {
+        superTarget = memberBuilder.constructor;
+      } else {
+        // The error in this case should be reported elsewhere.
+        return null;
+      }
+    }
+
+    MemberBuilder? constructorBuilder =
+        superclassBuilder.findConstructorOrFactory(
+            superTarget.name.text, charOffset, library.fileUri, library);
+    return constructorBuilder is ConstructorBuilder ||
+            constructorBuilder is DillConstructorBuilder
+        ? constructorBuilder
+        : null;
+  }
+
+  void finalizeSuperInitializingFormals(ClassHierarchy classHierarchy,
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
+    if (formals == null) return;
+    if (!_hasSuperInitializingFormals) return;
+
+    void performRecoveryForErroneousCase() {
+      for (FormalParameterBuilder formal in formals!) {
+        if (formal.isSuperInitializingFormal) {
+          formal.variable!.type = const DynamicType();
+        }
+      }
+    }
+
+    Object? superTargetBuilder = _computeSuperTargetBuilder();
+    Constructor superTarget;
+    List<FormalParameterBuilder>? superFormals;
+    if (superTargetBuilder is SourceConstructorBuilder) {
+      superTarget = superTargetBuilder.constructor;
+      superFormals = superTargetBuilder.formals!;
+    } else if (superTargetBuilder is DillConstructorBuilder) {
+      superTarget = superTargetBuilder.constructor;
+      if (superTargetBuilder is SyntheticConstructorBuilder) {
+        superFormals = superTargetBuilder.formals;
+      } else {
+        // The error in this case should be reported elsewhere. Here we perform
+        // a simple recovery.
+        return performRecoveryForErroneousCase();
+      }
+    } else {
+      // The error in this case should be reported elsewhere. Here we perform a
+      // simple recovery.
+      return performRecoveryForErroneousCase();
+    }
+
+    if (superFormals == null) {
+      // The error in this case should be reported elsewhere. Here we perform a
+      // simple recovery.
+      return performRecoveryForErroneousCase();
+    }
+
+    if (superTargetBuilder is SourceConstructorBuilder) {
+      superTargetBuilder.inferFormalTypes(classHierarchy);
+    } else if (superTargetBuilder is SyntheticConstructorBuilder) {
+      MemberBuilder? superTargetOriginBuilder = superTargetBuilder.actualOrigin;
+      if (superTargetOriginBuilder is SourceConstructorBuilder) {
+        superTargetOriginBuilder.inferFormalTypes(classHierarchy);
+      }
+    }
+
+    int superInitializingFormalIndex = -1;
+    List<int>? positionalSuperParameters;
+    List<String>? namedSuperParameters;
+
+    Supertype? supertype = classHierarchy.getClassAsInstanceOf(
+        classBuilder.cls, superTarget.enclosingClass);
+    assert(supertype != null);
+    Map<TypeParameter, DartType> substitution =
+        new Map<TypeParameter, DartType>.fromIterables(
+            supertype!.classNode.typeParameters, supertype.typeArguments);
+
+    for (int formalIndex = 0; formalIndex < formals!.length; formalIndex++) {
+      FormalParameterBuilder formal = formals![formalIndex];
+      if (formal.isSuperInitializingFormal) {
+        superInitializingFormalIndex++;
+        bool hasImmediatelyDeclaredInitializer = formal.hasDeclaredInitializer;
+        if (formal.type == null) {
+          DartType? type;
+
+          if (formal.isPositional) {
+            if (superInitializingFormalIndex < superFormals.length) {
+              FormalParameterBuilder correspondingSuperFormal =
+                  superFormals[superInitializingFormalIndex];
+              formal.hasDeclaredInitializer =
+                  hasImmediatelyDeclaredInitializer ||
+                      correspondingSuperFormal.hasDeclaredInitializer;
+              if (!hasImmediatelyDeclaredInitializer) {
+                (positionalSuperParameters ??= <int>[]).add(formalIndex);
+              }
+              type = correspondingSuperFormal.variable!.type;
+            } else {
+              // TODO(cstefantsova): Report an error.
+            }
+          } else {
+            FormalParameterBuilder? correspondingSuperFormal;
+            for (FormalParameterBuilder superFormal in superFormals) {
+              if (superFormal.isNamed && superFormal.name == formal.name) {
+                correspondingSuperFormal = superFormal;
+                break;
+              }
+            }
+
+            if (correspondingSuperFormal != null) {
+              formal.hasDeclaredInitializer =
+                  hasImmediatelyDeclaredInitializer ||
+                      correspondingSuperFormal.hasDeclaredInitializer;
+              if (!hasImmediatelyDeclaredInitializer) {
+                (namedSuperParameters ??= <String>[]).add(formal.name);
+              }
+              type = correspondingSuperFormal.variable!.type;
+            } else {
+              // TODO(cstefantsova): Report an error.
+            }
+          }
+
+          if (substitution.isNotEmpty && type != null) {
+            type = substitute(type, substitution);
+          }
+          formal.variable!.type = type ?? const DynamicType();
+        } else {
+          formal.variable!.type = const DynamicType();
+        }
+      }
+    }
+
+    if (positionalSuperParameters != null || namedSuperParameters != null) {
+      synthesizedFunctionNodes.add(new SynthesizedFunctionNode(
+          substitution, superTarget.function, constructor.function,
+          positionalSuperParameters: positionalSuperParameters ?? const <int>[],
+          namedSuperParameters: namedSuperParameters ?? const <String>[],
+          isOutlineNode: true));
+    }
+  }
+
+  bool _hasBuiltOutlines = false;
+
+  @override
+  void buildOutlineExpressions(
+      SourceLibraryBuilder library,
+      ClassHierarchy classHierarchy,
+      List<DelayedActionPerformer> delayedActionPerformers,
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
+    if (_hasBuiltOutlines) return;
+    if (isConst && isPatch) {
+      origin.buildOutlineExpressions(library, classHierarchy,
+          delayedActionPerformers, synthesizedFunctionNodes);
+    }
+    super.buildOutlineExpressions(library, classHierarchy,
+        delayedActionPerformers, synthesizedFunctionNodes);
+
+    // For modular compilation purposes we need to include initializers
+    // for const constructors into the outline. We also need to parse
+    // initializers to infer types of the super-initializing parameters.
+    if ((isConst || _hasSuperInitializingFormals) &&
+        beginInitializers != null) {
+      BodyBuilder bodyBuilder = library.loader
+          .createBodyBuilderForOutlineExpression(
+              library, classBuilder, this, classBuilder.scope, fileUri);
+      bodyBuilder.constantContext = ConstantContext.required;
+      bodyBuilder.parseInitializers(beginInitializers!,
+          doFinishConstructor: isConst);
+      bodyBuilder.performBacklogComputations(delayedActionPerformers);
+    }
+    beginInitializers = null;
+    addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
+    if (isConst && isPatch) {
+      _finishPatch();
+    }
+    _hasBuiltOutlines = true;
+  }
+
+  void addSuperParameterDefaultValueCloners(
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
+    Object? superTargetBuilder = _computeSuperTargetBuilder();
+    if (superTargetBuilder is SourceConstructorBuilder) {
+      superTargetBuilder
+          .addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
+    } else if (superTargetBuilder is SyntheticConstructorBuilder) {
+      superTargetBuilder
+          .addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
+    }
+    synthesizedFunctionNodes.addAll(_superParameterDefaultValueCloners);
+    _superParameterDefaultValueCloners.clear();
+  }
+
+  @override
+  void buildFunction(SourceLibraryBuilder library) {
+    // According to the specification §9.3 the return type of a constructor
+    // function is its enclosing class.
+    super.buildFunction(library);
+    Class enclosingClass = classBuilder.cls;
+    List<DartType> typeParameterTypes = <DartType>[];
+    for (int i = 0; i < enclosingClass.typeParameters.length; i++) {
+      TypeParameter typeParameter = enclosingClass.typeParameters[i];
+      typeParameterTypes.add(
+          new TypeParameterType.withDefaultNullabilityForLibrary(
+              typeParameter, library.library));
+    }
+    function.returnType = new InterfaceType(
+        enclosingClass, library.nonNullable, typeParameterTypes);
+  }
+
+  @override
+  Constructor get constructor => isPatch ? origin.constructor : _constructor;
+
+  @override
+  Member get member => constructor;
+
+  void injectInvalidInitializer(Message message, int charOffset, int length,
+      ExpressionGeneratorHelper helper) {
+    List<Initializer> initializers = _constructor.initializers;
+    Initializer lastInitializer = initializers.removeLast();
+    assert(lastInitializer == superInitializer ||
+        lastInitializer == redirectingInitializer);
+    Initializer error = helper.buildInvalidInitializer(
+        helper.buildProblem(message, charOffset, length));
+    initializers.add(error..parent = _constructor);
+    initializers.add(lastInitializer);
+  }
+
+  void addInitializer(Initializer initializer, ExpressionGeneratorHelper helper,
+      {required InitializerInferenceResult? inferenceResult}) {
+    List<Initializer> initializers = _constructor.initializers;
+    if (initializer is SuperInitializer) {
+      if (superInitializer != null) {
+        injectInvalidInitializer(messageMoreThanOneSuperInitializer,
+            initializer.fileOffset, "super".length, helper);
+      } else if (redirectingInitializer != null) {
+        injectInvalidInitializer(
+            messageRedirectingConstructorWithSuperInitializer,
+            initializer.fileOffset,
+            "super".length,
+            helper);
+      } else {
+        inferenceResult?.applyResult(initializers, _constructor);
+        initializers.add(initializer..parent = _constructor);
+        superInitializer = initializer;
+      }
+    } else if (initializer is RedirectingInitializer) {
+      if (superInitializer != null) {
+        // Point to the existing super initializer.
+        injectInvalidInitializer(
+            messageRedirectingConstructorWithSuperInitializer,
+            superInitializer!.fileOffset,
+            "super".length,
+            helper);
+      } else if (redirectingInitializer != null) {
+        injectInvalidInitializer(
+            messageRedirectingConstructorWithMultipleRedirectInitializers,
+            initializer.fileOffset,
+            noLength,
+            helper);
+      } else if (initializers.isNotEmpty) {
+        // Error on all previous ones.
+        for (int i = 0; i < initializers.length; i++) {
+          Initializer initializer = initializers[i];
+          int length = noLength;
+          if (initializer is AssertInitializer) length = "assert".length;
+          Initializer error = helper.buildInvalidInitializer(
+              helper.buildProblem(
+                  messageRedirectingConstructorWithAnotherInitializer,
+                  initializer.fileOffset,
+                  length));
+          error.parent = _constructor;
+          initializers[i] = error;
+        }
+        inferenceResult?.applyResult(initializers, _constructor);
+        initializers.add(initializer..parent = _constructor);
+        redirectingInitializer = initializer;
+      } else {
+        inferenceResult?.applyResult(initializers, _constructor);
+        initializers.add(initializer..parent = _constructor);
+        redirectingInitializer = initializer;
+      }
+    } else if (redirectingInitializer != null) {
+      int length = noLength;
+      if (initializer is AssertInitializer) length = "assert".length;
+      injectInvalidInitializer(
+          messageRedirectingConstructorWithAnotherInitializer,
+          initializer.fileOffset,
+          length,
+          helper);
+    } else if (superInitializer != null) {
+      injectInvalidInitializer(messageSuperInitializerNotLast,
+          initializer.fileOffset, noLength, helper);
+    } else {
+      inferenceResult?.applyResult(initializers, _constructor);
+      initializers.add(initializer..parent = _constructor);
+    }
+  }
+
+  @override
+  VariableDeclaration? getTearOffParameter(int index) {
+    if (_constructorTearOff != null) {
+      if (index < _constructorTearOff!.function.positionalParameters.length) {
+        return _constructorTearOff!.function.positionalParameters[index];
+      } else {
+        index -= _constructorTearOff!.function.positionalParameters.length;
+        if (index < _constructorTearOff!.function.namedParameters.length) {
+          return _constructorTearOff!.function.namedParameters[index];
+        }
+      }
+    }
+    return null;
+  }
+
+  void _finishPatch() {
+    // TODO(ahe): restore file-offset once we track both origin and patch file
+    // URIs. See https://github.com/dart-lang/sdk/issues/31579
+    origin.constructor.fileUri = fileUri;
+    origin.constructor.startFileOffset = _constructor.startFileOffset;
+    origin.constructor.fileOffset = _constructor.fileOffset;
+    origin.constructor.fileEndOffset = _constructor.fileEndOffset;
+    origin.constructor.annotations
+        .forEach((m) => m.fileOffset = _constructor.fileOffset);
+
+    origin.constructor.isExternal = _constructor.isExternal;
+    origin.constructor.function = _constructor.function;
+    origin.constructor.function.parent = origin.constructor;
+    origin.constructor.initializers = _constructor.initializers;
+    setParents(origin.constructor.initializers, origin.constructor);
+  }
+
+  @override
+  int finishPatch() {
+    if (!isPatch) return 0;
+    _finishPatch();
+    return 1;
+  }
+
+  @override
+  void becomeNative(SourceLoader loader) {
+    _constructor.isExternal = true;
+    super.becomeNative(loader);
+  }
+
+  @override
+  void applyPatch(Builder patch) {
+    if (patch is SourceConstructorBuilder) {
+      if (checkPatch(patch)) {
+        patch.actualOrigin = this;
+        dataForTesting?.patchForTesting = patch;
+      }
+    } else {
+      reportPatchMismatch(patch);
+    }
+  }
+
+  void prepareInitializers() {
+    // For const constructors we parse initializers already at the outlining
+    // stage, there is no easy way to make body building stage skip initializer
+    // parsing, so we simply clear parsed initializers and rebuild them
+    // again.
+    // For when doing an experimental incremental compilation they are also
+    // potentially done more than once (because it rebuilds the bodies of an old
+    // compile), and so we also clear them.
+    // Note: this method clears both initializers from the target Kernel node
+    // and internal state associated with parsing initializers.
+    _constructor.initializers = [];
+    redirectingInitializer = null;
+    superInitializer = null;
+    hasMovedSuperInitializer = false;
+  }
+
+  @override
+  List<ClassMember> get localMembers =>
+      throw new UnsupportedError('${runtimeType}.localMembers');
+
+  @override
+  List<ClassMember> get localSetters =>
+      throw new UnsupportedError('${runtimeType}.localSetters');
+
+  /// Registers field as being initialized by this constructor.
+  ///
+  /// The field can be initialized either via an initializing formal or via an
+  /// entry in the constructor initializer list.
+  void registerInitializedField(FieldBuilder fieldBuilder) {
+    (_initializedFields ??= {}).add(fieldBuilder);
+  }
+
+  /// Returns the fields registered as initialized by this constructor.
+  ///
+  /// Returns the set of fields previously registered via
+  /// [registerInitializedField] and passes on the ownership of the collection
+  /// to the caller.
+  Set<FieldBuilder>? takeInitializedFields() {
+    Set<FieldBuilder>? result = _initializedFields;
+    _initializedFields = null;
+    return result;
+  }
+}
+
+class SyntheticConstructorBuilder extends DillConstructorBuilder
+    with SourceMemberBuilderMixin {
+  // TODO(johnniwinther,cstefantsova): Rename [_origin] to avoid the confusion
+  // with patches.
+  // TODO(johnniwinther): Change the type of [_origin] to SourceMemberBuilder
+  // when it's the supertype for both old SourceMemberBuilder and
+  // SyntheticConstructorBuilder.
+  MemberBuilder? _origin;
+  SynthesizedFunctionNode? _synthesizedFunctionNode;
+
+  SyntheticConstructorBuilder(SourceClassBuilder parent,
+      Constructor constructor, Procedure? constructorTearOff,
+      {MemberBuilder? origin, SynthesizedFunctionNode? synthesizedFunctionNode})
+      : _origin = origin,
+        _synthesizedFunctionNode = synthesizedFunctionNode,
+        super(constructor, constructorTearOff, parent);
+
+  // TODO(johnniwinther,cstefantsova): Rename [actualOrigin] to avoid the
+  //  confusion with patches.
+  MemberBuilder? get actualOrigin {
+    MemberBuilder? origin = _origin;
+    while (origin is SyntheticConstructorBuilder) {
+      origin = origin._origin;
+    }
+    return origin;
+  }
+
+  List<FormalParameterBuilder>? get formals {
+    MemberBuilder? origin = actualOrigin;
+    return origin is SourceConstructorBuilder ? origin.formals : null;
+  }
+
+  @override
+  void buildOutlineExpressions(
+      SourceLibraryBuilder libraryBuilder,
+      ClassHierarchy classHierarchy,
+      List<DelayedActionPerformer> delayedActionPerformers,
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
+    if (_origin != null) {
+      // Ensure that default value expressions have been created for [_origin].
+      LibraryBuilder originLibraryBuilder = _origin!.library;
+      if (originLibraryBuilder is SourceLibraryBuilder) {
+        // If [_origin] is from a source library, we need to build the default
+        // values and initializers first.
+        MemberBuilder origin = _origin!;
+        if (origin is SourceConstructorBuilder) {
+          origin.buildOutlineExpressions(originLibraryBuilder, classHierarchy,
+              delayedActionPerformers, synthesizedFunctionNodes);
+        } else if (origin is SyntheticConstructorBuilder) {
+          origin.buildOutlineExpressions(originLibraryBuilder, classHierarchy,
+              delayedActionPerformers, synthesizedFunctionNodes);
+        }
+      }
+      addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
+      _origin = null;
+    }
+  }
+
+  void addSuperParameterDefaultValueCloners(
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
+    MemberBuilder? origin = _origin;
+    if (origin is SourceConstructorBuilder) {
+      origin.addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
+    } else if (origin is SyntheticConstructorBuilder) {
+      origin.addSuperParameterDefaultValueCloners(synthesizedFunctionNodes);
+    }
+    if (_synthesizedFunctionNode != null) {
+      synthesizedFunctionNodes
+          .add(_synthesizedFunctionNode!..isOutlineNode = true);
+      _synthesizedFunctionNode = null;
+    }
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
similarity index 95%
rename from pkg/front_end/lib/src/fasta/builder/enum_builder.dart
rename to pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
index 1253322..112e190 100644
--- a/pkg/front_end/lib/src/fasta/builder/enum_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_enum_builder.dart
@@ -28,9 +28,19 @@
         SuperInitializer,
         ThisExpression;
 import 'package:kernel/class_hierarchy.dart';
-
 import 'package:kernel/reference_from_index.dart' show IndexedClass;
 
+import '../builder/builder.dart';
+import '../builder/class_builder.dart';
+import '../builder/field_builder.dart';
+import '../builder/formal_parameter_builder.dart';
+import '../builder/library_builder.dart';
+import '../builder/member_builder.dart';
+import '../builder/metadata_builder.dart';
+import '../builder/named_type_builder.dart';
+import '../builder/nullability_builder.dart';
+import '../builder/procedure_builder.dart';
+import '../builder/type_builder.dart';
 import '../fasta_codes.dart'
     show
         LocatedMessage,
@@ -39,32 +49,17 @@
         templateDuplicatedDeclarationCause,
         templateDuplicatedDeclarationSyntheticCause,
         templateEnumConstantSameNameAsEnclosing;
-
 import '../kernel/constructor_tearoff_lowering.dart';
 import '../kernel/kernel_helper.dart';
-
-import '../util/helpers.dart';
-
 import '../modifier.dart' show constMask, hasInitializerMask, staticMask;
-
 import '../scope.dart';
-
-import '../source/name_scheme.dart';
-import '../source/source_class_builder.dart' show SourceClassBuilder;
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
-import 'builder.dart';
-import 'class_builder.dart';
-import 'constructor_builder.dart';
-import 'field_builder.dart';
-import 'formal_parameter_builder.dart';
-import 'library_builder.dart';
-import 'member_builder.dart';
-import 'metadata_builder.dart';
-import 'named_type_builder.dart';
-import 'nullability_builder.dart';
-import 'procedure_builder.dart';
-import 'type_builder.dart';
+import '../util/helpers.dart';
+import 'name_scheme.dart';
+import 'source_class_builder.dart' show SourceClassBuilder;
+import 'source_constructor_builder.dart';
+import 'source_field_builder.dart';
+import 'source_library_builder.dart' show SourceLibraryBuilder;
+import 'source_procedure_builder.dart';
 
 class EnumBuilder extends SourceClassBuilder {
   final List<EnumConstantInfo?>? enumConstantInfos;
diff --git a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
index e17ec41..6a8924b 100644
--- a/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_extension_builder.dart
@@ -7,36 +7,29 @@
 import 'package:kernel/type_environment.dart';
 
 import '../../base/common.dart';
-
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
 import '../builder/extension_builder.dart';
-import '../builder/field_builder.dart';
 import '../builder/library_builder.dart';
-import '../builder/member_builder.dart';
 import '../builder/metadata_builder.dart';
 import '../builder/procedure_builder.dart';
 import '../builder/type_builder.dart';
 import '../builder/type_variable_builder.dart';
-
 import '../fasta_codes.dart'
     show
         messagePatchDeclarationMismatch,
         messagePatchDeclarationOrigin,
         noLength,
         templateExtensionMemberConflictsWithObjectMember;
-
 import '../kernel/kernel_helper.dart';
-
 import '../operator.dart';
-
 import '../problems.dart';
-
 import '../scope.dart';
-
 import '../util/helpers.dart';
-
+import 'source_field_builder.dart';
 import 'source_library_builder.dart';
+import 'source_member_builder.dart';
+import 'source_procedure_builder.dart';
 
 const String extensionThisName = '#this';
 
diff --git a/pkg/front_end/lib/src/fasta/builder/factory_builder.dart b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
similarity index 96%
rename from pkg/front_end/lib/src/fasta/builder/factory_builder.dart
rename to pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
index 9d3f52d..56e6800 100644
--- a/pkg/front_end/lib/src/fasta/builder/factory_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_factory_builder.dart
@@ -6,8 +6,14 @@
 import 'package:kernel/class_hierarchy.dart';
 import 'package:kernel/type_algebra.dart';
 
+import '../builder/builder.dart';
+import '../builder/constructor_reference_builder.dart';
+import '../builder/formal_parameter_builder.dart';
+import '../builder/function_builder.dart';
+import '../builder/metadata_builder.dart';
+import '../builder/type_builder.dart';
+import '../builder/type_variable_builder.dart';
 import '../dill/dill_member_builder.dart';
-
 import '../kernel/constructor_tearoff_lowering.dart';
 import '../kernel/forest.dart';
 import '../kernel/hierarchy/class_member.dart';
@@ -15,30 +21,17 @@
 import '../kernel/kernel_helper.dart';
 import '../kernel/redirecting_factory_body.dart'
     show getRedirectingFactoryBody, RedirectingFactoryBody;
-
-import '../source/source_loader.dart' show SourceLoader;
-
 import '../messages.dart'
     show messageConstFactoryRedirectionToNonConst, noLength;
-
 import '../problems.dart' show unexpected, unhandled;
-
-import '../source/name_scheme.dart';
-import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
 import '../type_inference/type_inferrer.dart';
 import '../type_inference/type_schema.dart';
-
 import '../util/helpers.dart';
-
-import 'builder.dart';
-import 'constructor_reference_builder.dart';
-import 'formal_parameter_builder.dart';
-import 'function_builder.dart';
-import 'member_builder.dart';
-import 'metadata_builder.dart';
-import 'type_builder.dart';
-import 'type_variable_builder.dart';
+import 'name_scheme.dart';
+import 'source_function_builder.dart';
+import 'source_library_builder.dart' show SourceLibraryBuilder;
+import 'source_loader.dart' show SourceLoader;
+import 'source_member_builder.dart';
 
 class SourceFactoryBuilder extends FunctionBuilderImpl {
   final int charOpenParenOffset;
diff --git a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
new file mode 100644
index 0000000..634ffab
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
@@ -0,0 +1,1812 @@
+// Copyright (c) 2016, 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.
+
+library fasta.field_builder;
+
+import 'package:_fe_analyzer_shared/src/scanner/scanner.dart' show Token;
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+import 'package:kernel/core_types.dart';
+import 'package:kernel/src/legacy_erasure.dart';
+import 'package:kernel/type_algebra.dart';
+
+import '../builder/class_builder.dart';
+import '../builder/field_builder.dart';
+import '../builder/member_builder.dart';
+import '../builder/metadata_builder.dart';
+import '../builder/type_builder.dart';
+import '../constant_context.dart' show ConstantContext;
+import '../fasta_codes.dart' show messageInternalProblemAlreadyInitialized;
+import '../kernel/body_builder.dart' show BodyBuilder;
+import '../kernel/hierarchy/class_member.dart';
+import '../kernel/hierarchy/members_builder.dart';
+import '../kernel/implicit_field_type.dart';
+import '../kernel/kernel_helper.dart';
+import '../kernel/late_lowering.dart' as late_lowering;
+import '../kernel/member_covariance.dart';
+import '../modifier.dart' show covariantMask, hasInitializerMask, lateMask;
+import '../problems.dart' show internalProblem;
+import '../scope.dart' show Scope;
+import '../source/name_scheme.dart';
+import '../source/source_extension_builder.dart';
+import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_loader.dart' show SourceLoader;
+import '../type_inference/type_inference_engine.dart'
+    show IncludesTypeParametersNonCovariantly;
+import '../util/helpers.dart' show DelayedActionPerformer;
+import 'source_member_builder.dart';
+
+class SourceFieldBuilder extends SourceMemberBuilderImpl
+    implements FieldBuilder {
+  @override
+  final String name;
+
+  @override
+  final int modifiers;
+
+  late FieldEncoding _fieldEncoding;
+
+  @override
+  final List<MetadataBuilder>? metadata;
+
+  @override
+  final TypeBuilder? type;
+
+  Token? _constInitializerToken;
+
+  bool hadTypesInferred = false;
+
+  @override
+  bool hasBodyBeenBuilt = false;
+
+  // TODO(johnniwinther): [parent] is not trust-worthy for determining
+  //  properties since it is changed after the creation of the builder. For now
+  //  we require it has an argument here. A follow-up should clean up the
+  //  misuse of parent.
+  @override
+  final bool isTopLevel;
+
+  SourceFieldBuilder(
+      this.metadata,
+      this.type,
+      this.name,
+      this.modifiers,
+      this.isTopLevel,
+      SourceLibraryBuilder libraryBuilder,
+      int charOffset,
+      int charEndOffset,
+      NameScheme fieldNameScheme,
+      {Reference? fieldReference,
+      Reference? fieldGetterReference,
+      Reference? fieldSetterReference,
+      Reference? lateIsSetFieldReference,
+      Reference? lateIsSetGetterReference,
+      Reference? lateIsSetSetterReference,
+      Reference? lateGetterReference,
+      Reference? lateSetterReference,
+      Token? constInitializerToken})
+      : _constInitializerToken = constInitializerToken,
+        super(libraryBuilder, charOffset) {
+    bool isInstanceMember = fieldNameScheme.isInstanceMember;
+
+    Uri fileUri = libraryBuilder.fileUri;
+    // If in mixed mode, late lowerings cannot use `null` as a sentinel on
+    // non-nullable fields since they can be assigned from legacy code.
+    late_lowering.IsSetStrategy isSetStrategy =
+        late_lowering.computeIsSetStrategy(libraryBuilder);
+
+    if (isAbstract || isExternal) {
+      assert(fieldReference == null);
+      assert(lateIsSetFieldReference == null);
+      assert(lateIsSetGetterReference == null);
+      assert(lateIsSetSetterReference == null);
+      assert(lateGetterReference == null);
+      assert(lateSetterReference == null);
+      _fieldEncoding = new AbstractOrExternalFieldEncoding(
+          this,
+          name,
+          fieldNameScheme,
+          fileUri,
+          charOffset,
+          charEndOffset,
+          fieldGetterReference,
+          fieldSetterReference,
+          isAbstract: isAbstract,
+          isExternal: isExternal,
+          isFinal: isFinal,
+          isCovariantByDeclaration: isCovariantByDeclaration,
+          isNonNullableByDefault: library.isNonNullableByDefault);
+    } else if (isLate &&
+        libraryBuilder.loader.target.backendTarget.isLateFieldLoweringEnabled(
+            hasInitializer: hasInitializer,
+            isFinal: isFinal,
+            isStatic: !isInstanceMember)) {
+      if (hasInitializer) {
+        if (isFinal) {
+          _fieldEncoding = new LateFinalFieldWithInitializerEncoding(
+              name,
+              fieldNameScheme,
+              fileUri,
+              charOffset,
+              charEndOffset,
+              fieldReference,
+              fieldGetterReference,
+              fieldSetterReference,
+              lateIsSetFieldReference,
+              lateIsSetGetterReference,
+              lateIsSetSetterReference,
+              lateGetterReference,
+              lateSetterReference,
+              isCovariantByDeclaration,
+              isSetStrategy);
+        } else {
+          _fieldEncoding = new LateFieldWithInitializerEncoding(
+              name,
+              fieldNameScheme,
+              fileUri,
+              charOffset,
+              charEndOffset,
+              fieldReference,
+              fieldGetterReference,
+              fieldSetterReference,
+              lateIsSetFieldReference,
+              lateIsSetGetterReference,
+              lateIsSetSetterReference,
+              lateGetterReference,
+              lateSetterReference,
+              isCovariantByDeclaration,
+              isSetStrategy);
+        }
+      } else {
+        if (isFinal) {
+          _fieldEncoding = new LateFinalFieldWithoutInitializerEncoding(
+              name,
+              fieldNameScheme,
+              fileUri,
+              charOffset,
+              charEndOffset,
+              fieldReference,
+              fieldGetterReference,
+              fieldSetterReference,
+              lateIsSetFieldReference,
+              lateIsSetGetterReference,
+              lateIsSetSetterReference,
+              lateGetterReference,
+              lateSetterReference,
+              isCovariantByDeclaration,
+              isSetStrategy);
+        } else {
+          _fieldEncoding = new LateFieldWithoutInitializerEncoding(
+              name,
+              fieldNameScheme,
+              fileUri,
+              charOffset,
+              charEndOffset,
+              fieldReference,
+              fieldGetterReference,
+              fieldSetterReference,
+              lateIsSetFieldReference,
+              lateIsSetGetterReference,
+              lateIsSetSetterReference,
+              lateGetterReference,
+              lateSetterReference,
+              isCovariantByDeclaration,
+              isSetStrategy);
+        }
+      }
+    } else if (libraryBuilder.isNonNullableByDefault &&
+        libraryBuilder.loader.target.backendTarget.useStaticFieldLowering &&
+        !isInstanceMember &&
+        !isConst &&
+        hasInitializer) {
+      if (isFinal) {
+        _fieldEncoding = new LateFinalFieldWithInitializerEncoding(
+            name,
+            fieldNameScheme,
+            fileUri,
+            charOffset,
+            charEndOffset,
+            fieldReference,
+            fieldGetterReference,
+            fieldSetterReference,
+            lateIsSetFieldReference,
+            lateIsSetGetterReference,
+            lateIsSetSetterReference,
+            lateGetterReference,
+            lateSetterReference,
+            isCovariantByDeclaration,
+            isSetStrategy);
+      } else {
+        _fieldEncoding = new LateFieldWithInitializerEncoding(
+            name,
+            fieldNameScheme,
+            fileUri,
+            charOffset,
+            charEndOffset,
+            fieldReference,
+            fieldGetterReference,
+            fieldSetterReference,
+            lateIsSetFieldReference,
+            lateIsSetGetterReference,
+            lateIsSetSetterReference,
+            lateGetterReference,
+            lateSetterReference,
+            isCovariantByDeclaration,
+            isSetStrategy);
+      }
+    } else {
+      assert(lateIsSetFieldReference == null);
+      assert(lateIsSetGetterReference == null);
+      assert(lateIsSetSetterReference == null);
+      assert(lateGetterReference == null);
+      assert(lateSetterReference == null);
+      _fieldEncoding = new RegularFieldEncoding(
+          name, fieldNameScheme, fileUri, charOffset, charEndOffset,
+          isFinal: isFinal,
+          isConst: isConst,
+          isLate: isLate,
+          hasInitializer: hasInitializer,
+          isNonNullableByDefault: library.isNonNullableByDefault,
+          fieldReference: fieldReference,
+          getterReference: fieldGetterReference,
+          setterReference: fieldSetterReference);
+    }
+  }
+
+  bool get isLateLowered => _fieldEncoding.isLateLowering;
+
+  bool _typeEnsured = false;
+  Set<ClassMember>? _overrideDependencies;
+
+  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
+    assert(
+        overriddenMembers.every((overriddenMember) =>
+            overriddenMember.classBuilder != classBuilder),
+        "Unexpected override dependencies for $this: $overriddenMembers");
+    _overrideDependencies ??= {};
+    _overrideDependencies!.addAll(overriddenMembers);
+  }
+
+  void _ensureType(ClassMembersBuilder membersBuilder) {
+    if (_typeEnsured) return;
+    if (_overrideDependencies != null) {
+      membersBuilder.inferFieldType(this, _overrideDependencies!);
+      _overrideDependencies = null;
+    } else {
+      inferType();
+    }
+    _typeEnsured = true;
+  }
+
+  @override
+  SourceLibraryBuilder get library => super.library as SourceLibraryBuilder;
+
+  @override
+  Member get member => _fieldEncoding.field;
+
+  @override
+  String get debugName => "FieldBuilder";
+
+  @override
+  bool get isField => true;
+
+  @override
+  bool get isLate => (modifiers & lateMask) != 0;
+
+  @override
+  bool get isCovariantByDeclaration => (modifiers & covariantMask) != 0;
+
+  @override
+  bool get hasInitializer => (modifiers & hasInitializerMask) != 0;
+
+  @override
+  void buildBody(CoreTypes coreTypes, Expression? initializer) {
+    assert(!hasBodyBeenBuilt);
+    hasBodyBeenBuilt = true;
+    if (!hasInitializer &&
+        initializer != null &&
+        initializer is! NullLiteral &&
+        !isConst &&
+        !isFinal) {
+      internalProblem(
+          messageInternalProblemAlreadyInitialized, charOffset, fileUri);
+    }
+    _fieldEncoding.createBodies(coreTypes, initializer);
+  }
+
+  @override
+  List<Initializer> buildInitializer(int fileOffset, Expression value,
+      {required bool isSynthetic}) {
+    return _fieldEncoding.createInitializer(fileOffset, value,
+        isSynthetic: isSynthetic);
+  }
+
+  @override
+  bool get isEligibleForInference {
+    return type == null && (hasInitializer || isClassInstanceMember);
+  }
+
+  @override
+  bool get isAssignable {
+    if (isConst) return false;
+    if (isFinal) {
+      if (isLate) {
+        return !hasInitializer;
+      }
+      return false;
+    }
+    return true;
+  }
+
+  @override
+  Field get field => _fieldEncoding.field;
+
+  @override
+  Member get readTarget => _fieldEncoding.readTarget;
+
+  @override
+  Member? get writeTarget {
+    return isAssignable ? _fieldEncoding.writeTarget : null;
+  }
+
+  @override
+  Member get invokeTarget => readTarget;
+
+  @override
+  Iterable<Member> get exportedMembers => _fieldEncoding.exportedMembers;
+
+  @override
+  void buildMembers(
+      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
+    build(library);
+    _fieldEncoding.registerMembers(library, this, f);
+  }
+
+  /// Builds the core AST structures for this field as needed for the outline.
+  void build(SourceLibraryBuilder libraryBuilder) {
+    if (type != null) {
+      fieldType = type!.build(libraryBuilder);
+    }
+    _fieldEncoding.build(libraryBuilder, this);
+  }
+
+  @override
+  void buildOutlineExpressions(
+      SourceLibraryBuilder library,
+      ClassHierarchy classHierarchy,
+      List<DelayedActionPerformer> delayedActionPerformers,
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
+    _fieldEncoding.completeSignature(classHierarchy.coreTypes);
+
+    for (Annotatable annotatable in _fieldEncoding.annotatables) {
+      MetadataBuilder.buildAnnotations(
+          annotatable,
+          metadata,
+          library,
+          declarationBuilder,
+          this,
+          fileUri,
+          declarationBuilder?.scope ?? library.scope);
+    }
+
+    // For modular compilation we need to include initializers of all const
+    // fields and all non-static final fields in classes with const constructors
+    // into the outline.
+    if ((isConst ||
+            (isFinal &&
+                !isStatic &&
+                isClassMember &&
+                classBuilder!.declaresConstConstructor)) &&
+        _constInitializerToken != null) {
+      Scope scope = declarationBuilder?.scope ?? library.scope;
+      BodyBuilder bodyBuilder = library.loader
+          .createBodyBuilderForOutlineExpression(
+              library, declarationBuilder, this, scope, fileUri);
+      bodyBuilder.constantContext =
+          isConst ? ConstantContext.inferred : ConstantContext.required;
+      Expression initializer = bodyBuilder.typeInferrer.inferFieldInitializer(
+          bodyBuilder,
+          fieldType,
+          bodyBuilder.parseFieldInitializer(_constInitializerToken!));
+      if (bodyBuilder.transformSetLiterals ||
+          bodyBuilder.transformCollections) {
+        // Wrap the initializer in a temporary parent expression; the
+        // transformations need a parent relation.
+        Not wrapper = new Not(initializer);
+        SourceLoader loader = library.loader;
+        loader.transformPostInference(wrapper, bodyBuilder.transformSetLiterals,
+            bodyBuilder.transformCollections, library.library);
+        initializer = wrapper.operand;
+      }
+      buildBody(classHierarchy.coreTypes, initializer);
+      bodyBuilder.performBacklogComputations(delayedActionPerformers);
+    }
+    _constInitializerToken = null;
+  }
+
+  @override
+  DartType get fieldType => _fieldEncoding.type;
+
+  void set fieldType(DartType value) {
+    _fieldEncoding.type = value;
+    if (!isFinal && !isConst && parent is ClassBuilder) {
+      Class enclosingClass = classBuilder!.cls;
+      if (enclosingClass.typeParameters.isNotEmpty) {
+        IncludesTypeParametersNonCovariantly needsCheckVisitor =
+            new IncludesTypeParametersNonCovariantly(
+                enclosingClass.typeParameters,
+                // We are checking the field type as if it is the type of the
+                // parameter of the implicit setter and this is a contravariant
+                // position.
+                initialVariance: Variance.contravariant);
+        if (value.accept(needsCheckVisitor)) {
+          _fieldEncoding.setGenericCovariantImpl();
+        }
+      }
+    }
+  }
+
+  @override
+  DartType inferType() {
+    SourceLibraryBuilder library = this.library;
+    if (fieldType is! ImplicitFieldType) {
+      // We have already inferred a type.
+      return fieldType;
+    }
+
+    ImplicitFieldType implicitFieldType = fieldType as ImplicitFieldType;
+    DartType inferredType = implicitFieldType.computeType();
+    if (fieldType is ImplicitFieldType) {
+      // `fieldType` may have changed if a circularity was detected when
+      // [inferredType] was computed.
+      if (!library.isNonNullableByDefault) {
+        inferredType = legacyErasure(inferredType);
+      }
+      fieldType = implicitFieldType.checkInferred(inferredType);
+
+      IncludesTypeParametersNonCovariantly? needsCheckVisitor;
+      if (parent is ClassBuilder) {
+        Class enclosingClass = classBuilder!.cls;
+        if (enclosingClass.typeParameters.isNotEmpty) {
+          needsCheckVisitor = new IncludesTypeParametersNonCovariantly(
+              enclosingClass.typeParameters,
+              // We are checking the field type as if it is the type of the
+              // parameter of the implicit setter and this is a contravariant
+              // position.
+              initialVariance: Variance.contravariant);
+        }
+      }
+      if (needsCheckVisitor != null) {
+        if (fieldType.accept(needsCheckVisitor)) {
+          _fieldEncoding.setGenericCovariantImpl();
+        }
+      }
+    }
+    return fieldType;
+  }
+
+  @override
+  DartType get builtType => fieldType;
+
+  List<ClassMember>? _localMembers;
+  List<ClassMember>? _localSetters;
+
+  @override
+  List<ClassMember> get localMembers =>
+      _localMembers ??= _fieldEncoding.getLocalMembers(this);
+
+  @override
+  List<ClassMember> get localSetters =>
+      _localSetters ??= _fieldEncoding.getLocalSetters(this);
+}
+
+/// Strategy pattern for creating different encodings of a declared field.
+///
+/// This is used to provide lowerings for late fields using synthesized getters
+/// and setters.
+abstract class FieldEncoding {
+  /// The type of the declared field.
+  abstract DartType type;
+
+  /// Creates the bodies needed for the field encoding using [initializer] as
+  /// the declared initializer expression.
+  ///
+  /// This method is not called for fields in outlines unless their are constant
+  /// or part of a const constructor.
+  void createBodies(CoreTypes coreTypes, Expression? initializer);
+
+  List<Initializer> createInitializer(int fileOffset, Expression value,
+      {required bool isSynthetic});
+
+  /// Registers that the (implicit) setter associated with this field needs to
+  /// contain a runtime type check to deal with generic covariance.
+  void setGenericCovariantImpl();
+
+  /// Returns the field that holds the field value at runtime.
+  Field get field;
+
+  /// Returns the members that holds the field annotations.
+  Iterable<Annotatable> get annotatables;
+
+  /// Returns the member used to read the field value.
+  Member get readTarget;
+
+  /// Returns the member used to write to the field.
+  Member? get writeTarget;
+
+  /// Returns the generated members that are visible through exports.
+  Iterable<Member> get exportedMembers;
+
+  /// Creates the members necessary for this field encoding.
+  ///
+  /// This method is called for both outline and full compilation so the created
+  /// members should be without body. The member bodies are created through
+  /// [createBodies].
+  void build(
+      SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder);
+
+  /// Calls [f] for each member needed for this field encoding.
+  void registerMembers(
+      SourceLibraryBuilder library,
+      SourceFieldBuilder fieldBuilder,
+      void Function(Member, BuiltMemberKind) f);
+
+  /// Returns a list of the field, getters and methods created by this field
+  /// encoding.
+  List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder);
+
+  /// Returns a list of the setters created by this field encoding.
+  List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder);
+
+  /// Ensures that the signatures all members created by this field encoding
+  /// are fully typed.
+  void completeSignature(CoreTypes coreTypes);
+
+  /// Returns `true` if this encoding is a late lowering.
+  bool get isLateLowering;
+}
+
+class RegularFieldEncoding implements FieldEncoding {
+  late final Field _field;
+
+  RegularFieldEncoding(String name, NameScheme nameScheme, Uri fileUri,
+      int charOffset, int charEndOffset,
+      {required bool isFinal,
+      required bool isConst,
+      required bool isLate,
+      required bool hasInitializer,
+      required bool isNonNullableByDefault,
+      required Reference? fieldReference,
+      required Reference? getterReference,
+      required Reference? setterReference}) {
+    // ignore: unnecessary_null_comparison
+    assert(isFinal != null);
+    // ignore: unnecessary_null_comparison
+    assert(isConst != null);
+    // ignore: unnecessary_null_comparison
+    assert(isLate != null);
+    // ignore: unnecessary_null_comparison
+    assert(hasInitializer != null);
+    bool isImmutable =
+        isLate ? (isFinal && hasInitializer) : (isFinal || isConst);
+    _field = isImmutable
+        ? new Field.immutable(
+            nameScheme.getFieldName(FieldNameType.Field, name,
+                isSynthesized: false),
+            isFinal: isFinal,
+            isConst: isConst,
+            isLate: isLate,
+            fileUri: fileUri,
+            fieldReference: fieldReference,
+            getterReference: getterReference)
+        : new Field.mutable(
+            nameScheme.getFieldName(FieldNameType.Field, name,
+                isSynthesized: false),
+            isFinal: isFinal,
+            isLate: isLate,
+            fileUri: fileUri,
+            fieldReference: fieldReference,
+            getterReference: getterReference,
+            setterReference: setterReference);
+    _field
+      ..fileOffset = charOffset
+      ..fileEndOffset = charEndOffset
+      ..isNonNullableByDefault = isNonNullableByDefault;
+  }
+
+  @override
+  DartType get type => _field.type;
+
+  @override
+  void set type(DartType value) {
+    _field.type = value;
+  }
+
+  @override
+  void completeSignature(CoreTypes coreTypes) {}
+
+  @override
+  void createBodies(CoreTypes coreTypes, Expression? initializer) {
+    if (initializer != null) {
+      _field.initializer = initializer..parent = _field;
+    }
+  }
+
+  @override
+  List<Initializer> createInitializer(int fileOffset, Expression value,
+      {required bool isSynthetic}) {
+    return <Initializer>[
+      new FieldInitializer(_field, value)
+        ..fileOffset = fileOffset
+        ..isSynthetic = isSynthetic
+    ];
+  }
+
+  @override
+  void build(
+      SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder) {
+    _field..isCovariantByDeclaration = fieldBuilder.isCovariantByDeclaration;
+    if (fieldBuilder.isExtensionMember) {
+      _field
+        ..isStatic = true
+        ..isExtensionMember = true;
+    } else {
+      bool isInstanceMember =
+          !fieldBuilder.isStatic && !fieldBuilder.isTopLevel;
+      _field
+        ..isStatic = !isInstanceMember
+        ..isExtensionMember = false;
+    }
+    _field.isLate = fieldBuilder.isLate;
+    updatePrivateMemberName(_field, libraryBuilder);
+  }
+
+  @override
+  void registerMembers(
+      SourceLibraryBuilder library,
+      SourceFieldBuilder fieldBuilder,
+      void Function(Member, BuiltMemberKind) f) {
+    f(
+        _field,
+        fieldBuilder.isExtensionMember
+            ? BuiltMemberKind.ExtensionField
+            : BuiltMemberKind.Field);
+  }
+
+  @override
+  void setGenericCovariantImpl() {
+    _field.isCovariantByClass = true;
+  }
+
+  @override
+  Field get field => _field;
+
+  @override
+  Iterable<Annotatable> get annotatables => [_field];
+
+  @override
+  Member get readTarget => _field;
+
+  @override
+  Member get writeTarget => _field;
+
+  @override
+  Iterable<Member> get exportedMembers => [_field];
+
+  @override
+  List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) =>
+      <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: false)];
+
+  @override
+  List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) =>
+      fieldBuilder.isAssignable
+          ? <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: true)]
+          : const <ClassMember>[];
+
+  @override
+  bool get isLateLowering => false;
+}
+
+class SourceFieldMember extends BuilderClassMember {
+  @override
+  final SourceFieldBuilder memberBuilder;
+
+  Covariance? _covariance;
+
+  @override
+  final bool forSetter;
+
+  SourceFieldMember(this.memberBuilder, {required this.forSetter})
+      // ignore: unnecessary_null_comparison
+      : assert(forSetter != null);
+
+  @override
+  void inferType(ClassMembersBuilder membersBuilder) {
+    memberBuilder._ensureType(membersBuilder);
+  }
+
+  @override
+  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
+    memberBuilder.registerOverrideDependency(overriddenMembers);
+  }
+
+  @override
+  Member getMember(ClassMembersBuilder membersBuilder) {
+    memberBuilder._ensureType(membersBuilder);
+    return memberBuilder.field;
+  }
+
+  @override
+  Covariance getCovariance(ClassMembersBuilder membersBuilder) {
+    return _covariance ??= forSetter
+        ? new Covariance.fromMember(getMember(membersBuilder),
+            forSetter: forSetter)
+        : const Covariance.empty();
+  }
+
+  @override
+  bool get isSourceDeclaration => true;
+
+  @override
+  bool get isProperty => true;
+
+  @override
+  bool isSameDeclaration(ClassMember other) {
+    return other is SourceFieldMember && memberBuilder == other.memberBuilder;
+  }
+}
+
+abstract class AbstractLateFieldEncoding implements FieldEncoding {
+  final String name;
+  final int fileOffset;
+  final int fileEndOffset;
+  DartType? _type;
+  late final Field _field;
+  Field? _lateIsSetField;
+  late Procedure _lateGetter;
+  Procedure? _lateSetter;
+
+  // If `true`, an isSet field is used even when the type of the field is
+  // not potentially nullable.
+  //
+  // This is used to force use isSet fields in mixed mode encoding since
+  // we cannot trust non-nullable fields to be initialized with non-null values.
+  final late_lowering.IsSetStrategy _isSetStrategy;
+  late_lowering.IsSetEncoding? _isSetEncoding;
+
+  // If `true`, the is-set field was register before the type was known to be
+  // nullable or non-nullable. In this case we do not try to remove it from
+  // the generated AST to avoid inconsistency between the class hierarchy used
+  // during and after inference.
+  //
+  // This is also used to force use isSet fields in mixed mode encoding since
+  // we cannot trust non-nullable fields to be initialized with non-null values.
+  bool _forceIncludeIsSetField;
+
+  AbstractLateFieldEncoding(
+      this.name,
+      NameScheme nameScheme,
+      Uri fileUri,
+      int charOffset,
+      int charEndOffset,
+      Reference? fieldReference,
+      Reference? fieldGetterReference,
+      Reference? fieldSetterReference,
+      Reference? lateIsSetFieldReference,
+      Reference? lateIsSetGetterReference,
+      Reference? lateIsSetSetterReference,
+      Reference? lateGetterReference,
+      Reference? lateSetterReference,
+      bool isCovariantByDeclaration,
+      late_lowering.IsSetStrategy isSetStrategy)
+      : fileOffset = charOffset,
+        fileEndOffset = charEndOffset,
+        _isSetStrategy = isSetStrategy,
+        _forceIncludeIsSetField =
+            isSetStrategy == late_lowering.IsSetStrategy.forceUseIsSetField {
+    _field = new Field.mutable(
+        nameScheme.getFieldName(FieldNameType.Field, name, isSynthesized: true),
+        fileUri: fileUri,
+        fieldReference: fieldReference,
+        getterReference: fieldGetterReference,
+        setterReference: fieldSetterReference)
+      ..fileOffset = charOffset
+      ..fileEndOffset = charEndOffset
+      ..isNonNullableByDefault = true
+      ..isInternalImplementation = true;
+    switch (_isSetStrategy) {
+      case late_lowering.IsSetStrategy.useSentinelOrNull:
+      case late_lowering.IsSetStrategy.forceUseSentinel:
+        // [_lateIsSetField] is never needed.
+        break;
+      case late_lowering.IsSetStrategy.forceUseIsSetField:
+      case late_lowering.IsSetStrategy.useIsSetFieldOrNull:
+        _lateIsSetField = new Field.mutable(
+            nameScheme.getFieldName(FieldNameType.IsSetField, name,
+                isSynthesized: true),
+            fileUri: fileUri,
+            fieldReference: lateIsSetFieldReference,
+            getterReference: lateIsSetGetterReference,
+            setterReference: lateIsSetSetterReference)
+          ..fileOffset = charOffset
+          ..fileEndOffset = charEndOffset
+          ..isNonNullableByDefault = true
+          ..isInternalImplementation = true;
+        break;
+    }
+    _lateGetter = new Procedure(
+        nameScheme.getFieldName(FieldNameType.Getter, name,
+            isSynthesized: true),
+        ProcedureKind.Getter,
+        new FunctionNode(null)
+          ..fileOffset = charOffset
+          ..fileEndOffset = charEndOffset,
+        fileUri: fileUri,
+        reference: lateGetterReference)
+      ..fileOffset = charOffset
+      ..fileEndOffset = charEndOffset
+      ..isNonNullableByDefault = true;
+    _lateSetter = _createSetter(
+        nameScheme.getFieldName(FieldNameType.Setter, name,
+            isSynthesized: true),
+        fileUri,
+        charOffset,
+        lateSetterReference,
+        isCovariantByDeclaration: isCovariantByDeclaration);
+  }
+
+  late_lowering.IsSetEncoding get isSetEncoding {
+    assert(_type != null, "Type has not been computed for field $name.");
+    return _isSetEncoding ??=
+        late_lowering.computeIsSetEncoding(_type!, _isSetStrategy);
+  }
+
+  @override
+  void completeSignature(CoreTypes coreTypes) {
+    _lateIsSetField?.type = coreTypes.boolRawType(Nullability.nonNullable);
+  }
+
+  @override
+  void createBodies(CoreTypes coreTypes, Expression? initializer) {
+    assert(_type != null, "Type has not been computed for field $name.");
+    if (isSetEncoding == late_lowering.IsSetEncoding.useSentinel) {
+      _field.initializer = new StaticInvocation(coreTypes.createSentinelMethod,
+          new Arguments([], types: [_type!])..fileOffset = fileOffset)
+        ..fileOffset = fileOffset
+        ..parent = _field;
+    } else {
+      _field.initializer = new NullLiteral()
+        ..fileOffset = fileOffset
+        ..parent = _field;
+    }
+    if (_lateIsSetField != null) {
+      _lateIsSetField!.initializer = new BoolLiteral(false)
+        ..fileOffset = fileOffset
+        ..parent = _lateIsSetField;
+    }
+    _lateGetter.function.body = _createGetterBody(coreTypes, name, initializer)
+      ..parent = _lateGetter.function;
+    if (_lateSetter != null) {
+      _lateSetter!.function.body = _createSetterBody(
+          coreTypes, name, _lateSetter!.function.positionalParameters.first)
+        ..parent = _lateSetter!.function;
+    }
+  }
+
+  @override
+  List<Initializer> createInitializer(int fileOffset, Expression value,
+      {required bool isSynthetic}) {
+    List<Initializer> initializers = <Initializer>[];
+    if (_lateIsSetField != null) {
+      initializers.add(new FieldInitializer(
+          _lateIsSetField!, new BoolLiteral(true)..fileOffset = fileOffset)
+        ..fileOffset = fileOffset
+        ..isSynthetic = isSynthetic);
+    }
+    initializers.add(new FieldInitializer(_field, value)
+      ..fileOffset = fileOffset
+      ..isSynthetic = isSynthetic);
+    return initializers;
+  }
+
+  /// Creates an [Expression] that reads [_field].
+  ///
+  /// If [needsPromotion] is `true`, the field will be read through a `let`
+  /// expression that promotes the expression to [_type]. This is needed for a
+  /// sound encoding of fields with type variable type of undetermined
+  /// nullability.
+  Expression _createFieldRead({bool needsPromotion: false}) {
+    assert(_type != null, "Type has not been computed for field $name.");
+    if (needsPromotion) {
+      VariableDeclaration variable = new VariableDeclaration.forValue(
+          _createFieldGet(_field),
+          type: _type!.withDeclaredNullability(Nullability.nullable))
+        ..fileOffset = fileOffset;
+      return new Let(
+          variable, new VariableGet(variable, _type)..fileOffset = fileOffset);
+    } else {
+      return _createFieldGet(_field);
+    }
+  }
+
+  /// Creates an [Expression] that reads [field].
+  Expression _createFieldGet(Field field) {
+    if (field.isStatic) {
+      return new StaticGet(field)..fileOffset = fileOffset;
+    } else {
+      // No substitution needed for the result type, since any type variables
+      // in there are also in scope at the access site.
+      return new InstanceGet(InstanceAccessKind.Instance,
+          new ThisExpression()..fileOffset = fileOffset, field.name,
+          interfaceTarget: field, resultType: field.type)
+        ..fileOffset = fileOffset;
+    }
+  }
+
+  /// Creates an [Expression] that writes [value] to [field].
+  Expression _createFieldSet(Field field, Expression value) {
+    if (field.isStatic) {
+      return new StaticSet(field, value)..fileOffset = fileOffset;
+    } else {
+      return new InstanceSet(InstanceAccessKind.Instance,
+          new ThisExpression()..fileOffset = fileOffset, field.name, value,
+          interfaceTarget: field)
+        ..fileOffset = fileOffset;
+    }
+  }
+
+  Statement _createGetterBody(
+      CoreTypes coreTypes, String name, Expression? initializer);
+
+  Procedure? _createSetter(
+      Name name, Uri fileUri, int charOffset, Reference? reference,
+      {required bool isCovariantByDeclaration}) {
+    // ignore: unnecessary_null_comparison
+    assert(isCovariantByDeclaration != null);
+    VariableDeclaration parameter = new VariableDeclaration(null)
+      ..isCovariantByDeclaration = isCovariantByDeclaration
+      ..fileOffset = fileOffset;
+    return new Procedure(
+        name,
+        ProcedureKind.Setter,
+        new FunctionNode(null,
+            positionalParameters: [parameter], returnType: const VoidType())
+          ..fileOffset = charOffset
+          ..fileEndOffset = fileEndOffset,
+        fileUri: fileUri,
+        reference: reference)
+      ..fileOffset = charOffset
+      ..fileEndOffset = fileEndOffset
+      ..isNonNullableByDefault = true;
+  }
+
+  Statement _createSetterBody(
+      CoreTypes coreTypes, String name, VariableDeclaration parameter);
+
+  @override
+  DartType get type {
+    assert(_type != null, "Type has not been computed for field $name.");
+    return _type!;
+  }
+
+  @override
+  void set type(DartType value) {
+    assert(_type == null || _type is ImplicitFieldType,
+        "Type has already been computed for field $name.");
+    _type = value;
+    if (value is! ImplicitFieldType) {
+      _field.type = value.withDeclaredNullability(Nullability.nullable);
+      _lateGetter.function.returnType = value;
+      if (_lateSetter != null) {
+        _lateSetter!.function.positionalParameters.single.type = value;
+      }
+      if (!_type!.isPotentiallyNullable && !_forceIncludeIsSetField) {
+        // We only need the is-set field if the field is potentially nullable.
+        //  Otherwise we use `null` to signal that the field is uninitialized.
+        _lateIsSetField = null;
+      }
+    }
+  }
+
+  @override
+  void setGenericCovariantImpl() {
+    _field.isCovariantByClass = true;
+    _lateSetter?.function.positionalParameters.single.isCovariantByClass = true;
+  }
+
+  @override
+  Field get field => _field;
+
+  @override
+  Iterable<Annotatable> get annotatables {
+    List<Annotatable> list = [_lateGetter];
+    if (_lateSetter != null) {
+      list.add(_lateSetter!);
+    }
+    return list;
+  }
+
+  @override
+  Member get readTarget => _lateGetter;
+
+  @override
+  Member? get writeTarget => _lateSetter;
+
+  @override
+  Iterable<Member> get exportedMembers {
+    if (_lateSetter != null) {
+      return [_lateGetter, _lateSetter!];
+    }
+    return [_lateGetter];
+  }
+
+  @override
+  void build(
+      SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder) {
+    bool isInstanceMember;
+    bool isExtensionMember = fieldBuilder.isExtensionMember;
+    if (isExtensionMember) {
+      _field
+        ..isStatic = true
+        ..isExtensionMember = isExtensionMember;
+      isInstanceMember = false;
+    } else {
+      isInstanceMember = !fieldBuilder.isStatic && !fieldBuilder.isTopLevel;
+      _field
+        ..isStatic = !isInstanceMember
+        ..isExtensionMember = false;
+    }
+    updatePrivateMemberName(_field, libraryBuilder);
+    if (_lateIsSetField != null) {
+      _lateIsSetField!
+        ..isStatic = !isInstanceMember
+        ..isStatic = _field.isStatic
+        ..isExtensionMember = isExtensionMember;
+      updatePrivateMemberName(_lateIsSetField!, libraryBuilder);
+    }
+    _lateGetter
+      ..isStatic = !isInstanceMember
+      ..isExtensionMember = isExtensionMember;
+    updatePrivateMemberName(_lateGetter, libraryBuilder);
+    if (_lateSetter != null) {
+      _lateSetter!
+        ..isStatic = !isInstanceMember
+        ..isExtensionMember = isExtensionMember;
+      updatePrivateMemberName(_lateSetter!, libraryBuilder);
+    }
+  }
+
+  @override
+  void registerMembers(
+      SourceLibraryBuilder library,
+      SourceFieldBuilder fieldBuilder,
+      void Function(Member, BuiltMemberKind) f) {
+    f(
+        _field,
+        fieldBuilder.isExtensionMember
+            ? BuiltMemberKind.ExtensionField
+            : BuiltMemberKind.Field);
+    if (_lateIsSetField != null) {
+      _forceIncludeIsSetField = true;
+      f(_lateIsSetField!, BuiltMemberKind.LateIsSetField);
+    }
+    f(_lateGetter, BuiltMemberKind.LateGetter);
+    if (_lateSetter != null) {
+      f(_lateSetter!, BuiltMemberKind.LateSetter);
+    }
+  }
+
+  @override
+  List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) {
+    List<ClassMember> list = <ClassMember>[
+      new _SynthesizedFieldClassMember(
+          fieldBuilder, field, _SynthesizedFieldMemberKind.LateField,
+          isInternalImplementation: true),
+      new _SynthesizedFieldClassMember(fieldBuilder, _lateGetter,
+          _SynthesizedFieldMemberKind.LateGetterSetter,
+          isInternalImplementation: false)
+    ];
+    if (_lateIsSetField != null) {
+      list.add(new _SynthesizedFieldClassMember(
+          fieldBuilder, _lateIsSetField!, _SynthesizedFieldMemberKind.LateIsSet,
+          isInternalImplementation: true));
+    }
+    return list;
+  }
+
+  @override
+  List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) {
+    List<ClassMember> list = <ClassMember>[
+      new _SynthesizedFieldClassMember(
+          fieldBuilder, field, _SynthesizedFieldMemberKind.LateField,
+          forSetter: true, isInternalImplementation: true),
+    ];
+    if (_lateIsSetField != null) {
+      list.add(new _SynthesizedFieldClassMember(
+          fieldBuilder, _lateIsSetField!, _SynthesizedFieldMemberKind.LateIsSet,
+          forSetter: true, isInternalImplementation: true));
+    }
+    if (_lateSetter != null) {
+      list.add(new _SynthesizedFieldClassMember(fieldBuilder, _lateSetter!,
+          _SynthesizedFieldMemberKind.LateGetterSetter,
+          forSetter: true, isInternalImplementation: false));
+    }
+    return list;
+  }
+
+  @override
+  bool get isLateLowering => true;
+}
+
+mixin NonFinalLate on AbstractLateFieldEncoding {
+  @override
+  Statement _createSetterBody(
+      CoreTypes coreTypes, String name, VariableDeclaration parameter) {
+    assert(_type != null, "Type has not been computed for field $name.");
+    return late_lowering.createSetterBody(
+        coreTypes, fileOffset, name, parameter, _type!,
+        shouldReturnValue: false,
+        createVariableWrite: (Expression value) =>
+            _createFieldSet(_field, value),
+        createIsSetWrite: (Expression value) =>
+            _createFieldSet(_lateIsSetField!, value),
+        isSetEncoding: isSetEncoding);
+  }
+}
+
+mixin LateWithoutInitializer on AbstractLateFieldEncoding {
+  @override
+  Statement _createGetterBody(
+      CoreTypes coreTypes, String name, Expression? initializer) {
+    assert(_type != null, "Type has not been computed for field $name.");
+    return late_lowering.createGetterBodyWithoutInitializer(
+        coreTypes, fileOffset, name, type,
+        createVariableRead: _createFieldRead,
+        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
+        isSetEncoding: isSetEncoding,
+        forField: true);
+  }
+}
+
+class LateFieldWithoutInitializerEncoding extends AbstractLateFieldEncoding
+    with NonFinalLate, LateWithoutInitializer {
+  LateFieldWithoutInitializerEncoding(
+      String name,
+      NameScheme nameScheme,
+      Uri fileUri,
+      int charOffset,
+      int charEndOffset,
+      Reference? fieldReference,
+      Reference? fieldGetterReference,
+      Reference? fieldSetterReference,
+      Reference? lateIsSetFieldReference,
+      Reference? lateIsSetGetterReference,
+      Reference? lateIsSetSetterReference,
+      Reference? lateGetterReference,
+      Reference? lateSetterReference,
+      bool isCovariantByDeclaration,
+      late_lowering.IsSetStrategy isSetStrategy)
+      : super(
+            name,
+            nameScheme,
+            fileUri,
+            charOffset,
+            charEndOffset,
+            fieldReference,
+            fieldGetterReference,
+            fieldSetterReference,
+            lateIsSetFieldReference,
+            lateIsSetGetterReference,
+            lateIsSetSetterReference,
+            lateGetterReference,
+            lateSetterReference,
+            isCovariantByDeclaration,
+            isSetStrategy);
+}
+
+class LateFieldWithInitializerEncoding extends AbstractLateFieldEncoding
+    with NonFinalLate {
+  LateFieldWithInitializerEncoding(
+      String name,
+      NameScheme nameScheme,
+      Uri fileUri,
+      int charOffset,
+      int charEndOffset,
+      Reference? fieldReference,
+      Reference? fieldGetterReference,
+      Reference? fieldSetterReference,
+      Reference? lateIsSetFieldReference,
+      Reference? lateIsSetGetterReference,
+      Reference? lateIsSetSetterReference,
+      Reference? lateGetterReference,
+      Reference? lateSetterReference,
+      bool isCovariantByDeclaration,
+      late_lowering.IsSetStrategy isSetStrategy)
+      : super(
+            name,
+            nameScheme,
+            fileUri,
+            charOffset,
+            charEndOffset,
+            fieldReference,
+            fieldGetterReference,
+            fieldSetterReference,
+            lateIsSetFieldReference,
+            lateIsSetGetterReference,
+            lateIsSetSetterReference,
+            lateGetterReference,
+            lateSetterReference,
+            isCovariantByDeclaration,
+            isSetStrategy);
+
+  @override
+  Statement _createGetterBody(
+      CoreTypes coreTypes, String name, Expression? initializer) {
+    assert(_type != null, "Type has not been computed for field $name.");
+    return late_lowering.createGetterWithInitializer(
+        coreTypes, fileOffset, name, _type!, initializer!,
+        createVariableRead: _createFieldRead,
+        createVariableWrite: (Expression value) =>
+            _createFieldSet(_field, value),
+        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
+        createIsSetWrite: (Expression value) =>
+            _createFieldSet(_lateIsSetField!, value),
+        isSetEncoding: isSetEncoding);
+  }
+}
+
+class LateFinalFieldWithoutInitializerEncoding extends AbstractLateFieldEncoding
+    with LateWithoutInitializer {
+  LateFinalFieldWithoutInitializerEncoding(
+      String name,
+      NameScheme nameScheme,
+      Uri fileUri,
+      int charOffset,
+      int charEndOffset,
+      Reference? fieldReference,
+      Reference? fieldGetterReference,
+      Reference? fieldSetterReference,
+      Reference? lateIsSetFieldReference,
+      Reference? lateIsSetGetterReference,
+      Reference? lateIsSetSetterReference,
+      Reference? lateGetterReference,
+      Reference? lateSetterReference,
+      bool isCovariantByDeclaration,
+      late_lowering.IsSetStrategy isSetStrategy)
+      : super(
+            name,
+            nameScheme,
+            fileUri,
+            charOffset,
+            charEndOffset,
+            fieldReference,
+            fieldGetterReference,
+            fieldSetterReference,
+            lateIsSetFieldReference,
+            lateIsSetGetterReference,
+            lateIsSetSetterReference,
+            lateGetterReference,
+            lateSetterReference,
+            isCovariantByDeclaration,
+            isSetStrategy);
+
+  @override
+  Statement _createSetterBody(
+      CoreTypes coreTypes, String name, VariableDeclaration parameter) {
+    assert(_type != null, "Type has not been computed for field $name.");
+    return late_lowering.createSetterBodyFinal(
+        coreTypes, fileOffset, name, parameter, type,
+        shouldReturnValue: false,
+        createVariableRead: () => _createFieldGet(_field),
+        createVariableWrite: (Expression value) =>
+            _createFieldSet(_field, value),
+        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
+        createIsSetWrite: (Expression value) =>
+            _createFieldSet(_lateIsSetField!, value),
+        isSetEncoding: isSetEncoding,
+        forField: true);
+  }
+}
+
+class LateFinalFieldWithInitializerEncoding extends AbstractLateFieldEncoding {
+  LateFinalFieldWithInitializerEncoding(
+      String name,
+      NameScheme nameScheme,
+      Uri fileUri,
+      int charOffset,
+      int charEndOffset,
+      Reference? fieldReference,
+      Reference? fieldGetterReference,
+      Reference? fieldSetterReference,
+      Reference? lateIsSetFieldReference,
+      Reference? lateIsSetGetterReference,
+      Reference? lateIsSetSetterReference,
+      Reference? lateGetterReference,
+      Reference? lateSetterReference,
+      bool isCovariantByDeclaration,
+      late_lowering.IsSetStrategy isSetStrategy)
+      : super(
+            name,
+            nameScheme,
+            fileUri,
+            charOffset,
+            charEndOffset,
+            fieldReference,
+            fieldGetterReference,
+            fieldSetterReference,
+            lateIsSetFieldReference,
+            lateIsSetGetterReference,
+            lateIsSetSetterReference,
+            lateGetterReference,
+            lateSetterReference,
+            isCovariantByDeclaration,
+            isSetStrategy);
+
+  @override
+  Statement _createGetterBody(
+      CoreTypes coreTypes, String name, Expression? initializer) {
+    assert(_type != null, "Type has not been computed for field $name.");
+    return late_lowering.createGetterWithInitializerWithRecheck(
+        coreTypes, fileOffset, name, _type!, initializer!,
+        createVariableRead: _createFieldRead,
+        createVariableWrite: (Expression value) =>
+            _createFieldSet(_field, value),
+        createIsSetRead: () => _createFieldGet(_lateIsSetField!),
+        createIsSetWrite: (Expression value) =>
+            _createFieldSet(_lateIsSetField!, value),
+        isSetEncoding: isSetEncoding,
+        forField: true);
+  }
+
+  @override
+  Procedure? _createSetter(
+          Name name, Uri fileUri, int charOffset, Reference? reference,
+          {required bool isCovariantByDeclaration}) =>
+      null;
+
+  @override
+  Statement _createSetterBody(
+          CoreTypes coreTypes, String name, VariableDeclaration parameter) =>
+      throw new UnsupportedError(
+          '$runtimeType._createSetterBody is not supported.');
+}
+
+class _SynthesizedFieldClassMember implements ClassMember {
+  final SourceFieldBuilder fieldBuilder;
+  final _SynthesizedFieldMemberKind _kind;
+
+  final Member _member;
+
+  Covariance? _covariance;
+
+  @override
+  final bool forSetter;
+
+  @override
+  final bool isInternalImplementation;
+
+  _SynthesizedFieldClassMember(this.fieldBuilder, this._member, this._kind,
+      {this.forSetter: false, required this.isInternalImplementation})
+      // ignore: unnecessary_null_comparison
+      : assert(isInternalImplementation != null);
+
+  @override
+  Member getMember(ClassMembersBuilder membersBuilder) {
+    fieldBuilder._ensureType(membersBuilder);
+    return _member;
+  }
+
+  @override
+  Covariance getCovariance(ClassMembersBuilder membersBuilder) {
+    return _covariance ??= new Covariance.fromMember(getMember(membersBuilder),
+        forSetter: forSetter);
+  }
+
+  @override
+  void inferType(ClassMembersBuilder membersBuilder) {
+    fieldBuilder._ensureType(membersBuilder);
+  }
+
+  @override
+  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
+    fieldBuilder.registerOverrideDependency(overriddenMembers);
+  }
+
+  @override
+  bool get isSourceDeclaration => true;
+
+  @override
+  bool get isProperty => isField || isGetter || isSetter;
+
+  @override
+  ClassBuilder get classBuilder => fieldBuilder.classBuilder!;
+
+  @override
+  bool isObjectMember(ClassBuilder objectClass) {
+    return classBuilder == objectClass;
+  }
+
+  @override
+  bool get isDuplicate => fieldBuilder.isDuplicate;
+
+  @override
+  bool get isStatic => fieldBuilder.isStatic;
+
+  @override
+  bool get isField => _member is Field;
+
+  @override
+  bool get isAssignable {
+    Member field = _member;
+    return field is Field && field.hasSetter;
+  }
+
+  @override
+  bool get isSetter {
+    Member procedure = _member;
+    return procedure is Procedure && procedure.kind == ProcedureKind.Setter;
+  }
+
+  @override
+  bool get isGetter {
+    Member procedure = _member;
+    return procedure is Procedure && procedure.kind == ProcedureKind.Getter;
+  }
+
+  @override
+  bool get isFinal {
+    Member field = _member;
+    return field is Field && field.isFinal;
+  }
+
+  @override
+  bool get isConst {
+    Member field = _member;
+    return field is Field && field.isConst;
+  }
+
+  @override
+  Name get name => _member.name;
+
+  @override
+  String get fullName {
+    String suffix = isSetter ? "=" : "";
+    String className = classBuilder.fullNameForErrors;
+    // ignore: unnecessary_null_comparison
+    return className == null
+        ? "${fullNameForErrors}$suffix"
+        : "${className}.${fullNameForErrors}$suffix";
+  }
+
+  @override
+  String get fullNameForErrors => fieldBuilder.fullNameForErrors;
+
+  @override
+  Uri get fileUri => fieldBuilder.fileUri;
+
+  @override
+  int get charOffset => fieldBuilder.charOffset;
+
+  @override
+  bool get isAbstract => _member.isAbstract;
+
+  @override
+  bool get isSynthesized => false;
+
+  @override
+  bool get hasDeclarations => false;
+
+  @override
+  List<ClassMember> get declarations =>
+      throw new UnsupportedError("$runtimeType.declarations");
+
+  @override
+  ClassMember get interfaceMember => this;
+
+  @override
+  bool isSameDeclaration(ClassMember other) {
+    if (identical(this, other)) return true;
+    return other is _SynthesizedFieldClassMember &&
+        fieldBuilder == other.fieldBuilder &&
+        _kind == other._kind;
+  }
+
+  @override
+  String toString() => '_SynthesizedFieldClassMember('
+      '$fieldBuilder,$_member,$_kind,forSetter=${forSetter})';
+}
+
+class AbstractOrExternalFieldEncoding implements FieldEncoding {
+  final SourceFieldBuilder _fieldBuilder;
+  final bool isAbstract;
+  final bool isExternal;
+  final bool _isExtensionInstanceMember;
+
+  late Procedure _getter;
+  Procedure? _setter;
+  DartType? _type;
+
+  AbstractOrExternalFieldEncoding(
+      this._fieldBuilder,
+      String name,
+      NameScheme nameScheme,
+      Uri fileUri,
+      int charOffset,
+      int charEndOffset,
+      Reference? getterReference,
+      Reference? setterReference,
+      {required this.isAbstract,
+      required this.isExternal,
+      required bool isFinal,
+      required bool isCovariantByDeclaration,
+      required bool isNonNullableByDefault})
+      // ignore: unnecessary_null_comparison
+      : assert(isAbstract != null),
+        // ignore: unnecessary_null_comparison
+        assert(isExternal != null),
+        // ignore: unnecessary_null_comparison
+        assert(isFinal != null),
+        // ignore: unnecessary_null_comparison
+        assert(isCovariantByDeclaration != null),
+        // ignore: unnecessary_null_comparison
+        assert(isNonNullableByDefault != null),
+        _isExtensionInstanceMember = isExternal &&
+            nameScheme.isExtensionMember &&
+            nameScheme.isInstanceMember {
+    if (_isExtensionInstanceMember) {
+      _getter = new Procedure(
+          nameScheme.getProcedureName(ProcedureKind.Getter, name),
+          ProcedureKind.Method,
+          new FunctionNode(null, positionalParameters: [
+            new VariableDeclaration(extensionThisName)..fileOffset
+          ]),
+          fileUri: fileUri,
+          reference: getterReference)
+        ..fileOffset = charOffset
+        ..fileEndOffset = charEndOffset
+        ..isNonNullableByDefault = isNonNullableByDefault;
+      if (!isFinal) {
+        VariableDeclaration parameter =
+            new VariableDeclaration("#externalFieldValue")
+              ..isCovariantByDeclaration = isCovariantByDeclaration
+              ..fileOffset = charOffset;
+        _setter = new Procedure(
+            nameScheme.getProcedureName(ProcedureKind.Setter, name),
+            ProcedureKind.Method,
+            new FunctionNode(null,
+                positionalParameters: [
+                  new VariableDeclaration(extensionThisName)..fileOffset,
+                  parameter
+                ],
+                returnType: const VoidType())
+              ..fileOffset = charOffset
+              ..fileEndOffset = charEndOffset,
+            fileUri: fileUri,
+            reference: setterReference)
+          ..fileOffset = charOffset
+          ..fileEndOffset = charEndOffset
+          ..isNonNullableByDefault = isNonNullableByDefault;
+      }
+    } else {
+      _getter = new Procedure(
+          nameScheme.getFieldName(FieldNameType.Getter, name,
+              isSynthesized: true),
+          ProcedureKind.Getter,
+          new FunctionNode(null),
+          fileUri: fileUri,
+          reference: getterReference)
+        ..fileOffset = charOffset
+        ..fileEndOffset = charEndOffset
+        ..isNonNullableByDefault = isNonNullableByDefault;
+      if (!isFinal) {
+        VariableDeclaration parameter =
+            new VariableDeclaration("#externalFieldValue")
+              ..isCovariantByDeclaration = isCovariantByDeclaration
+              ..fileOffset = charOffset;
+        _setter = new Procedure(
+            nameScheme.getFieldName(FieldNameType.Setter, name,
+                isSynthesized: true),
+            ProcedureKind.Setter,
+            new FunctionNode(null,
+                positionalParameters: [parameter], returnType: const VoidType())
+              ..fileOffset = charOffset
+              ..fileEndOffset = charEndOffset,
+            fileUri: fileUri,
+            reference: setterReference)
+          ..fileOffset = charOffset
+          ..fileEndOffset = charEndOffset
+          ..isNonNullableByDefault = isNonNullableByDefault;
+      }
+    }
+  }
+
+  @override
+  DartType get type {
+    assert(_type != null,
+        "Type has not been computed for field ${_fieldBuilder.name}.");
+    return _type!;
+  }
+
+  @override
+  void set type(DartType value) {
+    assert(_type == null || _type is ImplicitFieldType,
+        "Type has already been computed for field ${_fieldBuilder.name}.");
+    _type = value;
+    if (value is! ImplicitFieldType) {
+      if (_isExtensionInstanceMember) {
+        SourceExtensionBuilder extensionBuilder =
+            _fieldBuilder.parent as SourceExtensionBuilder;
+        DartType onType = extensionBuilder.extension.onType;
+        List<TypeParameter> typeParameters =
+            extensionBuilder.extension.typeParameters;
+        if (typeParameters.isNotEmpty) {
+          FreshTypeParameters getterTypeParameters =
+              getFreshTypeParameters(typeParameters);
+          _getter.function.positionalParameters.first.type =
+              getterTypeParameters.substitute(onType);
+          _getter.function.returnType = getterTypeParameters.substitute(value);
+          _getter.function.typeParameters =
+              getterTypeParameters.freshTypeParameters;
+          setParents(
+              getterTypeParameters.freshTypeParameters, _getter.function);
+
+          Procedure? setter = _setter;
+          if (setter != null) {
+            FreshTypeParameters setterTypeParameters =
+                getFreshTypeParameters(typeParameters);
+            setter.function.positionalParameters.first.type =
+                setterTypeParameters.substitute(onType);
+            setter.function.positionalParameters[1].type =
+                setterTypeParameters.substitute(value);
+            setter.function.typeParameters =
+                setterTypeParameters.freshTypeParameters;
+            setParents(
+                setterTypeParameters.freshTypeParameters, setter.function);
+          }
+        } else {
+          _getter.function.returnType = value;
+          _setter?.function.positionalParameters[1].type = value;
+          _getter.function.positionalParameters.first.type = onType;
+          _setter?.function.positionalParameters.first.type = onType;
+        }
+      } else {
+        _getter.function.returnType = value;
+        Procedure? setter = _setter;
+        if (setter != null) {
+          if (setter.kind == ProcedureKind.Method) {
+            setter.function.positionalParameters[1].type = value;
+          } else {
+            setter.function.positionalParameters.first.type = value;
+          }
+        }
+      }
+    }
+  }
+
+  @override
+  void completeSignature(CoreTypes coreTypes) {}
+
+  @override
+  void createBodies(CoreTypes coreTypes, Expression? initializer) {
+    //assert(initializer != null);
+  }
+
+  @override
+  List<Initializer> createInitializer(int fileOffset, Expression value,
+      {required bool isSynthetic}) {
+    throw new UnsupportedError('ExternalFieldEncoding.createInitializer');
+  }
+
+  @override
+  void build(
+      SourceLibraryBuilder libraryBuilder, SourceFieldBuilder fieldBuilder) {
+    bool isExtensionMember = fieldBuilder.isExtensionMember;
+    bool isInstanceMember = !fieldBuilder.isExtensionMember &&
+        !fieldBuilder.isStatic &&
+        !fieldBuilder.isTopLevel;
+    _getter..isConst = fieldBuilder.isConst;
+    _getter
+      ..isStatic = !isInstanceMember
+      ..isExtensionMember = isExtensionMember
+      ..isAbstract = isAbstract && !isExternal
+      ..isExternal = isExternal;
+    updatePrivateMemberName(_getter, libraryBuilder);
+
+    if (_setter != null) {
+      _setter!
+        ..isStatic = !isInstanceMember
+        ..isExtensionMember = isExtensionMember
+        ..isAbstract = isAbstract && !isExternal
+        ..isExternal = isExternal;
+      updatePrivateMemberName(_setter!, libraryBuilder);
+    }
+  }
+
+  @override
+  void registerMembers(
+      SourceLibraryBuilder library,
+      SourceFieldBuilder fieldBuilder,
+      void Function(Member, BuiltMemberKind) f) {
+    f(
+        _getter,
+        fieldBuilder.isExtensionMember
+            ? BuiltMemberKind.ExtensionGetter
+            : BuiltMemberKind.Method);
+    if (_setter != null) {
+      f(
+          _setter!,
+          fieldBuilder.isExtensionMember
+              ? BuiltMemberKind.ExtensionSetter
+              : BuiltMemberKind.Method);
+    }
+  }
+
+  @override
+  void setGenericCovariantImpl() {
+    _setter!.function.positionalParameters.first.isCovariantByClass = true;
+  }
+
+  @override
+  Field get field {
+    throw new UnsupportedError("ExternalFieldEncoding.field");
+  }
+
+  @override
+  Iterable<Annotatable> get annotatables {
+    List<Annotatable> list = [_getter];
+    if (_setter != null) {
+      list.add(_setter!);
+    }
+    return list;
+  }
+
+  @override
+  Member get readTarget => _getter;
+
+  @override
+  Member? get writeTarget => _setter;
+
+  @override
+  Iterable<Member> get exportedMembers {
+    if (_setter != null) {
+      return [_getter, _setter!];
+    }
+    return [_getter];
+  }
+
+  @override
+  List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) =>
+      <ClassMember>[
+        new _SynthesizedFieldClassMember(fieldBuilder, _getter,
+            _SynthesizedFieldMemberKind.AbstractExternalGetterSetter,
+            forSetter: false, isInternalImplementation: false)
+      ];
+
+  @override
+  List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) =>
+      _setter != null
+          ? <ClassMember>[
+              new _SynthesizedFieldClassMember(fieldBuilder, _setter!,
+                  _SynthesizedFieldMemberKind.AbstractExternalGetterSetter,
+                  forSetter: true, isInternalImplementation: false)
+            ]
+          : const <ClassMember>[];
+
+  @override
+  bool get isLateLowering => false;
+}
+
+enum _SynthesizedFieldMemberKind {
+  /// A `isSet` field used for late lowering.
+  LateIsSet,
+
+  /// A field used for the value of a late lowered field.
+  LateField,
+
+  /// A getter or setter used for late lowering.
+  LateGetterSetter,
+
+  /// A getter or setter used for abstract or external fields.
+  AbstractExternalGetterSetter,
+}
diff --git a/pkg/front_end/lib/src/fasta/source/source_function_builder.dart b/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
new file mode 100644
index 0000000..c29ad33
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/source/source_function_builder.dart
@@ -0,0 +1,515 @@
+// Copyright (c) 2016, 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.
+
+library fasta.procedure_builder;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+
+import '../builder/builder.dart';
+import '../builder/class_builder.dart';
+import '../builder/declaration_builder.dart';
+import '../builder/extension_builder.dart';
+import '../builder/formal_parameter_builder.dart';
+import '../builder/function_builder.dart';
+import '../builder/library_builder.dart';
+import '../builder/member_builder.dart';
+import '../builder/metadata_builder.dart';
+import '../builder/type_builder.dart';
+import '../builder/type_variable_builder.dart';
+import '../identifiers.dart';
+import '../kernel/internal_ast.dart' show VariableDeclarationImpl;
+import '../kernel/kernel_helper.dart';
+import '../messages.dart'
+    show
+        messagePatchDeclarationMismatch,
+        messagePatchDeclarationOrigin,
+        messagePatchNonExternal,
+        noLength,
+        templateRequiredNamedParameterHasDefaultValueError;
+import '../modifier.dart';
+import '../scope.dart';
+import '../source/source_loader.dart' show SourceLoader;
+import '../type_inference/type_inference_engine.dart'
+    show IncludesTypeParametersNonCovariantly;
+import '../util/helpers.dart' show DelayedActionPerformer;
+import 'source_library_builder.dart' show SourceLibraryBuilder;
+import 'source_member_builder.dart';
+
+abstract class SourceFunctionBuilder
+    implements FunctionBuilder, SourceMemberBuilder {
+  List<MetadataBuilder>? get metadata;
+
+  TypeBuilder? get returnType;
+
+  List<TypeVariableBuilder>? get typeVariables;
+
+  List<FormalParameterBuilder>? get formals;
+
+  AsyncMarker get asyncModifier;
+
+  @override
+  ProcedureKind? get kind;
+
+  @override
+  bool get isAbstract;
+
+  @override
+  bool get isConstructor;
+
+  @override
+  bool get isRegularMethod;
+
+  @override
+  bool get isGetter;
+
+  @override
+  bool get isSetter;
+
+  @override
+  bool get isOperator;
+
+  @override
+  bool get isFactory;
+
+  /// This is the formal parameter scope as specified in the Dart Programming
+  /// Language Specification, 4th ed, section 9.2.
+  Scope computeFormalParameterScope(Scope parent);
+
+  Scope computeFormalParameterInitializerScope(Scope parent);
+
+  /// This scope doesn't correspond to any scope specified in the Dart
+  /// Programming Language Specification, 4th ed. It's an unspecified extension
+  /// to support generic methods.
+  Scope computeTypeParameterScope(Scope parent);
+
+  FormalParameterBuilder? getFormal(Identifier identifier);
+
+  String? get nativeMethodName;
+
+  Statement? get body;
+
+  void set body(Statement? newBody);
+
+  @override
+  bool get isNative;
+
+  /// Returns the [index]th parameter of this function.
+  ///
+  /// The index is the syntactical index, including both positional and named
+  /// parameter in the order they are declared, and excluding the synthesized
+  /// this parameter on extension instance members.
+  VariableDeclaration getFormalParameter(int index);
+
+  /// If this is an extension instance method or constructor with lowering
+  /// enabled, the tear off parameter corresponding to the [index]th parameter
+  /// on the instance method or constructor is returned.
+  ///
+  /// This is used to update the default value for the closure parameter when
+  /// it has been computed for the original parameter.
+  VariableDeclaration? getTearOffParameter(int index);
+
+  /// Returns the parameter for 'this' synthetically added to extension
+  /// instance members.
+  VariableDeclaration? get extensionThis;
+
+  /// Returns a list of synthetic type parameters added to extension instance
+  /// members.
+  List<TypeParameter>? get extensionTypeParameters;
+
+  void becomeNative(SourceLoader loader);
+
+  bool checkPatch(FunctionBuilder patch);
+
+  void reportPatchMismatch(Builder patch);
+}
+
+/// Common base class for constructor and procedure builders.
+abstract class FunctionBuilderImpl extends SourceMemberBuilderImpl
+    implements SourceFunctionBuilder {
+  @override
+  final List<MetadataBuilder>? metadata;
+
+  @override
+  final int modifiers;
+
+  @override
+  final TypeBuilder? returnType;
+
+  @override
+  final String name;
+
+  @override
+  final List<TypeVariableBuilder>? typeVariables;
+
+  @override
+  final List<FormalParameterBuilder>? formals;
+
+  /// If this procedure is an extension instance member, [_extensionThis] holds
+  /// the synthetically added `this` parameter.
+  VariableDeclaration? _extensionThis;
+
+  /// If this procedure is an extension instance member,
+  /// [_extensionTypeParameters] holds the type parameters copied from the
+  /// extension declaration.
+  List<TypeParameter>? _extensionTypeParameters;
+
+  FunctionBuilderImpl(
+      this.metadata,
+      this.modifiers,
+      this.returnType,
+      this.name,
+      this.typeVariables,
+      this.formals,
+      LibraryBuilder compilationUnit,
+      int charOffset,
+      this.nativeMethodName)
+      : super(compilationUnit, charOffset) {
+    if (formals != null) {
+      for (int i = 0; i < formals!.length; i++) {
+        formals![i].parent = this;
+      }
+    }
+  }
+
+  @override
+  String get debugName => "FunctionBuilder";
+
+  @override
+  AsyncMarker get asyncModifier;
+
+  @override
+  bool get isConstructor => false;
+
+  @override
+  bool get isAbstract => (modifiers & abstractMask) != 0;
+
+  @override
+  bool get isRegularMethod => identical(ProcedureKind.Method, kind);
+
+  @override
+  bool get isGetter => identical(ProcedureKind.Getter, kind);
+
+  @override
+  bool get isSetter => identical(ProcedureKind.Setter, kind);
+
+  @override
+  bool get isOperator => identical(ProcedureKind.Operator, kind);
+
+  @override
+  bool get isFactory => identical(ProcedureKind.Factory, kind);
+
+  @override
+  bool get isExternal => (modifiers & externalMask) != 0;
+
+  @override
+  bool get isAssignable => false;
+
+  @override
+  Scope computeFormalParameterScope(Scope parent) {
+    if (formals == null) return parent;
+    Map<String, Builder> local = <String, Builder>{};
+    for (FormalParameterBuilder formal in formals!) {
+      if (!isConstructor ||
+          !formal.isInitializingFormal && !formal.isSuperInitializingFormal) {
+        local[formal.name] = formal;
+      }
+    }
+    return new Scope(
+        local: local,
+        parent: parent,
+        debugName: "formal parameter",
+        isModifiable: false);
+  }
+
+  @override
+  Scope computeFormalParameterInitializerScope(Scope parent) {
+    // From
+    // [dartLangSpec.tex](../../../../../../docs/language/dartLangSpec.tex) at
+    // revision 94b23d3b125e9d246e07a2b43b61740759a0dace:
+    //
+    // When the formal parameter list of a non-redirecting generative
+    // constructor contains any initializing formals, a new scope is
+    // introduced, the _formal parameter initializer scope_, which is the
+    // current scope of the initializer list of the constructor, and which is
+    // enclosed in the scope where the constructor is declared.  Each
+    // initializing formal in the formal parameter list introduces a final
+    // local variable into the formal parameter initializer scope, but not into
+    // the formal parameter scope; every other formal parameter introduces a
+    // local variable into both the formal parameter scope and the formal
+    // parameter initializer scope.
+
+    if (formals == null) return parent;
+    Map<String, Builder> local = <String, Builder>{};
+    for (FormalParameterBuilder formal in formals!) {
+      local[formal.name] = formal.forFormalParameterInitializerScope();
+    }
+    return new Scope(
+        local: local,
+        parent: parent,
+        debugName: "formal parameter initializer",
+        isModifiable: false);
+  }
+
+  @override
+  Scope computeTypeParameterScope(Scope parent) {
+    if (typeVariables == null) return parent;
+    Map<String, Builder> local = <String, Builder>{};
+    for (TypeVariableBuilder variable in typeVariables!) {
+      local[variable.name] = variable;
+    }
+    return new Scope(
+        local: local,
+        parent: parent,
+        debugName: "type parameter",
+        isModifiable: false);
+  }
+
+  @override
+  FormalParameterBuilder? getFormal(Identifier identifier) {
+    if (formals != null) {
+      for (FormalParameterBuilder formal in formals!) {
+        if (formal.name == identifier.name &&
+            formal.charOffset == identifier.charOffset) {
+          return formal;
+        }
+      }
+      // If we have any formals we should find the one we're looking for.
+      assert(false, "$identifier not found in $formals");
+    }
+    return null;
+  }
+
+  @override
+  final String? nativeMethodName;
+
+  Statement? bodyInternal;
+
+  @override
+  void set body(Statement? newBody) {
+//    if (newBody != null) {
+//      if (isAbstract) {
+//        // TODO(danrubel): Is this check needed?
+//        return internalProblem(messageInternalProblemBodyOnAbstractMethod,
+//            newBody.fileOffset, fileUri);
+//      }
+//    }
+    bodyInternal = newBody;
+    // A forwarding semi-stub is a method that is abstract in the source code,
+    // but which needs to have a forwarding stub body in order to ensure that
+    // covariance checks occur.  We don't want to replace the forwarding stub
+    // body with null.
+    TreeNode? parent = function.parent;
+    if (!(newBody == null &&
+        parent is Procedure &&
+        parent.isForwardingSemiStub)) {
+      function.body = newBody;
+      newBody?.parent = function;
+    }
+  }
+
+  @override
+  Statement? get body => bodyInternal ??= new EmptyStatement();
+
+  @override
+  bool get isNative => nativeMethodName != null;
+
+  void buildFunction(SourceLibraryBuilder library) {
+    function.asyncMarker = asyncModifier;
+    function.body = body;
+    body?.parent = function;
+    IncludesTypeParametersNonCovariantly? needsCheckVisitor;
+    if (!isConstructor && !isFactory && parent is ClassBuilder) {
+      Class enclosingClass = classBuilder!.cls;
+      if (enclosingClass.typeParameters.isNotEmpty) {
+        needsCheckVisitor = new IncludesTypeParametersNonCovariantly(
+            enclosingClass.typeParameters,
+            // We are checking the parameter types which are in a
+            // contravariant position.
+            initialVariance: Variance.contravariant);
+      }
+    }
+    if (typeVariables != null) {
+      for (TypeVariableBuilder t in typeVariables!) {
+        TypeParameter parameter = t.parameter;
+        function.typeParameters.add(parameter);
+        if (needsCheckVisitor != null) {
+          if (parameter.bound.accept(needsCheckVisitor)) {
+            parameter.isCovariantByClass = true;
+          }
+        }
+      }
+      setParents(function.typeParameters, function);
+    }
+    if (formals != null) {
+      for (FormalParameterBuilder formal in formals!) {
+        VariableDeclaration parameter = formal.build(library, 0);
+        if (needsCheckVisitor != null) {
+          if (parameter.type.accept(needsCheckVisitor)) {
+            parameter.isCovariantByClass = true;
+          }
+        }
+        if (formal.isNamed) {
+          function.namedParameters.add(parameter);
+        } else {
+          function.positionalParameters.add(parameter);
+        }
+        parameter.parent = function;
+        if (formal.isRequired) {
+          function.requiredParameterCount++;
+        }
+
+        if (library.isNonNullableByDefault) {
+          // Required named parameters can't have default values.
+          if (formal.isNamedRequired && formal.initializerToken != null) {
+            library.addProblem(
+                templateRequiredNamedParameterHasDefaultValueError
+                    .withArguments(formal.name),
+                formal.charOffset,
+                formal.name.length,
+                formal.fileUri);
+          }
+        }
+      }
+    }
+    if (!isExtensionInstanceMember &&
+        isSetter &&
+        (formals?.length != 1 || formals![0].isOptional)) {
+      // Replace illegal parameters by single dummy parameter.
+      // Do this after building the parameters, since the diet listener
+      // assumes that parameters are built, even if illegal in number.
+      VariableDeclaration parameter =
+          new VariableDeclarationImpl("#synthetic", 0);
+      function.positionalParameters.clear();
+      function.positionalParameters.add(parameter);
+      parameter.parent = function;
+      function.namedParameters.clear();
+      function.requiredParameterCount = 1;
+    }
+    if (returnType != null) {
+      function.returnType = returnType!.build(library);
+    }
+    if (isExtensionInstanceMember) {
+      ExtensionBuilder extensionBuilder = parent as ExtensionBuilder;
+      _extensionThis = function.positionalParameters.first;
+      if (extensionBuilder.typeParameters != null) {
+        int count = extensionBuilder.typeParameters!.length;
+        _extensionTypeParameters = new List<TypeParameter>.generate(
+            count, (int index) => function.typeParameters[index],
+            growable: false);
+      }
+    }
+  }
+
+  @override
+  VariableDeclaration getFormalParameter(int index) {
+    if (isExtensionInstanceMember) {
+      return formals![index + 1].variable!;
+    } else {
+      return formals![index].variable!;
+    }
+  }
+
+  @override
+  VariableDeclaration? getTearOffParameter(int index) => null;
+
+  @override
+  VariableDeclaration? get extensionThis {
+    assert(_extensionThis != null || !isExtensionInstanceMember,
+        "ProcedureBuilder.extensionThis has not been set.");
+    return _extensionThis;
+  }
+
+  @override
+  List<TypeParameter>? get extensionTypeParameters {
+    // Use [_extensionThis] as marker for whether extension type parameters have
+    // been computed.
+    assert(_extensionThis != null || !isExtensionInstanceMember,
+        "ProcedureBuilder.extensionTypeParameters has not been set.");
+    return _extensionTypeParameters;
+  }
+
+  bool _hasBuiltOutlineExpressions = false;
+
+  @override
+  void buildOutlineExpressions(
+      SourceLibraryBuilder library,
+      ClassHierarchy classHierarchy,
+      List<DelayedActionPerformer> delayedActionPerformers,
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {
+    if (!_hasBuiltOutlineExpressions) {
+      DeclarationBuilder? classOrExtensionBuilder =
+          isClassMember || isExtensionMember
+              ? parent as DeclarationBuilder
+              : null;
+      Scope parentScope = classOrExtensionBuilder?.scope ?? library.scope;
+      MetadataBuilder.buildAnnotations(member, metadata, library,
+          classOrExtensionBuilder, this, fileUri, parentScope);
+      if (typeVariables != null) {
+        for (int i = 0; i < typeVariables!.length; i++) {
+          typeVariables![i].buildOutlineExpressions(
+              library,
+              classOrExtensionBuilder,
+              this,
+              classHierarchy,
+              delayedActionPerformers,
+              computeTypeParameterScope(parentScope));
+        }
+      }
+
+      if (formals != null) {
+        // For const constructors we need to include default parameter values
+        // into the outline. For all other formals we need to call
+        // buildOutlineExpressions to clear initializerToken to prevent
+        // consuming too much memory.
+        for (FormalParameterBuilder formal in formals!) {
+          formal.buildOutlineExpressions(library, delayedActionPerformers);
+        }
+      }
+      _hasBuiltOutlineExpressions = true;
+    }
+  }
+
+  Member build(SourceLibraryBuilder library);
+
+  @override
+  void becomeNative(SourceLoader loader) {
+    MemberBuilder constructor = loader.getNativeAnnotation();
+    Arguments arguments =
+        new Arguments(<Expression>[new StringLiteral(nativeMethodName!)]);
+    Expression annotation;
+    if (constructor.isConstructor) {
+      annotation = new ConstructorInvocation(
+          constructor.member as Constructor, arguments)
+        ..isConst = true;
+    } else {
+      annotation =
+          new StaticInvocation(constructor.member as Procedure, arguments)
+            ..isConst = true;
+    }
+    member.addAnnotation(annotation);
+  }
+
+  @override
+  bool checkPatch(FunctionBuilder patch) {
+    if (!isExternal) {
+      patch.library.addProblem(
+          messagePatchNonExternal, patch.charOffset, noLength, patch.fileUri!,
+          context: [
+            messagePatchDeclarationOrigin.withLocation(
+                fileUri, charOffset, noLength)
+          ]);
+      return false;
+    }
+    return true;
+  }
+
+  @override
+  void reportPatchMismatch(Builder patch) {
+    library.addProblem(messagePatchDeclarationMismatch, patch.charOffset,
+        noLength, patch.fileUri!, context: [
+      messagePatchDeclarationOrigin.withLocation(fileUri, charOffset, noLength)
+    ]);
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index b7551de..4b3cd4c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -8,43 +8,31 @@
 import 'dart:convert' show jsonEncode;
 
 import 'package:_fe_analyzer_shared/src/scanner/token.dart' show Token;
-
 import 'package:_fe_analyzer_shared/src/util/resolve_relative_uri.dart'
     show resolveRelativeUri;
-
 import 'package:kernel/ast.dart' hide Combinator, MapLiteralEntry;
-
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
 import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
-
 import 'package:kernel/reference_from_index.dart'
     show IndexedClass, IndexedContainer, IndexedLibrary;
-
 import 'package:kernel/src/bounds_checks.dart'
     show
         TypeArgumentIssue,
         findTypeArgumentIssues,
         findTypeArgumentIssuesForInvocation,
         getGenericTypeName;
-
 import 'package:kernel/type_algebra.dart' show Substitution, substitute;
-
 import 'package:kernel/type_environment.dart'
     show SubtypeCheckMode, TypeEnvironment;
 
 import '../../api_prototype/experimental_flags.dart';
 import '../../base/nnbd_mode.dart';
-
 import '../builder/builder.dart';
 import '../builder/builtin_type_declaration_builder.dart';
 import '../builder/class_builder.dart';
-import '../builder/constructor_builder.dart';
 import '../builder/constructor_reference_builder.dart';
 import '../builder/dynamic_type_declaration_builder.dart';
-import '../builder/enum_builder.dart';
 import '../builder/extension_builder.dart';
-import '../builder/factory_builder.dart';
 import '../builder/field_builder.dart';
 import '../builder/formal_parameter_builder.dart';
 import '../builder/function_builder.dart';
@@ -65,23 +53,15 @@
 import '../builder/type_declaration_builder.dart';
 import '../builder/type_variable_builder.dart';
 import '../builder/void_type_declaration_builder.dart';
-
 import '../combinator.dart' show CombinatorBuilder;
-
 import '../configuration.dart' show Configuration;
-
 import '../dill/dill_library_builder.dart' show DillLibraryBuilder;
-
 import '../export.dart' show Export;
-
 import '../fasta_codes.dart';
-
 import '../identifiers.dart' show QualifiedName, flattenName;
-
 import '../import.dart' show Import;
-
-import '../kernel/hierarchy/members_builder.dart';
 import '../kernel/constructor_tearoff_lowering.dart';
+import '../kernel/hierarchy/members_builder.dart';
 import '../kernel/implicit_field_type.dart';
 import '../kernel/internal_ast.dart';
 import '../kernel/kernel_helper.dart';
@@ -97,7 +77,6 @@
         getNonSimplicityIssuesForTypeVariables,
         pendingVariance;
 import '../kernel/utils.dart' show compareProcedures, toKernelCombinators;
-
 import '../modifier.dart'
     show
         abstractMask,
@@ -112,22 +91,23 @@
         mixinDeclarationMask,
         namedMixinApplicationMask,
         staticMask;
-
 import '../names.dart' show indexSetName;
-
 import '../operator.dart';
-
 import '../problems.dart' show unexpected, unhandled;
-
 import '../scope.dart';
-
 import '../type_inference/type_inferrer.dart' show TypeInferrerImpl;
-
 import '../util/helpers.dart';
 import 'name_scheme.dart';
 import 'source_class_builder.dart' show SourceClassBuilder;
+import 'source_constructor_builder.dart';
+import 'source_enum_builder.dart';
 import 'source_extension_builder.dart';
+import 'source_factory_builder.dart';
+import 'source_field_builder.dart';
+import 'source_function_builder.dart';
 import 'source_loader.dart' show SourceLoader;
+import 'source_member_builder.dart';
+import 'source_procedure_builder.dart';
 import 'source_type_alias_builder.dart';
 
 class SourceLibraryBuilder extends LibraryBuilderImpl {
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index b7bcf7a..4d9a9f9 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -35,28 +35,26 @@
 import '../../base/common.dart';
 import '../../base/instrumentation.dart' show Instrumentation;
 import '../../base/nnbd_mode.dart';
-import '../builder/metadata_builder.dart';
-import '../dill/dill_library_builder.dart';
-import '../builder_graph.dart';
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
-import '../builder/constructor_builder.dart';
 import '../builder/declaration_builder.dart';
-import '../builder/enum_builder.dart';
 import '../builder/extension_builder.dart';
 import '../builder/field_builder.dart';
 import '../builder/invalid_type_declaration_builder.dart';
 import '../builder/library_builder.dart';
 import '../builder/member_builder.dart';
+import '../builder/metadata_builder.dart';
 import '../builder/modifier_builder.dart';
 import '../builder/named_type_builder.dart';
 import '../builder/procedure_builder.dart';
 import '../builder/type_alias_builder.dart';
 import '../builder/type_builder.dart';
 import '../builder/type_declaration_builder.dart';
+import '../builder_graph.dart';
 import '../crash.dart' show firstSourceUri;
 import '../denylisted_classes.dart'
     show denylistedCoreClasses, denylistedTypedDataClasses;
+import '../dill/dill_library_builder.dart';
 import '../export.dart' show Export;
 import '../fasta_codes.dart';
 import '../kernel/body_builder.dart' show BodyBuilder;
@@ -84,12 +82,16 @@
 import 'name_scheme.dart';
 import 'outline_builder.dart' show OutlineBuilder;
 import 'source_class_builder.dart' show SourceClassBuilder;
+import 'source_constructor_builder.dart';
+import 'source_enum_builder.dart';
+import 'source_field_builder.dart';
 import 'source_library_builder.dart'
     show
         ImplicitLanguageVersion,
         InvalidLanguageVersion,
         LanguageVersion,
         SourceLibraryBuilder;
+import 'source_procedure_builder.dart';
 import 'stack_listener_impl.dart' show offsetForToken;
 
 class SourceLoader extends Loader {
diff --git a/pkg/front_end/lib/src/fasta/source/source_member_builder.dart b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
new file mode 100644
index 0000000..edfb1a1
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/source/source_member_builder.dart
@@ -0,0 +1,129 @@
+// Copyright (c) 2016, 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.
+
+library fasta.member_builder;
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/class_hierarchy.dart';
+
+import '../../base/common.dart';
+import '../builder/builder.dart';
+import '../builder/declaration_builder.dart';
+import '../builder/library_builder.dart';
+import '../builder/member_builder.dart';
+import '../kernel/kernel_helper.dart';
+import '../problems.dart' show unsupported;
+import '../source/source_library_builder.dart';
+import '../type_inference/type_inference_engine.dart'
+    show InferenceDataForTesting;
+import '../util/helpers.dart' show DelayedActionPerformer;
+
+abstract class SourceMemberBuilder implements MemberBuilder {
+  MemberDataForTesting? get dataForTesting;
+
+  /// Builds the core AST structures for this member as needed for the outline.
+  void buildMembers(
+      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f);
+
+  void buildOutlineExpressions(
+      SourceLibraryBuilder library,
+      ClassHierarchy classHierarchy,
+      List<DelayedActionPerformer> delayedActionPerformers,
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes);
+}
+
+mixin SourceMemberBuilderMixin implements SourceMemberBuilder {
+  @override
+  MemberDataForTesting? dataForTesting =
+      retainDataForTesting ? new MemberDataForTesting() : null;
+
+  @override
+  void buildMembers(
+      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
+    assert(false, "Unexpected call to $runtimeType.buildMembers.");
+  }
+}
+
+abstract class SourceMemberBuilderImpl extends MemberBuilderImpl
+    implements SourceMemberBuilder {
+  @override
+  MemberDataForTesting? dataForTesting;
+
+  SourceMemberBuilderImpl(Builder parent, int charOffset, [Uri? fileUri])
+      : dataForTesting =
+            retainDataForTesting ? new MemberDataForTesting() : null,
+        super(parent, charOffset, fileUri);
+
+  bool get isRedirectingGenerativeConstructor => false;
+
+  bool? _isConflictingSetter;
+
+  @override
+  bool get isConflictingSetter {
+    return _isConflictingSetter ??= false;
+  }
+
+  void set isConflictingSetter(bool value) {
+    assert(_isConflictingSetter == null,
+        '$this.isConflictingSetter has already been fixed.');
+    _isConflictingSetter = value;
+  }
+
+  // TODO(johnniwinther): Remove this and create a [ProcedureBuilder] interface.
+  @override
+  ProcedureKind? get kind => unsupported("kind", charOffset, fileUri);
+
+  @override
+  void buildOutlineExpressions(
+      SourceLibraryBuilder library,
+      ClassHierarchy classHierarchy,
+      List<DelayedActionPerformer> delayedActionPerformers,
+      List<SynthesizedFunctionNode> synthesizedFunctionNodes) {}
+
+  @override
+  StringBuffer printOn(StringBuffer buffer) {
+    if (isClassMember) {
+      buffer.write(classBuilder!.name);
+      buffer.write('.');
+    }
+    buffer.write(name);
+    return buffer;
+  }
+
+  /// The builder for the enclosing class or extension, if any.
+  DeclarationBuilder? get declarationBuilder =>
+      parent is DeclarationBuilder ? parent as DeclarationBuilder : null;
+}
+
+enum BuiltMemberKind {
+  Constructor,
+  RedirectingFactory,
+  Field,
+  Method,
+  ExtensionField,
+  ExtensionMethod,
+  ExtensionGetter,
+  ExtensionSetter,
+  ExtensionOperator,
+  ExtensionTearOff,
+  LateIsSetField,
+  LateGetter,
+  LateSetter,
+}
+
+class MemberDataForTesting {
+  final InferenceDataForTesting inferenceData = new InferenceDataForTesting();
+
+  MemberBuilder? patchForTesting;
+}
+
+/// If the name of [member] is private, update it to use the library reference
+/// of [libraryBuilder].
+// TODO(johnniwinther): Avoid having to update private names by setting
+// the correct library reference when creating parts.
+void updatePrivateMemberName(Member member, LibraryBuilder libraryBuilder) {
+  if (member.name.isPrivate) {
+    member.name = new Name(member.name.text, libraryBuilder.library);
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
new file mode 100644
index 0000000..a679d67
--- /dev/null
+++ b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
@@ -0,0 +1,541 @@
+// Copyright (c) 2019, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+import 'package:kernel/ast.dart';
+import 'package:kernel/type_algebra.dart';
+
+import '../builder/builder.dart';
+import '../builder/extension_builder.dart';
+import '../builder/formal_parameter_builder.dart';
+import '../builder/member_builder.dart';
+import '../builder/metadata_builder.dart';
+import '../builder/procedure_builder.dart';
+import '../builder/type_builder.dart';
+import '../builder/type_variable_builder.dart';
+import '../kernel/hierarchy/class_member.dart';
+import '../kernel/hierarchy/members_builder.dart';
+import '../kernel/member_covariance.dart';
+import '../source/name_scheme.dart';
+import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_loader.dart' show SourceLoader;
+import 'source_function_builder.dart';
+import 'source_member_builder.dart';
+
+class SourceProcedureBuilder extends FunctionBuilderImpl
+    implements ProcedureBuilder {
+  @override
+  final int charOpenParenOffset;
+
+  @override
+  AsyncMarker actualAsyncModifier = AsyncMarker.Sync;
+
+  @override
+  final bool isExtensionInstanceMember;
+
+  late Procedure _procedure;
+
+  final Reference? _tearOffReference;
+
+  /// If this is an extension instance method then [_extensionTearOff] holds
+  /// the synthetically created tear off function.
+  Procedure? _extensionTearOff;
+
+  /// If this is an extension instance method then
+  /// [_extensionTearOffParameterMap] holds a map from the parameters of
+  /// the methods to the parameter of the closure returned in the tear-off.
+  ///
+  /// This map is used to set the default values on the closure parameters when
+  /// these have been built.
+  Map<VariableDeclaration, VariableDeclaration>? _extensionTearOffParameterMap;
+
+  @override
+  final ProcedureKind kind;
+
+  SourceProcedureBuilder? actualOrigin;
+
+  SourceProcedureBuilder(
+      List<MetadataBuilder>? metadata,
+      int modifiers,
+      TypeBuilder? returnType,
+      String name,
+      List<TypeVariableBuilder>? typeVariables,
+      List<FormalParameterBuilder>? formals,
+      this.kind,
+      SourceLibraryBuilder libraryBuilder,
+      int startCharOffset,
+      int charOffset,
+      this.charOpenParenOffset,
+      int charEndOffset,
+      Reference? procedureReference,
+      this._tearOffReference,
+      AsyncMarker asyncModifier,
+      NameScheme nameScheme,
+      {required bool isExtensionMember,
+      required bool isInstanceMember,
+      String? nativeMethodName})
+      // ignore: unnecessary_null_comparison
+      : assert(isExtensionMember != null),
+        // ignore: unnecessary_null_comparison
+        assert(isInstanceMember != null),
+        assert(kind != ProcedureKind.Factory),
+        this.isExtensionInstanceMember = isInstanceMember && isExtensionMember,
+        super(metadata, modifiers, returnType, name, typeVariables, formals,
+            libraryBuilder, charOffset, nativeMethodName) {
+    _procedure = new Procedure(
+        nameScheme.getProcedureName(kind, name),
+        isExtensionInstanceMember ? ProcedureKind.Method : kind,
+        new FunctionNode(null),
+        fileUri: libraryBuilder.fileUri,
+        reference: procedureReference)
+      ..startFileOffset = startCharOffset
+      ..fileOffset = charOffset
+      ..fileEndOffset = charEndOffset
+      ..isNonNullableByDefault = libraryBuilder.isNonNullableByDefault;
+    this.asyncModifier = asyncModifier;
+    if (isExtensionMember && isInstanceMember && kind == ProcedureKind.Method) {
+      _extensionTearOff ??= new Procedure(
+          nameScheme.getProcedureName(ProcedureKind.Getter, name),
+          ProcedureKind.Method,
+          new FunctionNode(null),
+          isStatic: true,
+          isExtensionMember: true,
+          reference: _tearOffReference,
+          fileUri: fileUri)
+        ..isNonNullableByDefault = library.isNonNullableByDefault;
+    }
+  }
+
+  @override
+  ProcedureBuilder? get patchForTesting =>
+      dataForTesting?.patchForTesting as ProcedureBuilder?;
+
+  @override
+  AsyncMarker get asyncModifier => actualAsyncModifier;
+
+  @override
+  Statement? get body {
+    if (bodyInternal == null && !isAbstract && !isExternal) {
+      bodyInternal = new EmptyStatement();
+    }
+    return bodyInternal;
+  }
+
+  @override
+  void set asyncModifier(AsyncMarker newModifier) {
+    actualAsyncModifier = newModifier;
+    function.asyncMarker = actualAsyncModifier;
+    function.dartAsyncMarker = actualAsyncModifier;
+  }
+
+  @override
+  bool get isEligibleForTopLevelInference {
+    if (isDeclarationInstanceMember) {
+      if (returnType == null) return true;
+      if (formals != null) {
+        for (FormalParameterBuilder formal in formals!) {
+          if (formal.type == null) return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  @override
+  bool get isExtensionMethod {
+    return parent is ExtensionBuilder;
+  }
+
+  @override
+  Member get member => procedure;
+
+  @override
+  SourceProcedureBuilder get origin => actualOrigin ?? this;
+
+  @override
+  Procedure get procedure => isPatch ? origin.procedure : _procedure;
+
+  @override
+  Procedure get actualProcedure => _procedure;
+
+  @override
+  FunctionNode get function => _procedure.function;
+
+  bool _typeEnsured = false;
+  Set<ClassMember>? _overrideDependencies;
+
+  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
+    assert(
+        overriddenMembers.every((overriddenMember) =>
+            overriddenMember.classBuilder != classBuilder),
+        "Unexpected override dependencies for $this: $overriddenMembers");
+    _overrideDependencies ??= {};
+    _overrideDependencies!.addAll(overriddenMembers);
+  }
+
+  void _ensureTypes(ClassMembersBuilder membersBuilder) {
+    if (_typeEnsured) return;
+    if (_overrideDependencies != null) {
+      if (isGetter) {
+        membersBuilder.inferGetterType(this, _overrideDependencies!);
+      } else if (isSetter) {
+        membersBuilder.inferSetterType(this, _overrideDependencies!);
+      } else {
+        membersBuilder.inferMethodType(this, _overrideDependencies!);
+      }
+      _overrideDependencies = null;
+    }
+    _typeEnsured = true;
+  }
+
+  @override
+  Member? get readTarget {
+    switch (kind) {
+      case ProcedureKind.Method:
+        return extensionTearOff ?? procedure;
+      case ProcedureKind.Getter:
+        return procedure;
+      case ProcedureKind.Factory:
+        return procedure;
+      case ProcedureKind.Operator:
+      case ProcedureKind.Setter:
+        return null;
+    }
+  }
+
+  @override
+  Member? get writeTarget {
+    switch (kind) {
+      case ProcedureKind.Setter:
+        return procedure;
+      case ProcedureKind.Method:
+      case ProcedureKind.Getter:
+      case ProcedureKind.Operator:
+      case ProcedureKind.Factory:
+        return null;
+    }
+  }
+
+  @override
+  Member? get invokeTarget {
+    switch (kind) {
+      case ProcedureKind.Method:
+      case ProcedureKind.Getter:
+      case ProcedureKind.Operator:
+      case ProcedureKind.Factory:
+        return procedure;
+      case ProcedureKind.Setter:
+        return null;
+    }
+  }
+
+  @override
+  Iterable<Member> get exportedMembers => [procedure];
+
+  @override
+  void buildMembers(
+      SourceLibraryBuilder library, void Function(Member, BuiltMemberKind) f) {
+    Member member = build(library);
+    if (isExtensionMethod) {
+      switch (kind) {
+        case ProcedureKind.Method:
+          f(member, BuiltMemberKind.ExtensionMethod);
+          break;
+        case ProcedureKind.Getter:
+          f(member, BuiltMemberKind.ExtensionGetter);
+          break;
+        case ProcedureKind.Setter:
+          f(member, BuiltMemberKind.ExtensionSetter);
+          break;
+        case ProcedureKind.Operator:
+          f(member, BuiltMemberKind.ExtensionOperator);
+          break;
+        case ProcedureKind.Factory:
+          throw new UnsupportedError(
+              'Unexpected extension method kind ${kind}');
+      }
+      if (extensionTearOff != null) {
+        f(extensionTearOff!, BuiltMemberKind.ExtensionTearOff);
+      }
+    } else {
+      f(member, BuiltMemberKind.Method);
+    }
+  }
+
+  @override
+  Procedure build(SourceLibraryBuilder libraryBuilder) {
+    buildFunction(libraryBuilder);
+    _procedure.function.fileOffset = charOpenParenOffset;
+    _procedure.function.fileEndOffset = _procedure.fileEndOffset;
+    _procedure.isAbstract = isAbstract;
+    _procedure.isExternal = isExternal;
+    _procedure.isConst = isConst;
+    updatePrivateMemberName(_procedure, libraryBuilder);
+    if (isExtensionMethod) {
+      _procedure.isExtensionMember = true;
+      _procedure.isStatic = true;
+      if (isExtensionInstanceMember) {
+        assert(_procedure.kind == ProcedureKind.Method);
+      }
+    } else {
+      _procedure.isStatic = isStatic;
+    }
+    if (extensionTearOff != null) {
+      _buildExtensionTearOff(libraryBuilder, parent as ExtensionBuilder);
+      updatePrivateMemberName(extensionTearOff!, libraryBuilder);
+    }
+    return _procedure;
+  }
+
+  /// Creates a top level function that creates a tear off of an extension
+  /// instance method.
+  ///
+  /// For this declaration
+  ///
+  ///     extension E<T> on A<T> {
+  ///       X method<S>(S s, Y y) {}
+  ///     }
+  ///
+  /// we create the top level function
+  ///
+  ///     X E|method<T, S>(A<T> #this, S s, Y y) {}
+  ///
+  /// and the tear off function
+  ///
+  ///     X Function<S>(S, Y) E|get#method<T>(A<T> #this) {
+  ///       return (S s, Y y) => E|method<T, S>(#this, s, y);
+  ///     }
+  ///
+  void _buildExtensionTearOff(
+      SourceLibraryBuilder libraryBuilder, ExtensionBuilder extensionBuilder) {
+    assert(
+        _extensionTearOff != null, "No extension tear off created for $this.");
+
+    _extensionTearOffParameterMap = {};
+
+    int fileOffset = _procedure.fileOffset;
+    int fileEndOffset = _procedure.fileEndOffset;
+
+    int extensionTypeParameterCount =
+        extensionBuilder.typeParameters?.length ?? 0;
+
+    List<TypeParameter> typeParameters = <TypeParameter>[];
+
+    Map<TypeParameter, DartType> substitutionMap = {};
+    List<DartType> typeArguments = <DartType>[];
+    for (TypeParameter typeParameter in function.typeParameters) {
+      TypeParameter newTypeParameter = new TypeParameter(typeParameter.name);
+      typeParameters.add(newTypeParameter);
+      typeArguments.add(substitutionMap[typeParameter] =
+          new TypeParameterType.forAlphaRenaming(
+              typeParameter, newTypeParameter));
+    }
+
+    List<TypeParameter> tearOffTypeParameters = <TypeParameter>[];
+    List<TypeParameter> closureTypeParameters = <TypeParameter>[];
+    Substitution substitution = Substitution.fromMap(substitutionMap);
+    for (int index = 0; index < typeParameters.length; index++) {
+      TypeParameter newTypeParameter = typeParameters[index];
+      newTypeParameter.bound =
+          substitution.substituteType(function.typeParameters[index].bound);
+      newTypeParameter.defaultType = function.typeParameters[index].defaultType;
+      if (index < extensionTypeParameterCount) {
+        tearOffTypeParameters.add(newTypeParameter);
+      } else {
+        closureTypeParameters.add(newTypeParameter);
+      }
+    }
+
+    VariableDeclaration copyParameter(
+        VariableDeclaration parameter, DartType type,
+        {required bool isOptional}) {
+      VariableDeclaration newParameter = new VariableDeclaration(parameter.name,
+          type: type,
+          isFinal: parameter.isFinal,
+          isLowered: parameter.isLowered)
+        ..fileOffset = parameter.fileOffset;
+      _extensionTearOffParameterMap![parameter] = newParameter;
+      return newParameter;
+    }
+
+    VariableDeclaration extensionThis = copyParameter(
+        function.positionalParameters.first,
+        substitution.substituteType(function.positionalParameters.first.type),
+        isOptional: false);
+
+    DartType closureReturnType =
+        substitution.substituteType(function.returnType);
+    List<VariableDeclaration> closurePositionalParameters = [];
+    List<Expression> closurePositionalArguments = [];
+
+    for (int position = 0;
+        position < function.positionalParameters.length;
+        position++) {
+      VariableDeclaration parameter = function.positionalParameters[position];
+      if (position == 0) {
+        /// Pass `this` as a captured variable.
+        closurePositionalArguments
+            .add(new VariableGet(extensionThis)..fileOffset = fileOffset);
+      } else {
+        DartType type = substitution.substituteType(parameter.type);
+        VariableDeclaration newParameter = copyParameter(parameter, type,
+            isOptional: position >= function.requiredParameterCount);
+        closurePositionalParameters.add(newParameter);
+        closurePositionalArguments
+            .add(new VariableGet(newParameter)..fileOffset = fileOffset);
+      }
+    }
+    List<VariableDeclaration> closureNamedParameters = [];
+    List<NamedExpression> closureNamedArguments = [];
+    for (VariableDeclaration parameter in function.namedParameters) {
+      DartType type = substitution.substituteType(parameter.type);
+      VariableDeclaration newParameter =
+          copyParameter(parameter, type, isOptional: true);
+      closureNamedParameters.add(newParameter);
+      closureNamedArguments.add(new NamedExpression(parameter.name!,
+          new VariableGet(newParameter)..fileOffset = fileOffset));
+    }
+
+    Statement closureBody = new ReturnStatement(
+        new StaticInvocation(
+            _procedure,
+            new Arguments(closurePositionalArguments,
+                types: typeArguments, named: closureNamedArguments))
+          ..fileOffset = fileOffset)
+      ..fileOffset = fileOffset;
+
+    FunctionExpression closure = new FunctionExpression(
+        new FunctionNode(closureBody,
+            typeParameters: closureTypeParameters,
+            positionalParameters: closurePositionalParameters,
+            namedParameters: closureNamedParameters,
+            requiredParameterCount:
+                _procedure.function.requiredParameterCount - 1,
+            returnType: closureReturnType)
+          ..fileOffset = fileOffset
+          ..fileEndOffset = fileEndOffset)
+      ..fileOffset = fileOffset;
+
+    _extensionTearOff!
+      ..function = (new FunctionNode(
+          new ReturnStatement(closure)..fileOffset = fileOffset,
+          typeParameters: tearOffTypeParameters,
+          positionalParameters: [extensionThis],
+          requiredParameterCount: 1,
+          returnType: closure.function.computeFunctionType(library.nonNullable))
+        ..fileOffset = fileOffset
+        ..fileEndOffset = fileEndOffset)
+      ..fileUri = fileUri
+      ..fileOffset = fileOffset
+      ..fileEndOffset = fileEndOffset;
+    _extensionTearOff!.function.parent = _extensionTearOff;
+  }
+
+  Procedure? get extensionTearOff => _extensionTearOff;
+
+  @override
+  VariableDeclaration? getTearOffParameter(int index) {
+    return _extensionTearOffParameterMap?[getFormalParameter(index)];
+  }
+
+  List<ClassMember>? _localMembers;
+  List<ClassMember>? _localSetters;
+
+  @override
+  List<ClassMember> get localMembers => _localMembers ??= isSetter
+      ? const <ClassMember>[]
+      : <ClassMember>[new SourceProcedureMember(this)];
+
+  @override
+  List<ClassMember> get localSetters =>
+      _localSetters ??= isSetter && !isConflictingSetter
+          ? <ClassMember>[new SourceProcedureMember(this)]
+          : const <ClassMember>[];
+
+  @override
+  void becomeNative(SourceLoader loader) {
+    _procedure.isExternal = true;
+    super.becomeNative(loader);
+  }
+
+  @override
+  void applyPatch(Builder patch) {
+    if (patch is SourceProcedureBuilder) {
+      if (checkPatch(patch)) {
+        patch.actualOrigin = this;
+        dataForTesting?.patchForTesting = patch;
+      }
+    } else {
+      reportPatchMismatch(patch);
+    }
+  }
+
+  @override
+  int finishPatch() {
+    if (!isPatch) return 0;
+
+    // TODO(ahe): restore file-offset once we track both origin and patch file
+    // URIs. See https://github.com/dart-lang/sdk/issues/31579
+    origin.procedure.fileUri = fileUri;
+    origin.procedure.startFileOffset = _procedure.startFileOffset;
+    origin.procedure.fileOffset = _procedure.fileOffset;
+    origin.procedure.fileEndOffset = _procedure.fileEndOffset;
+    origin.procedure.annotations
+        .forEach((m) => m.fileOffset = _procedure.fileOffset);
+
+    origin.procedure.isAbstract = _procedure.isAbstract;
+    origin.procedure.isExternal = _procedure.isExternal;
+    origin.procedure.function = _procedure.function;
+    origin.procedure.function.parent = origin.procedure;
+    origin.procedure.isRedirectingFactory = _procedure.isRedirectingFactory;
+    return 1;
+  }
+}
+
+class SourceProcedureMember extends BuilderClassMember {
+  @override
+  final SourceProcedureBuilder memberBuilder;
+
+  Covariance? _covariance;
+
+  SourceProcedureMember(this.memberBuilder);
+
+  @override
+  bool get isSourceDeclaration => true;
+
+  @override
+  void inferType(ClassMembersBuilder membersBuilder) {
+    memberBuilder._ensureTypes(membersBuilder);
+  }
+
+  @override
+  void registerOverrideDependency(Set<ClassMember> overriddenMembers) {
+    memberBuilder.registerOverrideDependency(overriddenMembers);
+  }
+
+  @override
+  Member getMember(ClassMembersBuilder membersBuilder) {
+    memberBuilder._ensureTypes(membersBuilder);
+    return memberBuilder.member;
+  }
+
+  @override
+  Covariance getCovariance(ClassMembersBuilder membersBuilder) {
+    return _covariance ??= new Covariance.fromMember(getMember(membersBuilder),
+        forSetter: forSetter);
+  }
+
+  @override
+  bool get forSetter => isSetter;
+
+  @override
+  bool get isProperty =>
+      memberBuilder.kind == ProcedureKind.Getter ||
+      memberBuilder.kind == ProcedureKind.Setter;
+
+  @override
+  bool isSameDeclaration(ClassMember other) {
+    return other is SourceProcedureMember &&
+        memberBuilder == other.memberBuilder;
+  }
+}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
index 407f747..639f6b7 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inference_engine.dart
@@ -3,32 +3,22 @@
 // BSD-style license that can be found in the LICENSE.md file.
 
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
-
 import 'package:kernel/ast.dart';
-
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
 import 'package:kernel/core_types.dart' show CoreTypes;
-
 import 'package:kernel/type_environment.dart';
 
 import '../../base/instrumentation.dart' show Instrumentation;
-
-import '../builder/constructor_builder.dart';
-
 import '../kernel/forest.dart';
-import '../kernel/implicit_field_type.dart';
-import '../kernel/internal_ast.dart';
 import '../kernel/hierarchy/hierarchy_builder.dart' show ClassHierarchyBuilder;
 import '../kernel/hierarchy/members_builder.dart' show ClassMembersBuilder;
+import '../kernel/implicit_field_type.dart';
+import '../kernel/internal_ast.dart';
 import '../kernel/kernel_helper.dart';
-
+import '../source/source_constructor_builder.dart';
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
 import 'factor_type.dart';
-
 import 'type_inferrer.dart';
-
 import 'type_schema_environment.dart' show TypeSchemaEnvironment;
 
 /// Visitor to check whether a given type mentions any of a class's type
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index 1107037..78618cb 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -3,19 +3,17 @@
 // BSD-style license that can be found in the LICENSE.md file.
 
 import 'package:_fe_analyzer_shared/src/flow_analysis/flow_analysis.dart';
-
 import 'package:_fe_analyzer_shared/src/testing/id.dart';
 import 'package:_fe_analyzer_shared/src/util/link.dart';
-
 import 'package:kernel/ast.dart';
 import 'package:kernel/canonical_name.dart' as kernel;
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
 import 'package:kernel/core_types.dart' show CoreTypes;
-import 'package:kernel/type_algebra.dart';
-import 'package:kernel/type_environment.dart';
 import 'package:kernel/src/bounds_checks.dart' show calculateBounds;
 import 'package:kernel/src/future_value_type.dart';
 import 'package:kernel/src/legacy_erasure.dart';
+import 'package:kernel/type_algebra.dart';
+import 'package:kernel/type_environment.dart';
 
 import '../../base/instrumentation.dart'
     show
@@ -23,32 +21,23 @@
         InstrumentationValueForMember,
         InstrumentationValueForType,
         InstrumentationValueForTypeArgs;
-
 import '../../base/nnbd_mode.dart';
-
 import '../../testing/id_extractor.dart';
 import '../../testing/id_testing_utils.dart';
-
-import '../builder/constructor_builder.dart';
 import '../builder/extension_builder.dart';
 import '../builder/member_builder.dart';
-
 import '../fasta_codes.dart';
-
-import '../kernel/hierarchy/class_member.dart' show ClassMember;
 import '../kernel/constructor_tearoff_lowering.dart';
-import '../kernel/kernel_helper.dart';
+import '../kernel/hierarchy/class_member.dart' show ClassMember;
 import '../kernel/inference_visitor.dart';
 import '../kernel/internal_ast.dart';
 import '../kernel/invalid_type.dart';
+import '../kernel/kernel_helper.dart';
 import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
-
 import '../names.dart';
-
 import '../problems.dart' show internalProblem, unexpected, unhandled;
-
+import '../source/source_constructor_builder.dart';
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
 import 'inference_helper.dart' show InferenceHelper;
 import 'type_constraint_gatherer.dart' show TypeConstraintGatherer;
 import 'type_demotion.dart';
diff --git a/pkg/front_end/test/extensions/extensions_test.dart b/pkg/front_end/test/extensions/extensions_test.dart
index 82e937b..83e5bbf 100644
--- a/pkg/front_end/test/extensions/extensions_test.dart
+++ b/pkg/front_end/test/extensions/extensions_test.dart
@@ -3,20 +3,20 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' show Directory, Platform;
+
+import 'package:_fe_analyzer_shared/src/testing/features.dart';
 import 'package:_fe_analyzer_shared/src/testing/id.dart';
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
 import 'package:front_end/src/api_prototype/experimental_flags.dart';
-
 import 'package:front_end/src/fasta/builder/class_builder.dart';
 import 'package:front_end/src/fasta/builder/extension_builder.dart';
 import 'package:front_end/src/fasta/builder/formal_parameter_builder.dart';
-import 'package:front_end/src/fasta/builder/function_builder.dart';
 import 'package:front_end/src/fasta/builder/library_builder.dart';
 import 'package:front_end/src/fasta/builder/member_builder.dart';
 import 'package:front_end/src/fasta/builder/type_builder.dart';
 import 'package:front_end/src/fasta/builder/type_variable_builder.dart';
+import 'package:front_end/src/fasta/source/source_function_builder.dart';
 import 'package:front_end/src/fasta/source/source_library_builder.dart';
-import 'package:_fe_analyzer_shared/src/testing/features.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
 import 'package:kernel/ast.dart';
diff --git a/pkg/front_end/test/id_tests/assigned_variables_test.dart b/pkg/front_end/test/id_tests/assigned_variables_test.dart
index 4b1516b..1741638 100644
--- a/pkg/front_end/test/id_tests/assigned_variables_test.dart
+++ b/pkg/front_end/test/id_tests/assigned_variables_test.dart
@@ -9,9 +9,8 @@
     show ActualData, Id, IdKind;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
     show DataInterpreter, runTests;
-import 'package:front_end/src/fasta/builder/member_builder.dart';
 import 'package:front_end/src/fasta/source/source_loader.dart';
-
+import 'package:front_end/src/fasta/source/source_member_builder.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
 import 'package:kernel/ast.dart' hide Variance;
diff --git a/pkg/front_end/test/id_tests/definite_assignment_test.dart b/pkg/front_end/test/id_tests/definite_assignment_test.dart
index f51a939..b4112f5 100644
--- a/pkg/front_end/test/id_tests/definite_assignment_test.dart
+++ b/pkg/front_end/test/id_tests/definite_assignment_test.dart
@@ -3,12 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' show Directory, Platform;
+
 import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
-import 'package:front_end/src/testing/id_testing_helper.dart';
-import 'package:front_end/src/fasta/builder/member_builder.dart';
 import 'package:front_end/src/fasta/source/source_loader.dart';
+import 'package:front_end/src/fasta/source/source_member_builder.dart';
 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
+import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
 import 'package:kernel/ast.dart' hide Variance;
 
diff --git a/pkg/front_end/test/id_tests/definite_unassignment_test.dart b/pkg/front_end/test/id_tests/definite_unassignment_test.dart
index 7aeba6f..d51a02e 100644
--- a/pkg/front_end/test/id_tests/definite_unassignment_test.dart
+++ b/pkg/front_end/test/id_tests/definite_unassignment_test.dart
@@ -3,12 +3,13 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' show Directory, Platform;
+
 import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
-import 'package:front_end/src/testing/id_testing_helper.dart';
-import 'package:front_end/src/fasta/builder/member_builder.dart';
 import 'package:front_end/src/fasta/source/source_loader.dart';
+import 'package:front_end/src/fasta/source/source_member_builder.dart';
 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
+import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
 import 'package:kernel/ast.dart' hide Variance;
 
diff --git a/pkg/front_end/test/id_tests/inferred_type_arguments_test.dart b/pkg/front_end/test/id_tests/inferred_type_arguments_test.dart
index 12ea3ed..ef7a1ca 100644
--- a/pkg/front_end/test/id_tests/inferred_type_arguments_test.dart
+++ b/pkg/front_end/test/id_tests/inferred_type_arguments_test.dart
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' show Directory, Platform;
+
 import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
     show DataInterpreter, runTests;
-import 'package:front_end/src/fasta/builder/member_builder.dart';
+import 'package:front_end/src/fasta/source/source_member_builder.dart';
 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
diff --git a/pkg/front_end/test/id_tests/inferred_variable_types_test.dart b/pkg/front_end/test/id_tests/inferred_variable_types_test.dart
index a7bc0cb..02c50fa 100644
--- a/pkg/front_end/test/id_tests/inferred_variable_types_test.dart
+++ b/pkg/front_end/test/id_tests/inferred_variable_types_test.dart
@@ -3,10 +3,11 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' show Directory, Platform;
+
 import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
     show DataInterpreter, runTests;
-import 'package:front_end/src/fasta/builder/member_builder.dart';
+import 'package:front_end/src/fasta/source/source_member_builder.dart';
 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
diff --git a/pkg/front_end/test/id_tests/reachability_test.dart b/pkg/front_end/test/id_tests/reachability_test.dart
index 8ea7394..a2e6a1a 100644
--- a/pkg/front_end/test/id_tests/reachability_test.dart
+++ b/pkg/front_end/test/id_tests/reachability_test.dart
@@ -3,13 +3,14 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'dart:io' show Directory, Platform;
+
 import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
     show DataInterpreter, runTests;
-import 'package:front_end/src/testing/id_testing_helper.dart';
-import 'package:front_end/src/fasta/builder/member_builder.dart';
 import 'package:front_end/src/fasta/source/source_loader.dart';
+import 'package:front_end/src/fasta/source/source_member_builder.dart';
 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
+import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
 import 'package:kernel/ast.dart' hide Variance;
 
diff --git a/pkg/front_end/test/id_tests/why_not_promoted_test.dart b/pkg/front_end/test/id_tests/why_not_promoted_test.dart
index 5899c55..4362bf9 100644
--- a/pkg/front_end/test/id_tests/why_not_promoted_test.dart
+++ b/pkg/front_end/test/id_tests/why_not_promoted_test.dart
@@ -7,7 +7,7 @@
 import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart'
     show DataInterpreter, runTests;
-import 'package:front_end/src/fasta/builder/member_builder.dart';
+import 'package:front_end/src/fasta/source/source_member_builder.dart';
 import 'package:front_end/src/fasta/type_inference/type_inference_engine.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
diff --git a/pkg/front_end/test/patching/patching_test.dart b/pkg/front_end/test/patching/patching_test.dart
index 2dc83ee..6f237db 100644
--- a/pkg/front_end/test/patching/patching_test.dart
+++ b/pkg/front_end/test/patching/patching_test.dart
@@ -4,6 +4,7 @@
 
 import 'dart:io' show Directory, Platform;
 
+import 'package:_fe_analyzer_shared/src/testing/features.dart';
 import 'package:_fe_analyzer_shared/src/testing/id.dart' show ActualData, Id;
 import 'package:_fe_analyzer_shared/src/testing/id_testing.dart';
 import 'package:front_end/src/api_prototype/compiler_options.dart';
@@ -11,8 +12,7 @@
 import 'package:front_end/src/fasta/builder/builder.dart';
 import 'package:front_end/src/fasta/builder/class_builder.dart';
 import 'package:front_end/src/fasta/builder/member_builder.dart';
-
-import 'package:_fe_analyzer_shared/src/testing/features.dart';
+import 'package:front_end/src/fasta/source/source_member_builder.dart';
 import 'package:front_end/src/testing/id_testing_helper.dart';
 import 'package:front_end/src/testing/id_testing_utils.dart';
 import 'package:kernel/ast.dart';
diff --git a/tools/VERSION b/tools/VERSION
index 0557489..393bdb2 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 16
 PATCH 0
-PRERELEASE 142
+PRERELEASE 143
 PRERELEASE_PATCH 0
\ No newline at end of file
