[cfe] Add GetterDeclaration and SetterDeclaration

In preparation for handling getter/setter patches through fragments

Change-Id: I25778f96df35856f84654949eb9dc8ce65a37bac
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/416560
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fragment/enum_element.dart b/pkg/front_end/lib/src/fragment/enum_element.dart
index 3e333e0..133baf3 100644
--- a/pkg/front_end/lib/src/fragment/enum_element.dart
+++ b/pkg/front_end/lib/src/fragment/enum_element.dart
@@ -133,7 +133,7 @@
       required bool createFileUriExpression}) {
     BodyBuilderContext bodyBuilderContext = createBodyBuilderContext();
     for (Annotatable annotatable in annotatables) {
-      _buildMetadataForOutlineExpressions(libraryBuilder, enclosingScope,
+      buildMetadataForOutlineExpressions(libraryBuilder, enclosingScope,
           bodyBuilderContext, annotatable, metadata,
           fileUri: fileUri, createFileUriExpression: createFileUriExpression);
     }
diff --git a/pkg/front_end/lib/src/fragment/field.dart b/pkg/front_end/lib/src/fragment/field.dart
index 20d8b34..eb8de1a 100644
--- a/pkg/front_end/lib/src/fragment/field.dart
+++ b/pkg/front_end/lib/src/fragment/field.dart
@@ -298,7 +298,7 @@
       required bool createFileUriExpression}) {
     BodyBuilderContext bodyBuilderContext = createBodyBuilderContext();
     for (Annotatable annotatable in annotatables) {
-      _buildMetadataForOutlineExpressions(libraryBuilder, enclosingScope,
+      buildMetadataForOutlineExpressions(libraryBuilder, enclosingScope,
           bodyBuilderContext, annotatable, metadata,
           fileUri: fileUri, createFileUriExpression: createFileUriExpression);
     }
diff --git a/pkg/front_end/lib/src/fragment/fragment.dart b/pkg/front_end/lib/src/fragment/fragment.dart
index d2d4e30..95eff56 100644
--- a/pkg/front_end/lib/src/fragment/fragment.dart
+++ b/pkg/front_end/lib/src/fragment/fragment.dart
@@ -62,6 +62,10 @@
 import '../type_inference/type_inferrer.dart';
 import '../type_inference/type_schema.dart';
 import 'constructor/declaration.dart';
+import 'getter/declaration.dart';
+import 'getter/encoding.dart';
+import 'setter/declaration.dart';
+import 'setter/encoding.dart';
 
 part 'class.dart';
 part 'class/declaration.dart';
diff --git a/pkg/front_end/lib/src/fragment/getter.dart b/pkg/front_end/lib/src/fragment/getter.dart
index e3f0079..ea4731f 100644
--- a/pkg/front_end/lib/src/fragment/getter.dart
+++ b/pkg/front_end/lib/src/fragment/getter.dart
@@ -61,7 +61,7 @@
 
   SourcePropertyBuilder? _builder;
 
-  late final _GetterEncoding _encoding;
+  GetterDeclaration? _declaration;
 
   GetterFragment({
     required this.name,
@@ -91,19 +91,20 @@
     return _builder!;
   }
 
-  void setBuilder(
-      ProblemReporting problemReporting,
-      SourcePropertyBuilder value,
-      PropertyEncodingStrategy encodingStrategy,
-      List<NominalParameterBuilder> unboundNominalParameters) {
+  void set builder(SourcePropertyBuilder value) {
     assert(_builder == null, "Builder has already been computed for $this.");
     _builder = value;
-    _encoding = encodingStrategy.createGetterEncoding(
-        value, this, unboundNominalParameters);
-    typeParameterNameSpace.addTypeParameters(
-        problemReporting, _encoding.clonedAndDeclaredTypeParameters,
-        ownerName: name, allowNameConflict: true);
-    returnType.registerInferredTypeListener(_encoding);
+  }
+
+  GetterDeclaration get declaration {
+    assert(_declaration != null, "Builder has not been computed for $this.");
+    return _declaration!;
+  }
+
+  void set declaration(GetterDeclaration value) {
+    assert(_declaration == null,
+        "Declaration has already been computed for $this.");
+    _declaration = value;
   }
 
   @override
@@ -111,82 +112,6 @@
     return new _GetterBodyBuildingContext(this);
   }
 
-  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
-      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
-      {required List<TypeParameter>? classTypeParameters}) {
-    _encoding.buildOutlineNode(libraryBuilder, nameScheme, f, references,
-        isAbstractOrExternal: modifiers.isAbstract || modifiers.isExternal,
-        classTypeParameters: classTypeParameters);
-  }
-
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      Annotatable annotatable,
-      {required bool isClassInstanceMember,
-      required bool createFileUriExpression}) {
-    _encoding.buildOutlineExpressions(classHierarchy, libraryBuilder,
-        declarationBuilder, createBodyBuilderContext(), annotatable,
-        isClassInstanceMember: isClassInstanceMember,
-        createFileUriExpression: createFileUriExpression);
-  }
-
-  Iterable<Reference> getExportedMemberReferences(GetterReference references) =>
-      [references.getterReference];
-
-  BodyBuilderContext createBodyBuilderContext() {
-    return new _GetterFragmentBodyBuilderContext(
-        this, builder.libraryBuilder, builder.declarationBuilder,
-        isDeclarationInstanceMember: builder.isDeclarationInstanceMember);
-  }
-
-  void becomeNative(SourceLoader loader) {
-    _encoding.becomeNative(loader);
-  }
-
-  int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    return _encoding.computeDefaultTypes(context);
-  }
-
-  void ensureTypes(ClassMembersBuilder membersBuilder,
-      Set<ClassMember>? getterOverrideDependencies) {
-    if (getterOverrideDependencies != null) {
-      membersBuilder.inferGetterType(
-          builder.declarationBuilder as SourceClassBuilder,
-          returnType,
-          getterOverrideDependencies,
-          name: name,
-          fileUri: fileUri,
-          nameOffset: nameOffset,
-          nameLength: name.length);
-    }
-    _encoding.ensureTypes(
-        builder.libraryBuilder, membersBuilder.hierarchyBuilder);
-  }
-
-  void checkTypes(SourceLibraryBuilder libraryBuilder,
-      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
-      {required bool isAbstract, required bool isExternal}) {
-    _encoding.checkTypes(libraryBuilder, typeEnvironment, setterBuilder,
-        isAbstract: isAbstract, isExternal: isExternal);
-  }
-
-  void checkVariance(
-      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
-    _encoding.checkVariance(sourceClassBuilder, typeEnvironment);
-  }
-
-  Procedure get readTarget => _encoding.readTarget;
-
-  // Coverage-ignore(suite): Not run.
-  List<NominalParameterBuilder>? get typeParametersForTesting =>
-      _encoding.clonedAndDeclaredTypeParameters;
-
-  // Coverage-ignore(suite): Not run.
-  List<FormalParameterBuilder>? get formalsForTesting =>
-      _encoding.formalsForTesting;
-
   @override
   String toString() => '$runtimeType($name,$fileUri,$nameOffset)';
 }
@@ -208,7 +133,7 @@
 
   @override
   LocalScope computeFormalParameterScope(LookupScope typeParameterScope) {
-    return _fragment._encoding.createFormalParameterScope(typeParameterScope);
+    return _fragment.declaration.createFormalParameterScope(typeParameterScope);
   }
 
   @override
@@ -218,7 +143,7 @@
 
   @override
   BodyBuilderContext createBodyBuilderContext() {
-    return _fragment.createBodyBuilderContext();
+    return _fragment.declaration.createBodyBuilderContext(_fragment.builder);
   }
 
   @override
@@ -230,716 +155,8 @@
 
   @override
   List<TypeParameter>? get thisTypeParameters =>
-      _fragment._encoding.thisTypeParameters;
+      _fragment.declaration.thisTypeParameters;
 
   @override
-  VariableDeclaration? get thisVariable => _fragment._encoding.thisVariable;
-}
-
-sealed class _GetterEncoding implements InferredTypeListener {
-  VariableDeclaration? get thisVariable;
-  List<TypeParameter>? get thisTypeParameters;
-  FunctionNode get function;
-  Procedure get readTarget;
-
-  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
-      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
-      {required bool isAbstractOrExternal,
-      required List<TypeParameter>? classTypeParameters});
-
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      BodyBuilderContext bodyBuilderContext,
-      Annotatable annotatable,
-      {required bool isClassInstanceMember,
-      required bool createFileUriExpression});
-
-  LocalScope createFormalParameterScope(LookupScope typeParameterScope);
-
-  int computeDefaultTypes(ComputeDefaultTypeContext context);
-
-  void ensureTypes(
-      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy);
-
-  void becomeNative(SourceLoader loader);
-
-  List<FormalParameterBuilder>? get formals;
-
-  VariableDeclaration getFormalParameter(int index);
-
-  void checkTypes(SourceLibraryBuilder libraryBuilder,
-      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
-      {required bool isAbstract, required bool isExternal});
-
-  void checkVariance(
-      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment);
-
-  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters;
-
-  List<FormalParameterBuilder>? get formalsForTesting;
-}
-
-mixin _DirectGetterEncodingMixin implements _GetterEncoding {
-  GetterFragment get _fragment;
-
-  Procedure? _procedure;
-
-  @override
-  VariableDeclaration? get thisVariable => null;
-
-  @override
-  List<TypeParameter>? get thisTypeParameters => null;
-
-  BuiltMemberKind get _builtMemberKind;
-
-  bool get _isExtensionMember;
-
-  bool get _isExtensionTypeMember;
-
-  @override
-  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
-      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
-      {required bool isAbstractOrExternal,
-      List<TypeParameter>? classTypeParameters}) {
-    FunctionNode function = new FunctionNode(
-        isAbstractOrExternal ? null : new EmptyStatement(),
-        asyncMarker: _fragment.asyncModifier)
-      ..fileOffset = _fragment.formalsOffset
-      ..fileEndOffset = _fragment.endOffset;
-    buildTypeParametersAndFormals(
-        libraryBuilder,
-        function,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders,
-        _fragment.declaredFormals,
-        classTypeParameters: classTypeParameters,
-        supportsTypeParameters: true);
-    if (_fragment.returnType is! InferableTypeBuilder) {
-      function.returnType =
-          _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
-    }
-
-    MemberName memberName =
-        nameScheme.getProcedureMemberName(ProcedureKind.Getter, _fragment.name);
-    Procedure procedure = _procedure = new Procedure(
-        memberName.name, ProcedureKind.Getter, function,
-        reference: references.getterReference, fileUri: _fragment.fileUri)
-      ..fileStartOffset = _fragment.startOffset
-      ..fileOffset = _fragment.nameOffset
-      ..fileEndOffset = _fragment.endOffset
-      ..isAbstract = _fragment.modifiers.isAbstract
-      ..isExternal = _fragment.modifiers.isExternal
-      ..isConst = _fragment.modifiers.isConst
-      ..isStatic = _fragment.modifiers.isStatic
-      ..isExtensionMember = _isExtensionMember
-      ..isExtensionTypeMember = _isExtensionTypeMember;
-    memberName.attachMember(procedure);
-
-    f(kind: _builtMemberKind, member: procedure);
-  }
-
-  @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      BodyBuilderContext bodyBuilderContext,
-      Annotatable annotatable,
-      {required bool isClassInstanceMember,
-      required bool createFileUriExpression}) {
-    _buildMetadataForOutlineExpressions(
-        libraryBuilder,
-        _fragment.enclosingScope,
-        bodyBuilderContext,
-        annotatable,
-        _fragment.metadata,
-        fileUri: _fragment.fileUri,
-        createFileUriExpression: createFileUriExpression);
-    _buildTypeParametersForOutlineExpressions(
-        classHierarchy,
-        libraryBuilder,
-        bodyBuilderContext,
-        _fragment.typeParameterScope,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders);
-    _buildFormalsForOutlineExpressions(
-        libraryBuilder, declarationBuilder, _fragment.declaredFormals,
-        scope: _fragment.typeParameterScope,
-        isClassInstanceMember: isClassInstanceMember);
-  }
-
-  @override
-  FunctionNode get function => _procedure!.function;
-
-  @override
-  Procedure get readTarget => _procedure!;
-
-  @override
-  LocalScope createFormalParameterScope(LookupScope typeParameterScope) {
-    return new FormalParameterScope(parent: typeParameterScope);
-  }
-
-  @override
-  int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
-        .declaredTypeParameters
-        // Coverage-ignore(suite): Not run.
-        ?.builders);
-    context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
-    if (_fragment.returnType is! OmittedTypeBuilder) {
-      hasErrors |=
-          context.reportInboundReferenceIssuesForType(_fragment.returnType);
-      context.recursivelyReportGenericFunctionTypesAsBoundsForType(
-          _fragment.returnType);
-    }
-    return context.computeDefaultTypesForVariables(
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders,
-        inErrorRecovery: hasErrors);
-  }
-
-  @override
-  void ensureTypes(
-      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy) {
-    _fragment.returnType
-        .build(libraryBuilder, TypeUse.returnType, hierarchy: hierarchy);
-  }
-
-  @override
-  void onInferredType(DartType type) {
-    function.returnType = type;
-  }
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    loader.addNativeAnnotation(_procedure!, _fragment.nativeMethodName!);
-  }
-
-  @override
-  List<FormalParameterBuilder>? get formals => _fragment.declaredFormals;
-
-  @override
-  VariableDeclaration getFormalParameter(int index) =>
-      _fragment.declaredFormals![index].variable!;
-
-  @override
-  void checkTypes(SourceLibraryBuilder libraryBuilder,
-      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
-      {required bool isAbstract, required bool isExternal}) {
-    List<TypeParameterBuilder>? typeParameters = _fragment
-        .declaredTypeParameters
-        // Coverage-ignore(suite): Not run.
-        ?.builders;
-    // Coverage-ignore(suite): Not run.
-    if (typeParameters != null && typeParameters.isNotEmpty) {
-      libraryBuilder.checkTypeParameterDependencies(typeParameters);
-    }
-    libraryBuilder.checkInitializersInFormals(
-        _fragment.declaredFormals, typeEnvironment,
-        isAbstract: isAbstract, isExternal: isExternal);
-    if (setterBuilder != null) {
-      DartType getterType = function.returnType;
-      DartType setterType = SourcePropertyBuilder.getSetterType(setterBuilder,
-          getterExtensionTypeParameters: null);
-      libraryBuilder.checkGetterSetterTypes(typeEnvironment,
-          getterType: getterType,
-          getterName: _fragment.name,
-          getterFileOffset: _fragment.nameOffset,
-          getterFileUri: _fragment.fileUri,
-          getterNameLength: _fragment.name.length,
-          setterType: setterType,
-          setterName: setterBuilder.name,
-          setterFileOffset: setterBuilder.fileOffset,
-          setterFileUri: setterBuilder.fileUri,
-          setterNameLength: setterBuilder.name.length);
-    }
-  }
-
-  @override
-  void checkVariance(
-      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
-    sourceClassBuilder.checkVarianceInTypeParameters(
-        typeEnvironment,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders);
-    sourceClassBuilder.checkVarianceInFormals(
-        typeEnvironment, _fragment.declaredFormals);
-    sourceClassBuilder.checkVarianceInReturnType(
-        typeEnvironment, function.returnType,
-        fileOffset: _fragment.nameOffset, fileUri: _fragment.fileUri);
-  }
-
-  @override
-  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
-      _fragment
-          .declaredTypeParameters
-          // Coverage-ignore(suite): Not run.
-          ?.builders;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  List<FormalParameterBuilder>? get formalsForTesting =>
-      _fragment.declaredFormals;
-}
-
-class _RegularGetterEncoding extends _GetterEncoding
-    with _DirectGetterEncodingMixin {
-  @override
-  final GetterFragment _fragment;
-
-  _RegularGetterEncoding(this._fragment);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.Method;
-
-  @override
-  bool get _isExtensionMember => false;
-
-  @override
-  bool get _isExtensionTypeMember => false;
-}
-
-class _ExtensionStaticGetterEncoding extends _GetterEncoding
-    with _DirectGetterEncodingMixin {
-  @override
-  final GetterFragment _fragment;
-
-  _ExtensionStaticGetterEncoding(this._fragment);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionGetter;
-
-  @override
-  bool get _isExtensionMember => true;
-
-  @override
-  bool get _isExtensionTypeMember => false;
-}
-
-class _ExtensionTypeStaticGetterEncoding extends _GetterEncoding
-    with _DirectGetterEncodingMixin {
-  @override
-  final GetterFragment _fragment;
-
-  _ExtensionTypeStaticGetterEncoding(this._fragment);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionTypeGetter;
-
-  @override
-  bool get _isExtensionMember => false;
-
-  @override
-  bool get _isExtensionTypeMember => true;
-}
-
-mixin _ExtensionInstanceGetterEncodingMixin implements _GetterEncoding {
-  GetterFragment get _fragment;
-
-  List<NominalParameterBuilder>? get _clonedDeclarationTypeParameters;
-
-  FormalParameterBuilder get _thisFormal;
-
-  Procedure? _procedure;
-
-  @override
-  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
-      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
-      {required bool isAbstractOrExternal,
-      required List<TypeParameter>? classTypeParameters}) {
-    List<TypeParameter>? typeParameters;
-    if (_clonedDeclarationTypeParameters != null) {
-      typeParameters = [];
-      // TODO(johnniwinther): Ambivalent analyzer. `!` seems to be both required
-      // and unnecessary.
-      // ignore: unnecessary_non_null_assertion
-      for (NominalParameterBuilder t in _clonedDeclarationTypeParameters!) {
-        typeParameters.add(t.parameter);
-      }
-    }
-    FunctionNode function = new FunctionNode(
-        isAbstractOrExternal ? null : new EmptyStatement(),
-        typeParameters: typeParameters,
-        positionalParameters: [_thisFormal.build(libraryBuilder)],
-        asyncMarker: _fragment.asyncModifier)
-      ..fileOffset = _fragment.formalsOffset
-      ..fileEndOffset = _fragment.endOffset;
-    buildTypeParametersAndFormals(
-        libraryBuilder,
-        function,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders,
-        _fragment.declaredFormals,
-        classTypeParameters: classTypeParameters,
-        supportsTypeParameters: true);
-    if (_fragment.returnType is! InferableTypeBuilder) {
-      function.returnType =
-          _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
-    }
-
-    MemberName memberName =
-        nameScheme.getProcedureMemberName(ProcedureKind.Getter, _fragment.name);
-    Procedure procedure = _procedure = new Procedure(
-        memberName.name, ProcedureKind.Method, function,
-        reference: references.getterReference, fileUri: _fragment.fileUri)
-      ..fileStartOffset = _fragment.startOffset
-      ..fileOffset = _fragment.nameOffset
-      ..fileEndOffset = _fragment.endOffset
-      ..isAbstract = _fragment.modifiers.isAbstract
-      ..isExternal = _fragment.modifiers.isExternal
-      ..isConst = _fragment.modifiers.isConst
-      ..isStatic = true
-      ..isExtensionMember = _isExtensionMember
-      ..isExtensionTypeMember = _isExtensionTypeMember;
-    memberName.attachMember(procedure);
-
-    f(kind: _builtMemberKind, member: procedure);
-  }
-
-  @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      BodyBuilderContext bodyBuilderContext,
-      Annotatable annotatable,
-      {required bool isClassInstanceMember,
-      required bool createFileUriExpression}) {
-    _buildMetadataForOutlineExpressions(
-        libraryBuilder,
-        _fragment.enclosingScope,
-        bodyBuilderContext,
-        annotatable,
-        _fragment.metadata,
-        fileUri: _fragment.fileUri,
-        createFileUriExpression: createFileUriExpression);
-
-    _buildTypeParametersForOutlineExpressions(
-        classHierarchy,
-        libraryBuilder,
-        bodyBuilderContext,
-        _fragment.typeParameterScope,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders);
-    _buildFormalsForOutlineExpressions(
-        libraryBuilder, declarationBuilder, _fragment.declaredFormals,
-        scope: _fragment.typeParameterScope,
-        isClassInstanceMember: isClassInstanceMember);
-
-    _buildTypeParametersForOutlineExpressions(
-        classHierarchy,
-        libraryBuilder,
-        bodyBuilderContext,
-        _fragment.typeParameterScope,
-        _clonedDeclarationTypeParameters);
-    _buildFormalForOutlineExpressions(
-        libraryBuilder, declarationBuilder, _thisFormal,
-        scope: _fragment.typeParameterScope,
-        isClassInstanceMember: isClassInstanceMember);
-  }
-
-  @override
-  FunctionNode get function => _procedure!.function;
-
-  @override
-  Procedure get readTarget => _procedure!;
-
-  @override
-  List<TypeParameter>? get thisTypeParameters =>
-      _clonedDeclarationTypeParameters != null ? function.typeParameters : null;
-
-  @override
-  VariableDeclaration? get thisVariable => _thisFormal.variable!;
-
-  @override
-  LocalScope createFormalParameterScope(LookupScope typeParameterScope) {
-    Map<String, Builder> local = <String, Builder>{};
-    assert(!_thisFormal.isWildcard);
-    local[_thisFormal.name] = _thisFormal;
-    return new FormalParameterScope(local: local, parent: typeParameterScope);
-  }
-
-  @override
-  int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
-        .declaredTypeParameters
-        // Coverage-ignore(suite): Not run.
-        ?.builders);
-    context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
-    if (_fragment.returnType is! OmittedTypeBuilder) {
-      hasErrors |=
-          context.reportInboundReferenceIssuesForType(_fragment.returnType);
-      context.recursivelyReportGenericFunctionTypesAsBoundsForType(
-          _fragment.returnType);
-    }
-    if (_clonedDeclarationTypeParameters != null &&
-        _fragment.declaredTypeParameters != null) {
-      // Coverage-ignore-block(suite): Not run.
-      // We need to compute all default types together since they might be
-      // interdependent.
-      return context.computeDefaultTypesForVariables([
-        // TODO(johnniwinther): Ambivalent analyzer. `!` seems to be both
-        //  required and unnecessary.
-        // ignore: unnecessary_non_null_assertion
-        ..._clonedDeclarationTypeParameters!,
-        ..._fragment.declaredTypeParameters!.builders
-      ], inErrorRecovery: hasErrors);
-    } else if (_clonedDeclarationTypeParameters != null) {
-      return context.computeDefaultTypesForVariables(
-          _clonedDeclarationTypeParameters,
-          inErrorRecovery: hasErrors);
-    } else {
-      return context.computeDefaultTypesForVariables(
-          _fragment
-              .declaredTypeParameters
-              // Coverage-ignore(suite): Not run.
-              ?.builders,
-          inErrorRecovery: hasErrors);
-    }
-  }
-
-  BuiltMemberKind get _builtMemberKind;
-
-  bool get _isExtensionMember;
-
-  bool get _isExtensionTypeMember;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void ensureTypes(
-      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy) {
-    _fragment.returnType
-        .build(libraryBuilder, TypeUse.fieldType, hierarchy: hierarchy);
-    _thisFormal.type
-        .build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
-  }
-
-  @override
-  void onInferredType(DartType type) {
-    function.returnType = type;
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void becomeNative(SourceLoader loader) {
-    loader.addNativeAnnotation(_procedure!, _fragment.nativeMethodName!);
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  List<FormalParameterBuilder>? get formals =>
-      [_thisFormal, ...?_fragment.declaredFormals];
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  VariableDeclaration getFormalParameter(int index) =>
-      _fragment.declaredFormals![index].variable!;
-
-  @override
-  void checkTypes(SourceLibraryBuilder libraryBuilder,
-      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
-      {required bool isAbstract, required bool isExternal}) {
-    List<TypeParameterBuilder>? typeParameters = _fragment
-        .declaredTypeParameters
-        // Coverage-ignore(suite): Not run.
-        ?.builders;
-    // Coverage-ignore(suite): Not run.
-    if (typeParameters != null && typeParameters.isNotEmpty) {
-      libraryBuilder.checkTypeParameterDependencies(typeParameters);
-    }
-    libraryBuilder.checkInitializersInFormals(
-        _fragment.declaredFormals, typeEnvironment,
-        isAbstract: isAbstract, isExternal: isExternal);
-    if (setterBuilder != null) {
-      DartType getterType = function.returnType;
-      DartType setterType = SourcePropertyBuilder.getSetterType(setterBuilder,
-          getterExtensionTypeParameters: function.typeParameters);
-      libraryBuilder.checkGetterSetterTypes(typeEnvironment,
-          getterType: getterType,
-          getterName: _fragment.name,
-          getterFileOffset: _fragment.nameOffset,
-          getterFileUri: _fragment.fileUri,
-          getterNameLength: _fragment.name.length,
-          setterType: setterType,
-          setterName: setterBuilder.name,
-          setterFileOffset: setterBuilder.fileOffset,
-          setterFileUri: setterBuilder.fileUri,
-          setterNameLength: setterBuilder.name.length);
-    }
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void checkVariance(
-      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
-    sourceClassBuilder.checkVarianceInTypeParameters(
-        typeEnvironment, _fragment.declaredTypeParameters?.builders);
-    sourceClassBuilder.checkVarianceInFormals(
-        typeEnvironment, _fragment.declaredFormals);
-    sourceClassBuilder.checkVarianceInReturnType(
-        typeEnvironment, function.returnType,
-        fileOffset: _fragment.nameOffset, fileUri: _fragment.fileUri);
-  }
-
-  @override
-  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
-      _clonedDeclarationTypeParameters != null ||
-              _fragment.declaredTypeParameters != null
-          ? [
-              ...?_clonedDeclarationTypeParameters,
-              ...?_fragment
-                  .declaredTypeParameters
-                  // Coverage-ignore(suite): Not run.
-                  ?.builders
-            ]
-          : null;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  List<FormalParameterBuilder>? get formalsForTesting =>
-      [_thisFormal, ...?_fragment.declaredFormals];
-}
-
-class _ExtensionInstanceGetterEncoding extends _GetterEncoding
-    with _ExtensionInstanceGetterEncodingMixin {
-  @override
-  final GetterFragment _fragment;
-
-  @override
-  final List<NominalParameterBuilder>? _clonedDeclarationTypeParameters;
-
-  @override
-  final FormalParameterBuilder _thisFormal;
-
-  _ExtensionInstanceGetterEncoding(
-      this._fragment, this._clonedDeclarationTypeParameters, this._thisFormal);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionGetter;
-
-  @override
-  bool get _isExtensionMember => true;
-
-  @override
-  bool get _isExtensionTypeMember => false;
-}
-
-class _ExtensionTypeInstanceGetterEncoding extends _GetterEncoding
-    with _ExtensionInstanceGetterEncodingMixin {
-  @override
-  final GetterFragment _fragment;
-
-  @override
-  final List<NominalParameterBuilder>? _clonedDeclarationTypeParameters;
-
-  @override
-  final FormalParameterBuilder _thisFormal;
-
-  _ExtensionTypeInstanceGetterEncoding(
-      this._fragment, this._clonedDeclarationTypeParameters, this._thisFormal);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionTypeGetter;
-
-  @override
-  bool get _isExtensionMember => false;
-
-  @override
-  bool get _isExtensionTypeMember => true;
-}
-
-class _GetterFragmentBodyBuilderContext extends BodyBuilderContext {
-  final GetterFragment _fragment;
-
-  _GetterFragmentBodyBuilderContext(
-      this._fragment,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      {required bool isDeclarationInstanceMember})
-      : super(libraryBuilder, declarationBuilder,
-            isDeclarationInstanceMember: isDeclarationInstanceMember);
-
-  @override
-  LocalScope computeFormalParameterInitializerScope(LocalScope parent) {
-    /// Initializer formals or super parameters cannot occur in getters so
-    /// we don't need to create a new scope.
-    return parent;
-  }
-
-  @override
-  FunctionNode get function => _fragment._encoding.function;
-
-  @override
-  bool get isExternalFunction => _fragment.modifiers.isExternal;
-
-  @override
-  void setAsyncModifier(AsyncMarker asyncModifier) {
-    assert(
-        asyncModifier == _fragment.asyncModifier,
-        "Unexpected change in async modifier on $_fragment from "
-        "${_fragment.asyncModifier} to $asyncModifier.");
-  }
-
-  @override
-  int get memberNameOffset => _fragment.nameOffset;
-
-  @override
-  int get memberNameLength => _fragment.name.length;
-
-  @override
-  DartType get returnTypeContext {
-    final bool isReturnTypeUndeclared =
-        _fragment.returnType is OmittedTypeBuilder &&
-            function.returnType is DynamicType;
-    return isReturnTypeUndeclared ? const UnknownType() : function.returnType;
-  }
-
-  @override
-  TypeBuilder get returnType => _fragment.returnType;
-
-  @override
-  void registerFunctionBody(Statement body) {
-    function.body = body..parent = function;
-  }
-
-  @override
-  void registerSuperCall() {
-    // TODO(johnniwinther): This should be set on the member built from this
-    // fragment and copied to the origin if necessary.
-    _fragment.builder.readTarget!.transformerFlags |=
-        TransformerFlag.superCalls;
-  }
-
-  @override
-  List<FormalParameterBuilder>? get formals => _fragment._encoding.formals;
-
-  @override
-  VariableDeclaration getFormalParameter(int index) =>
-      _fragment._encoding.getFormalParameter(index);
-
-  @override
-  VariableDeclaration? getTearOffParameter(int index) => null;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  AugmentSuperTarget? get augmentSuperTarget {
-    if (_fragment.builder.isAugmentation) {
-      return _fragment.builder.augmentSuperTarget;
-    }
-    return null;
-  }
+  VariableDeclaration? get thisVariable => _fragment.declaration.thisVariable;
 }
diff --git a/pkg/front_end/lib/src/fragment/getter/body_builder_context.dart b/pkg/front_end/lib/src/fragment/getter/body_builder_context.dart
new file mode 100644
index 0000000..a1ed65f
--- /dev/null
+++ b/pkg/front_end/lib/src/fragment/getter/body_builder_context.dart
@@ -0,0 +1,100 @@
+// Copyright (c) 2025, 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/transformations/flags.dart';
+
+import '../../base/local_scope.dart';
+import '../../builder/declaration_builders.dart';
+import '../../builder/formal_parameter_builder.dart';
+import '../../builder/type_builder.dart';
+import '../../kernel/body_builder_context.dart';
+import '../../source/source_library_builder.dart';
+import '../../source/source_member_builder.dart';
+import '../../source/source_property_builder.dart';
+import '../../type_inference/type_schema.dart';
+import 'declaration.dart';
+
+class GetterFragmentBodyBuilderContext extends BodyBuilderContext {
+  final SourcePropertyBuilder _builder;
+  final GetterDeclaration _declaration;
+
+  GetterFragmentBodyBuilderContext(
+      this._builder,
+      this._declaration,
+      SourceLibraryBuilder libraryBuilder,
+      DeclarationBuilder? declarationBuilder,
+      {required bool isDeclarationInstanceMember})
+      : super(libraryBuilder, declarationBuilder,
+            isDeclarationInstanceMember: isDeclarationInstanceMember);
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  AugmentSuperTarget? get augmentSuperTarget {
+    if (_builder.isAugmentation) {
+      return _builder.augmentSuperTarget;
+    }
+    return null;
+  }
+
+  @override
+  List<FormalParameterBuilder>? get formals => _declaration.formals;
+
+  @override
+  FunctionNode get function => _declaration.function;
+
+  @override
+  bool get isExternalFunction => _declaration.isExternal;
+
+  @override
+  int get memberNameLength => _declaration.name.length;
+
+  @override
+  int get memberNameOffset => _declaration.nameOffset;
+
+  @override
+  TypeBuilder get returnType => _declaration.returnType;
+
+  @override
+  DartType get returnTypeContext {
+    final bool isReturnTypeUndeclared =
+        _declaration.returnType is OmittedTypeBuilder &&
+            function.returnType is DynamicType;
+    return isReturnTypeUndeclared ? const UnknownType() : function.returnType;
+  }
+
+  @override
+  LocalScope computeFormalParameterInitializerScope(LocalScope parent) {
+    /// Initializer formals or super parameters cannot occur in getters so
+    /// we don't need to create a new scope.
+    return parent;
+  }
+
+  @override
+  VariableDeclaration getFormalParameter(int index) =>
+      _declaration.getFormalParameter(index);
+
+  @override
+  VariableDeclaration? getTearOffParameter(int index) => null;
+
+  @override
+  void registerFunctionBody(Statement body) {
+    function.body = body..parent = function;
+  }
+
+  @override
+  void registerSuperCall() {
+    // TODO(johnniwinther): This should be set on the member built from this
+    // fragment and copied to the origin if necessary.
+    _builder.readTarget!.transformerFlags |= TransformerFlag.superCalls;
+  }
+
+  @override
+  void setAsyncModifier(AsyncMarker asyncModifier) {
+    assert(
+        asyncModifier == _declaration.asyncModifier,
+        "Unexpected change in async modifier on $_declaration from "
+        "${_declaration.asyncModifier} to $asyncModifier.");
+  }
+}
diff --git a/pkg/front_end/lib/src/fragment/getter/declaration.dart b/pkg/front_end/lib/src/fragment/getter/declaration.dart
new file mode 100644
index 0000000..e83c107
--- /dev/null
+++ b/pkg/front_end/lib/src/fragment/getter/declaration.dart
@@ -0,0 +1,264 @@
+// Copyright (c) 2025, 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/class_hierarchy.dart';
+import 'package:kernel/type_environment.dart';
+
+import '../../base/local_scope.dart';
+import '../../base/messages.dart';
+import '../../base/scope.dart';
+import '../../builder/declaration_builders.dart';
+import '../../builder/formal_parameter_builder.dart';
+import '../../builder/metadata_builder.dart';
+import '../../builder/type_builder.dart';
+import '../../kernel/body_builder_context.dart';
+import '../../kernel/hierarchy/class_member.dart';
+import '../../kernel/hierarchy/members_builder.dart';
+import '../../kernel/type_algorithms.dart';
+import '../../source/name_scheme.dart';
+import '../../source/source_class_builder.dart';
+import '../../source/source_library_builder.dart';
+import '../../source/source_loader.dart';
+import '../../source/source_member_builder.dart';
+import '../../source/source_property_builder.dart';
+import '../fragment.dart';
+import 'body_builder_context.dart';
+import 'encoding.dart';
+
+abstract class GetterDeclaration {
+  AsyncMarker get asyncModifier;
+
+  Uri get fileUri;
+
+  List<FormalParameterBuilder>? get formals;
+
+  FunctionNode get function;
+
+  bool get isAbstract;
+
+  bool get isExternal;
+
+  List<MetadataBuilder>? get metadata;
+
+  String get name;
+
+  int get nameOffset;
+
+  Procedure get readTarget;
+
+  TypeBuilder get returnType;
+
+  List<TypeParameter>? get thisTypeParameters;
+
+  VariableDeclaration? get thisVariable;
+
+  List<NominalParameterBuilder>? get typeParametersForTesting;
+
+  void becomeNative(SourceLoader loader);
+
+  void buildOutlineExpressions(
+      {required ClassHierarchy classHierarchy,
+      required SourceLibraryBuilder libraryBuilder,
+      required DeclarationBuilder? declarationBuilder,
+      required SourcePropertyBuilder propertyBuilder,
+      required Annotatable annotatable,
+      required bool isClassInstanceMember,
+      required bool createFileUriExpression});
+
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
+      {required List<TypeParameter>? classTypeParameters});
+
+  void checkTypes(SourceLibraryBuilder libraryBuilder,
+      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
+      {required bool isAbstract, required bool isExternal});
+
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment);
+
+  int computeDefaultTypes(ComputeDefaultTypeContext context);
+
+  BodyBuilderContext createBodyBuilderContext(
+      SourcePropertyBuilder propertyBuilder);
+
+  void createEncoding(
+      ProblemReporting problemReporting,
+      SourcePropertyBuilder builder,
+      PropertyEncodingStrategy encodingStrategy,
+      List<NominalParameterBuilder> unboundNominalParameters);
+
+  LocalScope createFormalParameterScope(LookupScope typeParameterScope);
+
+  void ensureTypes(
+      {required SourceLibraryBuilder libraryBuilder,
+      required DeclarationBuilder? declarationBuilder,
+      required ClassMembersBuilder membersBuilder,
+      required Set<ClassMember>? getterOverrideDependencies});
+
+  Iterable<Reference> getExportedMemberReferences(GetterReference references);
+
+  VariableDeclaration getFormalParameter(int index);
+}
+
+class GetterDeclarationImpl implements GetterDeclaration {
+  final GetterFragment _fragment;
+  late final GetterEncoding _encoding;
+
+  GetterDeclarationImpl(this._fragment) {
+    _fragment.declaration = this;
+  }
+
+  @override
+  AsyncMarker get asyncModifier => _fragment.asyncModifier;
+
+  @override
+  Uri get fileUri => _fragment.fileUri;
+
+  @override
+  List<FormalParameterBuilder>? get formals => _encoding.formals;
+
+  @override
+  FunctionNode get function => _encoding.function;
+
+  @override
+  bool get isAbstract => _fragment.modifiers.isAbstract;
+
+  @override
+  bool get isExternal => _fragment.modifiers.isExternal;
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  List<MetadataBuilder>? get metadata => _fragment.metadata;
+
+  @override
+  String get name => _fragment.name;
+
+  @override
+  int get nameOffset => _fragment.nameOffset;
+
+  @override
+  Procedure get readTarget => _encoding.readTarget;
+
+  @override
+  TypeBuilder get returnType => _fragment.returnType;
+
+  @override
+  List<TypeParameter>? get thisTypeParameters => _encoding.thisTypeParameters;
+
+  @override
+  VariableDeclaration? get thisVariable => _encoding.thisVariable;
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  List<NominalParameterBuilder>? get typeParametersForTesting =>
+      _encoding.clonedAndDeclaredTypeParameters;
+
+  @override
+  void becomeNative(SourceLoader loader) {
+    _encoding.becomeNative(loader);
+  }
+
+  @override
+  void buildOutlineExpressions(
+      {required ClassHierarchy classHierarchy,
+      required SourceLibraryBuilder libraryBuilder,
+      required DeclarationBuilder? declarationBuilder,
+      required SourcePropertyBuilder propertyBuilder,
+      required Annotatable annotatable,
+      required bool isClassInstanceMember,
+      required bool createFileUriExpression}) {
+    _encoding.buildOutlineExpressions(
+        classHierarchy,
+        libraryBuilder,
+        declarationBuilder,
+        createBodyBuilderContext(propertyBuilder),
+        annotatable,
+        isClassInstanceMember: isClassInstanceMember,
+        createFileUriExpression: createFileUriExpression);
+  }
+
+  @override
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
+      {required List<TypeParameter>? classTypeParameters}) {
+    _encoding.buildOutlineNode(libraryBuilder, nameScheme, f, references,
+        isAbstractOrExternal:
+            _fragment.modifiers.isAbstract || _fragment.modifiers.isExternal,
+        classTypeParameters: classTypeParameters);
+  }
+
+  @override
+  void checkTypes(SourceLibraryBuilder libraryBuilder,
+      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
+      {required bool isAbstract, required bool isExternal}) {
+    _encoding.checkTypes(libraryBuilder, typeEnvironment, setterBuilder,
+        isAbstract: isAbstract, isExternal: isExternal);
+  }
+
+  @override
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
+    _encoding.checkVariance(sourceClassBuilder, typeEnvironment);
+  }
+
+  @override
+  int computeDefaultTypes(ComputeDefaultTypeContext context) {
+    return _encoding.computeDefaultTypes(context);
+  }
+
+  @override
+  BodyBuilderContext createBodyBuilderContext(
+      SourcePropertyBuilder propertyBuilder) {
+    return new GetterFragmentBodyBuilderContext(propertyBuilder, this,
+        propertyBuilder.libraryBuilder, propertyBuilder.declarationBuilder,
+        isDeclarationInstanceMember:
+            propertyBuilder.isDeclarationInstanceMember);
+  }
+
+  @override
+  void createEncoding(
+      ProblemReporting problemReporting,
+      SourcePropertyBuilder builder,
+      PropertyEncodingStrategy encodingStrategy,
+      List<NominalParameterBuilder> unboundNominalParameters) {
+    _encoding = encodingStrategy.createGetterEncoding(
+        builder, _fragment, unboundNominalParameters);
+    _fragment.typeParameterNameSpace.addTypeParameters(
+        problemReporting, _encoding.clonedAndDeclaredTypeParameters,
+        ownerName: _fragment.name, allowNameConflict: true);
+    returnType.registerInferredTypeListener(_encoding);
+  }
+
+  @override
+  LocalScope createFormalParameterScope(LookupScope typeParameterScope) {
+    return _encoding.createFormalParameterScope(typeParameterScope);
+  }
+
+  @override
+  void ensureTypes(
+      {required SourceLibraryBuilder libraryBuilder,
+      required DeclarationBuilder? declarationBuilder,
+      required ClassMembersBuilder membersBuilder,
+      required Set<ClassMember>? getterOverrideDependencies}) {
+    if (getterOverrideDependencies != null) {
+      membersBuilder.inferGetterType(declarationBuilder as SourceClassBuilder,
+          _fragment.returnType, getterOverrideDependencies,
+          name: _fragment.name,
+          fileUri: _fragment.fileUri,
+          nameOffset: _fragment.nameOffset,
+          nameLength: _fragment.name.length);
+    }
+    _encoding.ensureTypes(libraryBuilder, membersBuilder.hierarchyBuilder);
+  }
+
+  @override
+  Iterable<Reference> getExportedMemberReferences(GetterReference references) =>
+      [references.getterReference];
+
+  @override
+  VariableDeclaration getFormalParameter(int index) {
+    return _encoding.getFormalParameter(index);
+  }
+}
diff --git a/pkg/front_end/lib/src/fragment/getter/encoding.dart b/pkg/front_end/lib/src/fragment/getter/encoding.dart
new file mode 100644
index 0000000..68afdf5
--- /dev/null
+++ b/pkg/front_end/lib/src/fragment/getter/encoding.dart
@@ -0,0 +1,632 @@
+// Copyright (c) 2025, 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/class_hierarchy.dart';
+import 'package:kernel/type_environment.dart';
+
+import '../../base/local_scope.dart';
+import '../../base/scope.dart';
+import '../../builder/builder.dart';
+import '../../builder/declaration_builders.dart';
+import '../../builder/formal_parameter_builder.dart';
+import '../../builder/omitted_type_builder.dart';
+import '../../builder/type_builder.dart';
+import '../../kernel/body_builder_context.dart';
+import '../../kernel/type_algorithms.dart';
+import '../../source/name_scheme.dart';
+import '../../source/source_class_builder.dart';
+import '../../source/source_function_builder.dart';
+import '../../source/source_library_builder.dart';
+import '../../source/source_loader.dart';
+import '../../source/source_member_builder.dart';
+import '../../source/source_property_builder.dart';
+import '../fragment.dart';
+
+class ExtensionInstanceGetterEncoding extends GetterEncoding
+    with _ExtensionInstanceGetterEncodingMixin {
+  @override
+  final GetterFragment _fragment;
+
+  @override
+  final List<NominalParameterBuilder>? _clonedDeclarationTypeParameters;
+
+  @override
+  final FormalParameterBuilder _thisFormal;
+
+  ExtensionInstanceGetterEncoding(
+      this._fragment, this._clonedDeclarationTypeParameters, this._thisFormal);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionGetter;
+
+  @override
+  bool get _isExtensionMember => true;
+
+  @override
+  bool get _isExtensionTypeMember => false;
+}
+
+class ExtensionStaticGetterEncoding extends GetterEncoding
+    with _DirectGetterEncodingMixin {
+  @override
+  final GetterFragment _fragment;
+
+  ExtensionStaticGetterEncoding(this._fragment);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionGetter;
+
+  @override
+  bool get _isExtensionMember => true;
+
+  @override
+  bool get _isExtensionTypeMember => false;
+}
+
+class ExtensionTypeInstanceGetterEncoding extends GetterEncoding
+    with _ExtensionInstanceGetterEncodingMixin {
+  @override
+  final GetterFragment _fragment;
+
+  @override
+  final List<NominalParameterBuilder>? _clonedDeclarationTypeParameters;
+
+  @override
+  final FormalParameterBuilder _thisFormal;
+
+  ExtensionTypeInstanceGetterEncoding(
+      this._fragment, this._clonedDeclarationTypeParameters, this._thisFormal);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionTypeGetter;
+
+  @override
+  bool get _isExtensionMember => false;
+
+  @override
+  bool get _isExtensionTypeMember => true;
+}
+
+class ExtensionTypeStaticGetterEncoding extends GetterEncoding
+    with _DirectGetterEncodingMixin {
+  @override
+  final GetterFragment _fragment;
+
+  ExtensionTypeStaticGetterEncoding(this._fragment);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionTypeGetter;
+
+  @override
+  bool get _isExtensionMember => false;
+
+  @override
+  bool get _isExtensionTypeMember => true;
+}
+
+sealed class GetterEncoding implements InferredTypeListener {
+  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters;
+  List<FormalParameterBuilder>? get formals;
+  FunctionNode get function;
+
+  Procedure get readTarget;
+
+  List<TypeParameter>? get thisTypeParameters;
+
+  VariableDeclaration? get thisVariable;
+
+  void becomeNative(SourceLoader loader);
+
+  void buildOutlineExpressions(
+      ClassHierarchy classHierarchy,
+      SourceLibraryBuilder libraryBuilder,
+      DeclarationBuilder? declarationBuilder,
+      BodyBuilderContext bodyBuilderContext,
+      Annotatable annotatable,
+      {required bool isClassInstanceMember,
+      required bool createFileUriExpression});
+
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
+      {required bool isAbstractOrExternal,
+      required List<TypeParameter>? classTypeParameters});
+
+  void checkTypes(SourceLibraryBuilder libraryBuilder,
+      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
+      {required bool isAbstract, required bool isExternal});
+
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment);
+
+  int computeDefaultTypes(ComputeDefaultTypeContext context);
+
+  LocalScope createFormalParameterScope(LookupScope typeParameterScope);
+
+  void ensureTypes(
+      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy);
+
+  VariableDeclaration getFormalParameter(int index);
+}
+
+class RegularGetterEncoding extends GetterEncoding
+    with _DirectGetterEncodingMixin {
+  @override
+  final GetterFragment _fragment;
+
+  RegularGetterEncoding(this._fragment);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.Method;
+
+  @override
+  bool get _isExtensionMember => false;
+
+  @override
+  bool get _isExtensionTypeMember => false;
+}
+
+mixin _DirectGetterEncodingMixin implements GetterEncoding {
+  Procedure? _procedure;
+
+  @override
+  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
+      _fragment
+          .declaredTypeParameters
+          // Coverage-ignore(suite): Not run.
+          ?.builders;
+
+  @override
+  List<FormalParameterBuilder>? get formals => _fragment.declaredFormals;
+
+  @override
+  FunctionNode get function => _procedure!.function;
+
+  @override
+  Procedure get readTarget => _procedure!;
+
+  @override
+  List<TypeParameter>? get thisTypeParameters => null;
+
+  @override
+  VariableDeclaration? get thisVariable => null;
+
+  BuiltMemberKind get _builtMemberKind;
+
+  GetterFragment get _fragment;
+
+  bool get _isExtensionMember;
+
+  bool get _isExtensionTypeMember;
+
+  @override
+  void becomeNative(SourceLoader loader) {
+    loader.addNativeAnnotation(_procedure!, _fragment.nativeMethodName!);
+  }
+
+  @override
+  void buildOutlineExpressions(
+      ClassHierarchy classHierarchy,
+      SourceLibraryBuilder libraryBuilder,
+      DeclarationBuilder? declarationBuilder,
+      BodyBuilderContext bodyBuilderContext,
+      Annotatable annotatable,
+      {required bool isClassInstanceMember,
+      required bool createFileUriExpression}) {
+    buildMetadataForOutlineExpressions(libraryBuilder, _fragment.enclosingScope,
+        bodyBuilderContext, annotatable, _fragment.metadata,
+        fileUri: _fragment.fileUri,
+        createFileUriExpression: createFileUriExpression);
+    buildTypeParametersForOutlineExpressions(
+        classHierarchy,
+        libraryBuilder,
+        bodyBuilderContext,
+        _fragment.typeParameterScope,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
+    buildFormalsForOutlineExpressions(
+        libraryBuilder, declarationBuilder, _fragment.declaredFormals,
+        scope: _fragment.typeParameterScope,
+        isClassInstanceMember: isClassInstanceMember);
+  }
+
+  @override
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
+      {required bool isAbstractOrExternal,
+      List<TypeParameter>? classTypeParameters}) {
+    FunctionNode function = new FunctionNode(
+        isAbstractOrExternal ? null : new EmptyStatement(),
+        asyncMarker: _fragment.asyncModifier)
+      ..fileOffset = _fragment.formalsOffset
+      ..fileEndOffset = _fragment.endOffset;
+    buildTypeParametersAndFormals(
+        libraryBuilder,
+        function,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        _fragment.declaredFormals,
+        classTypeParameters: classTypeParameters,
+        supportsTypeParameters: true);
+    if (_fragment.returnType is! InferableTypeBuilder) {
+      function.returnType =
+          _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
+    }
+
+    MemberName memberName =
+        nameScheme.getProcedureMemberName(ProcedureKind.Getter, _fragment.name);
+    Procedure procedure = _procedure = new Procedure(
+        memberName.name, ProcedureKind.Getter, function,
+        reference: references.getterReference, fileUri: _fragment.fileUri)
+      ..fileStartOffset = _fragment.startOffset
+      ..fileOffset = _fragment.nameOffset
+      ..fileEndOffset = _fragment.endOffset
+      ..isAbstract = _fragment.modifiers.isAbstract
+      ..isExternal = _fragment.modifiers.isExternal
+      ..isConst = _fragment.modifiers.isConst
+      ..isStatic = _fragment.modifiers.isStatic
+      ..isExtensionMember = _isExtensionMember
+      ..isExtensionTypeMember = _isExtensionTypeMember;
+    memberName.attachMember(procedure);
+
+    f(kind: _builtMemberKind, member: procedure);
+  }
+
+  @override
+  void checkTypes(SourceLibraryBuilder libraryBuilder,
+      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
+      {required bool isAbstract, required bool isExternal}) {
+    List<TypeParameterBuilder>? typeParameters = _fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders;
+    // Coverage-ignore(suite): Not run.
+    if (typeParameters != null && typeParameters.isNotEmpty) {
+      libraryBuilder.checkTypeParameterDependencies(typeParameters);
+    }
+    libraryBuilder.checkInitializersInFormals(
+        _fragment.declaredFormals, typeEnvironment,
+        isAbstract: isAbstract, isExternal: isExternal);
+    if (setterBuilder != null) {
+      DartType getterType = function.returnType;
+      DartType setterType = SourcePropertyBuilder.getSetterType(setterBuilder,
+          getterExtensionTypeParameters: null);
+      libraryBuilder.checkGetterSetterTypes(typeEnvironment,
+          getterType: getterType,
+          getterName: _fragment.name,
+          getterFileOffset: _fragment.nameOffset,
+          getterFileUri: _fragment.fileUri,
+          getterNameLength: _fragment.name.length,
+          setterType: setterType,
+          setterName: setterBuilder.name,
+          setterFileOffset: setterBuilder.fileOffset,
+          setterFileUri: setterBuilder.fileUri,
+          setterNameLength: setterBuilder.name.length);
+    }
+  }
+
+  @override
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
+    sourceClassBuilder.checkVarianceInTypeParameters(
+        typeEnvironment,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
+    sourceClassBuilder.checkVarianceInFormals(
+        typeEnvironment, _fragment.declaredFormals);
+    sourceClassBuilder.checkVarianceInReturnType(
+        typeEnvironment, function.returnType,
+        fileOffset: _fragment.nameOffset, fileUri: _fragment.fileUri);
+  }
+
+  @override
+  int computeDefaultTypes(ComputeDefaultTypeContext context) {
+    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders);
+    context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
+    if (_fragment.returnType is! OmittedTypeBuilder) {
+      hasErrors |=
+          context.reportInboundReferenceIssuesForType(_fragment.returnType);
+      context.recursivelyReportGenericFunctionTypesAsBoundsForType(
+          _fragment.returnType);
+    }
+    return context.computeDefaultTypesForVariables(
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        inErrorRecovery: hasErrors);
+  }
+
+  @override
+  LocalScope createFormalParameterScope(LookupScope typeParameterScope) {
+    return new FormalParameterScope(parent: typeParameterScope);
+  }
+
+  @override
+  void ensureTypes(
+      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy) {
+    _fragment.returnType
+        .build(libraryBuilder, TypeUse.returnType, hierarchy: hierarchy);
+  }
+
+  @override
+  VariableDeclaration getFormalParameter(int index) =>
+      _fragment.declaredFormals![index].variable!;
+
+  @override
+  void onInferredType(DartType type) {
+    function.returnType = type;
+  }
+}
+
+mixin _ExtensionInstanceGetterEncodingMixin implements GetterEncoding {
+  Procedure? _procedure;
+
+  @override
+  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
+      _clonedDeclarationTypeParameters != null ||
+              _fragment.declaredTypeParameters != null
+          ? [
+              ...?_clonedDeclarationTypeParameters,
+              ...?_fragment
+                  .declaredTypeParameters
+                  // Coverage-ignore(suite): Not run.
+                  ?.builders
+            ]
+          : null;
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  List<FormalParameterBuilder>? get formals =>
+      [_thisFormal, ...?_fragment.declaredFormals];
+
+  @override
+  FunctionNode get function => _procedure!.function;
+
+  @override
+  Procedure get readTarget => _procedure!;
+
+  @override
+  List<TypeParameter>? get thisTypeParameters =>
+      _clonedDeclarationTypeParameters != null ? function.typeParameters : null;
+
+  @override
+  VariableDeclaration? get thisVariable => _thisFormal.variable!;
+
+  BuiltMemberKind get _builtMemberKind;
+
+  List<NominalParameterBuilder>? get _clonedDeclarationTypeParameters;
+
+  GetterFragment get _fragment;
+
+  bool get _isExtensionMember;
+
+  bool get _isExtensionTypeMember;
+
+  FormalParameterBuilder get _thisFormal;
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  void becomeNative(SourceLoader loader) {
+    loader.addNativeAnnotation(_procedure!, _fragment.nativeMethodName!);
+  }
+
+  @override
+  void buildOutlineExpressions(
+      ClassHierarchy classHierarchy,
+      SourceLibraryBuilder libraryBuilder,
+      DeclarationBuilder? declarationBuilder,
+      BodyBuilderContext bodyBuilderContext,
+      Annotatable annotatable,
+      {required bool isClassInstanceMember,
+      required bool createFileUriExpression}) {
+    buildMetadataForOutlineExpressions(libraryBuilder, _fragment.enclosingScope,
+        bodyBuilderContext, annotatable, _fragment.metadata,
+        fileUri: _fragment.fileUri,
+        createFileUriExpression: createFileUriExpression);
+
+    buildTypeParametersForOutlineExpressions(
+        classHierarchy,
+        libraryBuilder,
+        bodyBuilderContext,
+        _fragment.typeParameterScope,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
+    buildFormalsForOutlineExpressions(
+        libraryBuilder, declarationBuilder, _fragment.declaredFormals,
+        scope: _fragment.typeParameterScope,
+        isClassInstanceMember: isClassInstanceMember);
+
+    buildTypeParametersForOutlineExpressions(
+        classHierarchy,
+        libraryBuilder,
+        bodyBuilderContext,
+        _fragment.typeParameterScope,
+        _clonedDeclarationTypeParameters);
+    buildFormalForOutlineExpressions(
+        libraryBuilder, declarationBuilder, _thisFormal,
+        scope: _fragment.typeParameterScope,
+        isClassInstanceMember: isClassInstanceMember);
+  }
+
+  @override
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, GetterReference references,
+      {required bool isAbstractOrExternal,
+      required List<TypeParameter>? classTypeParameters}) {
+    List<TypeParameter>? typeParameters;
+    if (_clonedDeclarationTypeParameters != null) {
+      typeParameters = [];
+      // TODO(johnniwinther): Ambivalent analyzer. `!` seems to be both required
+      // and unnecessary.
+      // ignore: unnecessary_non_null_assertion
+      for (NominalParameterBuilder t in _clonedDeclarationTypeParameters!) {
+        typeParameters.add(t.parameter);
+      }
+    }
+    FunctionNode function = new FunctionNode(
+        isAbstractOrExternal ? null : new EmptyStatement(),
+        typeParameters: typeParameters,
+        positionalParameters: [_thisFormal.build(libraryBuilder)],
+        asyncMarker: _fragment.asyncModifier)
+      ..fileOffset = _fragment.formalsOffset
+      ..fileEndOffset = _fragment.endOffset;
+    buildTypeParametersAndFormals(
+        libraryBuilder,
+        function,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        _fragment.declaredFormals,
+        classTypeParameters: classTypeParameters,
+        supportsTypeParameters: true);
+    if (_fragment.returnType is! InferableTypeBuilder) {
+      function.returnType =
+          _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
+    }
+
+    MemberName memberName =
+        nameScheme.getProcedureMemberName(ProcedureKind.Getter, _fragment.name);
+    Procedure procedure = _procedure = new Procedure(
+        memberName.name, ProcedureKind.Method, function,
+        reference: references.getterReference, fileUri: _fragment.fileUri)
+      ..fileStartOffset = _fragment.startOffset
+      ..fileOffset = _fragment.nameOffset
+      ..fileEndOffset = _fragment.endOffset
+      ..isAbstract = _fragment.modifiers.isAbstract
+      ..isExternal = _fragment.modifiers.isExternal
+      ..isConst = _fragment.modifiers.isConst
+      ..isStatic = true
+      ..isExtensionMember = _isExtensionMember
+      ..isExtensionTypeMember = _isExtensionTypeMember;
+    memberName.attachMember(procedure);
+
+    f(kind: _builtMemberKind, member: procedure);
+  }
+
+  @override
+  void checkTypes(SourceLibraryBuilder libraryBuilder,
+      TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
+      {required bool isAbstract, required bool isExternal}) {
+    List<TypeParameterBuilder>? typeParameters = _fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders;
+    // Coverage-ignore(suite): Not run.
+    if (typeParameters != null && typeParameters.isNotEmpty) {
+      libraryBuilder.checkTypeParameterDependencies(typeParameters);
+    }
+    libraryBuilder.checkInitializersInFormals(
+        _fragment.declaredFormals, typeEnvironment,
+        isAbstract: isAbstract, isExternal: isExternal);
+    if (setterBuilder != null) {
+      DartType getterType = function.returnType;
+      DartType setterType = SourcePropertyBuilder.getSetterType(setterBuilder,
+          getterExtensionTypeParameters: function.typeParameters);
+      libraryBuilder.checkGetterSetterTypes(typeEnvironment,
+          getterType: getterType,
+          getterName: _fragment.name,
+          getterFileOffset: _fragment.nameOffset,
+          getterFileUri: _fragment.fileUri,
+          getterNameLength: _fragment.name.length,
+          setterType: setterType,
+          setterName: setterBuilder.name,
+          setterFileOffset: setterBuilder.fileOffset,
+          setterFileUri: setterBuilder.fileUri,
+          setterNameLength: setterBuilder.name.length);
+    }
+  }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
+    sourceClassBuilder.checkVarianceInTypeParameters(
+        typeEnvironment, _fragment.declaredTypeParameters?.builders);
+    sourceClassBuilder.checkVarianceInFormals(
+        typeEnvironment, _fragment.declaredFormals);
+    sourceClassBuilder.checkVarianceInReturnType(
+        typeEnvironment, function.returnType,
+        fileOffset: _fragment.nameOffset, fileUri: _fragment.fileUri);
+  }
+
+  @override
+  int computeDefaultTypes(ComputeDefaultTypeContext context) {
+    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders);
+    context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
+    if (_fragment.returnType is! OmittedTypeBuilder) {
+      hasErrors |=
+          context.reportInboundReferenceIssuesForType(_fragment.returnType);
+      context.recursivelyReportGenericFunctionTypesAsBoundsForType(
+          _fragment.returnType);
+    }
+    if (_clonedDeclarationTypeParameters != null &&
+        _fragment.declaredTypeParameters != null) {
+      // Coverage-ignore-block(suite): Not run.
+      // We need to compute all default types together since they might be
+      // interdependent.
+      return context.computeDefaultTypesForVariables([
+        // TODO(johnniwinther): Ambivalent analyzer. `!` seems to be both
+        //  required and unnecessary.
+        // ignore: unnecessary_non_null_assertion
+        ..._clonedDeclarationTypeParameters!,
+        ..._fragment.declaredTypeParameters!.builders
+      ], inErrorRecovery: hasErrors);
+    } else if (_clonedDeclarationTypeParameters != null) {
+      return context.computeDefaultTypesForVariables(
+          _clonedDeclarationTypeParameters,
+          inErrorRecovery: hasErrors);
+    } else {
+      return context.computeDefaultTypesForVariables(
+          _fragment
+              .declaredTypeParameters
+              // Coverage-ignore(suite): Not run.
+              ?.builders,
+          inErrorRecovery: hasErrors);
+    }
+  }
+
+  @override
+  LocalScope createFormalParameterScope(LookupScope typeParameterScope) {
+    Map<String, Builder> local = <String, Builder>{};
+    assert(!_thisFormal.isWildcard);
+    local[_thisFormal.name] = _thisFormal;
+    return new FormalParameterScope(local: local, parent: typeParameterScope);
+  }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  void ensureTypes(
+      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy) {
+    _fragment.returnType
+        .build(libraryBuilder, TypeUse.fieldType, hierarchy: hierarchy);
+    _thisFormal.type
+        .build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
+  }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  VariableDeclaration getFormalParameter(int index) =>
+      _fragment.declaredFormals![index].variable!;
+
+  @override
+  void onInferredType(DartType type) {
+    function.returnType = type;
+  }
+}
diff --git a/pkg/front_end/lib/src/fragment/method.dart b/pkg/front_end/lib/src/fragment/method.dart
index 7ee30ed..a3208b9 100644
--- a/pkg/front_end/lib/src/fragment/method.dart
+++ b/pkg/front_end/lib/src/fragment/method.dart
@@ -468,21 +468,17 @@
       Annotatable annotatable,
       {required bool isClassInstanceMember,
       required bool createFileUriExpression}) {
-    _buildMetadataForOutlineExpressions(
-        libraryBuilder,
-        _fragment.enclosingScope,
-        bodyBuilderContext,
-        annotatable,
-        _fragment.metadata,
+    buildMetadataForOutlineExpressions(libraryBuilder, _fragment.enclosingScope,
+        bodyBuilderContext, annotatable, _fragment.metadata,
         fileUri: _fragment.fileUri,
         createFileUriExpression: createFileUriExpression);
-    _buildTypeParametersForOutlineExpressions(
+    buildTypeParametersForOutlineExpressions(
         classHierarchy,
         libraryBuilder,
         bodyBuilderContext,
         _fragment.typeParameterScope,
         _fragment.declaredTypeParameters);
-    _buildFormalsForOutlineExpressions(
+    buildFormalsForOutlineExpressions(
         libraryBuilder, declarationBuilder, _fragment.declaredFormals,
         scope: _fragment.typeParameterScope,
         isClassInstanceMember: isClassInstanceMember);
@@ -965,33 +961,29 @@
       Annotatable annotatable,
       {required bool isClassInstanceMember,
       required bool createFileUriExpression}) {
-    _buildMetadataForOutlineExpressions(
-        libraryBuilder,
-        _fragment.enclosingScope,
-        bodyBuilderContext,
-        annotatable,
-        _fragment.metadata,
+    buildMetadataForOutlineExpressions(libraryBuilder, _fragment.enclosingScope,
+        bodyBuilderContext, annotatable, _fragment.metadata,
         fileUri: _fragment.fileUri,
         createFileUriExpression: createFileUriExpression);
 
-    _buildTypeParametersForOutlineExpressions(
+    buildTypeParametersForOutlineExpressions(
         classHierarchy,
         libraryBuilder,
         bodyBuilderContext,
         _fragment.typeParameterScope,
         _fragment.declaredTypeParameters);
-    _buildFormalsForOutlineExpressions(
+    buildFormalsForOutlineExpressions(
         libraryBuilder, declarationBuilder, _fragment.declaredFormals,
         scope: _fragment.typeParameterScope,
         isClassInstanceMember: isClassInstanceMember);
 
-    _buildTypeParametersForOutlineExpressions(
+    buildTypeParametersForOutlineExpressions(
         classHierarchy,
         libraryBuilder,
         bodyBuilderContext,
         _fragment.typeParameterScope,
         _clonedDeclarationTypeParameters);
-    _buildFormalForOutlineExpressions(
+    buildFormalForOutlineExpressions(
         libraryBuilder, declarationBuilder, _thisFormal,
         scope: _fragment.typeParameterScope,
         isClassInstanceMember: isClassInstanceMember);
diff --git a/pkg/front_end/lib/src/fragment/setter.dart b/pkg/front_end/lib/src/fragment/setter.dart
index 85a1037..d9f2aeb 100644
--- a/pkg/front_end/lib/src/fragment/setter.dart
+++ b/pkg/front_end/lib/src/fragment/setter.dart
@@ -58,8 +58,7 @@
   final LibraryFragment enclosingCompilationUnit;
 
   SourcePropertyBuilder? _builder;
-
-  late final _SetterEncoding _encoding;
+  SetterDeclaration? _declaration;
 
   SetterFragment({
     required this.name,
@@ -89,109 +88,37 @@
     return _builder!;
   }
 
-  void setBuilder(
-      ProblemReporting problemReporting,
-      SourcePropertyBuilder value,
-      PropertyEncodingStrategy encodingStrategy,
-      List<NominalParameterBuilder> unboundNominalParameters) {
+  void set builder(SourcePropertyBuilder value) {
     assert(_builder == null, "Builder has already been computed for $this.");
     _builder = value;
-    _encoding = encodingStrategy.createSetterEncoding(
-        value, this, unboundNominalParameters);
-    typeParameterNameSpace.addTypeParameters(
-        problemReporting, _encoding.clonedAndDeclaredTypeParameters,
-        ownerName: name, allowNameConflict: true);
   }
 
-  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
-      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
-      {required List<TypeParameter>? classTypeParameters}) {
-    _encoding.buildOutlineNode(libraryBuilder, nameScheme, f, references,
-        isAbstractOrExternal: modifiers.isAbstract || modifiers.isExternal,
-        classTypeParameters: classTypeParameters);
+  SetterDeclaration get declaration {
+    assert(
+        _declaration != null, "Declaration has not been computed for $this.");
+    return _declaration!;
   }
 
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      Annotatable annotatable,
-      {required bool isClassInstanceMember,
-      required bool createFileUriExpression}) {
-    _encoding.buildOutlineExpressions(classHierarchy, libraryBuilder,
-        declarationBuilder, createBodyBuilderContext(), annotatable,
-        isClassInstanceMember: isClassInstanceMember,
-        createFileUriExpression: createFileUriExpression);
+  void set declaration(SetterDeclaration value) {
+    assert(_declaration == null,
+        "Declaration has already been computed for $this.");
+    _declaration = value;
   }
 
-  Iterable<Reference> getExportedMemberReferences(SetterReference references) =>
-      [references.setterReference];
-
-  void ensureTypes(ClassMembersBuilder membersBuilder,
-      Set<ClassMember>? setterOverrideDependencies) {
-    if (setterOverrideDependencies != null) {
-      membersBuilder.inferSetterType(
-          builder.declarationBuilder as SourceClassBuilder,
-          declaredFormals,
-          setterOverrideDependencies,
-          name: name,
-          fileUri: fileUri,
-          nameOffset: nameOffset,
-          nameLength: name.length);
-    }
-    _encoding.ensureTypes(
-        builder.libraryBuilder, membersBuilder.hierarchyBuilder);
-  }
-
-  void checkTypes(
-      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
-      {required bool isAbstract, required bool isExternal}) {
-    _encoding.checkTypes(libraryBuilder, typeEnvironment,
-        isAbstract: isAbstract, isExternal: isExternal);
-  }
-
-  void checkVariance(
-      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
-    _encoding.checkVariance(sourceClassBuilder, typeEnvironment);
-  }
-
-  int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    return _encoding.computeDefaultTypes(context);
-  }
-
-  Procedure get writeTarget => _encoding.writeTarget;
-
-  // Coverage-ignore(suite): Not run.
-  List<NominalParameterBuilder>? get typeParametersForTesting =>
-      _encoding.clonedAndDeclaredTypeParameters;
-
-  // Coverage-ignore(suite): Not run.
-  List<FormalParameterBuilder>? get formalsForTesting =>
-      _encoding.formalsForTesting;
-
   @override
   FunctionBodyBuildingContext createFunctionBodyBuildingContext() {
-    return new _SetterBodyBuildingContext(this);
-  }
-
-  BodyBuilderContext createBodyBuilderContext() {
-    return new _SetterFragmentBodyBuilderContext(
-        this, builder.libraryBuilder, builder.declarationBuilder,
-        isDeclarationInstanceMember: builder.isDeclarationInstanceMember);
-  }
-
-  void becomeNative(SourceLoader loader) {
-    _encoding.becomeNative(loader);
+    return new _SetterFunctionBodyBuildingContext(this);
   }
 
   @override
   String toString() => '$runtimeType($name,$fileUri,$nameOffset)';
 }
 
-class _SetterBodyBuildingContext implements FunctionBodyBuildingContext {
+class _SetterFunctionBodyBuildingContext
+    implements FunctionBodyBuildingContext {
   SetterFragment _fragment;
 
-  _SetterBodyBuildingContext(this._fragment);
+  _SetterFunctionBodyBuildingContext(this._fragment);
 
   @override
   MemberKind get memberKind => _fragment.isTopLevel
@@ -205,7 +132,7 @@
 
   @override
   LocalScope computeFormalParameterScope(LookupScope typeParameterScope) {
-    return _fragment._encoding.createFormalParameterScope(typeParameterScope);
+    return _fragment.declaration.createFormalParameterScope(typeParameterScope);
   }
 
   @override
@@ -215,7 +142,7 @@
 
   @override
   BodyBuilderContext createBodyBuilderContext() {
-    return _fragment.createBodyBuilderContext();
+    return _fragment.declaration.createBodyBuilderContext(_fragment.builder);
   }
 
   @override
@@ -227,740 +154,8 @@
 
   @override
   List<TypeParameter>? get thisTypeParameters =>
-      _fragment._encoding.thisTypeParameters;
+      _fragment.declaration.thisTypeParameters;
 
   @override
-  VariableDeclaration? get thisVariable => _fragment._encoding.thisVariable;
-}
-
-sealed class _SetterEncoding {
-  List<TypeParameter>? get thisTypeParameters;
-  VariableDeclaration? get thisVariable;
-  FunctionNode get function;
-  Procedure get writeTarget;
-
-  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
-      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
-      {required bool isAbstractOrExternal,
-      required List<TypeParameter>? classTypeParameters});
-
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      BodyBuilderContext bodyBuilderContext,
-      Annotatable annotatable,
-      {required bool isClassInstanceMember,
-      required bool createFileUriExpression});
-
-  LocalScope createFormalParameterScope(LookupScope typeParameterScope);
-
-  int computeDefaultTypes(ComputeDefaultTypeContext context);
-
-  void ensureTypes(
-      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy);
-
-  void becomeNative(SourceLoader loader);
-
-  List<FormalParameterBuilder>? get formals;
-
-  VariableDeclaration getFormalParameter(int index);
-
-  void checkTypes(
-      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
-      {required bool isAbstract, required bool isExternal});
-
-  void checkVariance(
-      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment);
-
-  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters;
-
-  List<FormalParameterBuilder>? get formalsForTesting;
-}
-
-mixin _DirectSetterEncodingMixin implements _SetterEncoding {
-  SetterFragment get _fragment;
-
-  Procedure? _procedure;
-
-  @override
-  VariableDeclaration? get thisVariable => null;
-
-  @override
-  List<TypeParameter>? get thisTypeParameters => null;
-
-  @override
-  LocalScope createFormalParameterScope(LookupScope parent) {
-    Map<String, Builder> local = <String, Builder>{};
-    List<FormalParameterBuilder>? formals = _fragment.declaredFormals;
-    if (formals != null) {
-      for (FormalParameterBuilder formal in formals) {
-        if (formal.isWildcard) {
-          continue;
-        }
-        local[formal.name] = formal;
-      }
-    }
-    return new FormalParameterScope(local: local, parent: parent);
-  }
-
-  @override
-  List<FormalParameterBuilder>? get formals => _fragment.declaredFormals;
-
-  @override
-  VariableDeclaration getFormalParameter(int index) =>
-      _fragment.declaredFormals![index].variable!;
-
-  BuiltMemberKind get _builtMemberKind;
-
-  bool get _isExtensionMember;
-
-  bool get _isExtensionTypeMember;
-
-  @override
-  FunctionNode get function => _procedure!.function;
-
-  @override
-  Procedure get writeTarget => _procedure!;
-
-  @override
-  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
-      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
-      {required bool isAbstractOrExternal,
-      List<TypeParameter>? classTypeParameters}) {
-    FunctionNode function = new FunctionNode(
-        isAbstractOrExternal ? null : new EmptyStatement(),
-        asyncMarker: _fragment.asyncModifier)
-      ..fileOffset = _fragment.formalsOffset
-      ..fileEndOffset = _fragment.endOffset;
-    buildTypeParametersAndFormals(
-        libraryBuilder,
-        function,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders,
-        _fragment.declaredFormals,
-        classTypeParameters: classTypeParameters,
-        supportsTypeParameters: true);
-    if (_fragment.returnType is! InferableTypeBuilder) {
-      function.returnType =
-          _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
-    }
-    if (_fragment.declaredFormals?.length != 1 ||
-        _fragment.declaredFormals![0].isOptionalPositional) {
-      // 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");
-      function.positionalParameters.clear();
-      function.positionalParameters.add(parameter);
-      parameter.parent = function;
-      function.namedParameters.clear();
-      function.requiredParameterCount = 1;
-    }
-    MemberName memberName =
-        nameScheme.getProcedureMemberName(ProcedureKind.Setter, _fragment.name);
-    Procedure procedure = _procedure = new Procedure(
-        memberName.name, ProcedureKind.Setter, function,
-        reference: references.setterReference, fileUri: _fragment.fileUri)
-      ..fileStartOffset = _fragment.startOffset
-      ..fileOffset = _fragment.nameOffset
-      ..fileEndOffset = _fragment.endOffset
-      ..isAbstract = _fragment.modifiers.isAbstract
-      ..isExternal = _fragment.modifiers.isExternal
-      ..isConst = _fragment.modifiers.isConst
-      ..isStatic = _fragment.modifiers.isStatic
-      ..isExtensionMember = _isExtensionMember
-      ..isExtensionTypeMember = _isExtensionTypeMember;
-    memberName.attachMember(procedure);
-
-    f(kind: _builtMemberKind, member: procedure);
-  }
-
-  @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      BodyBuilderContext bodyBuilderContext,
-      Annotatable annotatable,
-      {required bool isClassInstanceMember,
-      required bool createFileUriExpression}) {
-    _buildMetadataForOutlineExpressions(
-        libraryBuilder,
-        _fragment.enclosingScope,
-        bodyBuilderContext,
-        annotatable,
-        _fragment.metadata,
-        fileUri: _fragment.fileUri,
-        createFileUriExpression: createFileUriExpression);
-
-    _buildTypeParametersForOutlineExpressions(
-        classHierarchy,
-        libraryBuilder,
-        bodyBuilderContext,
-        _fragment.typeParameterScope,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders);
-    _buildFormalsForOutlineExpressions(
-        libraryBuilder, declarationBuilder, _fragment.declaredFormals,
-        scope: _fragment.typeParameterScope,
-        isClassInstanceMember: isClassInstanceMember);
-  }
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    loader.addNativeAnnotation(_procedure!, _fragment.nativeMethodName!);
-  }
-
-  @override
-  void checkTypes(
-      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
-      {required bool isAbstract, required bool isExternal}) {
-    List<TypeParameterBuilder>? typeParameters = _fragment
-        .declaredTypeParameters
-        // Coverage-ignore(suite): Not run.
-        ?.builders;
-    // Coverage-ignore(suite): Not run.
-    if (typeParameters != null && typeParameters.isNotEmpty) {
-      libraryBuilder.checkTypeParameterDependencies(typeParameters);
-    }
-    libraryBuilder.checkInitializersInFormals(
-        _fragment.declaredFormals, typeEnvironment,
-        isAbstract: isAbstract, isExternal: isExternal);
-  }
-
-  @override
-  void checkVariance(
-      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
-    sourceClassBuilder.checkVarianceInTypeParameters(
-        typeEnvironment,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders);
-    sourceClassBuilder.checkVarianceInFormals(
-        typeEnvironment, _fragment.declaredFormals);
-    sourceClassBuilder.checkVarianceInReturnType(
-        typeEnvironment, function.returnType,
-        fileOffset: _fragment.nameOffset, fileUri: _fragment.fileUri);
-  }
-
-  @override
-  int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
-        .declaredTypeParameters
-        // Coverage-ignore(suite): Not run.
-        ?.builders);
-    context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
-    if (_fragment.returnType is! OmittedTypeBuilder) {
-      hasErrors |=
-          context.reportInboundReferenceIssuesForType(_fragment.returnType);
-      context.recursivelyReportGenericFunctionTypesAsBoundsForType(
-          _fragment.returnType);
-    }
-    return context.computeDefaultTypesForVariables(
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders,
-        inErrorRecovery: hasErrors);
-  }
-
-  @override
-  void ensureTypes(
-      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy) {
-    _fragment.returnType
-        .build(libraryBuilder, TypeUse.returnType, hierarchy: hierarchy);
-    List<FormalParameterBuilder>? declaredFormals = _fragment.declaredFormals;
-    if (declaredFormals != null) {
-      for (FormalParameterBuilder formal in declaredFormals) {
-        formal.type
-            .build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
-      }
-    }
-  }
-
-  @override
-  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
-      _fragment
-          .declaredTypeParameters
-          // Coverage-ignore(suite): Not run.
-          ?.builders;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  List<FormalParameterBuilder>? get formalsForTesting =>
-      _fragment.declaredFormals;
-}
-
-class _RegularSetterEncoding extends _SetterEncoding
-    with _DirectSetterEncodingMixin {
-  @override
-  final SetterFragment _fragment;
-
-  _RegularSetterEncoding(this._fragment);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.Method;
-
-  @override
-  bool get _isExtensionMember => false;
-
-  @override
-  bool get _isExtensionTypeMember => false;
-}
-
-class _ExtensionStaticSetterEncoding extends _SetterEncoding
-    with _DirectSetterEncodingMixin {
-  @override
-  final SetterFragment _fragment;
-
-  _ExtensionStaticSetterEncoding(this._fragment);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionSetter;
-
-  @override
-  bool get _isExtensionMember => true;
-
-  @override
-  bool get _isExtensionTypeMember => false;
-}
-
-class _ExtensionTypeStaticSetterEncoding extends _SetterEncoding
-    with _DirectSetterEncodingMixin {
-  @override
-  final SetterFragment _fragment;
-
-  _ExtensionTypeStaticSetterEncoding(this._fragment);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionTypeSetter;
-
-  @override
-  bool get _isExtensionMember => false;
-
-  @override
-  bool get _isExtensionTypeMember => true;
-}
-
-mixin _ExtensionInstanceSetterEncodingMixin implements _SetterEncoding {
-  SetterFragment get _fragment;
-
-  Procedure? _procedure;
-
-  List<NominalParameterBuilder>? get _clonedDeclarationTypeParameters;
-
-  FormalParameterBuilder get _thisFormal;
-
-  @override
-  List<TypeParameter>? get thisTypeParameters =>
-      _clonedDeclarationTypeParameters != null ? function.typeParameters : null;
-
-  @override
-  VariableDeclaration? get thisVariable => _thisFormal.variable!;
-
-  BuiltMemberKind get _builtMemberKind;
-
-  bool get _isExtensionMember;
-
-  bool get _isExtensionTypeMember;
-
-  @override
-  FunctionNode get function => _procedure!.function;
-
-  @override
-  Procedure get writeTarget => _procedure!;
-
-  @override
-  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
-      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
-      {required bool isAbstractOrExternal,
-      required List<TypeParameter>? classTypeParameters}) {
-    List<TypeParameter>? typeParameters;
-    if (_clonedDeclarationTypeParameters != null) {
-      typeParameters = [];
-      // TODO(johnniwinther): Ambivalent analyzer. `!` seems to be both required
-      // and unnecessary.
-      // ignore: unnecessary_non_null_assertion
-      for (NominalParameterBuilder t in _clonedDeclarationTypeParameters!) {
-        typeParameters.add(t.parameter);
-      }
-    }
-    FunctionNode function = new FunctionNode(
-        isAbstractOrExternal ? null : new EmptyStatement(),
-        typeParameters: typeParameters,
-        positionalParameters: [_thisFormal.build(libraryBuilder)],
-        asyncMarker: _fragment.asyncModifier)
-      ..fileOffset = _fragment.formalsOffset
-      ..fileEndOffset = _fragment.endOffset;
-    buildTypeParametersAndFormals(
-        libraryBuilder,
-        function,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders,
-        _fragment.declaredFormals,
-        classTypeParameters: classTypeParameters,
-        supportsTypeParameters: true);
-    // TODO(johnniwinther): We should have a consistent normalization strategy.
-    // We ensure that setters have 1 parameter, but for getters we include all
-    // declared parameters.
-    if ((_fragment.declaredFormals?.length != 1 ||
-        _fragment.declaredFormals![0].isOptionalPositional)) {
-      // Replace illegal parameters by single dummy parameter (after #this).
-      // Do this after building the parameters, since the diet listener
-      // assumes that parameters are built, even if illegal in number.
-      VariableDeclaration thisParameter = function.positionalParameters[0];
-      VariableDeclaration parameter = new VariableDeclarationImpl("#synthetic");
-      function.positionalParameters.clear();
-      function.positionalParameters.add(thisParameter);
-      function.positionalParameters.add(parameter);
-      parameter.parent = function;
-      function.namedParameters.clear();
-      function.requiredParameterCount = 2;
-    }
-    if (_fragment.returnType is! InferableTypeBuilder) {
-      function.returnType =
-          _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
-    }
-
-    MemberName memberName =
-        nameScheme.getProcedureMemberName(ProcedureKind.Setter, _fragment.name);
-    Procedure procedure = _procedure = new Procedure(
-        memberName.name, ProcedureKind.Method, function,
-        reference: references.setterReference, fileUri: _fragment.fileUri)
-      ..fileStartOffset = _fragment.startOffset
-      ..fileOffset = _fragment.nameOffset
-      ..fileEndOffset = _fragment.endOffset
-      ..isAbstract = _fragment.modifiers.isAbstract
-      ..isExternal = _fragment.modifiers.isExternal
-      ..isConst = _fragment.modifiers.isConst
-      ..isStatic = true
-      ..isExtensionMember = _isExtensionMember
-      ..isExtensionTypeMember = _isExtensionTypeMember;
-    memberName.attachMember(procedure);
-
-    f(kind: _builtMemberKind, member: procedure);
-  }
-
-  @override
-  void buildOutlineExpressions(
-      ClassHierarchy classHierarchy,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      BodyBuilderContext bodyBuilderContext,
-      Annotatable annotatable,
-      {required bool isClassInstanceMember,
-      required bool createFileUriExpression}) {
-    _buildMetadataForOutlineExpressions(
-        libraryBuilder,
-        _fragment.enclosingScope,
-        bodyBuilderContext,
-        annotatable,
-        _fragment.metadata,
-        fileUri: _fragment.fileUri,
-        createFileUriExpression: createFileUriExpression);
-
-    _buildTypeParametersForOutlineExpressions(
-        classHierarchy,
-        libraryBuilder,
-        bodyBuilderContext,
-        _fragment.typeParameterScope,
-        _fragment
-            .declaredTypeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders);
-    _buildFormalsForOutlineExpressions(
-        libraryBuilder, declarationBuilder, _fragment.declaredFormals,
-        scope: _fragment.typeParameterScope,
-        isClassInstanceMember: isClassInstanceMember);
-
-    _buildTypeParametersForOutlineExpressions(
-        classHierarchy,
-        libraryBuilder,
-        bodyBuilderContext,
-        _fragment.typeParameterScope,
-        _clonedDeclarationTypeParameters);
-    _buildFormalForOutlineExpressions(
-        libraryBuilder, declarationBuilder, _thisFormal,
-        scope: _fragment.typeParameterScope,
-        isClassInstanceMember: isClassInstanceMember);
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void becomeNative(SourceLoader loader) {
-    loader.addNativeAnnotation(_procedure!, _fragment.nativeMethodName!);
-  }
-
-  @override
-  void checkTypes(
-      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
-      {required bool isAbstract, required bool isExternal}) {
-    List<TypeParameterBuilder>? typeParameters = _fragment
-        .declaredTypeParameters
-        // Coverage-ignore(suite): Not run.
-        ?.builders;
-    // Coverage-ignore(suite): Not run.
-    if (typeParameters != null && typeParameters.isNotEmpty) {
-      libraryBuilder.checkTypeParameterDependencies(typeParameters);
-    }
-    libraryBuilder.checkInitializersInFormals(
-        _fragment.declaredFormals, typeEnvironment,
-        isAbstract: isAbstract, isExternal: isExternal);
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void checkVariance(
-      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
-    sourceClassBuilder.checkVarianceInTypeParameters(
-        typeEnvironment, _fragment.declaredTypeParameters?.builders);
-    sourceClassBuilder.checkVarianceInFormals(
-        typeEnvironment, _fragment.declaredFormals);
-    sourceClassBuilder.checkVarianceInReturnType(
-        typeEnvironment, function.returnType,
-        fileOffset: _fragment.nameOffset, fileUri: _fragment.fileUri);
-  }
-
-  @override
-  LocalScope createFormalParameterScope(LookupScope parent) {
-    Map<String, Builder> local = <String, Builder>{};
-
-    assert(!_thisFormal.isWildcard);
-    local[_thisFormal.name] = _thisFormal;
-
-    List<FormalParameterBuilder>? formals = _fragment.declaredFormals;
-    if (formals != null) {
-      for (FormalParameterBuilder formal in formals) {
-        if (formal.isWildcard) {
-          continue;
-        }
-        local[formal.name] = formal;
-      }
-    }
-    return new FormalParameterScope(local: local, parent: parent);
-  }
-
-  @override
-  int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
-        .declaredTypeParameters
-        // Coverage-ignore(suite): Not run.
-        ?.builders);
-    context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
-    if (_fragment.returnType is! OmittedTypeBuilder) {
-      hasErrors |=
-          context.reportInboundReferenceIssuesForType(_fragment.returnType);
-      context.recursivelyReportGenericFunctionTypesAsBoundsForType(
-          _fragment.returnType);
-    }
-    if (_clonedDeclarationTypeParameters != null &&
-        _fragment.declaredTypeParameters != null) {
-      // Coverage-ignore-block(suite): Not run.
-      // We need to compute all default types together since they might be
-      // interdependent.
-      return context.computeDefaultTypesForVariables([
-        // TODO(johnniwinther): Ambivalent analyzer. `!` seems to be both
-        //  required and unnecessary.
-        // ignore: unnecessary_non_null_assertion
-        ..._clonedDeclarationTypeParameters!,
-        ..._fragment.declaredTypeParameters!.builders
-      ], inErrorRecovery: hasErrors);
-    } else if (_clonedDeclarationTypeParameters != null) {
-      return context.computeDefaultTypesForVariables(
-          _clonedDeclarationTypeParameters,
-          inErrorRecovery: hasErrors);
-    } else {
-      return context.computeDefaultTypesForVariables(
-          _fragment
-              .declaredTypeParameters
-              // Coverage-ignore(suite): Not run.
-              ?.builders,
-          inErrorRecovery: hasErrors);
-    }
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void ensureTypes(
-      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy) {
-    _fragment.returnType
-        .build(libraryBuilder, TypeUse.fieldType, hierarchy: hierarchy);
-    _thisFormal.type
-        .build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
-    List<FormalParameterBuilder>? declaredFormals = _fragment.declaredFormals;
-    if (declaredFormals != null) {
-      for (FormalParameterBuilder formal in declaredFormals) {
-        formal.type
-            .build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
-      }
-    }
-  }
-
-  @override
-  List<FormalParameterBuilder>? get formals =>
-      [_thisFormal, ...?_fragment.declaredFormals];
-
-  @override
-  VariableDeclaration getFormalParameter(int index) =>
-      _fragment.declaredFormals![index].variable!;
-
-  @override
-  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
-      _clonedDeclarationTypeParameters != null ||
-              _fragment.declaredTypeParameters != null
-          ? [
-              ...?_clonedDeclarationTypeParameters,
-              ...?_fragment
-                  .declaredTypeParameters
-                  // Coverage-ignore(suite): Not run.
-                  ?.builders
-            ]
-          : null;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  List<FormalParameterBuilder>? get formalsForTesting =>
-      [_thisFormal, ...?_fragment.declaredFormals];
-}
-
-class _ExtensionInstanceSetterEncoding extends _SetterEncoding
-    with _ExtensionInstanceSetterEncodingMixin {
-  @override
-  final SetterFragment _fragment;
-
-  @override
-  final List<NominalParameterBuilder>? _clonedDeclarationTypeParameters;
-
-  @override
-  final FormalParameterBuilder _thisFormal;
-
-  _ExtensionInstanceSetterEncoding(
-      this._fragment, this._clonedDeclarationTypeParameters, this._thisFormal);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionSetter;
-
-  @override
-  bool get _isExtensionMember => true;
-
-  @override
-  bool get _isExtensionTypeMember => false;
-}
-
-class _ExtensionTypeInstanceSetterEncoding extends _SetterEncoding
-    with _ExtensionInstanceSetterEncodingMixin {
-  @override
-  final SetterFragment _fragment;
-
-  @override
-  final List<NominalParameterBuilder>? _clonedDeclarationTypeParameters;
-
-  @override
-  final FormalParameterBuilder _thisFormal;
-
-  _ExtensionTypeInstanceSetterEncoding(
-      this._fragment, this._clonedDeclarationTypeParameters, this._thisFormal);
-
-  @override
-  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionTypeSetter;
-
-  @override
-  bool get _isExtensionMember => false;
-
-  @override
-  bool get _isExtensionTypeMember => true;
-}
-
-class _SetterFragmentBodyBuilderContext extends BodyBuilderContext {
-  final SetterFragment _fragment;
-
-  _SetterFragmentBodyBuilderContext(
-      this._fragment,
-      SourceLibraryBuilder libraryBuilder,
-      DeclarationBuilder? declarationBuilder,
-      {required bool isDeclarationInstanceMember})
-      : super(libraryBuilder, declarationBuilder,
-            isDeclarationInstanceMember: isDeclarationInstanceMember);
-
-  @override
-  bool get isSetter => true;
-
-  @override
-  LocalScope computeFormalParameterInitializerScope(LocalScope parent) {
-    /// Initializer formals or super parameters cannot occur in getters so
-    /// we don't need to create a new scope.
-    return parent;
-  }
-
-  @override
-  FunctionNode get function => _fragment._encoding.function;
-
-  @override
-  bool get isExternalFunction => _fragment.modifiers.isExternal;
-
-  @override
-  void setAsyncModifier(AsyncMarker asyncModifier) {
-    assert(
-        asyncModifier == _fragment.asyncModifier,
-        "Unexpected change in async modifier on $_fragment from "
-        "${_fragment.asyncModifier} to $asyncModifier.");
-  }
-
-  @override
-  int get memberNameOffset => _fragment.nameOffset;
-
-  @override
-  int get memberNameLength => _fragment.name.length;
-
-  @override
-  DartType get returnTypeContext {
-    final bool isReturnTypeUndeclared =
-        _fragment.returnType is OmittedTypeBuilder &&
-            // Coverage-ignore(suite): Not run.
-            function.returnType is DynamicType;
-    return isReturnTypeUndeclared ? const UnknownType() : function.returnType;
-  }
-
-  @override
-  TypeBuilder get returnType => _fragment.returnType;
-
-  @override
-  void registerFunctionBody(Statement body) {
-    function.body = body..parent = function;
-  }
-
-  @override
-  void registerSuperCall() {
-    // TODO(johnniwinther): This should be set on the member built from this
-    // fragment and copied to the origin if necessary.
-    _fragment.builder.writeTarget!.transformerFlags |=
-        TransformerFlag.superCalls;
-  }
-
-  @override
-  List<FormalParameterBuilder>? get formals => _fragment._encoding.formals;
-
-  @override
-  VariableDeclaration getFormalParameter(int index) =>
-      _fragment._encoding.getFormalParameter(index);
-
-  @override
-  VariableDeclaration? getTearOffParameter(int index) => null;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  AugmentSuperTarget? get augmentSuperTarget {
-    if (_fragment.builder.isAugmentation) {
-      return _fragment.builder.augmentSuperTarget;
-    }
-    return null;
-  }
+  VariableDeclaration? get thisVariable => _fragment.declaration.thisVariable;
 }
diff --git a/pkg/front_end/lib/src/fragment/setter/body_builder_context.dart b/pkg/front_end/lib/src/fragment/setter/body_builder_context.dart
new file mode 100644
index 0000000..f8953db
--- /dev/null
+++ b/pkg/front_end/lib/src/fragment/setter/body_builder_context.dart
@@ -0,0 +1,104 @@
+// Copyright (c) 2025, 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/transformations/flags.dart';
+
+import '../../base/local_scope.dart';
+import '../../builder/declaration_builders.dart';
+import '../../builder/formal_parameter_builder.dart';
+import '../../builder/type_builder.dart';
+import '../../kernel/body_builder_context.dart';
+import '../../source/source_library_builder.dart';
+import '../../source/source_member_builder.dart';
+import '../../source/source_property_builder.dart';
+import '../../type_inference/type_schema.dart';
+import 'declaration.dart';
+
+class SetterBodyBuilderContext extends BodyBuilderContext {
+  final SourcePropertyBuilder _builder;
+  final SetterDeclaration _declaration;
+
+  SetterBodyBuilderContext(
+      this._builder,
+      this._declaration,
+      SourceLibraryBuilder libraryBuilder,
+      DeclarationBuilder? declarationBuilder,
+      {required bool isDeclarationInstanceMember})
+      : super(libraryBuilder, declarationBuilder,
+            isDeclarationInstanceMember: isDeclarationInstanceMember);
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  AugmentSuperTarget? get augmentSuperTarget {
+    if (_builder.isAugmentation) {
+      return _builder.augmentSuperTarget;
+    }
+    return null;
+  }
+
+  @override
+  List<FormalParameterBuilder>? get formals => _declaration.formals;
+
+  @override
+  FunctionNode get function => _declaration.function;
+
+  @override
+  bool get isExternalFunction => _declaration.isExternal;
+
+  @override
+  bool get isSetter => true;
+
+  @override
+  int get memberNameLength => _declaration.name.length;
+
+  @override
+  int get memberNameOffset => _declaration.nameOffset;
+
+  @override
+  TypeBuilder get returnType => _declaration.returnType;
+
+  @override
+  DartType get returnTypeContext {
+    final bool isReturnTypeUndeclared =
+        _declaration.returnType is OmittedTypeBuilder &&
+            // Coverage-ignore(suite): Not run.
+            function.returnType is DynamicType;
+    return isReturnTypeUndeclared ? const UnknownType() : function.returnType;
+  }
+
+  @override
+  LocalScope computeFormalParameterInitializerScope(LocalScope parent) {
+    /// Initializer formals or super parameters cannot occur in getters so
+    /// we don't need to create a new scope.
+    return parent;
+  }
+
+  @override
+  VariableDeclaration getFormalParameter(int index) =>
+      _declaration.getFormalParameter(index);
+
+  @override
+  VariableDeclaration? getTearOffParameter(int index) => null;
+
+  @override
+  void registerFunctionBody(Statement body) {
+    function.body = body..parent = function;
+  }
+
+  @override
+  void registerSuperCall() {
+    // TODO(johnniwinther): This should be set on the member built from this
+    // fragment and copied to the origin if necessary.
+    _builder.writeTarget!.transformerFlags |= TransformerFlag.superCalls;
+  }
+
+  @override
+  void setAsyncModifier(AsyncMarker asyncModifier) {
+    assert(
+        asyncModifier == _declaration.asyncModifier,
+        "Unexpected change in async modifier on $_declaration from "
+        "${_declaration.asyncModifier} to $asyncModifier.");
+  }
+}
diff --git a/pkg/front_end/lib/src/fragment/setter/declaration.dart b/pkg/front_end/lib/src/fragment/setter/declaration.dart
new file mode 100644
index 0000000..74fcf57
--- /dev/null
+++ b/pkg/front_end/lib/src/fragment/setter/declaration.dart
@@ -0,0 +1,263 @@
+// Copyright (c) 2025, 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/class_hierarchy.dart';
+import 'package:kernel/type_environment.dart';
+
+import '../../base/local_scope.dart';
+import '../../base/messages.dart';
+import '../../base/scope.dart';
+import '../../builder/declaration_builders.dart';
+import '../../builder/formal_parameter_builder.dart';
+import '../../builder/metadata_builder.dart';
+import '../../builder/type_builder.dart';
+import '../../kernel/body_builder_context.dart';
+import '../../kernel/hierarchy/class_member.dart';
+import '../../kernel/hierarchy/members_builder.dart';
+import '../../kernel/type_algorithms.dart';
+import '../../source/name_scheme.dart';
+import '../../source/source_class_builder.dart';
+import '../../source/source_library_builder.dart';
+import '../../source/source_loader.dart';
+import '../../source/source_member_builder.dart';
+import '../../source/source_property_builder.dart';
+import '../fragment.dart';
+import 'body_builder_context.dart';
+import 'encoding.dart';
+
+abstract class SetterDeclaration {
+  AsyncMarker get asyncModifier;
+
+  Uri get fileUri;
+
+  List<FormalParameterBuilder>? get formals;
+
+  FunctionNode get function;
+
+  bool get isAbstract;
+
+  bool get isExternal;
+
+  List<MetadataBuilder>? get metadata;
+
+  String get name;
+
+  int get nameOffset;
+
+  TypeBuilder get returnType;
+
+  List<TypeParameter>? get thisTypeParameters;
+
+  VariableDeclaration? get thisVariable;
+
+  List<NominalParameterBuilder>? get typeParametersForTesting;
+
+  Procedure get writeTarget;
+
+  void becomeNative(SourceLoader loader);
+
+  void buildOutlineExpressions(
+      {required ClassHierarchy classHierarchy,
+      required SourceLibraryBuilder libraryBuilder,
+      required DeclarationBuilder? declarationBuilder,
+      required SourcePropertyBuilder propertyBuilder,
+      required Annotatable annotatable,
+      required bool isClassInstanceMember,
+      required bool createFileUriExpression});
+
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
+      {required List<TypeParameter>? classTypeParameters});
+
+  void checkTypes(
+      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
+      {required bool isAbstract, required bool isExternal});
+
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment);
+
+  int computeDefaultTypes(ComputeDefaultTypeContext context);
+
+  BodyBuilderContext createBodyBuilderContext(
+      SourcePropertyBuilder propertyBuilder);
+
+  void createEncoding(
+      ProblemReporting problemReporting,
+      SourcePropertyBuilder builder,
+      PropertyEncodingStrategy encodingStrategy,
+      List<NominalParameterBuilder> unboundNominalParameters);
+
+  LocalScope createFormalParameterScope(LookupScope typeParameterScope);
+
+  void ensureTypes(
+      {required SourceLibraryBuilder libraryBuilder,
+      required DeclarationBuilder? declarationBuilder,
+      required ClassMembersBuilder membersBuilder,
+      required Set<ClassMember>? setterOverrideDependencies});
+
+  Iterable<Reference> getExportedMemberReferences(SetterReference references);
+
+  VariableDeclaration getFormalParameter(int index);
+}
+
+class SetterDeclarationImpl implements SetterDeclaration {
+  final SetterFragment _fragment;
+  late final SetterEncoding _encoding;
+
+  SetterDeclarationImpl(this._fragment) {
+    _fragment.declaration = this;
+  }
+
+  @override
+  AsyncMarker get asyncModifier => _fragment.asyncModifier;
+
+  @override
+  Uri get fileUri => _fragment.fileUri;
+
+  @override
+  List<FormalParameterBuilder>? get formals => _encoding.formals;
+
+  @override
+  FunctionNode get function => _encoding.function;
+
+  @override
+  bool get isAbstract => _fragment.modifiers.isAbstract;
+
+  @override
+  bool get isExternal => _fragment.modifiers.isExternal;
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  List<MetadataBuilder>? get metadata => _fragment.metadata;
+
+  @override
+  String get name => _fragment.name;
+
+  @override
+  int get nameOffset => _fragment.nameOffset;
+
+  @override
+  TypeBuilder get returnType => _fragment.returnType;
+
+  @override
+  List<TypeParameter>? get thisTypeParameters => _encoding.thisTypeParameters;
+
+  @override
+  VariableDeclaration? get thisVariable => _encoding.thisVariable;
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  List<NominalParameterBuilder>? get typeParametersForTesting =>
+      _encoding.clonedAndDeclaredTypeParameters;
+
+  @override
+  Procedure get writeTarget => _encoding.writeTarget;
+
+  @override
+  void becomeNative(SourceLoader loader) {
+    _encoding.becomeNative(loader);
+  }
+
+  @override
+  void buildOutlineExpressions(
+      {required ClassHierarchy classHierarchy,
+      required SourceLibraryBuilder libraryBuilder,
+      required DeclarationBuilder? declarationBuilder,
+      required SourcePropertyBuilder propertyBuilder,
+      required Annotatable annotatable,
+      required bool isClassInstanceMember,
+      required bool createFileUriExpression}) {
+    _encoding.buildOutlineExpressions(
+        classHierarchy,
+        libraryBuilder,
+        declarationBuilder,
+        createBodyBuilderContext(propertyBuilder),
+        annotatable,
+        isClassInstanceMember: isClassInstanceMember,
+        createFileUriExpression: createFileUriExpression);
+  }
+
+  @override
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
+      {required List<TypeParameter>? classTypeParameters}) {
+    _encoding.buildOutlineNode(libraryBuilder, nameScheme, f, references,
+        isAbstractOrExternal:
+            _fragment.modifiers.isAbstract || _fragment.modifiers.isExternal,
+        classTypeParameters: classTypeParameters);
+  }
+
+  @override
+  void checkTypes(
+      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
+      {required bool isAbstract, required bool isExternal}) {
+    _encoding.checkTypes(libraryBuilder, typeEnvironment,
+        isAbstract: isAbstract, isExternal: isExternal);
+  }
+
+  @override
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
+    _encoding.checkVariance(sourceClassBuilder, typeEnvironment);
+  }
+
+  @override
+  int computeDefaultTypes(ComputeDefaultTypeContext context) {
+    return _encoding.computeDefaultTypes(context);
+  }
+
+  @override
+  BodyBuilderContext createBodyBuilderContext(
+      SourcePropertyBuilder propertyBuilder) {
+    return new SetterBodyBuilderContext(propertyBuilder, this,
+        propertyBuilder.libraryBuilder, propertyBuilder.declarationBuilder,
+        isDeclarationInstanceMember:
+            propertyBuilder.isDeclarationInstanceMember);
+  }
+
+  @override
+  void createEncoding(
+      ProblemReporting problemReporting,
+      SourcePropertyBuilder builder,
+      PropertyEncodingStrategy encodingStrategy,
+      List<NominalParameterBuilder> unboundNominalParameters) {
+    _encoding = encodingStrategy.createSetterEncoding(
+        builder, _fragment, unboundNominalParameters);
+    _fragment.typeParameterNameSpace.addTypeParameters(
+        problemReporting, _encoding.clonedAndDeclaredTypeParameters,
+        ownerName: _fragment.name, allowNameConflict: true);
+  }
+
+  @override
+  LocalScope createFormalParameterScope(LookupScope typeParameterScope) {
+    return _encoding.createFormalParameterScope(typeParameterScope);
+  }
+
+  @override
+  void ensureTypes(
+      {required SourceLibraryBuilder libraryBuilder,
+      required DeclarationBuilder? declarationBuilder,
+      required ClassMembersBuilder membersBuilder,
+      required Set<ClassMember>? setterOverrideDependencies}) {
+    if (setterOverrideDependencies != null) {
+      membersBuilder.inferSetterType(declarationBuilder as SourceClassBuilder,
+          _fragment.declaredFormals, setterOverrideDependencies,
+          name: _fragment.name,
+          fileUri: _fragment.fileUri,
+          nameOffset: _fragment.nameOffset,
+          nameLength: _fragment.name.length);
+    }
+    _encoding.ensureTypes(libraryBuilder, membersBuilder.hierarchyBuilder);
+  }
+
+  @override
+  Iterable<Reference> getExportedMemberReferences(SetterReference references) =>
+      [references.setterReference];
+
+  @override
+  VariableDeclaration getFormalParameter(int index) {
+    return _encoding.getFormalParameter(index);
+  }
+}
diff --git a/pkg/front_end/lib/src/fragment/setter/encoding.dart b/pkg/front_end/lib/src/fragment/setter/encoding.dart
new file mode 100644
index 0000000..6abce30
--- /dev/null
+++ b/pkg/front_end/lib/src/fragment/setter/encoding.dart
@@ -0,0 +1,653 @@
+// Copyright (c) 2025, 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/class_hierarchy.dart';
+import 'package:kernel/type_environment.dart';
+
+import '../../base/local_scope.dart';
+import '../../base/scope.dart';
+import '../../builder/builder.dart';
+import '../../builder/declaration_builders.dart';
+import '../../builder/formal_parameter_builder.dart';
+import '../../builder/omitted_type_builder.dart';
+import '../../builder/type_builder.dart';
+import '../../kernel/body_builder_context.dart';
+import '../../kernel/internal_ast.dart';
+import '../../kernel/type_algorithms.dart';
+import '../../source/name_scheme.dart';
+import '../../source/source_class_builder.dart';
+import '../../source/source_function_builder.dart';
+import '../../source/source_library_builder.dart';
+import '../../source/source_loader.dart';
+import '../../source/source_member_builder.dart';
+import '../../source/source_property_builder.dart';
+import '../fragment.dart';
+
+class ExtensionInstanceSetterEncoding extends SetterEncoding
+    with _ExtensionInstanceSetterEncodingMixin {
+  @override
+  final SetterFragment _fragment;
+
+  @override
+  final List<NominalParameterBuilder>? _clonedDeclarationTypeParameters;
+
+  @override
+  final FormalParameterBuilder _thisFormal;
+
+  ExtensionInstanceSetterEncoding(
+      this._fragment, this._clonedDeclarationTypeParameters, this._thisFormal);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionSetter;
+
+  @override
+  bool get _isExtensionMember => true;
+
+  @override
+  bool get _isExtensionTypeMember => false;
+}
+
+class ExtensionStaticSetterEncoding extends SetterEncoding
+    with _DirectSetterEncodingMixin {
+  @override
+  final SetterFragment _fragment;
+
+  ExtensionStaticSetterEncoding(this._fragment);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionSetter;
+
+  @override
+  bool get _isExtensionMember => true;
+
+  @override
+  bool get _isExtensionTypeMember => false;
+}
+
+class ExtensionTypeInstanceSetterEncoding extends SetterEncoding
+    with _ExtensionInstanceSetterEncodingMixin {
+  @override
+  final SetterFragment _fragment;
+
+  @override
+  final List<NominalParameterBuilder>? _clonedDeclarationTypeParameters;
+
+  @override
+  final FormalParameterBuilder _thisFormal;
+
+  ExtensionTypeInstanceSetterEncoding(
+      this._fragment, this._clonedDeclarationTypeParameters, this._thisFormal);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionTypeSetter;
+
+  @override
+  bool get _isExtensionMember => false;
+
+  @override
+  bool get _isExtensionTypeMember => true;
+}
+
+class ExtensionTypeStaticSetterEncoding extends SetterEncoding
+    with _DirectSetterEncodingMixin {
+  @override
+  final SetterFragment _fragment;
+
+  ExtensionTypeStaticSetterEncoding(this._fragment);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.ExtensionTypeSetter;
+
+  @override
+  bool get _isExtensionMember => false;
+
+  @override
+  bool get _isExtensionTypeMember => true;
+}
+
+class RegularSetterEncoding extends SetterEncoding
+    with _DirectSetterEncodingMixin {
+  @override
+  final SetterFragment _fragment;
+
+  RegularSetterEncoding(this._fragment);
+
+  @override
+  BuiltMemberKind get _builtMemberKind => BuiltMemberKind.Method;
+
+  @override
+  bool get _isExtensionMember => false;
+
+  @override
+  bool get _isExtensionTypeMember => false;
+}
+
+sealed class SetterEncoding {
+  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters;
+  List<FormalParameterBuilder>? get formals;
+  FunctionNode get function;
+
+  List<TypeParameter>? get thisTypeParameters;
+
+  VariableDeclaration? get thisVariable;
+
+  Procedure get writeTarget;
+
+  void becomeNative(SourceLoader loader);
+
+  void buildOutlineExpressions(
+      ClassHierarchy classHierarchy,
+      SourceLibraryBuilder libraryBuilder,
+      DeclarationBuilder? declarationBuilder,
+      BodyBuilderContext bodyBuilderContext,
+      Annotatable annotatable,
+      {required bool isClassInstanceMember,
+      required bool createFileUriExpression});
+
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
+      {required bool isAbstractOrExternal,
+      required List<TypeParameter>? classTypeParameters});
+
+  void checkTypes(
+      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
+      {required bool isAbstract, required bool isExternal});
+
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment);
+
+  int computeDefaultTypes(ComputeDefaultTypeContext context);
+
+  LocalScope createFormalParameterScope(LookupScope typeParameterScope);
+
+  void ensureTypes(
+      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy);
+
+  VariableDeclaration getFormalParameter(int index);
+}
+
+mixin _DirectSetterEncodingMixin implements SetterEncoding {
+  Procedure? _procedure;
+
+  @override
+  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
+      _fragment
+          .declaredTypeParameters
+          // Coverage-ignore(suite): Not run.
+          ?.builders;
+
+  @override
+  List<FormalParameterBuilder>? get formals => _fragment.declaredFormals;
+
+  @override
+  FunctionNode get function => _procedure!.function;
+
+  @override
+  List<TypeParameter>? get thisTypeParameters => null;
+
+  @override
+  VariableDeclaration? get thisVariable => null;
+
+  @override
+  Procedure get writeTarget => _procedure!;
+
+  BuiltMemberKind get _builtMemberKind;
+
+  SetterFragment get _fragment;
+
+  bool get _isExtensionMember;
+
+  bool get _isExtensionTypeMember;
+
+  @override
+  void becomeNative(SourceLoader loader) {
+    loader.addNativeAnnotation(_procedure!, _fragment.nativeMethodName!);
+  }
+
+  @override
+  void buildOutlineExpressions(
+      ClassHierarchy classHierarchy,
+      SourceLibraryBuilder libraryBuilder,
+      DeclarationBuilder? declarationBuilder,
+      BodyBuilderContext bodyBuilderContext,
+      Annotatable annotatable,
+      {required bool isClassInstanceMember,
+      required bool createFileUriExpression}) {
+    buildMetadataForOutlineExpressions(libraryBuilder, _fragment.enclosingScope,
+        bodyBuilderContext, annotatable, _fragment.metadata,
+        fileUri: _fragment.fileUri,
+        createFileUriExpression: createFileUriExpression);
+
+    buildTypeParametersForOutlineExpressions(
+        classHierarchy,
+        libraryBuilder,
+        bodyBuilderContext,
+        _fragment.typeParameterScope,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
+    buildFormalsForOutlineExpressions(
+        libraryBuilder, declarationBuilder, _fragment.declaredFormals,
+        scope: _fragment.typeParameterScope,
+        isClassInstanceMember: isClassInstanceMember);
+  }
+
+  @override
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
+      {required bool isAbstractOrExternal,
+      List<TypeParameter>? classTypeParameters}) {
+    FunctionNode function = new FunctionNode(
+        isAbstractOrExternal ? null : new EmptyStatement(),
+        asyncMarker: _fragment.asyncModifier)
+      ..fileOffset = _fragment.formalsOffset
+      ..fileEndOffset = _fragment.endOffset;
+    buildTypeParametersAndFormals(
+        libraryBuilder,
+        function,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        _fragment.declaredFormals,
+        classTypeParameters: classTypeParameters,
+        supportsTypeParameters: true);
+    if (_fragment.returnType is! InferableTypeBuilder) {
+      function.returnType =
+          _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
+    }
+    if (_fragment.declaredFormals?.length != 1 ||
+        _fragment.declaredFormals![0].isOptionalPositional) {
+      // 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");
+      function.positionalParameters.clear();
+      function.positionalParameters.add(parameter);
+      parameter.parent = function;
+      function.namedParameters.clear();
+      function.requiredParameterCount = 1;
+    }
+    MemberName memberName =
+        nameScheme.getProcedureMemberName(ProcedureKind.Setter, _fragment.name);
+    Procedure procedure = _procedure = new Procedure(
+        memberName.name, ProcedureKind.Setter, function,
+        reference: references.setterReference, fileUri: _fragment.fileUri)
+      ..fileStartOffset = _fragment.startOffset
+      ..fileOffset = _fragment.nameOffset
+      ..fileEndOffset = _fragment.endOffset
+      ..isAbstract = _fragment.modifiers.isAbstract
+      ..isExternal = _fragment.modifiers.isExternal
+      ..isConst = _fragment.modifiers.isConst
+      ..isStatic = _fragment.modifiers.isStatic
+      ..isExtensionMember = _isExtensionMember
+      ..isExtensionTypeMember = _isExtensionTypeMember;
+    memberName.attachMember(procedure);
+
+    f(kind: _builtMemberKind, member: procedure);
+  }
+
+  @override
+  void checkTypes(
+      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
+      {required bool isAbstract, required bool isExternal}) {
+    List<TypeParameterBuilder>? typeParameters = _fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders;
+    // Coverage-ignore(suite): Not run.
+    if (typeParameters != null && typeParameters.isNotEmpty) {
+      libraryBuilder.checkTypeParameterDependencies(typeParameters);
+    }
+    libraryBuilder.checkInitializersInFormals(
+        _fragment.declaredFormals, typeEnvironment,
+        isAbstract: isAbstract, isExternal: isExternal);
+  }
+
+  @override
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
+    sourceClassBuilder.checkVarianceInTypeParameters(
+        typeEnvironment,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
+    sourceClassBuilder.checkVarianceInFormals(
+        typeEnvironment, _fragment.declaredFormals);
+    sourceClassBuilder.checkVarianceInReturnType(
+        typeEnvironment, function.returnType,
+        fileOffset: _fragment.nameOffset, fileUri: _fragment.fileUri);
+  }
+
+  @override
+  int computeDefaultTypes(ComputeDefaultTypeContext context) {
+    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders);
+    context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
+    if (_fragment.returnType is! OmittedTypeBuilder) {
+      hasErrors |=
+          context.reportInboundReferenceIssuesForType(_fragment.returnType);
+      context.recursivelyReportGenericFunctionTypesAsBoundsForType(
+          _fragment.returnType);
+    }
+    return context.computeDefaultTypesForVariables(
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        inErrorRecovery: hasErrors);
+  }
+
+  @override
+  LocalScope createFormalParameterScope(LookupScope parent) {
+    Map<String, Builder> local = <String, Builder>{};
+    List<FormalParameterBuilder>? formals = _fragment.declaredFormals;
+    if (formals != null) {
+      for (FormalParameterBuilder formal in formals) {
+        if (formal.isWildcard) {
+          continue;
+        }
+        local[formal.name] = formal;
+      }
+    }
+    return new FormalParameterScope(local: local, parent: parent);
+  }
+
+  @override
+  void ensureTypes(
+      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy) {
+    _fragment.returnType
+        .build(libraryBuilder, TypeUse.returnType, hierarchy: hierarchy);
+    List<FormalParameterBuilder>? declaredFormals = _fragment.declaredFormals;
+    if (declaredFormals != null) {
+      for (FormalParameterBuilder formal in declaredFormals) {
+        formal.type
+            .build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
+      }
+    }
+  }
+
+  @override
+  VariableDeclaration getFormalParameter(int index) =>
+      _fragment.declaredFormals![index].variable!;
+}
+
+mixin _ExtensionInstanceSetterEncodingMixin implements SetterEncoding {
+  Procedure? _procedure;
+
+  @override
+  List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
+      _clonedDeclarationTypeParameters != null ||
+              _fragment.declaredTypeParameters != null
+          ? [
+              ...?_clonedDeclarationTypeParameters,
+              ...?_fragment
+                  .declaredTypeParameters
+                  // Coverage-ignore(suite): Not run.
+                  ?.builders
+            ]
+          : null;
+
+  @override
+  List<FormalParameterBuilder>? get formals =>
+      [_thisFormal, ...?_fragment.declaredFormals];
+
+  @override
+  FunctionNode get function => _procedure!.function;
+
+  @override
+  List<TypeParameter>? get thisTypeParameters =>
+      _clonedDeclarationTypeParameters != null ? function.typeParameters : null;
+
+  @override
+  VariableDeclaration? get thisVariable => _thisFormal.variable!;
+
+  @override
+  Procedure get writeTarget => _procedure!;
+
+  BuiltMemberKind get _builtMemberKind;
+
+  List<NominalParameterBuilder>? get _clonedDeclarationTypeParameters;
+
+  SetterFragment get _fragment;
+
+  bool get _isExtensionMember;
+
+  bool get _isExtensionTypeMember;
+
+  FormalParameterBuilder get _thisFormal;
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  void becomeNative(SourceLoader loader) {
+    loader.addNativeAnnotation(_procedure!, _fragment.nativeMethodName!);
+  }
+
+  @override
+  void buildOutlineExpressions(
+      ClassHierarchy classHierarchy,
+      SourceLibraryBuilder libraryBuilder,
+      DeclarationBuilder? declarationBuilder,
+      BodyBuilderContext bodyBuilderContext,
+      Annotatable annotatable,
+      {required bool isClassInstanceMember,
+      required bool createFileUriExpression}) {
+    buildMetadataForOutlineExpressions(libraryBuilder, _fragment.enclosingScope,
+        bodyBuilderContext, annotatable, _fragment.metadata,
+        fileUri: _fragment.fileUri,
+        createFileUriExpression: createFileUriExpression);
+
+    buildTypeParametersForOutlineExpressions(
+        classHierarchy,
+        libraryBuilder,
+        bodyBuilderContext,
+        _fragment.typeParameterScope,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
+    buildFormalsForOutlineExpressions(
+        libraryBuilder, declarationBuilder, _fragment.declaredFormals,
+        scope: _fragment.typeParameterScope,
+        isClassInstanceMember: isClassInstanceMember);
+
+    buildTypeParametersForOutlineExpressions(
+        classHierarchy,
+        libraryBuilder,
+        bodyBuilderContext,
+        _fragment.typeParameterScope,
+        _clonedDeclarationTypeParameters);
+    buildFormalForOutlineExpressions(
+        libraryBuilder, declarationBuilder, _thisFormal,
+        scope: _fragment.typeParameterScope,
+        isClassInstanceMember: isClassInstanceMember);
+  }
+
+  @override
+  void buildOutlineNode(SourceLibraryBuilder libraryBuilder,
+      NameScheme nameScheme, BuildNodesCallback f, SetterReference references,
+      {required bool isAbstractOrExternal,
+      required List<TypeParameter>? classTypeParameters}) {
+    List<TypeParameter>? typeParameters;
+    if (_clonedDeclarationTypeParameters != null) {
+      typeParameters = [];
+      // TODO(johnniwinther): Ambivalent analyzer. `!` seems to be both required
+      // and unnecessary.
+      // ignore: unnecessary_non_null_assertion
+      for (NominalParameterBuilder t in _clonedDeclarationTypeParameters!) {
+        typeParameters.add(t.parameter);
+      }
+    }
+    FunctionNode function = new FunctionNode(
+        isAbstractOrExternal ? null : new EmptyStatement(),
+        typeParameters: typeParameters,
+        positionalParameters: [_thisFormal.build(libraryBuilder)],
+        asyncMarker: _fragment.asyncModifier)
+      ..fileOffset = _fragment.formalsOffset
+      ..fileEndOffset = _fragment.endOffset;
+    buildTypeParametersAndFormals(
+        libraryBuilder,
+        function,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        _fragment.declaredFormals,
+        classTypeParameters: classTypeParameters,
+        supportsTypeParameters: true);
+    // TODO(johnniwinther): We should have a consistent normalization strategy.
+    // We ensure that setters have 1 parameter, but for getters we include all
+    // declared parameters.
+    if ((_fragment.declaredFormals?.length != 1 ||
+        _fragment.declaredFormals![0].isOptionalPositional)) {
+      // Replace illegal parameters by single dummy parameter (after #this).
+      // Do this after building the parameters, since the diet listener
+      // assumes that parameters are built, even if illegal in number.
+      VariableDeclaration thisParameter = function.positionalParameters[0];
+      VariableDeclaration parameter = new VariableDeclarationImpl("#synthetic");
+      function.positionalParameters.clear();
+      function.positionalParameters.add(thisParameter);
+      function.positionalParameters.add(parameter);
+      parameter.parent = function;
+      function.namedParameters.clear();
+      function.requiredParameterCount = 2;
+    }
+    if (_fragment.returnType is! InferableTypeBuilder) {
+      function.returnType =
+          _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
+    }
+
+    MemberName memberName =
+        nameScheme.getProcedureMemberName(ProcedureKind.Setter, _fragment.name);
+    Procedure procedure = _procedure = new Procedure(
+        memberName.name, ProcedureKind.Method, function,
+        reference: references.setterReference, fileUri: _fragment.fileUri)
+      ..fileStartOffset = _fragment.startOffset
+      ..fileOffset = _fragment.nameOffset
+      ..fileEndOffset = _fragment.endOffset
+      ..isAbstract = _fragment.modifiers.isAbstract
+      ..isExternal = _fragment.modifiers.isExternal
+      ..isConst = _fragment.modifiers.isConst
+      ..isStatic = true
+      ..isExtensionMember = _isExtensionMember
+      ..isExtensionTypeMember = _isExtensionTypeMember;
+    memberName.attachMember(procedure);
+
+    f(kind: _builtMemberKind, member: procedure);
+  }
+
+  @override
+  void checkTypes(
+      SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
+      {required bool isAbstract, required bool isExternal}) {
+    List<TypeParameterBuilder>? typeParameters = _fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders;
+    // Coverage-ignore(suite): Not run.
+    if (typeParameters != null && typeParameters.isNotEmpty) {
+      libraryBuilder.checkTypeParameterDependencies(typeParameters);
+    }
+    libraryBuilder.checkInitializersInFormals(
+        _fragment.declaredFormals, typeEnvironment,
+        isAbstract: isAbstract, isExternal: isExternal);
+  }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  void checkVariance(
+      SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
+    sourceClassBuilder.checkVarianceInTypeParameters(
+        typeEnvironment, _fragment.declaredTypeParameters?.builders);
+    sourceClassBuilder.checkVarianceInFormals(
+        typeEnvironment, _fragment.declaredFormals);
+    sourceClassBuilder.checkVarianceInReturnType(
+        typeEnvironment, function.returnType,
+        fileOffset: _fragment.nameOffset, fileUri: _fragment.fileUri);
+  }
+
+  @override
+  int computeDefaultTypes(ComputeDefaultTypeContext context) {
+    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders);
+    context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
+    if (_fragment.returnType is! OmittedTypeBuilder) {
+      hasErrors |=
+          context.reportInboundReferenceIssuesForType(_fragment.returnType);
+      context.recursivelyReportGenericFunctionTypesAsBoundsForType(
+          _fragment.returnType);
+    }
+    if (_clonedDeclarationTypeParameters != null &&
+        _fragment.declaredTypeParameters != null) {
+      // Coverage-ignore-block(suite): Not run.
+      // We need to compute all default types together since they might be
+      // interdependent.
+      return context.computeDefaultTypesForVariables([
+        // TODO(johnniwinther): Ambivalent analyzer. `!` seems to be both
+        //  required and unnecessary.
+        // ignore: unnecessary_non_null_assertion
+        ..._clonedDeclarationTypeParameters!,
+        ..._fragment.declaredTypeParameters!.builders
+      ], inErrorRecovery: hasErrors);
+    } else if (_clonedDeclarationTypeParameters != null) {
+      return context.computeDefaultTypesForVariables(
+          _clonedDeclarationTypeParameters,
+          inErrorRecovery: hasErrors);
+    } else {
+      return context.computeDefaultTypesForVariables(
+          _fragment
+              .declaredTypeParameters
+              // Coverage-ignore(suite): Not run.
+              ?.builders,
+          inErrorRecovery: hasErrors);
+    }
+  }
+
+  @override
+  LocalScope createFormalParameterScope(LookupScope parent) {
+    Map<String, Builder> local = <String, Builder>{};
+
+    assert(!_thisFormal.isWildcard);
+    local[_thisFormal.name] = _thisFormal;
+
+    List<FormalParameterBuilder>? formals = _fragment.declaredFormals;
+    if (formals != null) {
+      for (FormalParameterBuilder formal in formals) {
+        if (formal.isWildcard) {
+          continue;
+        }
+        local[formal.name] = formal;
+      }
+    }
+    return new FormalParameterScope(local: local, parent: parent);
+  }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  void ensureTypes(
+      SourceLibraryBuilder libraryBuilder, ClassHierarchyBase hierarchy) {
+    _fragment.returnType
+        .build(libraryBuilder, TypeUse.fieldType, hierarchy: hierarchy);
+    _thisFormal.type
+        .build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
+    List<FormalParameterBuilder>? declaredFormals = _fragment.declaredFormals;
+    if (declaredFormals != null) {
+      for (FormalParameterBuilder formal in declaredFormals) {
+        formal.type
+            .build(libraryBuilder, TypeUse.parameterType, hierarchy: hierarchy);
+      }
+    }
+  }
+
+  @override
+  VariableDeclaration getFormalParameter(int index) =>
+      _fragment.declaredFormals![index].variable!;
+}
diff --git a/pkg/front_end/lib/src/fragment/util.dart b/pkg/front_end/lib/src/fragment/util.dart
index 902c1b6..c7d39fe 100644
--- a/pkg/front_end/lib/src/fragment/util.dart
+++ b/pkg/front_end/lib/src/fragment/util.dart
@@ -45,7 +45,7 @@
       : assert(name != 'new');
 }
 
-void _buildMetadataForOutlineExpressions(
+void buildMetadataForOutlineExpressions(
     SourceLibraryBuilder libraryBuilder,
     LookupScope parentScope,
     BodyBuilderContext bodyBuilderContext,
@@ -58,7 +58,7 @@
       createFileUriExpression: createFileUriExpression);
 }
 
-void _buildTypeParametersForOutlineExpressions(
+void buildTypeParametersForOutlineExpressions(
     ClassHierarchy classHierarchy,
     SourceLibraryBuilder libraryBuilder,
     BodyBuilderContext bodyBuilderContext,
@@ -72,7 +72,7 @@
   }
 }
 
-void _buildFormalsForOutlineExpressions(
+void buildFormalsForOutlineExpressions(
     SourceLibraryBuilder libraryBuilder,
     DeclarationBuilder? declarationBuilder,
     List<FormalParameterBuilder>? formals,
@@ -80,14 +80,14 @@
     required bool isClassInstanceMember}) {
   if (formals != null) {
     for (FormalParameterBuilder formal in formals) {
-      _buildFormalForOutlineExpressions(
+      buildFormalForOutlineExpressions(
           libraryBuilder, declarationBuilder, formal,
           scope: scope, isClassInstanceMember: isClassInstanceMember);
     }
   }
 }
 
-void _buildFormalForOutlineExpressions(SourceLibraryBuilder libraryBuilder,
+void buildFormalForOutlineExpressions(SourceLibraryBuilder libraryBuilder,
     DeclarationBuilder? declarationBuilder, FormalParameterBuilder formal,
     {required LookupScope scope, required bool isClassInstanceMember}) {
   // For const constructors we need to include default parameter values
@@ -321,12 +321,12 @@
     }
   }
 
-  _GetterEncoding createGetterEncoding(
+  GetterEncoding createGetterEncoding(
       SourcePropertyBuilder builder,
       GetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters);
 
-  _SetterEncoding createSetterEncoding(
+  SetterEncoding createSetterEncoding(
       SourcePropertyBuilder builder,
       SetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters);
@@ -336,19 +336,19 @@
   const RegularPropertyEncodingStrategy();
 
   @override
-  _GetterEncoding createGetterEncoding(
+  GetterEncoding createGetterEncoding(
       SourcePropertyBuilder builder,
       GetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
-    return new _RegularGetterEncoding(fragment);
+    return new RegularGetterEncoding(fragment);
   }
 
   @override
-  _SetterEncoding createSetterEncoding(
+  SetterEncoding createSetterEncoding(
       SourcePropertyBuilder builder,
       SetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
-    return new _RegularSetterEncoding(fragment);
+    return new RegularSetterEncoding(fragment);
   }
 }
 
@@ -357,7 +357,7 @@
   const ExtensionInstancePropertyEncodingStrategy();
 
   @override
-  _GetterEncoding createGetterEncoding(
+  GetterEncoding createGetterEncoding(
       SourcePropertyBuilder builder,
       GetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
@@ -371,12 +371,12 @@
         onTypeBuilder: declarationBuilder.onType,
         fileUri: fragment.fileUri,
         fileOffset: fragment.nameOffset);
-    return new _ExtensionInstanceGetterEncoding(fragment,
+    return new ExtensionInstanceGetterEncoding(fragment,
         signature.clonedDeclarationTypeParameters, signature.thisFormal);
   }
 
   @override
-  _SetterEncoding createSetterEncoding(
+  SetterEncoding createSetterEncoding(
       SourcePropertyBuilder builder,
       SetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
@@ -390,7 +390,7 @@
         onTypeBuilder: declarationBuilder.onType,
         fileUri: fragment.fileUri,
         fileOffset: fragment.nameOffset);
-    return new _ExtensionInstanceSetterEncoding(fragment,
+    return new ExtensionInstanceSetterEncoding(fragment,
         signature.clonedDeclarationTypeParameters, signature.thisFormal);
   }
 }
@@ -400,19 +400,19 @@
   const ExtensionStaticPropertyEncodingStrategy();
 
   @override
-  _GetterEncoding createGetterEncoding(
+  GetterEncoding createGetterEncoding(
       SourcePropertyBuilder builder,
       GetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
-    return new _ExtensionStaticGetterEncoding(fragment);
+    return new ExtensionStaticGetterEncoding(fragment);
   }
 
   @override
-  _SetterEncoding createSetterEncoding(
+  SetterEncoding createSetterEncoding(
       SourcePropertyBuilder builder,
       SetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
-    return new _ExtensionStaticSetterEncoding(fragment);
+    return new ExtensionStaticSetterEncoding(fragment);
   }
 }
 
@@ -421,7 +421,7 @@
   const ExtensionTypeInstancePropertyEncodingStrategy();
 
   @override
-  _GetterEncoding createGetterEncoding(
+  GetterEncoding createGetterEncoding(
       SourcePropertyBuilder builder,
       GetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
@@ -435,12 +435,12 @@
             unboundNominalParameters: unboundNominalParameters,
             fileUri: fragment.fileUri,
             fileOffset: fragment.nameOffset);
-    return new _ExtensionTypeInstanceGetterEncoding(fragment,
+    return new ExtensionTypeInstanceGetterEncoding(fragment,
         signature.clonedDeclarationTypeParameters, signature.thisFormal);
   }
 
   @override
-  _SetterEncoding createSetterEncoding(
+  SetterEncoding createSetterEncoding(
       SourcePropertyBuilder builder,
       SetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
@@ -454,7 +454,7 @@
             unboundNominalParameters: unboundNominalParameters,
             fileUri: fragment.fileUri,
             fileOffset: fragment.nameOffset);
-    return new _ExtensionTypeInstanceSetterEncoding(fragment,
+    return new ExtensionTypeInstanceSetterEncoding(fragment,
         signature.clonedDeclarationTypeParameters, signature.thisFormal);
   }
 }
@@ -464,18 +464,18 @@
   const ExtensionTypeStaticPropertyEncodingStrategy();
 
   @override
-  _GetterEncoding createGetterEncoding(
+  GetterEncoding createGetterEncoding(
       SourcePropertyBuilder builder,
       GetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
-    return new _ExtensionTypeStaticGetterEncoding(fragment);
+    return new ExtensionTypeStaticGetterEncoding(fragment);
   }
 
   @override
-  _SetterEncoding createSetterEncoding(
+  SetterEncoding createSetterEncoding(
       SourcePropertyBuilder builder,
       SetterFragment fragment,
       List<NominalParameterBuilder> unboundNominalParameters) {
-    return new _ExtensionTypeStaticSetterEncoding(fragment);
+    return new ExtensionTypeStaticSetterEncoding(fragment);
   }
 }
diff --git a/pkg/front_end/lib/src/source/source_builder_factory.dart b/pkg/front_end/lib/src/source/source_builder_factory.dart
index fbde17f..8b89d19 100644
--- a/pkg/front_end/lib/src/source/source_builder_factory.dart
+++ b/pkg/front_end/lib/src/source/source_builder_factory.dart
@@ -2197,10 +2197,10 @@
       fragment.builder.becomeNative(loader);
     }
     for (GetterFragment fragment in _nativeGetterFragments) {
-      fragment.becomeNative(loader);
+      fragment.declaration.becomeNative(loader);
     }
     for (SetterFragment fragment in _nativeSetterFragments) {
-      fragment.becomeNative(loader);
+      fragment.declaration.becomeNative(loader);
     }
     for (MethodFragment fragment in _nativeMethodFragments) {
       fragment.becomeNative(loader);
diff --git a/pkg/front_end/lib/src/source/source_property_builder.dart b/pkg/front_end/lib/src/source/source_property_builder.dart
index 9ffe851..21bf172 100644
--- a/pkg/front_end/lib/src/source/source_property_builder.dart
+++ b/pkg/front_end/lib/src/source/source_property_builder.dart
@@ -18,6 +18,8 @@
 import '../builder/property_builder.dart';
 import '../builder/type_builder.dart';
 import '../fragment/fragment.dart';
+import '../fragment/getter/declaration.dart';
+import '../fragment/setter/declaration.dart';
 import '../kernel/augmentation_lowering.dart';
 import '../kernel/hierarchy/class_member.dart';
 import '../kernel/hierarchy/members_builder.dart';
@@ -54,8 +56,8 @@
   /// same name must be augmentations.
   // TODO(johnniwinther): Add [_augmentations] field.
   FieldDeclaration? _introductoryField;
-  GetterFragment? _introductoryGetable;
-  SetterFragment? _introductorySetable;
+  GetterDeclaration? _introductoryGetable;
+  SetterDeclaration? _introductorySetable;
 
   Modifiers _modifiers;
 
@@ -87,11 +89,12 @@
       required this.libraryBuilder,
       required this.declarationBuilder,
       required NameScheme nameScheme,
-      required GetterFragment fragment,
+      required GetterDeclaration declaration,
+      required Modifiers modifiers,
       required PropertyReferences references})
       : _nameScheme = nameScheme,
-        _introductoryGetable = fragment,
-        _modifiers = fragment.modifiers,
+        _introductoryGetable = declaration,
+        _modifiers = modifiers,
         _references = references,
         _memberName = nameScheme.getDeclaredName(name);
 
@@ -102,11 +105,12 @@
       required this.libraryBuilder,
       required this.declarationBuilder,
       required NameScheme nameScheme,
-      required SetterFragment fragment,
+      required SetterDeclaration declaration,
+      required Modifiers modifiers,
       required PropertyReferences references})
       : _nameScheme = nameScheme,
-        _introductorySetable = fragment,
-        _modifiers = fragment.modifiers,
+        _introductorySetable = declaration,
+        _modifiers = modifiers,
         _references = references,
         _memberName = nameScheme.getDeclaredName(name);
 
@@ -435,12 +439,20 @@
           ],
           isClassInstanceMember: isClassInstanceMember,
           createFileUriExpression: isAugmented);
-      _introductoryGetable?.buildOutlineExpressions(classHierarchy,
-          libraryBuilder, declarationBuilder, readTarget as Annotatable,
+      _introductoryGetable?.buildOutlineExpressions(
+          classHierarchy: classHierarchy,
+          libraryBuilder: libraryBuilder,
+          declarationBuilder: declarationBuilder,
+          propertyBuilder: this,
+          annotatable: readTarget as Annotatable,
           isClassInstanceMember: isClassInstanceMember,
           createFileUriExpression: isAugmented);
-      _introductorySetable?.buildOutlineExpressions(classHierarchy,
-          libraryBuilder, declarationBuilder, writeTarget as Annotatable,
+      _introductorySetable?.buildOutlineExpressions(
+          classHierarchy: classHierarchy,
+          libraryBuilder: libraryBuilder,
+          declarationBuilder: declarationBuilder,
+          propertyBuilder: this,
+          annotatable: writeTarget as Annotatable,
           isClassInstanceMember: isClassInstanceMember,
           createFileUriExpression: isAugmented);
       List<SourcePropertyBuilder>? getterAugmentations = _getterAugmentations;
@@ -619,8 +631,7 @@
 
   // Coverage-ignore(suite): Not run.
   List<FormalParameterBuilder>? get formalsForTesting =>
-      _introductoryGetable?.formalsForTesting ??
-      _introductorySetable?.formalsForTesting;
+      _introductoryGetable?.formals ?? _introductorySetable?.formals;
 
   // Coverage-ignore(suite): Not run.
   TypeBuilder? get returnTypeForTesting =>
@@ -684,9 +695,15 @@
       _introductoryField?.ensureTypes(_classMembersBuilder!,
           _getterOverrideDependencies, _setterOverrideDependencies);
       _introductoryGetable?.ensureTypes(
-          _classMembersBuilder!, _getterOverrideDependencies);
+          libraryBuilder: libraryBuilder,
+          declarationBuilder: declarationBuilder,
+          membersBuilder: _classMembersBuilder!,
+          getterOverrideDependencies: _getterOverrideDependencies);
       _introductorySetable?.ensureTypes(
-          _classMembersBuilder!, _setterOverrideDependencies);
+          libraryBuilder: libraryBuilder,
+          declarationBuilder: declarationBuilder,
+          membersBuilder: _classMembersBuilder!,
+          setterOverrideDependencies: _setterOverrideDependencies);
       _getterOverrideDependencies = null;
       _setterOverrideDependencies = null;
       _classMembersBuilder = null;
@@ -793,12 +810,12 @@
 
 class _GetterClassMember implements ClassMember {
   final SourcePropertyBuilder _builder;
-  final GetterFragment _fragment;
+  final GetterDeclaration _declaration;
 
-  _GetterClassMember(this._builder, this._fragment);
+  _GetterClassMember(this._builder, this._declaration);
 
   @override
-  int get charOffset => _fragment.nameOffset;
+  int get charOffset => _declaration.nameOffset;
 
   @override
   DeclarationBuilder get declarationBuilder => _builder.declarationBuilder!;
@@ -809,7 +826,7 @@
       throw new UnsupportedError('$runtimeType.declarations');
 
   @override
-  Uri get fileUri => _fragment.fileUri;
+  Uri get fileUri => _declaration.fileUri;
 
   @override
   bool get forSetter => false;
@@ -872,7 +889,7 @@
   // property can have a non-abstract getter and an abstract setter or the
   // reverse. With augmentations, abstract introductory declarations might even
   // be implemented by augmentations.
-  bool get isAbstract => _fragment.modifiers.isAbstract;
+  bool get isAbstract => _declaration.isAbstract;
 
   @override
   bool get isDuplicate => _builder.isDuplicate;
@@ -915,7 +932,7 @@
   bool get isSourceDeclaration => true;
 
   @override
-  bool get isStatic => _fragment.modifiers.isStatic;
+  bool get isStatic => _builder.isStatic;
 
   @override
   bool get isSynthesized => false;
@@ -939,14 +956,14 @@
 
 class _SetterClassMember implements ClassMember {
   final SourcePropertyBuilder _builder;
-  final SetterFragment _fragment;
+  final SetterDeclaration _declaration;
   late final Covariance _covariance =
       new Covariance.fromSetter(_builder.writeTarget as Procedure);
 
-  _SetterClassMember(this._builder, this._fragment);
+  _SetterClassMember(this._builder, this._declaration);
 
   @override
-  int get charOffset => _fragment.nameOffset;
+  int get charOffset => _declaration.nameOffset;
 
   @override
   DeclarationBuilder get declarationBuilder => _builder.declarationBuilder!;
@@ -957,7 +974,7 @@
       throw new UnsupportedError('$runtimeType.declarations');
 
   @override
-  Uri get fileUri => _fragment.fileUri;
+  Uri get fileUri => _declaration.fileUri;
 
   @override
   bool get forSetter => true;
@@ -1020,7 +1037,7 @@
   // property can have a non-abstract getter and an abstract setter or the
   // reverse. With augmentations, abstract introductory declarations might even
   // be implemented by augmentations.
-  bool get isAbstract => _fragment.modifiers.isAbstract;
+  bool get isAbstract => _declaration.isAbstract;
 
   @override
   bool get isDuplicate => _builder.isDuplicate;
@@ -1062,7 +1079,7 @@
   bool get isSourceDeclaration => true;
 
   @override
-  bool get isStatic => _fragment.modifiers.isStatic;
+  bool get isStatic => _builder.isStatic;
 
   @override
   bool get isSynthesized => false;
diff --git a/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart b/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart
index d61c459..5058aac 100644
--- a/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart
+++ b/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 
 import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
+import 'package:front_end/src/fragment/getter/declaration.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/reference_from_index.dart';
 
@@ -22,6 +23,7 @@
 import '../builder/type_builder.dart';
 import '../fragment/constructor/declaration.dart';
 import '../fragment/fragment.dart';
+import '../fragment/setter/declaration.dart';
 import 'builder_factory.dart';
 import 'name_scheme.dart';
 import 'source_class_builder.dart';
@@ -1546,6 +1548,8 @@
         final bool isInstanceMember = containerType != ContainerType.Library &&
             !fragment.modifiers.isStatic;
 
+        Modifiers modifiers = fragment.modifiers;
+
         PropertyEncodingStrategy propertyEncodingStrategy =
             new PropertyEncodingStrategy(declarationBuilder,
                 isInstanceMember: isInstanceMember);
@@ -1568,6 +1572,8 @@
             name, nameScheme, indexedContainer,
             isAugmentation: isAugmentation);
 
+        GetterDeclaration declaration = new GetterDeclarationImpl(fragment);
+
         SourcePropertyBuilder propertyBuilder =
             new SourcePropertyBuilder.forGetter(
                 fileUri: fragment.fileUri,
@@ -1575,10 +1581,12 @@
                 name: name,
                 libraryBuilder: enclosingLibraryBuilder,
                 declarationBuilder: declarationBuilder,
-                fragment: fragment,
+                declaration: declaration,
+                modifiers: modifiers,
                 nameScheme: nameScheme,
                 references: references);
-        fragment.setBuilder(problemReporting, propertyBuilder,
+        fragment.builder = propertyBuilder;
+        declaration.createEncoding(problemReporting, propertyBuilder,
             propertyEncodingStrategy, unboundNominalParameters);
         builders.add(new _AddBuilder(fragment.name, propertyBuilder,
             fragment.fileUri, fragment.nameOffset,
@@ -1590,6 +1598,8 @@
         final bool isInstanceMember = containerType != ContainerType.Library &&
             !fragment.modifiers.isStatic;
 
+        Modifiers modifiers = fragment.modifiers;
+
         PropertyEncodingStrategy propertyEncodingStrategy =
             new PropertyEncodingStrategy(declarationBuilder,
                 isInstanceMember: isInstanceMember);
@@ -1612,6 +1622,8 @@
             name, nameScheme, indexedContainer,
             isAugmentation: isAugmentation);
 
+        SetterDeclaration declaration = new SetterDeclarationImpl(fragment);
+
         SourcePropertyBuilder propertyBuilder =
             new SourcePropertyBuilder.forSetter(
                 fileUri: fragment.fileUri,
@@ -1619,10 +1631,12 @@
                 name: name,
                 libraryBuilder: enclosingLibraryBuilder,
                 declarationBuilder: declarationBuilder,
-                fragment: fragment,
+                declaration: declaration,
+                modifiers: modifiers,
                 nameScheme: nameScheme,
                 references: references);
-        fragment.setBuilder(problemReporting, propertyBuilder,
+        fragment.builder = propertyBuilder;
+        declaration.createEncoding(problemReporting, propertyBuilder,
             propertyEncodingStrategy, unboundNominalParameters);
         builders.add(new _AddBuilder(fragment.name, propertyBuilder,
             fragment.fileUri, fragment.nameOffset,
diff --git a/pkg/front_end/test/coverage_suite_expected.dart b/pkg/front_end/test/coverage_suite_expected.dart
index 823e946..d5bb70f 100644
--- a/pkg/front_end/test/coverage_suite_expected.dart
+++ b/pkg/front_end/test/coverage_suite_expected.dart
@@ -540,7 +540,22 @@
   ),
   // 100.0%.
   "package:front_end/src/fragment/getter.dart": (
-    hitCount: 530,
+    hitCount: 48,
+    missCount: 0,
+  ),
+  // 100.0%.
+  "package:front_end/src/fragment/getter/body_builder_context.dart": (
+    hitCount: 50,
+    missCount: 0,
+  ),
+  // 100.0%.
+  "package:front_end/src/fragment/getter/declaration.dart": (
+    hitCount: 110,
+    missCount: 0,
+  ),
+  // 100.0%.
+  "package:front_end/src/fragment/getter/encoding.dart": (
+    hitCount: 374,
     missCount: 0,
   ),
   // 100.0%.
@@ -565,7 +580,22 @@
   ),
   // 100.0%.
   "package:front_end/src/fragment/setter.dart": (
-    hitCount: 550,
+    hitCount: 48,
+    missCount: 0,
+  ),
+  // 100.0%.
+  "package:front_end/src/fragment/setter/body_builder_context.dart": (
+    hitCount: 48,
+    missCount: 0,
+  ),
+  // 100.0%.
+  "package:front_end/src/fragment/setter/declaration.dart": (
+    hitCount: 107,
+    missCount: 0,
+  ),
+  // 100.0%.
+  "package:front_end/src/fragment/setter/encoding.dart": (
+    hitCount: 399,
     missCount: 0,
   ),
   // 100.0%.
@@ -855,7 +885,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/source_builder_factory.dart": (
-    hitCount: 1191,
+    hitCount: 1193,
     missCount: 0,
   ),
   // 100.0%.
@@ -926,7 +956,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/source_property_builder.dart": (
-    hitCount: 698,
+    hitCount: 696,
     missCount: 0,
   ),
   // 100.0%.
@@ -946,7 +976,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/type_parameter_scope_builder.dart": (
-    hitCount: 1591,
+    hitCount: 1597,
     missCount: 0,
   ),
   // 100.0%.