[cfe] Add ConstructorEncodingStrategy

This adds [ConstructorEncodingStrategy] similar to
[PropertyEncodingStrategy] which allows for separating
[ConstructorDeclaration] from [ConstructorEncoding] such that we don't
need special [ConstructorDeclaration]s for extension (types).

Change-Id: I1c7f17e1759d47abae4af97d84455a37cbb70c17
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/435460
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fragment/constructor/declaration.dart b/pkg/front_end/lib/src/fragment/constructor/declaration.dart
index 9639a2d..a3c02d2 100644
--- a/pkg/front_end/lib/src/fragment/constructor/declaration.dart
+++ b/pkg/front_end/lib/src/fragment/constructor/declaration.dart
@@ -11,6 +11,7 @@
 import '../../base/constant_context.dart';
 import '../../base/identifiers.dart';
 import '../../base/local_scope.dart';
+import '../../base/messages.dart';
 import '../../base/name_space.dart';
 import '../../base/scope.dart';
 import '../../builder/constructor_builder.dart';
@@ -23,19 +24,18 @@
 import '../../builder/variable_builder.dart';
 import '../../kernel/body_builder.dart';
 import '../../kernel/body_builder_context.dart';
-import '../../kernel/internal_ast.dart';
 import '../../kernel/kernel_helper.dart';
 import '../../kernel/type_algorithms.dart';
 import '../../source/name_scheme.dart';
 import '../../source/source_class_builder.dart';
 import '../../source/source_constructor_builder.dart';
-import '../../source/source_extension_builder.dart';
 import '../../source/source_extension_type_declaration_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_type_parameter_builder.dart';
+import '../../source/type_parameter_scope_builder.dart';
 import '../fragment.dart';
 import 'encoding.dart';
 
@@ -55,9 +55,14 @@
 
   List<Initializer> get initializers;
 
-  void createEncoding(SourceConstructorBuilder builder);
-
-  void registerInferable(Inferable inferable);
+  void createEncoding({
+    required ProblemReporting problemReporting,
+    required SourceLoader loader,
+    required DeclarationBuilder declarationBuilder,
+    required SourceConstructorBuilder constructorBuilder,
+    required List<NominalParameterBuilder> unboundNominalParameters,
+    required ConstructorEncodingStrategy encodingStrategy,
+  });
 
   void buildOutlineNodes(
     BuildNodesCallback f, {
@@ -593,9 +598,18 @@
 }
 
 mixin _ConstructorEncodingMixin
-    implements ConstructorDeclaration, ConstructorFragmentDeclaration {
+    implements
+        ConstructorDeclaration,
+        _ConstructorDeclarationMixin,
+        ConstructorFragmentDeclaration {
   ConstructorEncoding get _encoding;
 
+  String? get _nativeMethodName;
+
+  @override
+  late final bool _hasSuperInitializingFormals =
+      formals?.any((formal) => formal.isSuperInitializingFormal) ?? false;
+
   @override
   FunctionNode get function => _encoding.function;
 
@@ -603,6 +617,9 @@
   List<Initializer> get initializers => _encoding.initializers;
 
   @override
+  bool get isRedirecting => _encoding.isRedirecting;
+
+  @override
   void prepareInitializers() {
     _encoding.prepareInitializers();
   }
@@ -626,15 +643,12 @@
   void markAsErroneous() {
     _encoding.markAsErroneous();
   }
-}
 
-mixin _RegularConstructorDeclarationMixin
-    implements
-        _ConstructorDeclarationMixin,
-        _ConstructorEncodingMixin,
-        InferredTypeListener {
   @override
-  RegularConstructorEncoding get _encoding;
+  VariableDeclaration? get thisVariable => _encoding.thisVariable;
+
+  @override
+  List<TypeParameter>? get thisTypeParameters => _encoding.thisTypeParameters;
 
   @override
   void registerFunctionBody(Statement value) {
@@ -647,37 +661,11 @@
   }
 
   @override
-  VariableDeclaration? get thisVariable => null;
-
-  @override
-  List<TypeParameter>? get thisTypeParameters => null;
-
-  @override
-  Substitution computeFieldTypeSubstitution(
-      DeclarationBuilder declarationBuilder) {
-    // Nothing to substitute. Regular generative constructors don't have their
-    // own type parameters.
-    return Substitution.empty;
+  void buildBody() {
+    _encoding.buildBody();
   }
 
   @override
-  void buildBody() {}
-
-  @override
-  bool get isRedirecting {
-    for (Initializer initializer in initializers) {
-      if (initializer is RedirectingInitializer) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  late final bool _hasSuperInitializingFormals =
-      formals?.any((formal) => formal.isSuperInitializingFormal) ?? false;
-
-  @override
   void _addSuperParameterDefaultValueCloners(
       {required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
       required Member superTarget,
@@ -692,6 +680,24 @@
         libraryBuilder: libraryBuilder);
   }
 
+  @override
+  Substitution computeFieldTypeSubstitution(
+      DeclarationBuilder declarationBuilder) {
+    return _encoding.computeFieldTypeSubstitution(
+        declarationBuilder, _typeParameters);
+  }
+
+  @override
+  void becomeNative(SourceLoader loader) {
+    _encoding.becomeNative(loader, _nativeMethodName!);
+  }
+}
+
+mixin _RegularConstructorDeclarationMixin
+    implements
+        _ConstructorDeclarationMixin,
+        _ConstructorEncodingMixin,
+        InferredTypeListener {
   void _buildTypeParametersAndFormals({
     required SourceLibraryBuilder libraryBuilder,
     required DeclarationBuilder declarationBuilder,
@@ -729,8 +735,7 @@
     function.returnType = type;
   }
 
-  @override
-  void registerInferable(Inferable inferable) {
+  void _registerInferable(Inferable inferable) {
     returnType.registerInferredTypeListener(this);
     if (formals != null) {
       for (FormalParameterBuilder formal in formals!) {
@@ -749,41 +754,25 @@
         _RegularConstructorDeclarationMixin
     implements ConstructorDeclaration, ConstructorFragmentDeclaration {
   final ConstructorFragment _fragment;
-  final List<FormalParameterBuilder>? _syntheticFormals;
 
   @override
-  final RegularConstructorEncoding _encoding;
+  late final ConstructorEncoding _encoding;
+
+  late final List<FormalParameterBuilder>? _formals;
 
   @override
-  final List<SourceNominalParameterBuilder>? _typeParameters;
+  late final List<SourceNominalParameterBuilder>? _typeParameters;
 
   @override
   Token? _beginInitializers;
 
-  RegularConstructorDeclaration(this._fragment,
-      {required List<FormalParameterBuilder>? syntheticFormals,
-      required List<SourceNominalParameterBuilder>? typeParameters,
-      // TODO(johnniwinther): Create a separate [ConstructorDeclaration] for
-      // enum constructors.
-      required bool isEnumConstructor})
-      : _typeParameters = typeParameters,
-        _syntheticFormals = syntheticFormals,
-        _beginInitializers = _fragment.beginInitializers,
-        _encoding = new RegularConstructorEncoding(
-            isExternal: _fragment.modifiers.isExternal,
-            isEnumConstructor: isEnumConstructor) {
+  RegularConstructorDeclaration(this._fragment)
+      : _beginInitializers = _fragment.beginInitializers {
     _fragment.declaration = this;
   }
 
   @override
-  void createEncoding(SourceConstructorBuilder builder) {
-    _fragment.builder = builder;
-  }
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    _encoding.becomeNative(loader, _fragment.nativeMethodName!);
-  }
+  String? get _nativeMethodName => _fragment.nativeMethodName;
 
   @override
   LookupScope get _typeParameterScope => _fragment.typeParameterScope;
@@ -796,17 +785,51 @@
   OmittedTypeBuilder get returnType => _fragment.returnType;
 
   @override
-  late final List<FormalParameterBuilder>? formals = _syntheticFormals != null
-      ? [..._syntheticFormals, ...?_fragment.formals]
-      : _fragment.formals;
-
-  @override
   bool get isConst => _fragment.modifiers.isConst;
 
   @override
   bool get isExternal => _fragment.modifiers.isExternal;
 
   @override
+  int get fileOffset => _fragment.fullNameOffset;
+
+  @override
+  Uri get fileUri => _fragment.fileUri;
+
+  @override
+  void createEncoding({
+    required ProblemReporting problemReporting,
+    required SourceLoader loader,
+    required DeclarationBuilder declarationBuilder,
+    required SourceConstructorBuilder constructorBuilder,
+    required List<NominalParameterBuilder> unboundNominalParameters,
+    required ConstructorEncodingStrategy encodingStrategy,
+  }) {
+    _fragment.builder = constructorBuilder;
+    _typeParameters = encodingStrategy.createTypeParameters(
+        declarationBuilder: declarationBuilder,
+        declarationTypeParameterFragments:
+            _fragment.enclosingDeclaration.typeParameters,
+        typeParameters: createNominalParameterBuilders(
+            _fragment.typeParameters, unboundNominalParameters),
+        unboundNominalParameters: unboundNominalParameters);
+    _fragment.typeParameterNameSpace.addTypeParameters(
+        problemReporting, _typeParameters,
+        ownerName: _fragment.name, allowNameConflict: true);
+    _formals = encodingStrategy.createFormals(
+        loader: loader,
+        formals: _fragment.formals,
+        fileUri: _fragment.fileUri,
+        fileOffset: _fragment.fullNameOffset);
+    _encoding = encodingStrategy.createEncoding(
+        isExternal: _fragment.modifiers.isExternal);
+    _registerInferable(constructorBuilder);
+  }
+
+  @override
+  List<FormalParameterBuilder>? get formals => _formals;
+
+  @override
   void buildOutlineNodes(BuildNodesCallback f,
       {required SourceConstructorBuilder constructorBuilder,
       required SourceLibraryBuilder libraryBuilder,
@@ -816,8 +839,7 @@
     _encoding.buildOutlineNodes(f,
         constructorBuilder: constructorBuilder,
         libraryBuilder: libraryBuilder,
-        declarationBuilder:
-            constructorBuilder.declarationBuilder as SourceClassBuilder,
+        declarationBuilder: constructorBuilder.declarationBuilder,
         name: _fragment.name,
         nameScheme: nameScheme,
         constructorReferences: constructorReferences,
@@ -868,129 +890,6 @@
         classHierarchy: classHierarchy,
         typeParameterScope: _fragment.typeParameterScope);
   }
-
-  @override
-  int get fileOffset => _fragment.fullNameOffset;
-
-  @override
-  Uri get fileUri => _fragment.fileUri;
-}
-
-// Coverage-ignore(suite): Not run.
-class PrimaryConstructorDeclaration
-    with
-        _ConstructorDeclarationMixin,
-        _ConstructorEncodingMixin,
-        _RegularConstructorDeclarationMixin
-    implements ConstructorDeclaration, ConstructorFragmentDeclaration {
-  final PrimaryConstructorFragment _fragment;
-
-  @override
-  final RegularConstructorEncoding _encoding;
-
-  @override
-  Token? _beginInitializers;
-
-  PrimaryConstructorDeclaration(this._fragment)
-      : _beginInitializers = _fragment.beginInitializers,
-        _encoding = new RegularConstructorEncoding(
-            isExternal: _fragment.modifiers.isExternal,
-            isEnumConstructor: false) {
-    _fragment.declaration = this;
-  }
-
-  @override
-  void createEncoding(SourceConstructorBuilder builder) {
-    _fragment.builder = builder;
-  }
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    throw new UnsupportedError("$runtimeType.becomeNative()");
-  }
-
-  @override
-  LookupScope get _typeParameterScope => _fragment.typeParameterScope;
-
-  @override
-  OmittedTypeBuilder get returnType => _fragment.returnType;
-
-  @override
-  List<MetadataBuilder>? get metadata => null;
-
-  @override
-  List<FormalParameterBuilder>? get formals => _fragment.formals;
-
-  @override
-  List<SourceNominalParameterBuilder>? get _typeParameters => null;
-
-  @override
-  bool get isConst => _fragment.modifiers.isConst;
-
-  @override
-  bool get isExternal => _fragment.modifiers.isExternal;
-
-  @override
-  void buildOutlineNodes(BuildNodesCallback f,
-      {required SourceConstructorBuilder constructorBuilder,
-      required SourceLibraryBuilder libraryBuilder,
-      required NameScheme nameScheme,
-      required ConstructorReferences? constructorReferences,
-      required List<DelayedDefaultValueCloner> delayedDefaultValueCloners}) {
-    _encoding.buildOutlineNodes(f,
-        constructorBuilder: constructorBuilder,
-        libraryBuilder: libraryBuilder,
-        declarationBuilder:
-            constructorBuilder.declarationBuilder as SourceClassBuilder,
-        name: _fragment.name,
-        nameScheme: nameScheme,
-        constructorReferences: constructorReferences,
-        fileUri: _fragment.fileUri,
-        startOffset: _fragment.startOffset,
-        fileOffset: _fragment.fileOffset,
-        formalsOffset: _fragment.formalsOffset,
-        // TODO(johnniwinther): Provide `endOffset`.
-        endOffset: _fragment.formalsOffset,
-        isSynthetic: false,
-        forAbstractClassOrEnumOrMixin: _fragment.forAbstractClassOrMixin,
-        isConst: _fragment.modifiers.isConst,
-        returnType: returnType,
-        typeParameters: _typeParameters,
-        formals: formals,
-        delayedDefaultValueCloners: delayedDefaultValueCloners);
-  }
-
-  @override
-  void _buildMetadataForOutlineExpressions(
-      {required Iterable<Annotatable> annotatables,
-      required Uri annotatablesFileUri,
-      required SourceLibraryBuilder libraryBuilder,
-      required DeclarationBuilder declarationBuilder,
-      required SourceConstructorBuilder constructorBuilder,
-      required BodyBuilderContext bodyBuilderContext,
-      required ClassHierarchy classHierarchy}) {
-    // There is no metadata on a primary constructor.
-  }
-
-  @override
-  void _buildTypeParametersAndFormalsForOutlineExpressions(
-      {required SourceLibraryBuilder libraryBuilder,
-      required DeclarationBuilder declarationBuilder,
-      required BodyBuilderContext bodyBuilderContext,
-      required ClassHierarchy classHierarchy}) {
-    _buildTypeParametersAndFormals(
-        libraryBuilder: libraryBuilder,
-        declarationBuilder: declarationBuilder,
-        bodyBuilderContext: bodyBuilderContext,
-        classHierarchy: classHierarchy,
-        typeParameterScope: _fragment.typeParameterScope);
-  }
-
-  @override
-  int get fileOffset => _fragment.fileOffset;
-
-  @override
-  Uri get fileUri => _fragment.fileUri;
 }
 
 class DefaultEnumConstructorDeclaration
@@ -1012,8 +911,7 @@
   final List<FormalParameterBuilder> formals;
 
   @override
-  final RegularConstructorEncoding _encoding = new RegularConstructorEncoding(
-      isExternal: false, isEnumConstructor: true);
+  late final ConstructorEncoding _encoding;
 
   /// The scope in which to build the formal parameters.
   final LookupScope _lookupScope;
@@ -1036,8 +934,17 @@
         _beginInitializers = new Token.eof(-1);
 
   @override
-  // Coverage-ignore(suite): Not run.
-  void createEncoding(SourceConstructorBuilder builder) {}
+  void createEncoding({
+    required ProblemReporting problemReporting,
+    required SourceLoader loader,
+    required DeclarationBuilder declarationBuilder,
+    required SourceConstructorBuilder constructorBuilder,
+    required List<NominalParameterBuilder> unboundNominalParameters,
+    required ConstructorEncodingStrategy encodingStrategy,
+  }) {
+    _encoding = encodingStrategy.createEncoding(isExternal: false);
+    _registerInferable(constructorBuilder);
+  }
 
   @override
   void becomeNative(SourceLoader loader) {
@@ -1070,8 +977,7 @@
     _encoding.buildOutlineNodes(f,
         constructorBuilder: constructorBuilder,
         libraryBuilder: libraryBuilder,
-        declarationBuilder:
-            constructorBuilder.declarationBuilder as SourceClassBuilder,
+        declarationBuilder: constructorBuilder.declarationBuilder,
         name: '',
         nameScheme: nameScheme,
         constructorReferences: constructorReferences,
@@ -1114,84 +1020,67 @@
         classHierarchy: classHierarchy,
         typeParameterScope: _lookupScope);
   }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  String? get _nativeMethodName => null;
 }
 
-mixin _ExtensionTypeConstructorDeclarationMixin
+class PrimaryConstructorDeclaration
+    with _ConstructorDeclarationMixin, _ConstructorEncodingMixin
     implements
-        _ConstructorDeclarationMixin,
-        _ConstructorEncodingMixin,
+        ConstructorDeclaration,
+        ConstructorFragmentDeclaration,
         InferredTypeListener {
-  @override
-  ExtensionTypeConstructorEncoding get _encoding;
+  final PrimaryConstructorFragment _fragment;
+
+  late final List<FormalParameterBuilder>? _formals;
 
   @override
-  void registerFunctionBody(Statement value) {
-    _encoding.registerFunctionBody(value);
+  late final List<SourceNominalParameterBuilder>? _typeParameters;
+
+  @override
+  late final ConstructorEncoding _encoding;
+
+  @override
+  Token? _beginInitializers;
+
+  PrimaryConstructorDeclaration(this._fragment)
+      : _beginInitializers = _fragment.beginInitializers {
+    _fragment.declaration = this;
   }
 
   @override
-  void registerNoBodyConstructor() {
-    _encoding.registerNoBodyConstructor();
-  }
+  // Coverage-ignore(suite): Not run.
+  String? get _nativeMethodName => null;
 
   @override
-  VariableDeclaration? get thisVariable => _encoding.thisVariable;
-
-  @override
-  List<TypeParameter>? get thisTypeParameters => _encoding.thisTypeParameters;
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    throw new UnsupportedError("$runtimeType.becomeNative()");
-  }
-
-  @override
-  Substitution computeFieldTypeSubstitution(
-      DeclarationBuilder declarationBuilder) {
-    if (_typeParameters != null) {
-      assert(
-          declarationBuilder.typeParameters!.length == _typeParameters?.length);
-      return Substitution.fromPairs(
-          (declarationBuilder as SourceExtensionTypeDeclarationBuilder)
-              .extensionTypeDeclaration
-              .typeParameters,
-          new List<DartType>.generate(
-              declarationBuilder.typeParameters!.length,
-              (int index) => new TypeParameterType.withDefaultNullability(
-                  function.typeParameters[index])));
-    } else {
-      return Substitution.empty;
-    }
-  }
-
-  @override
-  void buildBody() {
-    _encoding.buildBody();
-  }
-
-  @override
-  bool get isRedirecting {
-    for (Initializer initializer in initializers) {
-      if (initializer is ExtensionTypeRedirectingInitializer) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  late final bool _hasSuperInitializingFormals =
-      formals?.any((formal) => formal.isSuperInitializingFormal) ?? false;
-
-  @override
-  void _addSuperParameterDefaultValueCloners(
-      {required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
-      required Member superTarget,
-      required List<int?>? positionalSuperParameters,
-      required List<String>? namedSuperParameters,
-      required SourceLibraryBuilder libraryBuilder}) {
-    throw new UnsupportedError(
-        '$runtimeType.addSuperParameterDefaultValueCloners');
+  void createEncoding({
+    required ProblemReporting problemReporting,
+    required SourceLoader loader,
+    required DeclarationBuilder declarationBuilder,
+    required SourceConstructorBuilder constructorBuilder,
+    required List<NominalParameterBuilder> unboundNominalParameters,
+    required ConstructorEncodingStrategy encodingStrategy,
+  }) {
+    _fragment.builder = constructorBuilder;
+    _typeParameters = encodingStrategy.createTypeParameters(
+        declarationBuilder: declarationBuilder,
+        declarationTypeParameterFragments:
+            _fragment.enclosingDeclaration.typeParameters,
+        typeParameters: null,
+        unboundNominalParameters: unboundNominalParameters);
+    _fragment.typeParameterNameSpace.addTypeParameters(
+        problemReporting, _typeParameters,
+        ownerName: _fragment.name, allowNameConflict: true);
+    _formals = encodingStrategy.createFormals(
+        loader: loader,
+        formals: _fragment.formals,
+        fileUri: _fragment.fileUri,
+        fileOffset: _fragment.fileOffset);
+    _encoding = encodingStrategy.createEncoding(
+        isExternal: _fragment.modifiers.isExternal);
+    _registerInferable(constructorBuilder);
   }
 
   void _buildTypeParametersAndFormals({
@@ -1231,167 +1120,18 @@
     function.returnType = type;
   }
 
-  @override
-  void registerInferable(Inferable inferable) {
+  void _registerInferable(Inferable inferable) {
     returnType.registerInferredTypeListener(this);
     if (formals != null) {
       for (FormalParameterBuilder formal in formals!) {
-        if (formal.isInitializingFormal || formal.isSuperInitializingFormal) {
+        if (formal.isInitializingFormal ||
+            // Coverage-ignore(suite): Not run.
+            formal.isSuperInitializingFormal) {
           formal.type.registerInferable(inferable);
         }
       }
     }
   }
-}
-
-class ExtensionTypeConstructorDeclaration
-    with
-        _ConstructorDeclarationMixin,
-        _ConstructorEncodingMixin,
-        _ExtensionTypeConstructorDeclarationMixin
-    implements ConstructorDeclaration, ConstructorFragmentDeclaration {
-  final ConstructorFragment _fragment;
-
-  @override
-  final List<SourceNominalParameterBuilder>? _typeParameters;
-
-  @override
-  final ExtensionTypeConstructorEncoding _encoding;
-
-  @override
-  Token? _beginInitializers;
-
-  ExtensionTypeConstructorDeclaration(this._fragment,
-      {required List<SourceNominalParameterBuilder>? typeParameters})
-      : _typeParameters = typeParameters,
-        _beginInitializers = _fragment.beginInitializers,
-        _encoding = new ExtensionTypeConstructorEncoding(
-            isExternal: _fragment.modifiers.isExternal) {
-    _fragment.declaration = this;
-  }
-
-  @override
-  void createEncoding(SourceConstructorBuilder builder) {
-    _fragment.builder = builder;
-  }
-
-  @override
-  LookupScope get _typeParameterScope => _fragment.typeParameterScope;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  List<MetadataBuilder>? get metadata => _fragment.metadata;
-
-  @override
-  OmittedTypeBuilder get returnType => _fragment.returnType;
-
-  @override
-  List<FormalParameterBuilder>? get formals => _fragment.formals;
-
-  @override
-  bool get isConst => _fragment.modifiers.isConst;
-
-  @override
-  bool get isExternal => _fragment.modifiers.isExternal;
-
-  @override
-  void buildOutlineNodes(BuildNodesCallback f,
-      {required SourceConstructorBuilder constructorBuilder,
-      required SourceLibraryBuilder libraryBuilder,
-      required NameScheme nameScheme,
-      required ConstructorReferences? constructorReferences,
-      required List<DelayedDefaultValueCloner> delayedDefaultValueCloners}) {
-    _encoding.buildOutlineNodes(f,
-        constructorBuilder: constructorBuilder,
-        libraryBuilder: libraryBuilder,
-        declarationBuilder: constructorBuilder.declarationBuilder
-            as SourceExtensionTypeDeclarationBuilder,
-        name: _fragment.name,
-        nameScheme: nameScheme,
-        constructorReferences: constructorReferences,
-        fileUri: _fragment.fileUri,
-        fileOffset: _fragment.fullNameOffset,
-        formalsOffset: _fragment.formalsOffset,
-        endOffset: _fragment.endOffset,
-        forAbstractClassOrEnumOrMixin: _fragment.forAbstractClassOrMixin,
-        isConst: _fragment.modifiers.isConst,
-        returnType: returnType,
-        typeParameters: _typeParameters,
-        formals: formals,
-        delayedDefaultValueCloners: delayedDefaultValueCloners);
-  }
-
-  @override
-  void _buildMetadataForOutlineExpressions(
-      {required Iterable<Annotatable> annotatables,
-      required Uri annotatablesFileUri,
-      required SourceLibraryBuilder libraryBuilder,
-      required DeclarationBuilder declarationBuilder,
-      required SourceConstructorBuilder constructorBuilder,
-      required BodyBuilderContext bodyBuilderContext,
-      required ClassHierarchy classHierarchy}) {
-    for (Annotatable annotatable in annotatables) {
-      MetadataBuilder.buildAnnotations(
-          annotatable: annotatable,
-          annotatableFileUri: annotatablesFileUri,
-          metadata: _fragment.metadata,
-          bodyBuilderContext: bodyBuilderContext,
-          libraryBuilder: libraryBuilder,
-          scope: _fragment.enclosingScope);
-    }
-  }
-
-  @override
-  void _buildTypeParametersAndFormalsForOutlineExpressions(
-      {required SourceLibraryBuilder libraryBuilder,
-      required DeclarationBuilder declarationBuilder,
-      required BodyBuilderContext bodyBuilderContext,
-      required ClassHierarchy classHierarchy}) {
-    _buildTypeParametersAndFormals(
-        libraryBuilder: libraryBuilder,
-        declarationBuilder: declarationBuilder,
-        bodyBuilderContext: bodyBuilderContext,
-        classHierarchy: classHierarchy,
-        typeParameterScope: _fragment.typeParameterScope);
-  }
-
-  @override
-  int get fileOffset => _fragment.fullNameOffset;
-
-  @override
-  Uri get fileUri => _fragment.fileUri;
-}
-
-class ExtensionTypePrimaryConstructorDeclaration
-    with
-        _ConstructorDeclarationMixin,
-        _ConstructorEncodingMixin,
-        _ExtensionTypeConstructorDeclarationMixin
-    implements ConstructorDeclaration, ConstructorFragmentDeclaration {
-  final PrimaryConstructorFragment _fragment;
-
-  @override
-  final List<SourceNominalParameterBuilder>? _typeParameters;
-
-  @override
-  final ExtensionTypeConstructorEncoding _encoding;
-
-  @override
-  Token? _beginInitializers;
-
-  ExtensionTypePrimaryConstructorDeclaration(this._fragment,
-      {required List<SourceNominalParameterBuilder>? typeParameters})
-      : _typeParameters = typeParameters,
-        _beginInitializers = _fragment.beginInitializers,
-        _encoding = new ExtensionTypeConstructorEncoding(
-            isExternal: _fragment.modifiers.isExternal) {
-    _fragment.declaration = this;
-  }
-
-  @override
-  void createEncoding(SourceConstructorBuilder builder) {
-    _fragment.builder = builder;
-  }
 
   @override
   LookupScope get _typeParameterScope => _fragment.typeParameterScope;
@@ -1404,7 +1144,7 @@
   OmittedTypeBuilder get returnType => _fragment.returnType;
 
   @override
-  List<FormalParameterBuilder>? get formals => _fragment.formals;
+  List<FormalParameterBuilder>? get formals => _formals;
 
   @override
   bool get isConst => _fragment.modifiers.isConst;
@@ -1429,11 +1169,13 @@
         constructorReferences: constructorReferences,
         fileUri: _fragment.fileUri,
         fileOffset: _fragment.fileOffset,
+        startOffset: _fragment.startOffset,
         formalsOffset: _fragment.formalsOffset,
         // TODO(johnniwinther): Provide `endOffset`.
         endOffset: _fragment.formalsOffset,
         forAbstractClassOrEnumOrMixin: _fragment.forAbstractClassOrMixin,
         isConst: _fragment.modifiers.isConst,
+        isSynthetic: false,
         returnType: returnType,
         typeParameters: _typeParameters,
         formals: formals,
@@ -1473,267 +1215,6 @@
   Uri get fileUri => _fragment.fileUri;
 }
 
-mixin _ExtensionConstructorDeclarationMixin
-    implements
-        _ConstructorDeclarationMixin,
-        _ConstructorEncodingMixin,
-        InferredTypeListener {
-  @override
-  ExtensionConstructorEncoding get _encoding;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void registerFunctionBody(Statement value) {
-    _encoding.registerFunctionBody(value);
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void registerNoBodyConstructor() {
-    _encoding.registerNoBodyConstructor();
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  VariableDeclaration? get thisVariable => _encoding.thisVariable;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  List<TypeParameter>? get thisTypeParameters => _encoding.thisTypeParameters;
-
-  @override
-  void becomeNative(SourceLoader loader) {
-    throw new UnsupportedError("$runtimeType.becomeNative()");
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  Substitution computeFieldTypeSubstitution(
-      DeclarationBuilder declarationBuilder) {
-    if (_typeParameters != null) {
-      assert(
-          declarationBuilder.typeParameters!.length == _typeParameters?.length);
-      return Substitution.fromPairs(
-          (declarationBuilder as SourceExtensionTypeDeclarationBuilder)
-              .extensionTypeDeclaration
-              .typeParameters,
-          new List<DartType>.generate(
-              declarationBuilder.typeParameters!.length,
-              (int index) => new TypeParameterType.withDefaultNullability(
-                  function.typeParameters[index])));
-    } else {
-      return Substitution.empty;
-    }
-  }
-
-  @override
-  void buildBody() {
-    _encoding.buildBody();
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  bool get isRedirecting {
-    for (Initializer initializer in initializers) {
-      if (initializer is ExtensionTypeRedirectingInitializer) {
-        return true;
-      }
-    }
-    return false;
-  }
-
-  @override
-  late final bool _hasSuperInitializingFormals =
-      formals?.any((formal) => formal.isSuperInitializingFormal) ?? false;
-
-  @override
-  void _addSuperParameterDefaultValueCloners(
-      {required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
-      required Member superTarget,
-      required List<int?>? positionalSuperParameters,
-      required List<String>? namedSuperParameters,
-      required SourceLibraryBuilder libraryBuilder}) {
-    throw new UnsupportedError(
-        '$runtimeType.addSuperParameterDefaultValueCloners');
-  }
-
-  // Coverage-ignore(suite): Not run.
-  void _buildTypeParametersAndFormals({
-    required SourceLibraryBuilder libraryBuilder,
-    required DeclarationBuilder declarationBuilder,
-    required BodyBuilderContext bodyBuilderContext,
-    required ClassHierarchy classHierarchy,
-    required LookupScope typeParameterScope,
-  }) {
-    if (_typeParameters != null) {
-      for (int i = 0; i < _typeParameters!.length; i++) {
-        _typeParameters![i].buildOutlineExpressions(
-            libraryBuilder, bodyBuilderContext, classHierarchy);
-      }
-    }
-
-    if (formals != null) {
-      // For const constructors we need to include default parameter values
-      // into the outline. For all other formals we need to call
-      // buildOutlineExpressions to clear initializerToken to prevent
-      // consuming too much memory.
-      for (FormalParameterBuilder formal in formals!) {
-        formal.buildOutlineExpressions(libraryBuilder, declarationBuilder,
-            scope: typeParameterScope, buildDefaultValue: true);
-      }
-    }
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  BodyBuilderContext createBodyBuilderContext(
-      SourceConstructorBuilder constructorBuilder) {
-    return _encoding.createBodyBuilderContext(constructorBuilder, this);
-  }
-
-  @override
-  void onInferredType(DartType type) {
-    function.returnType = type;
-  }
-
-  @override
-  void registerInferable(Inferable inferable) {
-    returnType.registerInferredTypeListener(this);
-    if (formals != null) {
-      for (FormalParameterBuilder formal in formals!) {
-        if (formal.isInitializingFormal || formal.isSuperInitializingFormal) {
-          // Coverage-ignore-block(suite): Not run.
-          formal.type.registerInferable(inferable);
-        }
-      }
-    }
-  }
-}
-
-class ExtensionConstructorDeclaration
-    with
-        _ConstructorDeclarationMixin,
-        _ConstructorEncodingMixin,
-        _ExtensionConstructorDeclarationMixin
-    implements ConstructorDeclaration, ConstructorFragmentDeclaration {
-  final ConstructorFragment _fragment;
-
-  @override
-  final List<SourceNominalParameterBuilder>? _typeParameters;
-
-  @override
-  final ExtensionConstructorEncoding _encoding;
-
-  @override
-  Token? _beginInitializers;
-
-  ExtensionConstructorDeclaration(this._fragment,
-      {required List<SourceNominalParameterBuilder>? typeParameters})
-      : _typeParameters = typeParameters,
-        _beginInitializers = _fragment.beginInitializers,
-        _encoding = new ExtensionConstructorEncoding(
-            isExternal: _fragment.modifiers.isExternal) {
-    _fragment.declaration = this;
-  }
-
-  @override
-  void createEncoding(SourceConstructorBuilder builder) {
-    _fragment.builder = builder;
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  LookupScope get _typeParameterScope => _fragment.typeParameterScope;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  List<MetadataBuilder>? get metadata => _fragment.metadata;
-
-  @override
-  OmittedTypeBuilder get returnType => _fragment.returnType;
-
-  @override
-  List<FormalParameterBuilder>? get formals => _fragment.formals;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  bool get isConst => _fragment.modifiers.isConst;
-
-  @override
-  bool get isExternal => _fragment.modifiers.isExternal;
-
-  @override
-  void buildOutlineNodes(BuildNodesCallback f,
-      {required SourceConstructorBuilder constructorBuilder,
-      required SourceLibraryBuilder libraryBuilder,
-      required NameScheme nameScheme,
-      required ConstructorReferences? constructorReferences,
-      required List<DelayedDefaultValueCloner> delayedDefaultValueCloners}) {
-    _encoding.buildOutlineNodes(f,
-        constructorBuilder: constructorBuilder,
-        libraryBuilder: libraryBuilder,
-        declarationBuilder:
-            constructorBuilder.declarationBuilder as SourceExtensionBuilder,
-        name: _fragment.name,
-        nameScheme: nameScheme,
-        constructorReferences: constructorReferences,
-        fileUri: _fragment.fileUri,
-        fileOffset: _fragment.fullNameOffset,
-        formalsOffset: _fragment.formalsOffset,
-        endOffset: _fragment.endOffset,
-        forAbstractClassOrEnumOrMixin: _fragment.forAbstractClassOrMixin,
-        isConst: _fragment.modifiers.isConst,
-        returnType: returnType,
-        typeParameters: _typeParameters,
-        formals: formals,
-        delayedDefaultValueCloners: delayedDefaultValueCloners);
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void _buildMetadataForOutlineExpressions(
-      {required Iterable<Annotatable> annotatables,
-      required Uri annotatablesFileUri,
-      required SourceLibraryBuilder libraryBuilder,
-      required DeclarationBuilder declarationBuilder,
-      required SourceConstructorBuilder constructorBuilder,
-      required BodyBuilderContext bodyBuilderContext,
-      required ClassHierarchy classHierarchy}) {
-    for (Annotatable annotatable in annotatables) {
-      MetadataBuilder.buildAnnotations(
-          annotatable: annotatable,
-          annotatableFileUri: annotatablesFileUri,
-          metadata: _fragment.metadata,
-          bodyBuilderContext: bodyBuilderContext,
-          libraryBuilder: libraryBuilder,
-          scope: _fragment.enclosingScope);
-    }
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void _buildTypeParametersAndFormalsForOutlineExpressions(
-      {required SourceLibraryBuilder libraryBuilder,
-      required DeclarationBuilder declarationBuilder,
-      required BodyBuilderContext bodyBuilderContext,
-      required ClassHierarchy classHierarchy}) {
-    _buildTypeParametersAndFormals(
-        libraryBuilder: libraryBuilder,
-        declarationBuilder: declarationBuilder,
-        bodyBuilderContext: bodyBuilderContext,
-        classHierarchy: classHierarchy,
-        typeParameterScope: _fragment.typeParameterScope);
-  }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  int get fileOffset => _fragment.fullNameOffset;
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  Uri get fileUri => _fragment.fileUri;
-}
-
 /// Interface for using a [ConstructorFragment] or [PrimaryConstructorFragment]
 /// to create a [BodyBuilderContext].
 abstract class ConstructorFragmentDeclaration {
@@ -1851,13 +1332,6 @@
   }
 
   @override
-  Substitution computeFieldTypeSubstitution(
-      DeclarationBuilder declarationBuilder) {
-    throw new UnsupportedError(
-        "Unexpected call to $runtimeType.computeFieldTypeSubstitution");
-  }
-
-  @override
   List<Initializer> get initializers {
     throw new UnsupportedError("Unexpected call to $runtimeType.initializers");
   }
@@ -1875,7 +1349,11 @@
   }
 
   @override
-  void registerInferable(Inferable inferable) {}
+  // Coverage-ignore(suite): Not run.
+  Substitution computeFieldTypeSubstitution(
+      DeclarationBuilder declarationBuilder) {
+    return Substitution.empty;
+  }
 }
 
 class DefaultConstructorDeclaration
@@ -1895,7 +1373,14 @@
 
   @override
   // Coverage-ignore(suite): Not run.
-  void createEncoding(SourceConstructorBuilder builder) {}
+  void createEncoding({
+    required ProblemReporting problemReporting,
+    required SourceLoader loader,
+    required DeclarationBuilder declarationBuilder,
+    required SourceConstructorBuilder constructorBuilder,
+    required List<NominalParameterBuilder> unboundNominalParameters,
+    required ConstructorEncodingStrategy encodingStrategy,
+  }) {}
 
   @override
   void addSuperParameterDefaultValueCloners(
@@ -1957,7 +1442,14 @@
 
   @override
   // Coverage-ignore(suite): Not run.
-  void createEncoding(SourceConstructorBuilder builder) {}
+  void createEncoding({
+    required ProblemReporting problemReporting,
+    required SourceLoader loader,
+    required DeclarationBuilder declarationBuilder,
+    required SourceConstructorBuilder constructorBuilder,
+    required List<NominalParameterBuilder> unboundNominalParameters,
+    required ConstructorEncodingStrategy encodingStrategy,
+  }) {}
 
   @override
   void addSuperParameterDefaultValueCloners(
diff --git a/pkg/front_end/lib/src/fragment/constructor/encoding.dart b/pkg/front_end/lib/src/fragment/constructor/encoding.dart
index c82cf9f..02aabb0 100644
--- a/pkg/front_end/lib/src/fragment/constructor/encoding.dart
+++ b/pkg/front_end/lib/src/fragment/constructor/encoding.dart
@@ -2,18 +2,22 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
+import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/type_algebra.dart';
 
 import '../../api_prototype/lowering_predicates.dart';
+import '../../base/modifiers.dart';
 import '../../builder/declaration_builders.dart';
 import '../../builder/formal_parameter_builder.dart';
+import '../../builder/named_type_builder.dart';
 import '../../builder/omitted_type_builder.dart';
 import '../../builder/type_builder.dart';
 import '../../kernel/body_builder_context.dart';
 import '../../kernel/constructor_tearoff_lowering.dart';
 import '../../kernel/internal_ast.dart';
 import '../../kernel/kernel_helper.dart';
+import '../../source/builder_factory.dart';
 import '../../source/name_scheme.dart';
 import '../../source/source_class_builder.dart';
 import '../../source/source_constructor_builder.dart';
@@ -25,6 +29,7 @@
 import '../../source/source_member_builder.dart';
 import '../../source/source_type_parameter_builder.dart';
 import '../../type_inference/type_schema.dart';
+import '../fragment.dart';
 import 'body_builder_context.dart';
 import 'declaration.dart';
 
@@ -41,12 +46,63 @@
 
   VariableDeclaration? getTearOffParameter(int index);
 
+  VariableDeclaration? get thisVariable;
+
+  List<TypeParameter>? get thisTypeParameters;
+
   /// Mark the constructor as erroneous.
   ///
   /// This is used during the compilation phase to set the appropriate flag on
   /// the input AST node. The flag helps the verifier to skip apriori erroneous
   /// members and to avoid reporting cascading errors.
   void markAsErroneous();
+
+  void buildOutlineNodes(
+    BuildNodesCallback f, {
+    required SourceConstructorBuilder constructorBuilder,
+    required SourceLibraryBuilder libraryBuilder,
+    required covariant DeclarationBuilder declarationBuilder,
+    required String name,
+    required NameScheme nameScheme,
+    required ConstructorReferences? constructorReferences,
+    required Uri fileUri,
+    required int startOffset,
+    required int fileOffset,
+    required int formalsOffset,
+    required int endOffset,
+    required bool forAbstractClassOrEnumOrMixin,
+    required bool isConst,
+    required bool isSynthetic,
+    required TypeBuilder returnType,
+    required List<SourceNominalParameterBuilder>? typeParameters,
+    required List<FormalParameterBuilder>? formals,
+    required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
+  });
+
+  void buildBody();
+
+  BodyBuilderContext createBodyBuilderContext(
+      SourceConstructorBuilder constructorBuilder,
+      ConstructorFragmentDeclaration constructorDeclaration);
+
+  void registerFunctionBody(Statement value);
+
+  void registerNoBodyConstructor();
+
+  void addSuperParameterDefaultValueCloners(
+      {required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
+      required Member superTarget,
+      required List<int?>? positionalSuperParameters,
+      required List<String>? namedSuperParameters,
+      required SourceLibraryBuilder libraryBuilder});
+
+  void becomeNative(SourceLoader loader, String nativeMethodName);
+
+  Substitution computeFieldTypeSubstitution(
+      covariant DeclarationBuilder declarationBuilder,
+      List<SourceNominalParameterBuilder>? typeParameters);
+
+  bool get isRedirecting;
 }
 
 class RegularConstructorEncoding implements ConstructorEncoding {
@@ -65,10 +121,12 @@
       : _isExternal = isExternal,
         _isEnumConstructor = isEnumConstructor;
 
+  @override
   void registerFunctionBody(Statement value) {
     function.body = value..parent = function;
   }
 
+  @override
   void registerNoBodyConstructor() {
     if (!_isExternal) {
       registerFunctionBody(new EmptyStatement());
@@ -87,6 +145,23 @@
   @override
   List<Initializer> get initializers => _constructor.initializers;
 
+  @override
+  bool get isRedirecting {
+    for (Initializer initializer in initializers) {
+      if (initializer is RedirectingInitializer) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @override
+  VariableDeclaration? get thisVariable => null;
+
+  @override
+  List<TypeParameter>? get thisTypeParameters => null;
+
+  @override
   void buildOutlineNodes(
     BuildNodesCallback f, {
     required SourceConstructorBuilder constructorBuilder,
@@ -233,6 +308,9 @@
   }
 
   @override
+  void buildBody() {}
+
+  @override
   void prepareInitializers() {
     // For const constructors we parse initializers already at the outlining
     // stage, there is no easy way to make body building stage skip initializer
@@ -256,6 +334,7 @@
     _constructor.initializers.insert(0, initializer);
   }
 
+  @override
   void becomeNative(SourceLoader loader, String nativeMethodName) {
     _constructor.isExternal = true;
 
@@ -295,6 +374,7 @@
 
   bool _hasAddedDefaultValueCloners = false;
 
+  @override
   void addSuperParameterDefaultValueCloners(
       {required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
       required Member superTarget,
@@ -323,6 +403,7 @@
     }
   }
 
+  @override
   BodyBuilderContext createBodyBuilderContext(
       SourceConstructorBuilder constructorBuilder,
       ConstructorFragmentDeclaration constructorDeclaration) {
@@ -334,6 +415,15 @@
   void markAsErroneous() {
     _constructor.isErroneous = true;
   }
+
+  @override
+  Substitution computeFieldTypeSubstitution(
+      covariant DeclarationBuilder declarationBuilder,
+      List<SourceNominalParameterBuilder>? typeParameters) {
+    // Nothing to substitute. Regular generative constructors don't have their
+    // own type parameters.
+    return Substitution.empty;
+  }
 }
 
 mixin _ExtensionTypeConstructorEncodingMixin<T extends DeclarationBuilder>
@@ -365,10 +455,12 @@
   @override
   List<Initializer> get initializers => _initializers;
 
+  @override
   void registerFunctionBody(Statement value) {
     function.body = value..parent = function;
   }
 
+  @override
   void registerNoBodyConstructor() {
     if (!_hasBuiltBody && !_isExternal) {
       registerFunctionBody(new EmptyStatement());
@@ -495,12 +587,14 @@
     }
   }
 
+  @override
   VariableDeclaration? get thisVariable {
     assert(_thisVariable != null,
         "ProcedureBuilder.thisVariable has not been set.");
     return _thisVariable;
   }
 
+  @override
   List<TypeParameter>? get thisTypeParameters {
     // Use [_thisVariable] as marker for whether this type parameters have
     // been computed.
@@ -561,6 +655,7 @@
 
   bool _hasBuiltBody = false;
 
+  @override
   void buildBody() {
     if (_hasBuiltBody) {
       return;
@@ -583,6 +678,7 @@
     _hasBuiltBody = true;
   }
 
+  @override
   BodyBuilderContext createBodyBuilderContext(
       SourceConstructorBuilder constructorBuilder,
       ConstructorFragmentDeclaration constructorDeclaration) {
@@ -594,6 +690,22 @@
   void markAsErroneous() {
     _constructor.isErroneous = true;
   }
+
+  @override
+  void addSuperParameterDefaultValueCloners(
+      {required List<DelayedDefaultValueCloner> delayedDefaultValueCloners,
+      required Member superTarget,
+      required List<int?>? positionalSuperParameters,
+      required List<String>? namedSuperParameters,
+      required SourceLibraryBuilder libraryBuilder}) {
+    throw new UnsupportedError(
+        '$runtimeType.addSuperParameterDefaultValueCloners');
+  }
+
+  @override
+  void becomeNative(SourceLoader loader, String nativeMethodName) {
+    throw new UnsupportedError('$runtimeType.becomeNative');
+  }
 }
 
 class _ExtensionTypeInitializerToStatementConverter
@@ -687,6 +799,7 @@
         extensionTypeDeclaration, Nullability.nonNullable, typeArguments);
   }
 
+  @override
   void buildOutlineNodes(
     BuildNodesCallback f, {
     required SourceConstructorBuilder constructorBuilder,
@@ -696,11 +809,13 @@
     required NameScheme nameScheme,
     required ConstructorReferences? constructorReferences,
     required Uri fileUri,
+    required int startOffset,
     required int fileOffset,
     required int formalsOffset,
     required int endOffset,
     required bool forAbstractClassOrEnumOrMixin,
     required bool isConst,
+    required bool isSynthetic,
     required TypeBuilder returnType,
     required List<SourceNominalParameterBuilder>? typeParameters,
     required List<FormalParameterBuilder>? formals,
@@ -734,6 +849,36 @@
 
   @override
   bool get _isExtensionTypeMember => true;
+
+  @override
+  Substitution computeFieldTypeSubstitution(
+      DeclarationBuilder declarationBuilder,
+      List<SourceNominalParameterBuilder>? typeParameters) {
+    if (typeParameters != null) {
+      assert(
+          declarationBuilder.typeParameters!.length == typeParameters.length);
+      return Substitution.fromPairs(
+          (declarationBuilder as SourceExtensionTypeDeclarationBuilder)
+              .extensionTypeDeclaration
+              .typeParameters,
+          new List<DartType>.generate(
+              declarationBuilder.typeParameters!.length,
+              (int index) => new TypeParameterType.withDefaultNullability(
+                  function.typeParameters[index])));
+    } else {
+      return Substitution.empty;
+    }
+  }
+
+  @override
+  bool get isRedirecting {
+    for (Initializer initializer in initializers) {
+      if (initializer is ExtensionTypeRedirectingInitializer) {
+        return true;
+      }
+    }
+    return false;
+  }
 }
 
 class ExtensionConstructorEncoding
@@ -745,6 +890,7 @@
   ExtensionConstructorEncoding({required bool isExternal})
       : _isExternal = isExternal;
 
+  @override
   void buildOutlineNodes(
     BuildNodesCallback f, {
     required SourceConstructorBuilder constructorBuilder,
@@ -754,11 +900,13 @@
     required NameScheme nameScheme,
     required ConstructorReferences? constructorReferences,
     required Uri fileUri,
+    required int startOffset,
     required int fileOffset,
     required int formalsOffset,
     required int endOffset,
     required bool forAbstractClassOrEnumOrMixin,
     required bool isConst,
+    required bool isSynthetic,
     required TypeBuilder returnType,
     required List<SourceNominalParameterBuilder>? typeParameters,
     required List<FormalParameterBuilder>? formals,
@@ -798,4 +946,221 @@
     return Substitution.fromPairs(extension.typeParameters, typeArguments)
         .substituteType(extension.onType);
   }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  Substitution computeFieldTypeSubstitution(
+      SourceExtensionBuilder declarationBuilder,
+      List<SourceNominalParameterBuilder>? typeParameters) {
+    if (typeParameters != null) {
+      assert(
+          declarationBuilder.typeParameters!.length == typeParameters.length);
+      return Substitution.fromPairs(
+          declarationBuilder.extension.typeParameters,
+          new List<DartType>.generate(
+              declarationBuilder.typeParameters!.length,
+              (int index) => new TypeParameterType.withDefaultNullability(
+                  function.typeParameters[index])));
+    } else {
+      return Substitution.empty;
+    }
+  }
+
+  @override
+  // Coverage-ignore(suite): Not run.
+  bool get isRedirecting {
+    // TODO(johnniwinther): Update this if redirecting extension constructors
+    //  are supported.
+    return false;
+  }
+}
+
+abstract class ConstructorEncodingStrategy {
+  factory ConstructorEncodingStrategy(DeclarationBuilder declarationBuilder) {
+    switch (declarationBuilder) {
+      case ClassBuilder():
+        if (declarationBuilder.isEnum) {
+          return const EnumConstructorEncodingStrategy();
+        } else {
+          return const RegularConstructorEncodingStrategy();
+        }
+      case ExtensionBuilder():
+        return const ExtensionConstructorEncodingStrategy();
+      case ExtensionTypeDeclarationBuilder():
+        return const ExtensionTypeConstructorEncodingStrategy();
+    }
+  }
+
+  List<FormalParameterBuilder>? createFormals({
+    required SourceLoader loader,
+    required List<FormalParameterBuilder>? formals,
+    required Uri fileUri,
+    required int fileOffset,
+  });
+
+  List<SourceNominalParameterBuilder>? createTypeParameters({
+    required DeclarationBuilder declarationBuilder,
+    required List<TypeParameterFragment>? declarationTypeParameterFragments,
+    required List<SourceNominalParameterBuilder>? typeParameters,
+    required List<NominalParameterBuilder> unboundNominalParameters,
+  });
+
+  ConstructorEncoding createEncoding({required bool isExternal});
+}
+
+class RegularConstructorEncodingStrategy
+    implements ConstructorEncodingStrategy {
+  const RegularConstructorEncodingStrategy();
+
+  @override
+  ConstructorEncoding createEncoding({required bool isExternal}) {
+    return new RegularConstructorEncoding(
+        isExternal: isExternal, isEnumConstructor: false);
+  }
+
+  @override
+  List<FormalParameterBuilder>? createFormals(
+      {required SourceLoader loader,
+      required List<FormalParameterBuilder>? formals,
+      required Uri fileUri,
+      required int fileOffset}) {
+    return formals;
+  }
+
+  @override
+  List<SourceNominalParameterBuilder>? createTypeParameters(
+      {required DeclarationBuilder declarationBuilder,
+      required List<TypeParameterFragment>? declarationTypeParameterFragments,
+      required List<SourceNominalParameterBuilder>? typeParameters,
+      required List<NominalParameterBuilder> unboundNominalParameters}) {
+    return typeParameters;
+  }
+}
+
+class EnumConstructorEncodingStrategy implements ConstructorEncodingStrategy {
+  const EnumConstructorEncodingStrategy();
+
+  @override
+  ConstructorEncoding createEncoding({required bool isExternal}) {
+    return new RegularConstructorEncoding(
+        isExternal: isExternal, isEnumConstructor: true);
+  }
+
+  @override
+  List<FormalParameterBuilder>? createFormals({
+    required SourceLoader loader,
+    required List<FormalParameterBuilder>? formals,
+    required Uri fileUri,
+    required int fileOffset,
+  }) {
+    return [
+      new FormalParameterBuilder(FormalParameterKind.requiredPositional,
+          Modifiers.empty, loader.target.intType, "#index", fileOffset,
+          fileUri: fileUri, hasImmediatelyDeclaredInitializer: false),
+      new FormalParameterBuilder(FormalParameterKind.requiredPositional,
+          Modifiers.empty, loader.target.stringType, "#name", fileOffset,
+          fileUri: fileUri, hasImmediatelyDeclaredInitializer: false),
+      ...?formals
+    ];
+  }
+
+  @override
+  List<SourceNominalParameterBuilder>? createTypeParameters(
+      {required DeclarationBuilder declarationBuilder,
+      required List<TypeParameterFragment>? declarationTypeParameterFragments,
+      required List<SourceNominalParameterBuilder>? typeParameters,
+      required List<NominalParameterBuilder> unboundNominalParameters}) {
+    return typeParameters;
+  }
+}
+
+class ExtensionConstructorEncodingStrategy
+    implements ConstructorEncodingStrategy {
+  const ExtensionConstructorEncodingStrategy();
+
+  @override
+  ConstructorEncoding createEncoding({required bool isExternal}) {
+    return new ExtensionConstructorEncoding(isExternal: isExternal);
+  }
+
+  @override
+  List<FormalParameterBuilder>? createFormals(
+      {required SourceLoader loader,
+      required List<FormalParameterBuilder>? formals,
+      required Uri fileUri,
+      required int fileOffset}) {
+    return formals;
+  }
+
+  @override
+  List<SourceNominalParameterBuilder>? createTypeParameters(
+      {required DeclarationBuilder declarationBuilder,
+      required List<TypeParameterFragment>? declarationTypeParameterFragments,
+      required List<SourceNominalParameterBuilder>? typeParameters,
+      required List<NominalParameterBuilder> unboundNominalParameters}) {
+    NominalParameterCopy? nominalVariableCopy =
+        NominalParameterCopy.copyTypeParameters(
+            unboundNominalParameters: unboundNominalParameters,
+            oldParameterBuilders: declarationBuilder.typeParameters,
+            oldParameterFragments: declarationTypeParameterFragments,
+            kind: TypeParameterKind.extensionSynthesized,
+            instanceTypeParameterAccess:
+                InstanceTypeParameterAccessState.Allowed);
+    if (nominalVariableCopy != null) {
+      if (typeParameters != null) {
+        // Coverage-ignore-block(suite): Not run.
+        typeParameters = nominalVariableCopy.newParameterBuilders
+          ..addAll(typeParameters);
+      } else {
+        typeParameters = nominalVariableCopy.newParameterBuilders;
+      }
+    }
+    return typeParameters;
+  }
+}
+
+class ExtensionTypeConstructorEncodingStrategy
+    implements ConstructorEncodingStrategy {
+  const ExtensionTypeConstructorEncodingStrategy();
+
+  @override
+  List<FormalParameterBuilder>? createFormals(
+      {required SourceLoader loader,
+      required List<FormalParameterBuilder>? formals,
+      required Uri fileUri,
+      required int fileOffset}) {
+    return formals;
+  }
+
+  @override
+  List<SourceNominalParameterBuilder>? createTypeParameters({
+    required DeclarationBuilder declarationBuilder,
+    required List<TypeParameterFragment>? declarationTypeParameterFragments,
+    required List<SourceNominalParameterBuilder>? typeParameters,
+    required List<NominalParameterBuilder> unboundNominalParameters,
+  }) {
+    NominalParameterCopy? nominalVariableCopy =
+        NominalParameterCopy.copyTypeParameters(
+            unboundNominalParameters: unboundNominalParameters,
+            oldParameterBuilders: declarationBuilder.typeParameters,
+            oldParameterFragments: declarationTypeParameterFragments,
+            kind: TypeParameterKind.extensionSynthesized,
+            instanceTypeParameterAccess:
+                InstanceTypeParameterAccessState.Allowed);
+    if (nominalVariableCopy != null) {
+      if (typeParameters != null) {
+        // Coverage-ignore-block(suite): Not run.
+        typeParameters = nominalVariableCopy.newParameterBuilders
+          ..addAll(typeParameters);
+      } else {
+        typeParameters = nominalVariableCopy.newParameterBuilders;
+      }
+    }
+    return typeParameters;
+  }
+
+  @override
+  ConstructorEncoding createEncoding({required bool isExternal}) {
+    return new ExtensionTypeConstructorEncoding(isExternal: isExternal);
+  }
 }
diff --git a/pkg/front_end/lib/src/source/source_constructor_builder.dart b/pkg/front_end/lib/src/source/source_constructor_builder.dart
index 1a6ead6..200970a 100644
--- a/pkg/front_end/lib/src/source/source_constructor_builder.dart
+++ b/pkg/front_end/lib/src/source/source_constructor_builder.dart
@@ -160,11 +160,6 @@
       _augmentedDeclarations = [_introductory, ..._augmentations];
       _lastDeclaration = _augmentedDeclarations.removeLast();
     }
-
-    _introductory.registerInferable(this);
-    for (ConstructorDeclaration augmentation in _augmentations) {
-      augmentation.registerInferable(this);
-    }
   }
 
   // TODO(johnniwinther): Add annotations to tear-offs.
diff --git a/pkg/front_end/lib/src/source/source_enum_builder.dart b/pkg/front_end/lib/src/source/source_enum_builder.dart
index e745f8f..ea88097 100644
--- a/pkg/front_end/lib/src/source/source_enum_builder.dart
+++ b/pkg/front_end/lib/src/source/source_enum_builder.dart
@@ -6,6 +6,7 @@
 import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
 import 'package:front_end/src/base/messages.dart';
 import 'package:front_end/src/builder/property_builder.dart';
+import 'package:front_end/src/fragment/constructor/encoding.dart';
 import 'package:front_end/src/fragment/method/encoding.dart';
 import 'package:front_end/src/source/source_method_builder.dart';
 import 'package:kernel/ast.dart';
@@ -286,6 +287,9 @@
       }
     }
     if (needsSynthesizedDefaultConstructor) {
+      ConstructorEncodingStrategy encodingStrategy =
+          new ConstructorEncodingStrategy(this);
+
       FormalParameterBuilder nameFormalParameterBuilder =
           new FormalParameterBuilder(
               FormalParameterKind.requiredPositional,
@@ -343,6 +347,14 @@
               introductory: constructorDeclaration,
               isConst: true,
               isExternal: false);
+      constructorDeclaration.createEncoding(
+          problemReporting: libraryBuilder,
+          loader: libraryBuilder.loader,
+          declarationBuilder: this,
+          constructorBuilder: constructorBuilder,
+          unboundNominalParameters: const [],
+          encodingStrategy: encodingStrategy);
+
       constructorBuilder.registerInitializedField(valuesBuilder);
       addConstructorInternal(constructorBuilder, addToNameSpace: true);
       nameSpaceBuilder.checkTypeParameterConflict(
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 a7ff41c..a4a7246 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
@@ -2,7 +2,7 @@
 // for details. All rights reserved. Use of this source code is governed by a
 // BSD-style license that can be found in the LICENSE file.
 
-import 'package:_fe_analyzer_shared/src/parser/formal_parameter_kind.dart';
+import 'package:front_end/src/fragment/constructor/encoding.dart';
 import 'package:kernel/ast.dart';
 import 'package:kernel/reference_from_index.dart';
 import 'package:kernel/src/bounds_checks.dart' show VarianceCalculationValue;
@@ -18,7 +18,6 @@
 import '../builder/constructor_builder.dart';
 import '../builder/declaration_builders.dart';
 import '../builder/factory_builder.dart';
-import '../builder/formal_parameter_builder.dart';
 import '../builder/function_builder.dart';
 import '../builder/member_builder.dart';
 import '../builder/named_type_builder.dart';
@@ -2760,119 +2759,8 @@
   bool isConst = fragment.modifiers.isConst;
   bool isExternal = fragment.modifiers.isExternal;
 
-  NameScheme nameScheme = new NameScheme(
-      isInstanceMember: false,
-      containerName: containerName,
-      containerType: containerType,
-      libraryName: indexedLibrary != null
-          ? new LibraryName(indexedLibrary.library.reference)
-          : enclosingLibraryBuilder.libraryName);
-
-  createNominalParameterBuilders(
-      fragment.typeParameters, unboundNominalParameters);
-
-  ConstructorReferences constructorReferences = new ConstructorReferences(
-      name: name,
-      nameScheme: nameScheme,
-      indexedContainer: indexedContainer,
-      loader: loader,
-      declarationBuilder: declarationBuilder!);
-
-  ConstructorDeclaration createConstructorDeclaration(
-      ConstructorFragment fragment) {
-    switch (declarationBuilder) {
-      case ExtensionTypeDeclarationBuilder():
-        List<SourceNominalParameterBuilder>? typeParameters = fragment
-            .typeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders;
-        NominalParameterCopy? nominalVariableCopy =
-            NominalParameterCopy.copyTypeParameters(
-                unboundNominalParameters: unboundNominalParameters,
-                oldParameterBuilders: declarationBuilder.typeParameters,
-                oldParameterFragments:
-                    fragment.enclosingDeclaration.typeParameters,
-                kind: TypeParameterKind.extensionSynthesized,
-                instanceTypeParameterAccess:
-                    InstanceTypeParameterAccessState.Allowed);
-        if (nominalVariableCopy != null) {
-          if (typeParameters != null) {
-            // Coverage-ignore-block(suite): Not run.
-            typeParameters = nominalVariableCopy.newParameterBuilders
-              ..addAll(typeParameters);
-          } else {
-            typeParameters = nominalVariableCopy.newParameterBuilders;
-          }
-        }
-        fragment.typeParameterNameSpace.addTypeParameters(
-            problemReporting, typeParameters,
-            ownerName: fragment.name, allowNameConflict: true);
-        return new ExtensionTypeConstructorDeclaration(fragment,
-            typeParameters: typeParameters);
-      case ClassBuilder():
-        List<FormalParameterBuilder>? syntheticFormals;
-        if (declarationBuilder.isEnum) {
-          syntheticFormals = [
-            new FormalParameterBuilder(
-                FormalParameterKind.requiredPositional,
-                Modifiers.empty,
-                loader.target.intType,
-                "#index",
-                fragment.fullNameOffset,
-                fileUri: fragment.fileUri,
-                hasImmediatelyDeclaredInitializer: false),
-            new FormalParameterBuilder(
-                FormalParameterKind.requiredPositional,
-                Modifiers.empty,
-                loader.target.stringType,
-                "#name",
-                fragment.fullNameOffset,
-                fileUri: fragment.fileUri,
-                hasImmediatelyDeclaredInitializer: false),
-          ];
-        }
-        List<SourceNominalParameterBuilder>? typeParameters =
-            fragment.typeParameters?.builders;
-        fragment.typeParameterNameSpace.addTypeParameters(
-            problemReporting, typeParameters,
-            ownerName: fragment.name, allowNameConflict: true);
-        return new RegularConstructorDeclaration(fragment,
-            typeParameters: typeParameters,
-            syntheticFormals: syntheticFormals,
-            isEnumConstructor: declarationBuilder.isEnum);
-      case ExtensionBuilder():
-        List<SourceNominalParameterBuilder>? typeParameters = fragment
-            .typeParameters
-            // Coverage-ignore(suite): Not run.
-            ?.builders;
-        NominalParameterCopy? nominalVariableCopy =
-            NominalParameterCopy.copyTypeParameters(
-                unboundNominalParameters: unboundNominalParameters,
-                oldParameterBuilders: declarationBuilder.typeParameters,
-                oldParameterFragments:
-                    fragment.enclosingDeclaration.typeParameters,
-                kind: TypeParameterKind.extensionSynthesized,
-                instanceTypeParameterAccess:
-                    InstanceTypeParameterAccessState.Allowed);
-        if (nominalVariableCopy != null) {
-          if (typeParameters != null) {
-            // Coverage-ignore-block(suite): Not run.
-            typeParameters = nominalVariableCopy.newParameterBuilders
-              ..addAll(typeParameters);
-          } else {
-            typeParameters = nominalVariableCopy.newParameterBuilders;
-          }
-        }
-        fragment.typeParameterNameSpace.addTypeParameters(
-            problemReporting, typeParameters,
-            ownerName: fragment.name, allowNameConflict: true);
-        return new ExtensionConstructorDeclaration(fragment,
-            typeParameters: typeParameters);
-    }
-  }
-
   ConstructorDeclaration constructorDeclaration =
-      createConstructorDeclaration(fragment);
+      new RegularConstructorDeclaration(fragment);
 
   List<ConstructorDeclaration> augmentationDeclarations = [];
   if (augmentations != null) {
@@ -2880,10 +2768,8 @@
       // Promote [augmentation] to [ConstructorFragment].
       augmentation as ConstructorFragment;
 
-      createNominalParameterBuilders(
-          augmentation.typeParameters, unboundNominalParameters);
-
-      augmentationDeclarations.add(createConstructorDeclaration(augmentation));
+      augmentationDeclarations
+          .add(new RegularConstructorDeclaration(augmentation));
 
       if (!augmentation.modifiers.isExternal) {
         isExternal = false;
@@ -2898,7 +2784,6 @@
       loader: loader,
       name: name,
       uriOffset: fragment.uriOffset,
-      nameScheme: nameScheme,
       enclosingLibraryBuilder: enclosingLibraryBuilder,
       declarationBuilder: declarationBuilder,
       unboundNominalParameters: unboundNominalParameters,
@@ -2906,7 +2791,6 @@
       containerType: containerType,
       indexedContainer: indexedContainer,
       containerName: containerName,
-      constructorReferences: constructorReferences,
       nativeMethodName: fragment.nativeMethodName,
       isConst: isConst,
       isExternal: isExternal,
@@ -2920,7 +2804,6 @@
     required SourceLoader loader,
     required String name,
     required UriOffsetLength uriOffset,
-    required NameScheme nameScheme,
     required SourceLibraryBuilder enclosingLibraryBuilder,
     required DeclarationBuilder? declarationBuilder,
     required List<NominalParameterBuilder> unboundNominalParameters,
@@ -2928,15 +2811,32 @@
     required ContainerType containerType,
     required IndexedContainer? indexedContainer,
     required ContainerName? containerName,
-    required ConstructorReferences constructorReferences,
     required String? nativeMethodName,
     required bool isConst,
     required bool isExternal,
     required bool inPatch}) {
+  NameScheme nameScheme = new NameScheme(
+      isInstanceMember: false,
+      containerName: containerName,
+      containerType: containerType,
+      libraryName: indexedLibrary != null
+          ? new LibraryName(indexedLibrary.library.reference)
+          : enclosingLibraryBuilder.libraryName);
+
+  ConstructorEncodingStrategy encodingStrategy =
+      new ConstructorEncodingStrategy(declarationBuilder!);
+
+  ConstructorReferences constructorReferences = new ConstructorReferences(
+      name: name,
+      nameScheme: nameScheme,
+      indexedContainer: indexedContainer,
+      loader: loader,
+      declarationBuilder: declarationBuilder);
+
   SourceConstructorBuilder constructorBuilder = new SourceConstructorBuilder(
       name: name,
       libraryBuilder: enclosingLibraryBuilder,
-      declarationBuilder: declarationBuilder!,
+      declarationBuilder: declarationBuilder,
       fileUri: uriOffset.fileUri,
       fileOffset: uriOffset.fileOffset,
       constructorReferences: constructorReferences,
@@ -2948,9 +2848,21 @@
       isExternal: isExternal);
   constructorReferences.registerReference(loader, constructorBuilder);
 
-  constructorDeclaration.createEncoding(constructorBuilder);
+  constructorDeclaration.createEncoding(
+      problemReporting: problemReporting,
+      loader: loader,
+      declarationBuilder: declarationBuilder,
+      constructorBuilder: constructorBuilder,
+      unboundNominalParameters: unboundNominalParameters,
+      encodingStrategy: encodingStrategy);
   for (ConstructorDeclaration augmentation in augmentationDeclarations) {
-    augmentation.createEncoding(constructorBuilder);
+    augmentation.createEncoding(
+        problemReporting: problemReporting,
+        loader: loader,
+        declarationBuilder: declarationBuilder,
+        constructorBuilder: constructorBuilder,
+        unboundNominalParameters: unboundNominalParameters,
+        encodingStrategy: encodingStrategy);
   }
   return new _AddBuilder(name, constructorBuilder, uriOffset, inPatch: inPatch);
 }
@@ -2968,57 +2880,15 @@
     required ContainerName? containerName}) {
   String name = fragment.name;
 
-  NameScheme nameScheme = new NameScheme(
-      isInstanceMember: false,
-      containerName: containerName,
-      containerType: containerType,
-      libraryName: indexedLibrary != null
-          ? new LibraryName(indexedLibrary.library.reference)
-          : enclosingLibraryBuilder.libraryName);
+  ConstructorDeclaration constructorDeclaration =
+      new PrimaryConstructorDeclaration(fragment);
 
-  ConstructorReferences constructorReferences = new ConstructorReferences(
-      name: name,
-      nameScheme: nameScheme,
-      indexedContainer: indexedContainer,
-      loader: loader,
-      declarationBuilder: declarationBuilder!);
-
-  ConstructorDeclaration constructorDeclaration;
-  switch (declarationBuilder) {
-    case ExtensionTypeDeclarationBuilder():
-      NominalParameterCopy? nominalVariableCopy =
-          NominalParameterCopy.copyTypeParameters(
-              unboundNominalParameters: unboundNominalParameters,
-              oldParameterBuilders: declarationBuilder.typeParameters,
-              oldParameterFragments:
-                  fragment.enclosingDeclaration.typeParameters,
-              kind: TypeParameterKind.extensionSynthesized,
-              instanceTypeParameterAccess:
-                  InstanceTypeParameterAccessState.Allowed);
-
-      List<SourceNominalParameterBuilder>? typeParameters =
-          nominalVariableCopy?.newParameterBuilders;
-      fragment.typeParameterNameSpace.addTypeParameters(
-          problemReporting, typeParameters,
-          ownerName: fragment.name, allowNameConflict: true);
-      constructorDeclaration = new ExtensionTypePrimaryConstructorDeclaration(
-          fragment,
-          typeParameters: typeParameters);
-    // Coverage-ignore(suite): Not run.
-    case ClassBuilder():
-      constructorDeclaration = new PrimaryConstructorDeclaration(fragment);
-    // Coverage-ignore(suite): Not run.
-    case ExtensionBuilder():
-      throw new UnsupportedError(
-          'Unexpected extension primary constructor $fragment');
-  }
   return _createConstructorBuilderFromDeclarations(
       constructorDeclaration, const [],
       problemReporting: problemReporting,
       loader: loader,
       name: name,
       uriOffset: fragment.uriOffset,
-      nameScheme: nameScheme,
       enclosingLibraryBuilder: enclosingLibraryBuilder,
       declarationBuilder: declarationBuilder,
       unboundNominalParameters: unboundNominalParameters,
@@ -3026,7 +2896,6 @@
       containerType: containerType,
       indexedContainer: indexedContainer,
       containerName: containerName,
-      constructorReferences: constructorReferences,
       nativeMethodName: null,
       isConst: fragment.modifiers.isConst,
       isExternal: fragment.modifiers.isExternal,
diff --git a/pkg/front_end/test/coverage_suite_expected.dart b/pkg/front_end/test/coverage_suite_expected.dart
index 75cb31b..47cf26d 100644
--- a/pkg/front_end/test/coverage_suite_expected.dart
+++ b/pkg/front_end/test/coverage_suite_expected.dart
@@ -505,12 +505,12 @@
   ),
   // 100.0%.
   "package:front_end/src/fragment/constructor/declaration.dart": (
-    hitCount: 735,
+    hitCount: 622,
     missCount: 0,
   ),
   // 100.0%.
   "package:front_end/src/fragment/constructor/encoding.dart": (
-    hitCount: 421,
+    hitCount: 489,
     missCount: 0,
   ),
   // 100.0%.
@@ -955,12 +955,12 @@
   ),
   // 100.0%.
   "package:front_end/src/source/source_constructor_builder.dart": (
-    hitCount: 360,
+    hitCount: 356,
     missCount: 0,
   ),
   // 100.0%.
   "package:front_end/src/source/source_enum_builder.dart": (
-    hitCount: 423,
+    hitCount: 428,
     missCount: 0,
   ),
   // 100.0%.
@@ -1026,7 +1026,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/type_parameter_scope_builder.dart": (
-    hitCount: 1519,
+    hitCount: 1458,
     missCount: 0,
   ),
   // 100.0%.