[cfe] Add ClassMember.memberKind and .getTearOff

This adds the functionality to ClassMember that enables us to
fully compute the ExtensionTypeAccessTarget.

Change-Id: I62dd5e24f664c2edd70c2fe794f66595cc017173
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/332427
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/member_builder.dart b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
index d01f095..de4f4ce 100644
--- a/pkg/front_end/lib/src/fasta/builder/member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/member_builder.dart
@@ -255,6 +255,12 @@
   bool get hasDeclarations => false;
 
   @override
+  bool get forSetter => memberKind == ClassMemberKind.Setter;
+
+  @override
+  bool get isProperty => memberKind != ClassMemberKind.Method;
+
+  @override
   List<ClassMember> get declarations =>
       throw new UnsupportedError("$runtimeType.declarations");
 
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
index 5008045..365d6ac 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_member_builder.dart
@@ -22,7 +22,8 @@
 import '../builder/member_builder.dart';
 
 import '../builder/procedure_builder.dart';
-import '../kernel/hierarchy/class_member.dart' show ClassMember;
+import '../kernel/hierarchy/class_member.dart'
+    show ClassMember, ClassMemberKind;
 import '../kernel/hierarchy/members_builder.dart' show ClassMembersBuilder;
 import '../kernel/member_covariance.dart';
 
@@ -93,12 +94,18 @@
   @override
   List<ClassMember> get localMembers => _localMembers ??= isSetter
       ? const <ClassMember>[]
-      : <ClassMember>[new DillClassMember(this, forSetter: false)];
+      : <ClassMember>[
+          new DillClassMember(
+              this,
+              member is Field || isGetter
+                  ? ClassMemberKind.Getter
+                  : ClassMemberKind.Method)
+        ];
 
   @override
   List<ClassMember> get localSetters =>
       _localSetters ??= isSetter || member is Field && member.hasSetter
-          ? <ClassMember>[new DillClassMember(this, forSetter: true)]
+          ? <ClassMember>[new DillClassMember(this, ClassMemberKind.Setter)]
           : const <ClassMember>[];
 
   @override
@@ -268,9 +275,9 @@
   Covariance? _covariance;
 
   @override
-  final bool forSetter;
+  final ClassMemberKind memberKind;
 
-  DillClassMember(this.memberBuilder, {required this.forSetter});
+  DillClassMember(this.memberBuilder, this.memberKind);
 
   @override
   bool get isSourceDeclaration => false;
@@ -295,12 +302,6 @@
   }
 
   @override
-  bool get isProperty =>
-      memberBuilder.kind == null ||
-      memberBuilder.kind == ProcedureKind.Getter ||
-      memberBuilder.kind == ProcedureKind.Setter;
-
-  @override
   bool get isSynthesized {
     Member member = memberBuilder.member;
     return member is Procedure && member.isSynthetic;
@@ -310,6 +311,12 @@
   Member getMember(ClassMembersBuilder membersBuilder) => memberBuilder.member;
 
   @override
+  Member? getTearOff(ClassMembersBuilder membersBuilder) {
+    Member? readTarget = memberBuilder.readTarget;
+    return readTarget != memberBuilder.invokeTarget ? readTarget : null;
+  }
+
+  @override
   Covariance getCovariance(ClassMembersBuilder membersBuilder) {
     return _covariance ??=
         new Covariance.fromMember(memberBuilder.member, forSetter: forSetter);
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/class_member.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/class_member.dart
index f9eb7e7..40e8326 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/class_member.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/class_member.dart
@@ -22,6 +22,12 @@
 import '../member_covariance.dart';
 import 'members_builder.dart';
 
+enum ClassMemberKind {
+  Method,
+  Getter,
+  Setter,
+}
+
 abstract class ClassMember {
   Name get name;
   bool get isStatic;
@@ -33,6 +39,8 @@
   bool get isConst;
   bool get forSetter;
 
+  ClassMemberKind get memberKind;
+
   /// Returns `true` if this member corresponds to a declaration in the source
   /// code.
   bool get isSourceDeclaration;
@@ -43,6 +51,12 @@
   /// Computes the [Member] node resulting from this class member.
   Member getMember(ClassMembersBuilder membersBuilder);
 
+  /// Computes the tear off [Member] node resulting from this class member, if
+  /// this is different from the [Member] returned from [getMember].
+  ///
+  /// Returns `null` if this class member does not have a tear off.
+  Member? getTearOff(ClassMembersBuilder membersBuilder);
+
   /// Returns the member [Covariance] for this class member.
   Covariance getCovariance(ClassMembersBuilder membersBuilder);
 
@@ -154,13 +168,15 @@
   final Name name;
 
   @override
-  final bool forSetter;
+  final ClassMemberKind memberKind;
+
+  SynthesizedMember(this.name, this.memberKind);
 
   @override
-  final bool isProperty;
+  bool get forSetter => memberKind == ClassMemberKind.Setter;
 
-  SynthesizedMember(this.name,
-      {required this.forSetter, required this.isProperty});
+  @override
+  bool get isProperty => memberKind != ClassMemberKind.Method;
 
   @override
   List<ClassMember> get declarations => throw new UnimplementedError();
@@ -206,6 +222,13 @@
 
   @override
   bool get isExtensionTypeMember => false;
+
+  @override
+  Member? getTearOff(ClassMembersBuilder membersBuilder) {
+    // Ensure member is computed.
+    getMember(membersBuilder);
+    return null;
+  }
 }
 
 /// Class member for a set of interface members.
@@ -316,15 +339,14 @@
       ClassMember? canonicalMember,
       ClassMember? mixedInMember,
       ClassMember? noSuchMethodTarget,
-      required bool isProperty,
-      required bool forSetter,
+      required ClassMemberKind memberKind,
       required bool shouldModifyKernel})
       : this._superClassMember = superClassMember,
         this._canonicalMember = canonicalMember,
         this._mixedInMember = mixedInMember,
         this._noSuchMethodTarget = noSuchMethodTarget,
         this._shouldModifyKernel = shouldModifyKernel,
-        super(name, isProperty: isProperty, forSetter: forSetter);
+        super(name, memberKind);
 
   @override
   bool get hasDeclarations => true;
@@ -540,9 +562,8 @@
   InheritedClassMemberImplementsInterface(this.classBuilder, Name name,
       {required this.inheritedClassMember,
       required this.implementedInterfaceMember,
-      required bool isProperty,
-      required bool forSetter})
-      : super(name, isProperty: isProperty, forSetter: forSetter);
+      required ClassMemberKind memberKind})
+      : super(name, memberKind);
 
   @override
   DeclarationBuilder get declarationBuilder => classBuilder;
@@ -713,11 +734,9 @@
 
   SynthesizedNonExtensionTypeMember(
       this.extensionTypeDeclarationBuilder, Name name, this.declarations,
-      {required bool isProperty,
-      required bool forSetter,
-      required bool shouldModifyKernel})
+      {required ClassMemberKind memberKind, required bool shouldModifyKernel})
       : this._shouldModifyKernel = shouldModifyKernel,
-        super(name, isProperty: isProperty, forSetter: forSetter);
+        super(name, memberKind);
 
   @override
   DeclarationBuilder get declarationBuilder => extensionTypeDeclarationBuilder;
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/extension_type_members.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/extension_type_members.dart
index ff43c6e3..8349926 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/extension_type_members.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/extension_type_members.dart
@@ -972,8 +972,7 @@
             extensionTypeDeclarationBuilder,
             name,
             _implementedNonExtensionTypeMembers,
-            isProperty: _definingMember.isProperty,
-            forSetter: _definingMember.forSetter,
+            memberKind: _definingMember.memberKind,
             shouldModifyKernel: builder.shouldModifyKernel);
         builder._membersBuilder.registerMemberComputation(classMember);
         return nonExtensionTypeMemberMap[name] = classMember;
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart
index 378cecc..6e5322c 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_builder.dart
@@ -171,11 +171,18 @@
   Member? getExtensionTypeMember(
       ExtensionTypeDeclaration extensionTypeDeclaration, Name name,
       {bool setter = false}) {
-    return getNodeFromExtensionTypeDeclaration(extensionTypeDeclaration)
-        .getMember(name, setter)
+    return getExtensionTypeClassMember(extensionTypeDeclaration, name,
+            setter: setter)
         ?.getMember(this);
   }
 
+  ClassMember? getExtensionTypeClassMember(
+      ExtensionTypeDeclaration extensionTypeDeclaration, Name name,
+      {bool setter = false}) {
+    return getNodeFromExtensionTypeDeclaration(extensionTypeDeclaration)
+        .getMember(name, setter);
+  }
+
   @override
   Member? getDispatchTarget(Class cls, Name name, {bool setter = false}) {
     return getNodeFromClass(cls)
diff --git a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
index 2578513..fad8b34 100644
--- a/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/hierarchy/members_node.dart
@@ -2023,8 +2023,7 @@
             canonicalMember: _mixedInMember,
             mixedInMember: _mixedInMember,
             noSuchMethodTarget: noSuchMethodTarget,
-            isProperty: _definingMember.isProperty,
-            forSetter: _definingMember.forSetter,
+            memberKind: _definingMember.memberKind,
             shouldModifyKernel: builder.shouldModifyKernel);
         builder._membersBuilder.registerMemberComputation(interfaceMember);
 
@@ -2058,8 +2057,7 @@
               classBuilder, name,
               inheritedClassMember: _extendedMember,
               implementedInterfaceMember: interfaceMember,
-              forSetter: _definingMember.forSetter,
-              isProperty: _definingMember.isProperty);
+              memberKind: _definingMember.memberKind);
           builder._membersBuilder.registerMemberComputation(classMember);
           if (!classBuilder.isAbstract) {
             overrides.registerInheritedImplements(
@@ -2153,8 +2151,7 @@
             // is the defining member.
             canonicalMember: _mixedInMember,
             mixedInMember: _mixedInMember,
-            isProperty: _definingMember.isProperty,
-            forSetter: _definingMember.forSetter,
+            memberKind: _definingMember.memberKind,
             shouldModifyKernel: builder.shouldModifyKernel);
         builder._membersBuilder.registerMemberComputation(interfaceMember);
 
@@ -2173,8 +2170,7 @@
             classBuilder, name,
             inheritedClassMember: _mixedInMember,
             implementedInterfaceMember: interfaceMember,
-            forSetter: _definingMember.forSetter,
-            isProperty: _definingMember.isProperty);
+            memberKind: _definingMember.memberKind);
         builder._membersBuilder.registerMemberComputation(classMember);
 
         if (!classBuilder.isAbstract) {
@@ -2278,8 +2274,7 @@
               // _because_ it is the defining member.
               canonicalMember: _declaredMember,
               noSuchMethodTarget: noSuchMethodTarget,
-              isProperty: _definingMember.isProperty,
-              forSetter: _definingMember.forSetter,
+              memberKind: _definingMember.memberKind,
               shouldModifyKernel: builder.shouldModifyKernel);
           builder._membersBuilder.registerMemberComputation(interfaceMember);
         }
@@ -2311,8 +2306,7 @@
               classBuilder, name,
               inheritedClassMember: _extendedMember,
               implementedInterfaceMember: interfaceMember,
-              forSetter: _definingMember.forSetter,
-              isProperty: _definingMember.isProperty);
+              memberKind: _definingMember.memberKind);
           builder._membersBuilder.registerMemberComputation(classMember);
 
           if (!classBuilder.isAbstract && noSuchMethodTarget == null) {
@@ -2448,8 +2442,7 @@
               classBuilder, name, interfaceMembers.toList(),
               superClassMember: _extendedMember,
               noSuchMethodTarget: noSuchMethodTarget,
-              isProperty: _definingMember.isProperty,
-              forSetter: _definingMember.forSetter,
+              memberKind: _definingMember.memberKind,
               shouldModifyKernel: builder.shouldModifyKernel);
           builder._membersBuilder.registerMemberComputation(interfaceMember);
         }
@@ -2493,8 +2486,7 @@
               classBuilder, name,
               inheritedClassMember: _extendedMember,
               implementedInterfaceMember: interfaceMember,
-              isProperty: _definingMember.isProperty,
-              forSetter: _definingMember.forSetter);
+              memberKind: _definingMember.memberKind);
           builder._membersBuilder.registerMemberComputation(classMember);
           if (!classBuilder.isAbstract && noSuchMethodTarget == null) {
             ///    class Super {
@@ -2519,8 +2511,7 @@
         interfaceMember = new SynthesizedInterfaceMember(
             classBuilder, name, [_extendedMember],
             superClassMember: _extendedMember,
-            isProperty: _definingMember.isProperty,
-            forSetter: _definingMember.forSetter,
+            memberKind: _definingMember.memberKind,
             shouldModifyKernel: builder.shouldModifyKernel);
         builder._membersBuilder.registerMemberComputation(interfaceMember);
 
@@ -2531,8 +2522,7 @@
             classBuilder, name,
             inheritedClassMember: _extendedMember,
             implementedInterfaceMember: interfaceMember,
-            isProperty: _definingMember.isProperty,
-            forSetter: _definingMember.forSetter);
+            memberKind: _definingMember.memberKind);
         builder._membersBuilder.registerMemberComputation(classMember);
       }
     } else if (_implementedMembers != null) {
@@ -2589,8 +2579,7 @@
           interfaceMember = new SynthesizedInterfaceMember(
               classBuilder, name, interfaceMembers.toList(),
               noSuchMethodTarget: noSuchMethodTarget,
-              isProperty: _definingMember.isProperty,
-              forSetter: _definingMember.forSetter,
+              memberKind: _definingMember.memberKind,
               shouldModifyKernel: builder.shouldModifyKernel);
           builder._membersBuilder.registerMemberComputation(interfaceMember);
         }
diff --git a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
index d83c204..7ca8c3e 100644
--- a/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_field_builder.dart
@@ -782,12 +782,16 @@
 
   @override
   List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) =>
-      <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: false)];
+      <ClassMember>[
+        new SourceFieldMember(fieldBuilder, ClassMemberKind.Getter)
+      ];
 
   @override
   List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) =>
       fieldBuilder.isAssignable
-          ? <ClassMember>[new SourceFieldMember(fieldBuilder, forSetter: true)]
+          ? <ClassMember>[
+              new SourceFieldMember(fieldBuilder, ClassMemberKind.Setter)
+            ]
           : const <ClassMember>[];
 
   @override
@@ -818,9 +822,9 @@
   Covariance? _covariance;
 
   @override
-  final bool forSetter;
+  final ClassMemberKind memberKind;
 
-  SourceFieldMember(this.memberBuilder, {required this.forSetter});
+  SourceFieldMember(this.memberBuilder, this.memberKind);
 
   @override
   void inferType(ClassMembersBuilder membersBuilder) {
@@ -839,6 +843,13 @@
   }
 
   @override
+  Member? getTearOff(ClassMembersBuilder membersBuilder) {
+    // Ensure field type is computed.
+    getMember(membersBuilder);
+    return null;
+  }
+
+  @override
   Covariance getCovariance(ClassMembersBuilder membersBuilder) {
     return _covariance ??= forSetter
         ? new Covariance.fromMember(getMember(membersBuilder),
@@ -850,9 +861,6 @@
   bool get isSourceDeclaration => true;
 
   @override
-  bool get isProperty => true;
-
-  @override
   bool get isSynthesized => memberBuilder.isSynthesized;
 
   @override
@@ -1210,15 +1218,23 @@
   List<ClassMember> getLocalMembers(SourceFieldBuilder fieldBuilder) {
     List<ClassMember> list = <ClassMember>[
       new _SynthesizedFieldClassMember(fieldBuilder, field, field.name,
-          _SynthesizedFieldMemberKind.LateField,
+          _SynthesizedFieldMemberKind.LateField, ClassMemberKind.Getter,
           isInternalImplementation: true),
-      new _SynthesizedFieldClassMember(fieldBuilder, _lateGetter,
-          fieldBuilder.memberName, _SynthesizedFieldMemberKind.LateGetterSetter,
+      new _SynthesizedFieldClassMember(
+          fieldBuilder,
+          _lateGetter,
+          fieldBuilder.memberName,
+          _SynthesizedFieldMemberKind.LateGetterSetter,
+          ClassMemberKind.Getter,
           isInternalImplementation: false)
     ];
     if (_lateIsSetField != null) {
-      list.add(new _SynthesizedFieldClassMember(fieldBuilder, _lateIsSetField!,
-          _lateIsSetField!.name, _SynthesizedFieldMemberKind.LateIsSet,
+      list.add(new _SynthesizedFieldClassMember(
+          fieldBuilder,
+          _lateIsSetField!,
+          _lateIsSetField!.name,
+          _SynthesizedFieldMemberKind.LateIsSet,
+          ClassMemberKind.Getter,
           isInternalImplementation: true));
     }
     return list;
@@ -1228,18 +1244,26 @@
   List<ClassMember> getLocalSetters(SourceFieldBuilder fieldBuilder) {
     List<ClassMember> list = <ClassMember>[
       new _SynthesizedFieldClassMember(fieldBuilder, field, field.name,
-          _SynthesizedFieldMemberKind.LateField,
-          forSetter: true, isInternalImplementation: true),
+          _SynthesizedFieldMemberKind.LateField, ClassMemberKind.Setter,
+          isInternalImplementation: true),
     ];
     if (_lateIsSetField != null) {
-      list.add(new _SynthesizedFieldClassMember(fieldBuilder, _lateIsSetField!,
-          _lateIsSetField!.name, _SynthesizedFieldMemberKind.LateIsSet,
-          forSetter: true, isInternalImplementation: true));
+      list.add(new _SynthesizedFieldClassMember(
+          fieldBuilder,
+          _lateIsSetField!,
+          _lateIsSetField!.name,
+          _SynthesizedFieldMemberKind.LateIsSet,
+          ClassMemberKind.Setter,
+          isInternalImplementation: true));
     }
     if (_lateSetter != null) {
-      list.add(new _SynthesizedFieldClassMember(fieldBuilder, _lateSetter!,
-          fieldBuilder.memberName, _SynthesizedFieldMemberKind.LateGetterSetter,
-          forSetter: true, isInternalImplementation: false));
+      list.add(new _SynthesizedFieldClassMember(
+          fieldBuilder,
+          _lateSetter!,
+          fieldBuilder.memberName,
+          _SynthesizedFieldMemberKind.LateGetterSetter,
+          ClassMemberKind.Setter,
+          isInternalImplementation: false));
     }
     return list;
   }
@@ -1539,14 +1563,14 @@
   Covariance? _covariance;
 
   @override
-  final bool forSetter;
-
-  @override
   final bool isInternalImplementation;
 
+  @override
+  final ClassMemberKind memberKind;
+
   _SynthesizedFieldClassMember(
-      this.fieldBuilder, this._member, this._name, this._kind,
-      {this.forSetter = false, required this.isInternalImplementation});
+      this.fieldBuilder, this._member, this._name, this._kind, this.memberKind,
+      {required this.isInternalImplementation});
 
   @override
   Member getMember(ClassMembersBuilder membersBuilder) {
@@ -1555,6 +1579,13 @@
   }
 
   @override
+  Member? getTearOff(ClassMembersBuilder membersBuilder) {
+    // Ensure field type is computed.
+    getMember(membersBuilder);
+    return null;
+  }
+
+  @override
   Covariance getCovariance(ClassMembersBuilder membersBuilder) {
     return _covariance ??= new Covariance.fromMember(getMember(membersBuilder),
         forSetter: forSetter);
@@ -1574,7 +1605,10 @@
   bool get isSourceDeclaration => true;
 
   @override
-  bool get isProperty => isField || isGetter || isSetter;
+  bool get forSetter => memberKind == ClassMemberKind.Setter;
+
+  @override
+  bool get isProperty => memberKind != ClassMemberKind.Method;
 
   @override
   DeclarationBuilder get declarationBuilder => fieldBuilder.declarationBuilder!;
@@ -1970,7 +2004,7 @@
             _getter,
             fieldBuilder.memberName,
             _SynthesizedFieldMemberKind.AbstractExternalGetterSetter,
-            forSetter: false,
+            ClassMemberKind.Getter,
             isInternalImplementation: false)
       ];
 
@@ -1983,7 +2017,7 @@
                   _setter!,
                   fieldBuilder.memberName,
                   _SynthesizedFieldMemberKind.AbstractExternalGetterSetter,
-                  forSetter: true,
+                  ClassMemberKind.Setter,
                   isInternalImplementation: false)
             ]
           : const <ClassMember>[];
@@ -2117,7 +2151,7 @@
             _getter,
             fieldBuilder.memberName,
             _SynthesizedFieldMemberKind.RepresentationField,
-            forSetter: false,
+            ClassMemberKind.Getter,
             isInternalImplementation: false)
       ];
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
index 1ed1904..2a3d416 100644
--- a/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_procedure_builder.dart
@@ -500,12 +500,17 @@
   @override
   List<ClassMember> get localMembers => _localMembers ??= isSetter
       ? const <ClassMember>[]
-      : <ClassMember>[new SourceProcedureMember(this)];
+      : <ClassMember>[
+          new SourceProcedureMember(
+              this, isGetter ? ClassMemberKind.Getter : ClassMemberKind.Method)
+        ];
 
   @override
   List<ClassMember> get localSetters =>
       _localSetters ??= isSetter && !isConflictingSetter
-          ? <ClassMember>[new SourceProcedureMember(this)]
+          ? <ClassMember>[
+              new SourceProcedureMember(this, ClassMemberKind.Setter)
+            ]
           : const <ClassMember>[];
 
   @override
@@ -670,9 +675,12 @@
   @override
   final SourceProcedureBuilder memberBuilder;
 
+  @override
+  final ClassMemberKind memberKind;
+
   Covariance? _covariance;
 
-  SourceProcedureMember(this.memberBuilder);
+  SourceProcedureMember(this.memberBuilder, this.memberKind);
 
   @override
   bool get isSourceDeclaration => true;
@@ -694,20 +702,20 @@
   }
 
   @override
+  Member? getTearOff(ClassMembersBuilder membersBuilder) {
+    // Ensure function type is computed.
+    getMember(membersBuilder);
+    Member? readTarget = memberBuilder.readTarget;
+    return readTarget != memberBuilder.invokeTarget ? readTarget : null;
+  }
+
+  @override
   Covariance getCovariance(ClassMembersBuilder membersBuilder) {
     return _covariance ??= new Covariance.fromMember(getMember(membersBuilder),
         forSetter: forSetter);
   }
 
   @override
-  bool get forSetter => isSetter;
-
-  @override
-  bool get isProperty =>
-      memberBuilder.kind == ProcedureKind.Getter ||
-      memberBuilder.kind == ProcedureKind.Setter;
-
-  @override
   bool isSameDeclaration(ClassMember other) {
     return other is SourceProcedureMember &&
         memberBuilder == other.memberBuilder;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
index 0e61b0c..89d492b 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor.dart
@@ -41,6 +41,7 @@
         SpreadMapEntry,
         convertToElement;
 import '../kernel/exhaustiveness.dart';
+import '../kernel/hierarchy/class_member.dart';
 import '../kernel/implicit_type_argument.dart' show ImplicitTypeArgument;
 import '../kernel/internal_ast.dart';
 import '../kernel/late_lowering.dart' as late_lowering;
@@ -673,7 +674,7 @@
         case ObjectAccessTargetKind.extensionMember:
         case ObjectAccessTargetKind.extensionTypeMember:
           if (callMember.tearoffTarget != null &&
-              callMember.declarationMethodKind == ProcedureKind.Method) {
+              callMember.declarationMethodKind == ClassMemberKind.Method) {
             operandType = callMember.getGetterType(this);
             operand = new StaticInvocation(
                 callMember.tearoffTarget as Procedure,
@@ -1063,7 +1064,7 @@
         ensureAssignableResult(receiverType, receiverResult).expression;
 
     ObjectAccessTarget target = new ExtensionAccessTarget(receiverType,
-        node.target, null, ProcedureKind.Setter, extensionTypeArguments);
+        node.target, null, ClassMemberKind.Setter, extensionTypeArguments);
 
     DartType valueType = target.getSetterType(this);
 
@@ -1145,7 +1146,7 @@
     ObjectAccessTarget readTarget = node.getter == null
         ? const ObjectAccessTarget.missing()
         : new ExtensionAccessTarget(receiverType, node.getter!, null,
-            ProcedureKind.Getter, extensionTypeArguments);
+            ClassMemberKind.Getter, extensionTypeArguments);
 
     DartType readType = readTarget.getGetterType(this);
 
@@ -1168,7 +1169,7 @@
     ObjectAccessTarget writeTarget = node.setter == null
         ? const ObjectAccessTarget.missing()
         : new ExtensionAccessTarget(receiverType, node.setter!, null,
-            ProcedureKind.Setter, extensionTypeArguments);
+            ClassMemberKind.Setter, extensionTypeArguments);
 
     DartType valueType = writeTarget.getSetterType(this);
 
@@ -5459,7 +5460,7 @@
     }
 
     ObjectAccessTarget target = new ExtensionAccessTarget(receiverType,
-        node.setter, null, ProcedureKind.Operator, extensionTypeArguments);
+        node.setter, null, ClassMemberKind.Method, extensionTypeArguments);
 
     DartType indexType = target.getIndexKeyType(this);
     DartType valueType = target.getIndexSetValueType(this);
@@ -5864,14 +5865,14 @@
 
     ObjectAccessTarget readTarget = node.getter != null
         ? new ExtensionAccessTarget(receiverType, node.getter!, null,
-            ProcedureKind.Operator, extensionTypeArguments)
+            ClassMemberKind.Method, extensionTypeArguments)
         : const ObjectAccessTarget.missing();
 
     DartType readIndexType = readTarget.getIndexKeyType(this);
 
     ObjectAccessTarget writeTarget = node.setter != null
         ? new ExtensionAccessTarget(receiverType, node.setter!, null,
-            ProcedureKind.Operator, extensionTypeArguments)
+            ClassMemberKind.Method, extensionTypeArguments)
         : const ObjectAccessTarget.missing();
 
     DartType writeIndexType = writeTarget.getIndexKeyType(this);
@@ -6178,7 +6179,7 @@
       case ObjectAccessTargetKind.nullableExtensionMember:
       case ObjectAccessTargetKind.extensionTypeMember:
       case ObjectAccessTargetKind.nullableExtensionTypeMember:
-        assert(binaryTarget.declarationMethodKind != ProcedureKind.Setter);
+        assert(binaryTarget.declarationMethodKind != ClassMemberKind.Setter);
         binary = new StaticInvocation(
             binaryTarget.member as Procedure,
             new Arguments(<Expression>[
@@ -6323,7 +6324,7 @@
       case ObjectAccessTargetKind.nullableExtensionMember:
       case ObjectAccessTargetKind.extensionTypeMember:
       case ObjectAccessTargetKind.nullableExtensionTypeMember:
-        assert(unaryTarget.declarationMethodKind != ProcedureKind.Setter);
+        assert(unaryTarget.declarationMethodKind != ClassMemberKind.Setter);
         unary = new StaticInvocation(
             unaryTarget.member as Procedure,
             new Arguments(<Expression>[
@@ -6583,7 +6584,7 @@
       case ObjectAccessTargetKind.nullableExtensionMember:
       case ObjectAccessTargetKind.extensionTypeMember:
       case ObjectAccessTargetKind.nullableExtensionTypeMember:
-        assert(writeTarget.declarationMethodKind != ProcedureKind.Setter);
+        assert(writeTarget.declarationMethodKind != ClassMemberKind.Setter);
         write = new StaticInvocation(
             writeTarget.member as Procedure,
             new Arguments(<Expression>[receiver, index, value],
@@ -7307,7 +7308,7 @@
 
     ObjectAccessTarget readTarget = node.getter != null
         ? new ExtensionAccessTarget(receiverType, node.getter!, null,
-            ProcedureKind.Operator, extensionTypeArguments)
+            ClassMemberKind.Method, extensionTypeArguments)
         : const ObjectAccessTarget.missing();
 
     Expression receiver =
@@ -7368,7 +7369,7 @@
 
     ObjectAccessTarget writeTarget = node.setter != null
         ? new ExtensionAccessTarget(receiverType, node.setter!, null,
-            ProcedureKind.Operator, extensionTypeArguments)
+            ClassMemberKind.Method, extensionTypeArguments)
         : const ObjectAccessTarget.missing();
 
     DartType writeIndexType = writeTarget.getIndexKeyType(this);
diff --git a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
index ef35c35..a7e81b1 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/inference_visitor_base.dart
@@ -35,6 +35,7 @@
 import '../builder/member_builder.dart';
 import '../fasta_codes.dart';
 import '../kernel/constructor_tearoff_lowering.dart';
+import '../kernel/hierarchy/class_member.dart';
 import '../kernel/internal_ast.dart';
 import '../kernel/kernel_helper.dart';
 import '../kernel/type_algorithms.dart' show hasAnyTypeVariables;
@@ -967,11 +968,12 @@
       ExtensionType extensionType, Name name, int fileOffset,
       {required bool isSetter,
       required bool isReceiverTypePotentiallyNullable}) {
-    Member? member = _getExtensionTypeMember(
+    ClassMember? classMember = _getExtensionTypeMember(
         extensionType.extensionTypeDeclaration, name, isSetter);
-    if (member == null) {
+    if (classMember == null) {
       return null;
     }
+    Member? member = classMember.getMember(engine.membersBuilder);
     if (member is Procedure &&
         member.stubKind == ProcedureStubKind.RepresentationField) {
       return new ObjectAccessTarget.extensionTypeRepresentation(
@@ -979,50 +981,18 @@
           isPotentiallyNullable: isReceiverTypePotentiallyNullable);
     }
     if (member.isExtensionTypeMember) {
-      // TODO(johnniwinther): Derive this from the [ClassMember].
-      ExtensionTypeMemberDescriptor? memberDescriptor;
-      ExtensionTypeDeclaration? extensionTypeDeclaration;
-      outer:
-      for (ExtensionTypeDeclaration declaration
-          in member.enclosingLibrary.extensionTypeDeclarations) {
-        for (ExtensionTypeMemberDescriptor descriptor
-            in declaration.memberDescriptors) {
-          if (descriptor.memberReference == member.reference) {
-            extensionTypeDeclaration = declaration;
-            memberDescriptor = descriptor;
-            break outer;
-          }
-        }
-      }
-      assert(extensionTypeDeclaration != null,
-          "No enclosing extension type declaration found for $member.");
-      assert(memberDescriptor != null,
-          "No extension type member descriptor found for $member.");
-      ProcedureKind kind;
-      switch (memberDescriptor!.kind) {
-        case ExtensionTypeMemberKind.Method:
-          kind = ProcedureKind.Method;
-        case ExtensionTypeMemberKind.Operator:
-          kind = ProcedureKind.Operator;
-        case ExtensionTypeMemberKind.Getter:
-          kind = ProcedureKind.Getter;
-        case ExtensionTypeMemberKind.Setter:
-          kind = ProcedureKind.Setter;
-        case ExtensionTypeMemberKind.Constructor:
-        case ExtensionTypeMemberKind.Factory:
-        case ExtensionTypeMemberKind.Field:
-        case ExtensionTypeMemberKind.RedirectingFactory:
-          throw new UnsupportedError("Unexpected extension type member kind: "
-              "${memberDescriptor.kind}.");
-      }
-
+      ExtensionTypeDeclarationBuilder extensionTypeDeclarationBuilder =
+          classMember.declarationBuilder as ExtensionTypeDeclarationBuilder;
+      ExtensionTypeDeclaration extensionTypeDeclaration =
+          extensionTypeDeclarationBuilder.extensionTypeDeclaration;
+      ClassMemberKind kind = classMember.memberKind;
       return new ObjectAccessTarget.extensionTypeMember(
           receiverType,
-          memberDescriptor.memberReference.asMember,
-          memberDescriptor.tearOffReference?.asMember,
+          member,
+          classMember.getTearOff(engine.membersBuilder),
           kind,
           hierarchyBuilder.getTypeArgumentsAsInstanceOf(
-              extensionType, extensionTypeDeclaration!)!,
+              extensionType, extensionTypeDeclaration)!,
           isPotentiallyNullable: isReceiverTypePotentiallyNullable);
     } else {
       return new ObjectAccessTarget.interfaceMember(receiverType, member,
@@ -1117,16 +1087,31 @@
                     receiverType,
                     setter ? thisBuilder.writeTarget! : thisBuilder.readTarget!,
                     thisBuilder.readTarget,
-                    setter ? ProcedureKind.Setter : ProcedureKind.Getter,
+                    setter ? ClassMemberKind.Setter : ClassMemberKind.Getter,
                     inferredTypeArguments,
                     isPotentiallyNullable: isPotentiallyNullableAccess);
               }
             } else {
+              ClassMemberKind classMemberKind;
+              switch (thisBuilder.kind) {
+                case ProcedureKind.Method:
+                case ProcedureKind.Operator:
+                  classMemberKind = ClassMemberKind.Method;
+                case ProcedureKind.Getter:
+                  classMemberKind = ClassMemberKind.Getter;
+                case ProcedureKind.Setter:
+                  classMemberKind = ClassMemberKind.Setter;
+                case ProcedureKind.Factory:
+                case null:
+                  throw new UnsupportedError(
+                      "Unexpected procedure kind ${thisBuilder.kind} on "
+                      "builder $thisBuilder.");
+              }
               target = new ObjectAccessTarget.extensionMember(
                   receiverType,
                   setter ? thisBuilder.writeTarget! : thisBuilder.invokeTarget!,
                   thisBuilder.readTarget,
-                  thisBuilder.kind!,
+                  classMemberKind,
                   inferredTypeArguments,
                   isPotentiallyNullable: isPotentiallyNullableAccess);
             }
@@ -2458,7 +2443,7 @@
     DartType calleeType = target.getGetterType(this);
     FunctionType functionType = target.getFunctionType(this);
 
-    if (target.declarationMethodKind == ProcedureKind.Getter) {
+    if (target.declarationMethodKind == ClassMemberKind.Getter) {
       StaticInvocation staticInvocation = transformExtensionMethodInvocation(
           fileOffset, target, receiver, new Arguments.empty());
       ExpressionInferenceResult result = inferMethodInvocation(
@@ -3828,13 +3813,16 @@
     return TypeInferenceEngine.resolveInferenceNode(member, hierarchyBuilder);
   }
 
-  Member? _getExtensionTypeMember(
+  ClassMember? _getExtensionTypeMember(
       ExtensionTypeDeclaration extensionTypeDeclaration,
       Name name,
       bool setter) {
-    Member? member = engine.membersBuilder
-        .getExtensionTypeMember(extensionTypeDeclaration, name, setter: setter);
-    return TypeInferenceEngine.resolveInferenceNode(member, hierarchyBuilder);
+    ClassMember? member = engine.membersBuilder.getExtensionTypeClassMember(
+        extensionTypeDeclaration, name,
+        setter: setter);
+    TypeInferenceEngine.resolveInferenceNode(
+        member?.getMember(engine.membersBuilder), hierarchyBuilder);
+    return member;
   }
 
   bool _isLoweredSetLiteral(Expression expression) {
@@ -4093,7 +4081,7 @@
       case ObjectAccessTargetKind.extensionTypeMember:
       case ObjectAccessTargetKind.nullableExtensionTypeMember:
         switch (readTarget.declarationMethodKind) {
-          case ProcedureKind.Getter:
+          case ClassMemberKind.Getter:
             read = new StaticInvocation(
                 readTarget.member as Procedure,
                 new ArgumentsImpl(<Expression>[
@@ -4102,7 +4090,7 @@
                   ..fileOffset = fileOffset)
               ..fileOffset = fileOffset;
             break;
-          case ProcedureKind.Method:
+          case ClassMemberKind.Method:
             read = new StaticInvocation(
                 readTarget.tearoffTarget as Procedure,
                 new Arguments(<Expression>[
@@ -4112,9 +4100,7 @@
               ..fileOffset = fileOffset;
             readResult = instantiateTearOff(readType, typeContext, read);
             break;
-          case ProcedureKind.Setter:
-          case ProcedureKind.Factory:
-          case ProcedureKind.Operator:
+          case ClassMemberKind.Setter:
             unhandled('$readTarget', "inferPropertyGet", -1, null);
         }
         break;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart b/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart
index b3cc01c..46f947c 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/object_access_target.dart
@@ -8,6 +8,7 @@
 import 'package:kernel/type_environment.dart' show SubtypeCheckMode;
 
 import '../builder/member_builder.dart';
+import '../kernel/hierarchy/class_member.dart';
 import '../problems.dart' show unexpected;
 import 'inference_visitor_base.dart';
 import 'type_schema_environment.dart';
@@ -122,7 +123,7 @@
       DartType receiverType,
       Member member,
       Member? tearoffTarget,
-      ProcedureKind kind,
+      ClassMemberKind kind,
       List<DartType> inferredTypeArguments,
       {bool isPotentiallyNullable}) = ExtensionAccessTarget;
 
@@ -131,7 +132,7 @@
       DartType receiverType,
       Member member,
       Member? tearoffTarget,
-      ProcedureKind kind,
+      ClassMemberKind kind,
       List<DartType> extensionTypeArguments,
       {bool isPotentiallyNullable}) = ExtensionTypeAccessTarget;
 
@@ -295,7 +296,7 @@
   /// This is need because getters, setters, and methods are converted into
   /// top level methods, but access and invocation should still be treated as
   /// if they are the original procedure kind.
-  ProcedureKind get declarationMethodKind =>
+  ClassMemberKind get declarationMethodKind =>
       throw new UnsupportedError('ObjectAccessTarget.declarationMethodKind');
 
   /// Returns type arguments for the type parameters of an extension or
@@ -695,7 +696,7 @@
   @override
   final Member? tearoffTarget;
   @override
-  final ProcedureKind declarationMethodKind;
+  final ClassMemberKind declarationMethodKind;
   @override
   final List<DartType> receiverTypeArguments;
 
@@ -709,19 +710,17 @@
   @override
   FunctionType getFunctionType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Method:
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         if (!base.isNonNullableByDefault) {
           functionType = legacyErasure(functionType) as FunctionType;
         }
         return functionType;
-      case ProcedureKind.Getter:
+      case ClassMemberKind.Getter:
         // TODO(johnniwinther): Handle implicit .call on extension getter.
         return _getFunctionType(base, member.function!.returnType);
-      case ProcedureKind.Setter:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Setter:
         throw unexpected('$this', 'getFunctionType', -1, null);
     }
   }
@@ -729,8 +728,7 @@
   @override
   DartType getGetterType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Method:
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         List<StructuralParameter> extensionTypeParameters = functionType
@@ -753,7 +751,7 @@
           resultType = legacyErasure(resultType);
         }
         return resultType;
-      case ProcedureKind.Getter:
+      case ClassMemberKind.Getter:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         List<StructuralParameter> extensionTypeParameters = functionType
@@ -768,8 +766,7 @@
           resultType = legacyErasure(resultType);
         }
         return resultType;
-      case ProcedureKind.Setter:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Setter:
         throw unexpected('$this', 'getGetterType', -1, null);
     }
   }
@@ -777,7 +774,7 @@
   @override
   DartType getSetterType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Setter:
+      case ClassMemberKind.Setter:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         List<StructuralParameter> extensionTypeParameters = functionType
@@ -793,10 +790,8 @@
           setterType = legacyErasure(setterType);
         }
         return setterType;
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Operator:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Method:
+      case ClassMemberKind.Getter:
         throw unexpected('$this', 'getSetterType', -1, null);
     }
   }
@@ -804,7 +799,7 @@
   @override
   DartType getIndexKeyType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         if (functionType.positionalParameters.length >= 2) {
@@ -821,10 +816,8 @@
           return keyType;
         }
         return const InvalidType();
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Setter:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Getter:
+      case ClassMemberKind.Setter:
         throw unexpected('$this', 'getIndexKeyType', -1, null);
     }
   }
@@ -832,7 +825,7 @@
   @override
   DartType getIndexSetValueType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         if (functionType.positionalParameters.length >= 3) {
@@ -849,10 +842,8 @@
           return indexType;
         }
         return const InvalidType();
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Setter:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Getter:
+      case ClassMemberKind.Setter:
         throw unexpected('$this', 'getIndexSetValueType', -1, null);
     }
   }
@@ -860,9 +851,8 @@
   @override
   DartType getReturnType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Operator:
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
+      case ClassMemberKind.Method:
+      case ClassMemberKind.Getter:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         DartType returnType = functionType.returnType;
@@ -876,17 +866,15 @@
           returnType = legacyErasure(returnType);
         }
         return returnType;
-      case ProcedureKind.Setter:
+      case ClassMemberKind.Setter:
         return const VoidType();
-      case ProcedureKind.Factory:
-        throw unexpected('$this', 'getReturnType', -1, null);
     }
   }
 
   @override
   DartType getBinaryOperandType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         if (functionType.positionalParameters.length > 1) {
@@ -903,12 +891,9 @@
           return keyType;
         }
         return const InvalidType();
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Setter:
+      case ClassMemberKind.Getter:
+      case ClassMemberKind.Setter:
         return const InvalidType();
-      case ProcedureKind.Factory:
-        throw unexpected('$this', 'getBinaryOperandType', -1, null);
     }
   }
 
@@ -1109,7 +1094,7 @@
   @override
   final Member? tearoffTarget;
   @override
-  final ProcedureKind declarationMethodKind;
+  final ClassMemberKind declarationMethodKind;
   @override
   final List<DartType> receiverTypeArguments;
 
@@ -1123,19 +1108,17 @@
   @override
   FunctionType getFunctionType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Method:
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         if (!base.isNonNullableByDefault) {
           functionType = legacyErasure(functionType) as FunctionType;
         }
         return functionType;
-      case ProcedureKind.Getter:
+      case ClassMemberKind.Getter:
         // TODO(johnniwinther): Handle implicit .call on extension getter.
         return _getFunctionType(base, member.function!.returnType);
-      case ProcedureKind.Setter:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Setter:
         throw unexpected('$this', 'getFunctionType', -1, null);
     }
   }
@@ -1143,8 +1126,7 @@
   @override
   DartType getGetterType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Method:
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         List<StructuralParameter> extensionTypeParameters = functionType
@@ -1167,7 +1149,7 @@
           resultType = legacyErasure(resultType);
         }
         return resultType;
-      case ProcedureKind.Getter:
+      case ClassMemberKind.Getter:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         List<StructuralParameter> extensionTypeParameters = functionType
@@ -1182,8 +1164,7 @@
           resultType = legacyErasure(resultType);
         }
         return resultType;
-      case ProcedureKind.Setter:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Setter:
         throw unexpected('$this', 'getGetterType', -1, null);
     }
   }
@@ -1191,7 +1172,7 @@
   @override
   DartType getSetterType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Setter:
+      case ClassMemberKind.Setter:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         List<StructuralParameter> extensionTypeParameters = functionType
@@ -1207,10 +1188,8 @@
           setterType = legacyErasure(setterType);
         }
         return setterType;
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Operator:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Method:
+      case ClassMemberKind.Getter:
         throw unexpected('$this', 'getSetterType', -1, null);
     }
   }
@@ -1218,7 +1197,7 @@
   @override
   DartType getIndexKeyType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         if (functionType.positionalParameters.length >= 2) {
@@ -1235,10 +1214,8 @@
           return keyType;
         }
         return const InvalidType();
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Setter:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Getter:
+      case ClassMemberKind.Setter:
         throw unexpected('$this', 'getIndexKeyType', -1, null);
     }
   }
@@ -1246,7 +1223,7 @@
   @override
   DartType getIndexSetValueType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         if (functionType.positionalParameters.length >= 3) {
@@ -1263,10 +1240,8 @@
           return indexType;
         }
         return const InvalidType();
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Setter:
-      case ProcedureKind.Factory:
+      case ClassMemberKind.Getter:
+      case ClassMemberKind.Setter:
         throw unexpected('$this', 'getIndexSetValueType', -1, null);
     }
   }
@@ -1274,9 +1249,8 @@
   @override
   DartType getReturnType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Operator:
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
+      case ClassMemberKind.Method:
+      case ClassMemberKind.Getter:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         DartType returnType = functionType.returnType;
@@ -1290,17 +1264,15 @@
           returnType = legacyErasure(returnType);
         }
         return returnType;
-      case ProcedureKind.Setter:
+      case ClassMemberKind.Setter:
         return const VoidType();
-      case ProcedureKind.Factory:
-        throw unexpected('$this', 'getReturnType', -1, null);
     }
   }
 
   @override
   DartType getBinaryOperandType(InferenceVisitorBase base) {
     switch (declarationMethodKind) {
-      case ProcedureKind.Operator:
+      case ClassMemberKind.Method:
         FunctionType functionType = member.function!
             .computeFunctionType(base.libraryBuilder.nonNullable);
         if (functionType.positionalParameters.length > 1) {
@@ -1317,12 +1289,9 @@
           return keyType;
         }
         return const InvalidType();
-      case ProcedureKind.Method:
-      case ProcedureKind.Getter:
-      case ProcedureKind.Setter:
+      case ClassMemberKind.Getter:
+      case ClassMemberKind.Setter:
         return const InvalidType();
-      case ProcedureKind.Factory:
-        throw unexpected('$this', 'getBinaryOperandType', -1, null);
     }
   }