[cfe] Add TypeParameterFragment

This is a step towards only creating NominalParameterBuilders on the Builder.

Change-Id: Ic47ca37e980cfe641180dc03053bb9b45cd3fac3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/408022
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fragment/class/declaration.dart b/pkg/front_end/lib/src/fragment/class/declaration.dart
index 56f7480..d4ace97 100644
--- a/pkg/front_end/lib/src/fragment/class/declaration.dart
+++ b/pkg/front_end/lib/src/fragment/class/declaration.dart
@@ -47,7 +47,8 @@
   int get startOffset => _fragment.startOffset;
 
   @override
-  List<NominalParameterBuilder>? get typeParameters => _fragment.typeParameters;
+  List<NominalParameterBuilder>? get typeParameters =>
+      _fragment.typeParameters?.builders;
 
   @override
   bool get isMixinDeclaration => false;
@@ -92,7 +93,8 @@
   int get startOffset => _fragment.startOffset;
 
   @override
-  List<NominalParameterBuilder>? get typeParameters => _fragment.typeParameters;
+  List<NominalParameterBuilder>? get typeParameters =>
+      _fragment.typeParameters?.builders;
 
   @override
   bool get isMixinDeclaration => false;
@@ -134,7 +136,8 @@
   int get startOffset => _fragment.startOffset;
 
   @override
-  List<NominalParameterBuilder>? get typeParameters => _fragment.typeParameters;
+  List<NominalParameterBuilder>? get typeParameters =>
+      _fragment.typeParameters?.builders;
 
   @override
   bool get isMixinDeclaration => false;
@@ -222,7 +225,8 @@
   int get startOffset => _fragment.startOffset;
 
   @override
-  List<NominalParameterBuilder>? get typeParameters => _fragment.typeParameters;
+  List<NominalParameterBuilder>? get typeParameters =>
+      _fragment.typeParameters?.builders;
 
   @override
   bool get isMixinDeclaration => true;
diff --git a/pkg/front_end/lib/src/fragment/constructor.dart b/pkg/front_end/lib/src/fragment/constructor.dart
index cc14d00..55ce76f 100644
--- a/pkg/front_end/lib/src/fragment/constructor.dart
+++ b/pkg/front_end/lib/src/fragment/constructor.dart
@@ -14,7 +14,7 @@
   final Modifiers modifiers;
   final List<MetadataBuilder>? metadata;
   final OmittedTypeBuilder returnType;
-  final List<NominalParameterBuilder>? typeParameters;
+  final List<TypeParameterFragment>? typeParameters;
   final NominalParameterNameSpace typeParameterNameSpace;
   final LookupScope typeParameterScope;
   final List<FormalParameterBuilder>? formals;
diff --git a/pkg/front_end/lib/src/fragment/fragment.dart b/pkg/front_end/lib/src/fragment/fragment.dart
index 5fdae9c..bc8edd6 100644
--- a/pkg/front_end/lib/src/fragment/fragment.dart
+++ b/pkg/front_end/lib/src/fragment/fragment.dart
@@ -80,6 +80,7 @@
 part 'named_mixin_application.dart';
 part 'primary_constructor.dart';
 part 'setter.dart';
+part 'type_parameter.dart';
 part 'typedef.dart';
 part 'util.dart';
 
diff --git a/pkg/front_end/lib/src/fragment/getter.dart b/pkg/front_end/lib/src/fragment/getter.dart
index a0ba8ef..526b22d 100644
--- a/pkg/front_end/lib/src/fragment/getter.dart
+++ b/pkg/front_end/lib/src/fragment/getter.dart
@@ -33,7 +33,7 @@
   ///
   /// This is only non-null in erroneous cases since getters don't have type
   /// parameters.
-  final List<NominalParameterBuilder>? declaredTypeParameters;
+  final List<TypeParameterFragment>? declaredTypeParameters;
 
   /// The scope that introduces type parameters on this getter.
   ///
@@ -303,9 +303,16 @@
         asyncMarker: _fragment.asyncModifier)
       ..fileOffset = _fragment.formalsOffset
       ..fileEndOffset = _fragment.endOffset;
-    buildTypeParametersAndFormals(libraryBuilder, function,
-        _fragment.declaredTypeParameters, _fragment.declaredFormals,
-        classTypeParameters: classTypeParameters, supportsTypeParameters: true);
+    buildTypeParametersAndFormals(
+        libraryBuilder,
+        function,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        _fragment.declaredFormals,
+        classTypeParameters: classTypeParameters,
+        supportsTypeParameters: true);
     if (_fragment.returnType is! InferableTypeBuilder) {
       function.returnType =
           _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
@@ -349,7 +356,10 @@
         libraryBuilder,
         bodyBuilderContext,
         _fragment.typeParameterScope,
-        _fragment.declaredTypeParameters);
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
     _buildFormalsForOutlineExpressions(
         libraryBuilder, declarationBuilder, _fragment.declaredFormals,
         isClassInstanceMember: isClassInstanceMember);
@@ -368,8 +378,10 @@
 
   @override
   int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(
-        _fragment.declaredTypeParameters);
+    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders);
     context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
     if (_fragment.returnType is! OmittedTypeBuilder) {
       hasErrors |=
@@ -378,7 +390,10 @@
           _fragment.returnType);
     }
     return context.computeDefaultTypesForVariables(
-        _fragment.declaredTypeParameters,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
         inErrorRecovery: hasErrors);
   }
 
@@ -410,8 +425,10 @@
   void checkTypes(SourceLibraryBuilder libraryBuilder,
       TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
       {required bool isAbstract, required bool isExternal}) {
-    List<TypeParameterBuilder>? typeParameters =
-        _fragment.declaredTypeParameters;
+    List<TypeParameterBuilder>? typeParameters = _fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders;
     // Coverage-ignore(suite): Not run.
     if (typeParameters != null && typeParameters.isNotEmpty) {
       libraryBuilder.checkTypeParameterDependencies(typeParameters);
@@ -441,7 +458,11 @@
   void checkVariance(
       SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
     sourceClassBuilder.checkVarianceInTypeParameters(
-        typeEnvironment, _fragment.declaredTypeParameters);
+        typeEnvironment,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
     sourceClassBuilder.checkVarianceInFormals(
         typeEnvironment, _fragment.declaredFormals);
     sourceClassBuilder.checkVarianceInReturnType(
@@ -451,7 +472,10 @@
 
   @override
   List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
-      _fragment.declaredTypeParameters;
+      _fragment
+          .declaredTypeParameters
+          // Coverage-ignore(suite): Not run.
+          ?.builders;
 
   @override
   // Coverage-ignore(suite): Not run.
@@ -541,9 +565,16 @@
         asyncMarker: _fragment.asyncModifier)
       ..fileOffset = _fragment.formalsOffset
       ..fileEndOffset = _fragment.endOffset;
-    buildTypeParametersAndFormals(libraryBuilder, function,
-        _fragment.declaredTypeParameters, _fragment.declaredFormals,
-        classTypeParameters: classTypeParameters, supportsTypeParameters: true);
+    buildTypeParametersAndFormals(
+        libraryBuilder,
+        function,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        _fragment.declaredFormals,
+        classTypeParameters: classTypeParameters,
+        supportsTypeParameters: true);
     if (_fragment.returnType is! InferableTypeBuilder) {
       function.returnType =
           _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
@@ -588,7 +619,10 @@
         libraryBuilder,
         bodyBuilderContext,
         _fragment.typeParameterScope,
-        _fragment.declaredTypeParameters);
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
     _buildFormalsForOutlineExpressions(
         libraryBuilder, declarationBuilder, _fragment.declaredFormals,
         isClassInstanceMember: isClassInstanceMember);
@@ -627,8 +661,10 @@
 
   @override
   int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(
-        _fragment.declaredTypeParameters);
+    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders);
     context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
     if (_fragment.returnType is! OmittedTypeBuilder) {
       hasErrors |=
@@ -646,7 +682,7 @@
         //  required and unnecessary.
         // ignore: unnecessary_non_null_assertion
         ..._clonedDeclarationTypeParameters!,
-        ..._fragment.declaredTypeParameters!
+        ..._fragment.declaredTypeParameters!.builders
       ], inErrorRecovery: hasErrors);
     } else if (_clonedDeclarationTypeParameters != null) {
       return context.computeDefaultTypesForVariables(
@@ -654,7 +690,10 @@
           inErrorRecovery: hasErrors);
     } else {
       return context.computeDefaultTypesForVariables(
-          _fragment.declaredTypeParameters,
+          _fragment
+              .declaredTypeParameters
+              // Coverage-ignore(suite): Not run.
+              ?.builders,
           inErrorRecovery: hasErrors);
     }
   }
@@ -700,8 +739,10 @@
   void checkTypes(SourceLibraryBuilder libraryBuilder,
       TypeEnvironment typeEnvironment, SourcePropertyBuilder? setterBuilder,
       {required bool isAbstract, required bool isExternal}) {
-    List<TypeParameterBuilder>? typeParameters =
-        _fragment.declaredTypeParameters;
+    List<TypeParameterBuilder>? typeParameters = _fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders;
     // Coverage-ignore(suite): Not run.
     if (typeParameters != null && typeParameters.isNotEmpty) {
       libraryBuilder.checkTypeParameterDependencies(typeParameters);
@@ -732,7 +773,7 @@
   void checkVariance(
       SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
     sourceClassBuilder.checkVarianceInTypeParameters(
-        typeEnvironment, _fragment.declaredTypeParameters);
+        typeEnvironment, _fragment.declaredTypeParameters?.builders);
     sourceClassBuilder.checkVarianceInFormals(
         typeEnvironment, _fragment.declaredFormals);
     sourceClassBuilder.checkVarianceInReturnType(
@@ -746,7 +787,10 @@
               _fragment.declaredTypeParameters != null
           ? [
               ...?_clonedDeclarationTypeParameters,
-              ...?_fragment.declaredTypeParameters
+              ...?_fragment
+                  .declaredTypeParameters
+                  // Coverage-ignore(suite): Not run.
+                  ?.builders
             ]
           : null;
 
diff --git a/pkg/front_end/lib/src/fragment/named_mixin_application.dart b/pkg/front_end/lib/src/fragment/named_mixin_application.dart
index bd9cbbe..708487e 100644
--- a/pkg/front_end/lib/src/fragment/named_mixin_application.dart
+++ b/pkg/front_end/lib/src/fragment/named_mixin_application.dart
@@ -14,7 +14,7 @@
   final int endOffset;
   final Modifiers modifiers;
   final List<MetadataBuilder>? metadata;
-  final List<NominalParameterBuilder>? typeParameters;
+  final List<TypeParameterFragment>? typeParameters;
   final TypeBuilder? supertype;
   final List<TypeBuilder> mixins;
   final List<TypeBuilder>? interfaces;
diff --git a/pkg/front_end/lib/src/fragment/setter.dart b/pkg/front_end/lib/src/fragment/setter.dart
index b220a49..40e0733 100644
--- a/pkg/front_end/lib/src/fragment/setter.dart
+++ b/pkg/front_end/lib/src/fragment/setter.dart
@@ -33,7 +33,7 @@
   ///
   /// This is only non-null in erroneous cases since setters don't have type
   /// parameters.
-  final List<NominalParameterBuilder>? declaredTypeParameters;
+  final List<TypeParameterFragment>? declaredTypeParameters;
 
   /// The scope that introduces type parameters on this setter.
   ///
@@ -328,9 +328,16 @@
         asyncMarker: _fragment.asyncModifier)
       ..fileOffset = _fragment.formalsOffset
       ..fileEndOffset = _fragment.endOffset;
-    buildTypeParametersAndFormals(libraryBuilder, function,
-        _fragment.declaredTypeParameters, _fragment.declaredFormals,
-        classTypeParameters: classTypeParameters, supportsTypeParameters: true);
+    buildTypeParametersAndFormals(
+        libraryBuilder,
+        function,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        _fragment.declaredFormals,
+        classTypeParameters: classTypeParameters,
+        supportsTypeParameters: true);
     if (_fragment.returnType is! InferableTypeBuilder) {
       function.returnType =
           _fragment.returnType.build(libraryBuilder, TypeUse.returnType);
@@ -386,7 +393,10 @@
         libraryBuilder,
         bodyBuilderContext,
         _fragment.typeParameterScope,
-        _fragment.declaredTypeParameters);
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
     _buildFormalsForOutlineExpressions(
         libraryBuilder, declarationBuilder, _fragment.declaredFormals,
         isClassInstanceMember: isClassInstanceMember);
@@ -401,8 +411,10 @@
   void checkTypes(
       SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
       {required bool isAbstract, required bool isExternal}) {
-    List<TypeParameterBuilder>? typeParameters =
-        _fragment.declaredTypeParameters;
+    List<TypeParameterBuilder>? typeParameters = _fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders;
     // Coverage-ignore(suite): Not run.
     if (typeParameters != null && typeParameters.isNotEmpty) {
       libraryBuilder.checkTypeParameterDependencies(typeParameters);
@@ -416,7 +428,11 @@
   void checkVariance(
       SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
     sourceClassBuilder.checkVarianceInTypeParameters(
-        typeEnvironment, _fragment.declaredTypeParameters);
+        typeEnvironment,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
     sourceClassBuilder.checkVarianceInFormals(
         typeEnvironment, _fragment.declaredFormals);
     sourceClassBuilder.checkVarianceInReturnType(
@@ -426,8 +442,10 @@
 
   @override
   int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(
-        _fragment.declaredTypeParameters);
+    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders);
     context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
     if (_fragment.returnType is! OmittedTypeBuilder) {
       hasErrors |=
@@ -436,7 +454,10 @@
           _fragment.returnType);
     }
     return context.computeDefaultTypesForVariables(
-        _fragment.declaredTypeParameters,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
         inErrorRecovery: hasErrors);
   }
 
@@ -456,7 +477,10 @@
 
   @override
   List<NominalParameterBuilder>? get clonedAndDeclaredTypeParameters =>
-      _fragment.declaredTypeParameters;
+      _fragment
+          .declaredTypeParameters
+          // Coverage-ignore(suite): Not run.
+          ?.builders;
 
   @override
   // Coverage-ignore(suite): Not run.
@@ -565,9 +589,16 @@
         asyncMarker: _fragment.asyncModifier)
       ..fileOffset = _fragment.formalsOffset
       ..fileEndOffset = _fragment.endOffset;
-    buildTypeParametersAndFormals(libraryBuilder, function,
-        _fragment.declaredTypeParameters, _fragment.declaredFormals,
-        classTypeParameters: classTypeParameters, supportsTypeParameters: true);
+    buildTypeParametersAndFormals(
+        libraryBuilder,
+        function,
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        _fragment.declaredFormals,
+        classTypeParameters: classTypeParameters,
+        supportsTypeParameters: true);
     // TODO(johnniwinther): We should have a consistent normalization strategy.
     // We ensure that setters have 1 parameter, but for getters we include all
     // declared parameters.
@@ -629,7 +660,10 @@
         libraryBuilder,
         bodyBuilderContext,
         _fragment.typeParameterScope,
-        _fragment.declaredTypeParameters);
+        _fragment
+            .declaredTypeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders);
     _buildFormalsForOutlineExpressions(
         libraryBuilder, declarationBuilder, _fragment.declaredFormals,
         isClassInstanceMember: isClassInstanceMember);
@@ -655,8 +689,10 @@
   void checkTypes(
       SourceLibraryBuilder libraryBuilder, TypeEnvironment typeEnvironment,
       {required bool isAbstract, required bool isExternal}) {
-    List<TypeParameterBuilder>? typeParameters =
-        _fragment.declaredTypeParameters;
+    List<TypeParameterBuilder>? typeParameters = _fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders;
     // Coverage-ignore(suite): Not run.
     if (typeParameters != null && typeParameters.isNotEmpty) {
       libraryBuilder.checkTypeParameterDependencies(typeParameters);
@@ -671,7 +707,7 @@
   void checkVariance(
       SourceClassBuilder sourceClassBuilder, TypeEnvironment typeEnvironment) {
     sourceClassBuilder.checkVarianceInTypeParameters(
-        typeEnvironment, _fragment.declaredTypeParameters);
+        typeEnvironment, _fragment.declaredTypeParameters?.builders);
     sourceClassBuilder.checkVarianceInFormals(
         typeEnvironment, _fragment.declaredFormals);
     sourceClassBuilder.checkVarianceInReturnType(
@@ -700,8 +736,10 @@
 
   @override
   int computeDefaultTypes(ComputeDefaultTypeContext context) {
-    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(
-        _fragment.declaredTypeParameters);
+    bool hasErrors = context.reportSimplicityIssuesForTypeParameters(_fragment
+        .declaredTypeParameters
+        // Coverage-ignore(suite): Not run.
+        ?.builders);
     context.reportGenericFunctionTypesForFormals(_fragment.declaredFormals);
     if (_fragment.returnType is! OmittedTypeBuilder) {
       hasErrors |=
@@ -719,7 +757,7 @@
         //  required and unnecessary.
         // ignore: unnecessary_non_null_assertion
         ..._clonedDeclarationTypeParameters!,
-        ..._fragment.declaredTypeParameters!
+        ..._fragment.declaredTypeParameters!.builders
       ], inErrorRecovery: hasErrors);
     } else if (_clonedDeclarationTypeParameters != null) {
       return context.computeDefaultTypesForVariables(
@@ -727,7 +765,10 @@
           inErrorRecovery: hasErrors);
     } else {
       return context.computeDefaultTypesForVariables(
-          _fragment.declaredTypeParameters,
+          _fragment
+              .declaredTypeParameters
+              // Coverage-ignore(suite): Not run.
+              ?.builders,
           inErrorRecovery: hasErrors);
     }
   }
@@ -763,7 +804,10 @@
               _fragment.declaredTypeParameters != null
           ? [
               ...?_clonedDeclarationTypeParameters,
-              ...?_fragment.declaredTypeParameters
+              ...?_fragment
+                  .declaredTypeParameters
+                  // Coverage-ignore(suite): Not run.
+                  ?.builders
             ]
           : null;
 
diff --git a/pkg/front_end/lib/src/fragment/type_parameter.dart b/pkg/front_end/lib/src/fragment/type_parameter.dart
new file mode 100644
index 0000000..85d7f2b
--- /dev/null
+++ b/pkg/front_end/lib/src/fragment/type_parameter.dart
@@ -0,0 +1,41 @@
+// Copyright (c) 2025, the Dart project authors.  Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+part of 'fragment.dart';
+
+class TypeParameterFragment {
+  final List<MetadataBuilder>? metadata;
+  final String name;
+  final TypeBuilder? bound;
+  final int nameOffset;
+  final Uri fileUri;
+  final TypeParameterKind kind;
+  final bool isWildcard;
+  final String variableName;
+
+  late final NominalParameterBuilder _builder;
+
+  TypeParameterFragment(
+      {required this.metadata,
+      required this.name,
+      required this.bound,
+      required this.nameOffset,
+      required this.fileUri,
+      required this.kind,
+      required this.isWildcard,
+      required this.variableName});
+
+  NominalParameterBuilder get builder => _builder;
+
+  void set builder(NominalParameterBuilder value) {
+    _builder = value;
+  }
+}
+
+// TODO(johnniwinther): Avoid this.
+extension TypeParameterFragmentHelper on List<TypeParameterFragment> {
+  List<NominalParameterBuilder> get builders {
+    return this.map((p) => p.builder).toList();
+  }
+}
diff --git a/pkg/front_end/lib/src/fragment/typedef.dart b/pkg/front_end/lib/src/fragment/typedef.dart
index f237a1f..a222f7d 100644
--- a/pkg/front_end/lib/src/fragment/typedef.dart
+++ b/pkg/front_end/lib/src/fragment/typedef.dart
@@ -10,7 +10,7 @@
   @override
   final String name;
 
-  final List<NominalParameterBuilder>? typeParameters;
+  final List<TypeParameterFragment>? typeParameters;
   final TypeBuilder type;
   final Uri fileUri;
   final int nameOffset;
diff --git a/pkg/front_end/lib/src/kernel/utils.dart b/pkg/front_end/lib/src/kernel/utils.dart
index 0c7612b..b25cd7f 100644
--- a/pkg/front_end/lib/src/kernel/utils.dart
+++ b/pkg/front_end/lib/src/kernel/utils.dart
@@ -25,6 +25,7 @@
 import '../builder/omitted_type_builder.dart';
 import '../builder/record_type_builder.dart';
 import '../builder/type_builder.dart';
+import '../fragment/fragment.dart';
 import '../source/builder_factory.dart';
 import 'body_builder.dart';
 
@@ -260,6 +261,16 @@
     new NominalParameterBuilder(
         NominalParameterBuilder.noNameSentinel, -1, null,
         kind: TypeParameterKind.function);
+final TypeParameterFragment dummyTypeParameterFragment =
+    new TypeParameterFragment(
+        metadata: null,
+        name: '',
+        bound: null,
+        nameOffset: -1,
+        fileUri: dummyUri,
+        kind: TypeParameterKind.function,
+        isWildcard: false,
+        variableName: '');
 final StructuralParameterBuilder dummyStructuralVariableBuilder =
     new StructuralParameterBuilder(
         StructuralParameterBuilder.noNameSentinel, -1, null);
diff --git a/pkg/front_end/lib/src/source/builder_factory.dart b/pkg/front_end/lib/src/source/builder_factory.dart
index 7440e40..e3004da7 100644
--- a/pkg/front_end/lib/src/source/builder_factory.dart
+++ b/pkg/front_end/lib/src/source/builder_factory.dart
@@ -70,58 +70,58 @@
 
   /// Registers that this builder is preparing for a class declaration with the
   /// given [name] and [typeParameters] located at [nameOffset].
-  void beginClassDeclaration(String name, int nameOffset,
-      List<NominalParameterBuilder>? typeParameters);
+  void beginClassDeclaration(
+      String name, int nameOffset, List<TypeParameterFragment>? typeParameters);
 
   void beginClassBody();
 
   void endClassDeclaration(String name);
 
   void endClassDeclarationForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   /// Registers that this builder is preparing for a mixin declaration with the
   /// given [name] and [typeParameters] located at [nameOffset].
-  void beginMixinDeclaration(String name, int nameOffset,
-      List<NominalParameterBuilder>? typeParameters);
+  void beginMixinDeclaration(
+      String name, int nameOffset, List<TypeParameterFragment>? typeParameters);
 
   void beginMixinBody();
 
   void endMixinDeclaration(String name);
 
   void endMixinDeclarationForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   /// Registers that this builder is preparing for a named mixin application
   /// with the given [name] and [typeParameters] located [charOffset].
-  void beginNamedMixinApplication(String name, int charOffset,
-      List<NominalParameterBuilder>? typeParameters);
+  void beginNamedMixinApplication(
+      String name, int charOffset, List<TypeParameterFragment>? typeParameters);
 
   void endNamedMixinApplication(String name);
 
   void endNamedMixinApplicationForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   void beginEnumDeclarationHeader(String name);
 
   /// Registers that this builder is preparing for an enum declaration with
   /// the given [name] and [typeParameters] located at [nameOffset].
-  void beginEnumDeclaration(String name, int nameOffset,
-      List<NominalParameterBuilder>? typeParameters);
+  void beginEnumDeclaration(
+      String name, int nameOffset, List<TypeParameterFragment>? typeParameters);
 
   void beginEnumBody();
 
   void endEnumDeclaration(String name);
 
   void endEnumDeclarationForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   void beginExtensionOrExtensionTypeHeader();
 
   /// Registers that this builder is preparing for an extension declaration with
   /// the given [name] and [typeParameters] located [charOffset].
   void beginExtensionDeclaration(String? name, int charOffset,
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   void beginExtensionBody();
 
@@ -129,8 +129,8 @@
 
   /// Registers that this builder is preparing for an extension type declaration
   /// with the given [name] and [typeParameters] located at [nameOffset].
-  void beginExtensionTypeDeclaration(String name, int nameOffset,
-      List<NominalParameterBuilder>? typeParameters);
+  void beginExtensionTypeDeclaration(
+      String name, int nameOffset, List<TypeParameterFragment>? typeParameters);
 
   void beginExtensionTypeBody();
 
@@ -147,29 +147,28 @@
   void beginConstructor();
 
   void endConstructorForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   void beginStaticMethod();
 
   void endStaticMethodForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   void beginInstanceMethod();
 
   void endInstanceMethodForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   void beginTopLevelMethod();
 
   void endTopLevelMethodForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+      List<TypeParameterFragment>? typeParameters);
 
   void beginTypedef();
 
   void endTypedef();
 
-  void endTypedefForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters);
+  void endTypedefForParserRecovery(List<TypeParameterFragment>? typeParameters);
 
   void checkStacks();
 
@@ -215,7 +214,7 @@
       required List<MetadataBuilder>? metadata,
       required Modifiers modifiers,
       required Identifier identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required TypeBuilder? supertype,
       required List<TypeBuilder>? mixins,
       required List<TypeBuilder>? interfaces,
@@ -228,7 +227,7 @@
       {required OffsetMap offsetMap,
       required List<MetadataBuilder>? metadata,
       required Identifier identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<TypeBuilder>? mixins,
       required List<TypeBuilder>? interfaces,
       required int startOffset,
@@ -247,7 +246,7 @@
       required List<MetadataBuilder>? metadata,
       required Modifiers modifiers,
       required Identifier? identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required TypeBuilder onType,
       required int startOffset,
       required int nameOrExtensionOffset,
@@ -258,7 +257,7 @@
       required List<MetadataBuilder>? metadata,
       required Modifiers modifiers,
       required Identifier identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<TypeBuilder>? interfaces,
       required int startOffset,
       required int endOffset});
@@ -268,7 +267,7 @@
       required List<MetadataBuilder>? metadata,
       required Modifiers modifiers,
       required Identifier identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<TypeBuilder>? supertypeConstraints,
       required List<TypeBuilder>? interfaces,
       required int startOffset,
@@ -278,7 +277,7 @@
   void addNamedMixinApplication(
       {required List<MetadataBuilder>? metadata,
       required String name,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required Modifiers modifiers,
       required TypeBuilder? supertype,
       required List<TypeBuilder> mixins,
@@ -290,7 +289,7 @@
   void addFunctionTypeAlias(
       List<MetadataBuilder>? metadata,
       String name,
-      List<NominalParameterBuilder>? typeParameters,
+      List<TypeParameterFragment>? typeParameters,
       TypeBuilder type,
       int nameOffset);
 
@@ -301,7 +300,7 @@
       required String name,
       required TypeBuilder? returnType,
       required List<FormalParameterBuilder>? formals,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required Token? beginInitializers,
       required int startOffset,
       required int endOffset,
@@ -324,7 +323,7 @@
       required Modifiers modifiers,
       required Identifier identifier,
       required ConstructorName constructorName,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<FormalParameterBuilder>? formals,
       required int startOffset,
       required int formalsOffset,
@@ -374,7 +373,7 @@
       required TypeBuilder? returnType,
       required Identifier identifier,
       required String name,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<FormalParameterBuilder>? formals,
       required int startOffset,
       required int nameOffset,
@@ -394,7 +393,7 @@
       required TypeBuilder? returnType,
       required Identifier identifier,
       required String name,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<FormalParameterBuilder>? formals,
       required int startOffset,
       required int nameOffset,
@@ -413,7 +412,7 @@
       required TypeBuilder? returnType,
       required Identifier identifier,
       required String name,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<FormalParameterBuilder>? formals,
       required int startOffset,
       required int nameOffset,
@@ -471,7 +470,7 @@
 
   InferableTypeBuilder addInferableType();
 
-  NominalParameterBuilder addNominalParameter(List<MetadataBuilder>? metadata,
+  TypeParameterFragment addNominalParameter(List<MetadataBuilder>? metadata,
       String name, TypeBuilder? bound, int charOffset, Uri fileUri,
       {required TypeParameterKind kind});
 
diff --git a/pkg/front_end/lib/src/source/outline_builder.dart b/pkg/front_end/lib/src/source/outline_builder.dart
index af8670f..38b6e3f 100644
--- a/pkg/front_end/lib/src/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/source/outline_builder.dart
@@ -47,6 +47,7 @@
 import '../builder/omitted_type_builder.dart';
 import '../builder/record_type_builder.dart';
 import '../builder/type_builder.dart';
+import '../fragment/fragment.dart';
 import '../kernel/utils.dart';
 import 'builder_factory.dart';
 import 'offset_map.dart';
@@ -1008,8 +1009,8 @@
     popDeclarationContext(
         DeclarationContext.ClassOrMixinOrNamedMixinApplication);
     pushDeclarationContext(DeclarationContext.Class);
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     push(typeParameters ?? NullValues.NominalParameters);
     if (macroToken != null) {
       if (reportIfNotEnabled(
@@ -1070,8 +1071,8 @@
     popDeclarationContext(
         DeclarationContext.ClassOrMixinOrNamedMixinApplication);
     pushDeclarationContext(DeclarationContext.Mixin);
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     if (baseToken != null) {
       if (reportIfNotEnabled(libraryFeatures.classModifiers,
           baseToken.charOffset, baseToken.length)) {
@@ -1138,8 +1139,8 @@
     popDeclarationContext(
         DeclarationContext.ClassOrMixinOrNamedMixinApplication);
     pushDeclarationContext(DeclarationContext.NamedMixinApplication);
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     push(typeParameters ?? NullValues.NominalParameters);
     _builderFactory.beginNamedMixinApplication(
         name.lexeme, name.charOffset, typeParameters);
@@ -1272,7 +1273,7 @@
         ValueKinds.ParserRecovery,
       ]),
       /* modifiers */ ValueKinds.Modifiers,
-      /* type parameters */ ValueKinds.NominalVariableListOrNull,
+      /* type parameters */ ValueKinds.TypeParameterFragmentListOrNull,
       /* name */ ValueKinds.IdentifierOrParserRecovery,
       /* metadata */ ValueKinds.MetadataListOrNull,
     ]));
@@ -1285,8 +1286,8 @@
     int supertypeOffset = popCharOffset();
     TypeBuilder? supertype = nullIfParserRecovery(pop()) as TypeBuilder?;
     Modifiers modifiers = pop() as Modifiers;
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     Object? name = pop();
     List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
     inAbstractOrSealedClass = false;
@@ -1367,7 +1368,7 @@
         ValueKinds.TypeBuilderListOrNull,
         ValueKinds.ParserRecovery,
       ]),
-      /* type parameters */ ValueKinds.NominalVariableListOrNull,
+      /* type parameters */ ValueKinds.TypeParameterFragmentListOrNull,
       /* modifiers */ ValueKinds.Modifiers,
       /* name */ ValueKinds.IdentifierOrParserRecovery,
       /* metadata */ ValueKinds.MetadataListOrNull,
@@ -1377,8 +1378,8 @@
         pop(NullValues.TypeBuilderList) as List<TypeBuilder>?;
     List<TypeBuilder>? supertypeConstraints =
         nullIfParserRecovery(pop()) as List<TypeBuilder>?;
-    List<NominalParameterBuilder>? typeParameters =
-        pop(NullValues.NominalParameters) as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop(NullValues.NominalParameters) as List<TypeParameterFragment>?;
     Modifiers modifiers = pop() as Modifiers;
     Object? name = pop();
     List<MetadataBuilder>? metadata =
@@ -1446,13 +1447,15 @@
   @override
   void beginExtensionDeclaration(
       Token? augmentToken, Token extensionKeyword, Token? nameToken) {
-    assert(checkState(extensionKeyword,
-        [ValueKinds.NominalVariableListOrNull, ValueKinds.MetadataListOrNull]));
+    assert(checkState(extensionKeyword, [
+      ValueKinds.TypeParameterFragmentListOrNull,
+      ValueKinds.MetadataListOrNull
+    ]));
     debugEvent("beginExtensionDeclaration");
     popDeclarationContext(DeclarationContext.ExtensionOrExtensionType);
     pushDeclarationContext(DeclarationContext.Extension);
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     int offset = nameToken?.charOffset ?? extensionKeyword.charOffset;
     push(nameToken != null
         ? new SimpleIdentifier(nameToken)
@@ -1467,7 +1470,7 @@
       Token? onKeyword, Token endToken) {
     assert(checkState(extensionKeyword, [
       unionOfKinds([ValueKinds.ParserRecovery, ValueKinds.TypeBuilder]),
-      ValueKinds.NominalVariableListOrNull,
+      ValueKinds.TypeParameterFragmentListOrNull,
       ValueKinds.IdentifierOrNull,
       ValueKinds.MetadataListOrNull
     ]));
@@ -1479,8 +1482,8 @@
       onType = new FixedTypeBuilderImpl(
           const InvalidType(), uri, parserRecovery.charOffset);
     }
-    List<NominalParameterBuilder>? typeParameters =
-        pop(NullValues.NominalParameters) as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop(NullValues.NominalParameters) as List<TypeParameterFragment>?;
     Identifier? name = pop(NullValues.Identifier) as Identifier?;
     int nameOrExtensionOffset = name?.nameOffset ?? extensionKeyword.charOffset;
     List<MetadataBuilder>? metadata =
@@ -1505,13 +1508,15 @@
   @override
   void beginExtensionTypeDeclaration(
       Token? augmentToken, Token extensionKeyword, Token nameToken) {
-    assert(checkState(extensionKeyword,
-        [ValueKinds.NominalVariableListOrNull, ValueKinds.MetadataListOrNull]));
+    assert(checkState(extensionKeyword, [
+      ValueKinds.TypeParameterFragmentListOrNull,
+      ValueKinds.MetadataListOrNull
+    ]));
     debugEvent("beginExtensionTypeDeclaration");
     popDeclarationContext(DeclarationContext.ExtensionOrExtensionType);
     pushDeclarationContext(DeclarationContext.ExtensionType);
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     String name = nameToken.lexeme;
     int nameOffset = nameToken.charOffset;
     push(new SimpleIdentifier(nameToken));
@@ -1525,7 +1530,7 @@
       Token extensionKeyword, Token typeKeyword, Token endToken) {
     assert(checkState(extensionKeyword, [
       ValueKinds.TypeBuilderListOrNull,
-      ValueKinds.NominalVariableListOrNull,
+      ValueKinds.TypeParameterFragmentListOrNull,
       ValueKinds.Identifier,
       ValueKinds.MetadataListOrNull,
     ]));
@@ -1534,8 +1539,8 @@
 
     List<TypeBuilder>? interfaces =
         pop(NullValues.TypeBuilderList) as List<TypeBuilder>?;
-    List<NominalParameterBuilder>? typeParameters =
-        pop(NullValues.NominalParameters) as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop(NullValues.NominalParameters) as List<TypeParameterFragment>?;
     Identifier identifier = pop() as Identifier;
     List<MetadataBuilder>? metadata =
         pop(NullValues.Metadata) as List<MetadataBuilder>?;
@@ -1699,7 +1704,7 @@
       ValueKinds.AsyncMarker,
       ValueKinds.FormalListOrNull,
       /* formalsOffset */ ValueKinds.Integer,
-      ValueKinds.NominalVariableListOrNull,
+      ValueKinds.TypeParameterFragmentListOrNull,
       ValueKinds.IdentifierOrParserRecovery,
       ValueKinds.TypeBuilderOrNull,
       ValueKinds.Modifiers,
@@ -1711,8 +1716,8 @@
     List<FormalParameterBuilder>? formals =
         pop() as List<FormalParameterBuilder>?;
     int formalsOffset = popCharOffset();
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     Object? identifier = pop();
     TypeBuilder? returnType = pop() as TypeBuilder?;
     bool isAbstract = kind == MethodBody.Abstract;
@@ -2018,7 +2023,7 @@
       ValueKinds.AsyncModifier,
       ValueKinds.FormalListOrNull,
       ValueKinds.Integer, // formals offset
-      ValueKinds.NominalVariableListOrNull,
+      ValueKinds.TypeParameterFragmentListOrNull,
       ValueKinds.IdentifierOrParserRecovery,
       ValueKinds.TypeBuilderOrNull,
       ValueKinds.Modifiers,
@@ -2030,8 +2035,8 @@
     List<FormalParameterBuilder>? formals =
         pop() as List<FormalParameterBuilder>?;
     int formalsOffset = popCharOffset();
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     Object? identifier = pop();
     TypeBuilder? returnType = pop() as TypeBuilder?;
     Modifiers modifiers = pop() as Modifiers;
@@ -2107,9 +2112,9 @@
         }
       }
       if (typeParameters != null) {
-        NominalParameterBuilder typeParameterBuilder = typeParameters.first;
+        TypeParameterFragment typeParameterBuilder = typeParameters.first;
         addProblem(messageOperatorWithTypeParameters,
-            typeParameterBuilder.fileOffset, typeParameterBuilder.name.length);
+            typeParameterBuilder.nameOffset, typeParameterBuilder.name.length);
       }
     } else {
       name = identifier.name;
@@ -2289,7 +2294,7 @@
         ValueKinds.TypeBuilder,
       ]),
       /* modifiers */ ValueKinds.Modifiers,
-      /* type parameters */ ValueKinds.NominalVariableListOrNull,
+      /* type parameters */ ValueKinds.TypeParameterFragmentListOrNull,
       /* name */ ValueKinds.IdentifierOrParserRecovery,
       /* metadata */ ValueKinds.MetadataListOrNull,
     ]));
@@ -2300,8 +2305,8 @@
     Object? mixinApplication = pop();
     Object? supertype = pop();
     Modifiers modifiers = pop() as Modifiers;
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     Object? name = pop();
     List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
     checkEmpty(beginToken.charOffset);
@@ -2760,7 +2765,7 @@
         ValueKinds.TypeBuilderListOrNull,
         ValueKinds.ParserRecovery,
       ]),
-      /* type parameters */ ValueKinds.NominalVariableListOrNull,
+      /* type parameters */ ValueKinds.TypeParameterFragmentListOrNull,
       /* name */ ValueKinds.IdentifierOrParserRecovery,
     ]));
     debugEvent("EnumHeader");
@@ -2769,8 +2774,8 @@
     List<TypeBuilder>? interfaces =
         pop(NullValues.TypeBuilderList) as List<TypeBuilder>?;
     Object? mixins = pop(NullValues.TypeBuilderList);
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
 
     Object? identifier = peek();
     if (identifier is Identifier) {
@@ -2815,7 +2820,7 @@
         ValueKinds.TypeBuilderListOrNull,
         ValueKinds.ParserRecovery,
       ]),
-      /* type parameters */ ValueKinds.NominalVariableListOrNull,
+      /* type parameters */ ValueKinds.TypeParameterFragmentListOrNull,
       /* name */ ValueKinds.IdentifierOrParserRecovery,
       /* metadata */ ValueKinds.MetadataListOrNull,
     ]));
@@ -2850,8 +2855,8 @@
         nullIfParserRecovery(pop()) as List<TypeBuilder>?;
     List<TypeBuilder>? mixins =
         nullIfParserRecovery(pop()) as List<TypeBuilder>?;
-    List<NominalParameterBuilder>? typeParameters =
-        pop() as List<NominalParameterBuilder>?;
+    List<TypeParameterFragment>? typeParameters =
+        pop() as List<TypeParameterFragment>?;
     Object? identifier = pop();
     List<MetadataBuilder>? metadata = pop() as List<MetadataBuilder>?;
     checkEmpty(beginToken.charOffset);
@@ -3046,7 +3051,8 @@
             ? [
                 /* formals */ ValueKinds.FormalListOrNull,
                 /* formals offset */ ValueKinds.Integer,
-                /* type parameters */ ValueKinds.NominalVariableListOrNull,
+                /* type parameters */ ValueKinds
+                    .TypeParameterFragmentListOrNull,
                 /* name */ ValueKinds.IdentifierOrParserRecovery,
                 /* return type */ ValueKinds.TypeBuilderOrNull,
                 /* metadata */ ValueKinds.MetadataListOrNull,
@@ -3056,12 +3062,13 @@
                   ValueKinds.TypeBuilderOrNull,
                   ValueKinds.ParserRecovery,
                 ]),
-                /* type parameters */ ValueKinds.NominalVariableListOrNull,
+                /* type parameters */ ValueKinds
+                    .TypeParameterFragmentListOrNull,
                 /* name */ ValueKinds.IdentifierOrParserRecovery,
                 /* metadata */ ValueKinds.MetadataListOrNull,
               ]));
 
-    List<NominalParameterBuilder>? typeParameters;
+    List<TypeParameterFragment>? typeParameters;
     Object? name;
     Identifier identifier;
     TypeBuilder aliasedType;
@@ -3070,7 +3077,7 @@
           pop(NullValues.FormalParameters) as List<FormalParameterBuilder>?;
       pop(); // formals offset
       typeParameters =
-          pop(NullValues.NominalParameters) as List<NominalParameterBuilder>?;
+          pop(NullValues.NominalParameters) as List<TypeParameterFragment>?;
       name = pop();
       TypeBuilder? returnType = pop(NullValues.TypeBuilder) as TypeBuilder?;
       // Create a nested declaration that is ended below by
@@ -3096,7 +3103,7 @@
     } else {
       Object? type = pop(NullValues.TypeBuilder);
       typeParameters =
-          pop(NullValues.NominalParameters) as List<NominalParameterBuilder>?;
+          pop(NullValues.NominalParameters) as List<TypeParameterFragment>?;
       name = pop();
       if (name is ParserRecovery) {
         // Coverage-ignore-block(suite): Not run.
@@ -3412,8 +3419,8 @@
               .popNonNullable(stack, count, dummyStructuralVariableBuilder) ??
           NullValues.StructuralParameters);
     } else {
-      push(const FixedNullableList<NominalParameterBuilder>()
-              .popNonNullable(stack, count, dummyNominalVariableBuilder) ??
+      push(const FixedNullableList<TypeParameterFragment>()
+              .popNonNullable(stack, count, dummyTypeParameterFragment) ??
           NullValues.NominalParameters);
     }
   }
@@ -3423,18 +3430,35 @@
       Token token, int index, Token? extendsOrSuper, Token? variance) {
     debugEvent("endTypeVariable");
     TypeBuilder? bound = nullIfParserRecovery(pop()) as TypeBuilder?;
-    // Peek to leave type parameters on top of stack.
-    List<TypeParameterBuilder>? typeParameters =
-        peek() as List<TypeParameterBuilder>?;
-    if (typeParameters != null) {
-      typeParameters[index].bound = bound;
-      if (variance != null) {
-        if (!libraryFeatures.variance.isEnabled) {
+    if (inFunctionType) {
+      // Peek to leave type parameters on top of stack.
+      List<StructuralParameterBuilder>? typeParameters =
+          peek() as List<StructuralParameterBuilder>?;
+      if (typeParameters != null) {
+        typeParameters[index].bound = bound;
+        if (variance != null) {
           // Coverage-ignore-block(suite): Not run.
-          reportVarianceModifierNotEnabled(variance);
+          if (!libraryFeatures.variance.isEnabled) {
+            reportVarianceModifierNotEnabled(variance);
+          }
+          typeParameters[index].variance =
+              new Variance.fromKeywordString(variance.lexeme);
         }
-        typeParameters[index].variance =
-            new Variance.fromKeywordString(variance.lexeme);
+      }
+    } else {
+      // Peek to leave type parameters on top of stack.
+      List<TypeParameterFragment>? typeParameters =
+          peek() as List<TypeParameterFragment>?;
+      if (typeParameters != null) {
+        typeParameters[index].builder.bound = bound;
+        if (variance != null) {
+          if (!libraryFeatures.variance.isEnabled) {
+            // Coverage-ignore-block(suite): Not run.
+            reportVarianceModifierNotEnabled(variance);
+          }
+          typeParameters[index].builder.variance =
+              new Variance.fromKeywordString(variance.lexeme);
+        }
       }
     }
   }
@@ -3568,7 +3592,7 @@
       ValueKinds.AsyncMarker,
       ValueKinds.FormalListOrNull,
       /* formals offset */ ValueKinds.Integer,
-      ValueKinds.NominalVariableListOrNull,
+      ValueKinds.TypeParameterFragmentListOrNull,
       ValueKinds.IdentifierOrParserRecovery,
       ValueKinds.Modifiers,
       ValueKinds.MetadataListOrNull,
diff --git a/pkg/front_end/lib/src/source/source_builder_factory.dart b/pkg/front_end/lib/src/source/source_builder_factory.dart
index 322a61c..25cb6ba 100644
--- a/pkg/front_end/lib/src/source/source_builder_factory.dart
+++ b/pkg/front_end/lib/src/source/source_builder_factory.dart
@@ -148,7 +148,7 @@
 
   @override
   void beginClassDeclaration(String name, int nameOffset,
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     _declarationFragments.push(new ClassFragment(
         name,
         _compilationUnit.fileUri,
@@ -177,7 +177,7 @@
   @override
   // Coverage-ignore(suite): Not run.
   void endClassDeclarationForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope bodyScope = _typeScopes.pop();
     assert(bodyScope.kind == TypeScopeKind.classDeclaration,
         "Unexpected type scope: $bodyScope.");
@@ -187,13 +187,13 @@
 
     _declarationFragments.pop();
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: null, allowNameConflict: true);
   }
 
   @override
   void beginMixinDeclaration(String name, int nameOffset,
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     _declarationFragments.push(new MixinFragment(
         name,
         _compilationUnit.fileUri,
@@ -222,7 +222,7 @@
   @override
   // Coverage-ignore(suite): Not run.
   void endMixinDeclarationForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope bodyScope = _typeScopes.pop();
     assert(bodyScope.kind == TypeScopeKind.mixinDeclaration,
         "Unexpected type scope: $bodyScope.");
@@ -232,13 +232,13 @@
 
     _declarationFragments.pop();
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: null, allowNameConflict: true);
   }
 
   @override
   void beginNamedMixinApplication(String name, int charOffset,
-      List<NominalParameterBuilder>? typeParameters) {}
+      List<TypeParameterFragment>? typeParameters) {}
 
   @override
   void endNamedMixinApplication(String name) {
@@ -249,13 +249,13 @@
 
   @override
   void endNamedMixinApplicationForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope typeParameterScope = _typeScopes.pop();
     assert(typeParameterScope.kind == TypeScopeKind.declarationTypeParameters,
         "Unexpected type scope: $typeParameterScope.");
 
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -273,7 +273,7 @@
 
   @override
   void beginEnumDeclaration(String name, int nameOffset,
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     _declarationFragments.push(new EnumFragment(
         name,
         _compilationUnit.fileUri,
@@ -301,7 +301,7 @@
 
   @override
   void endEnumDeclarationForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope bodyScope = _typeScopes.pop();
     assert(bodyScope.kind == TypeScopeKind.enumDeclaration,
         "Unexpected type scope: $bodyScope.");
@@ -311,8 +311,12 @@
 
     _declarationFragments.pop();
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
-        ownerName: null, allowNameConflict: true);
+        _problemReporting,
+        typeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        ownerName: null,
+        allowNameConflict: true);
   }
 
   @override
@@ -329,7 +333,7 @@
 
   @override
   void beginExtensionDeclaration(String? name, int charOffset,
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     _declarationFragments.push(new ExtensionFragment(
         name,
         _compilationUnit.fileUri,
@@ -359,7 +363,7 @@
 
   @override
   void beginExtensionTypeDeclaration(String name, int nameOffset,
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     _declarationFragments.push(new ExtensionTypeFragment(
         name,
         _compilationUnit.fileUri,
@@ -422,14 +426,18 @@
 
   @override
   void endConstructorForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope typeParameterScope = _typeScopes.pop();
     assert(typeParameterScope.kind == TypeScopeKind.memberTypeParameters,
         "Unexpected type scope: $typeParameterScope.");
 
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
-        ownerName: null, allowNameConflict: true);
+        _problemReporting,
+        typeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        ownerName: null,
+        allowNameConflict: true);
   }
 
   @override
@@ -447,13 +455,13 @@
   @override
   // Coverage-ignore(suite): Not run.
   void endStaticMethodForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope typeParameterScope = _typeScopes.pop();
     assert(typeParameterScope.kind == TypeScopeKind.memberTypeParameters,
         "Unexpected type scope: $typeParameterScope.");
 
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -471,14 +479,18 @@
 
   @override
   void endInstanceMethodForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope typeParameterScope = _typeScopes.pop();
     assert(typeParameterScope.kind == TypeScopeKind.memberTypeParameters,
         "Unexpected type scope: $typeParameterScope.");
 
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
-        ownerName: null, allowNameConflict: true);
+        _problemReporting,
+        typeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        ownerName: null,
+        allowNameConflict: true);
   }
 
   @override
@@ -495,14 +507,18 @@
 
   @override
   void endTopLevelMethodForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope typeParameterScope = _typeScopes.pop();
     assert(typeParameterScope.kind == TypeScopeKind.memberTypeParameters,
         "Unexpected type scope: $typeParameterScope.");
 
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
-        ownerName: null, allowNameConflict: true);
+        _problemReporting,
+        typeParameters
+            // Coverage-ignore(suite): Not run.
+            ?.builders,
+        ownerName: null,
+        allowNameConflict: true);
   }
 
   @override
@@ -527,13 +543,13 @@
   @override
   // Coverage-ignore(suite): Not run.
   void endTypedefForParserRecovery(
-      List<NominalParameterBuilder>? typeParameters) {
+      List<TypeParameterFragment>? typeParameters) {
     TypeScope typeParameterScope = _typeScopes.pop();
     assert(typeParameterScope.kind == TypeScopeKind.declarationTypeParameters,
         "Unexpected type scope: $typeParameterScope.");
 
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -776,7 +792,7 @@
       required List<MetadataBuilder>? metadata,
       required Modifiers modifiers,
       required Identifier identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required TypeBuilder? supertype,
       required List<TypeBuilder>? mixins,
       required List<TypeBuilder>? interfaces,
@@ -794,7 +810,7 @@
     NominalParameterNameSpace nominalParameterNameSpace =
         _nominalParameterNameSpaces.pop();
     nominalParameterNameSpace.addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: className, allowNameConflict: false);
 
     if (declarationFragment.declaresConstConstructor) {
@@ -823,7 +839,7 @@
       {required OffsetMap offsetMap,
       required List<MetadataBuilder>? metadata,
       required Identifier identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<TypeBuilder>? mixins,
       required List<TypeBuilder>? interfaces,
       required int startOffset,
@@ -839,7 +855,7 @@
     NominalParameterNameSpace nominalParameterNameSpace =
         _nominalParameterNameSpaces.pop();
     nominalParameterNameSpace.addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: name, allowNameConflict: false);
 
     declarationFragment.compilationUnitScope = _compilationUnitScope;
@@ -883,7 +899,7 @@
       required List<MetadataBuilder>? metadata,
       required Modifiers modifiers,
       required Identifier identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<TypeBuilder>? supertypeConstraints,
       required List<TypeBuilder>? interfaces,
       required int startOffset,
@@ -907,7 +923,7 @@
     NominalParameterNameSpace nominalParameterNameSpace =
         _nominalParameterNameSpaces.pop();
     nominalParameterNameSpace.addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: className, allowNameConflict: false);
 
     modifiers |= Modifiers.Abstract;
@@ -937,7 +953,7 @@
   void addNamedMixinApplication(
       {required List<MetadataBuilder>? metadata,
       required String name,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required Modifiers modifiers,
       required TypeBuilder? supertype,
       required List<TypeBuilder> mixins,
@@ -952,7 +968,7 @@
         _mixinApplications != null, "Late registration of mixin application.");
 
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: name, allowNameConflict: false);
 
     _addFragment(new NamedMixinApplicationFragment(
@@ -977,7 +993,7 @@
       required List<MetadataBuilder>? metadata,
       required Modifiers modifiers,
       required Identifier? identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required TypeBuilder onType,
       required int startOffset,
       required int nameOrExtensionOffset,
@@ -993,7 +1009,7 @@
     NominalParameterNameSpace nominalParameterNameSpace =
         _nominalParameterNameSpaces.pop();
     nominalParameterNameSpace.addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: name, allowNameConflict: false);
 
     declarationFragment.metadata = metadata;
@@ -1021,7 +1037,7 @@
       required List<MetadataBuilder>? metadata,
       required Modifiers modifiers,
       required Identifier identifier,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<TypeBuilder>? interfaces,
       required int startOffset,
       required int endOffset}) {
@@ -1035,7 +1051,7 @@
     NominalParameterNameSpace nominalParameterNameSpace =
         _nominalParameterNameSpaces.pop();
     nominalParameterNameSpace.addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: name, allowNameConflict: false);
 
     declarationFragment.metadata = metadata;
@@ -1056,17 +1072,17 @@
   void addFunctionTypeAlias(
       List<MetadataBuilder>? metadata,
       String name,
-      List<NominalParameterBuilder>? typeParameters,
+      List<TypeParameterFragment>? typeParameters,
       TypeBuilder type,
       int nameOffset) {
     if (typeParameters != null) {
-      for (NominalParameterBuilder typeParameter in typeParameters) {
+      for (NominalParameterBuilder typeParameter in typeParameters.builders) {
         typeParameter.varianceCalculationValue =
             VarianceCalculationValue.pending;
       }
     }
     _nominalParameterNameSpaces.pop().addTypeParameters(
-        _problemReporting, typeParameters,
+        _problemReporting, typeParameters?.builders,
         ownerName: name, allowNameConflict: true);
     // Nested declaration began in `OutlineBuilder.beginFunctionTypeAlias`.
     endTypedef();
@@ -1088,7 +1104,7 @@
       required String name,
       required TypeBuilder? returnType,
       required List<FormalParameterBuilder>? formals,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required Token? beginInitializers,
       required int startOffset,
       required int endOffset,
@@ -1293,7 +1309,7 @@
       required Modifiers modifiers,
       required Identifier identifier,
       required ConstructorName constructorName,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<FormalParameterBuilder>? formals,
       required int startOffset,
       required int formalsOffset,
@@ -1565,7 +1581,7 @@
       required TypeBuilder? returnType,
       required Identifier identifier,
       required String name,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<FormalParameterBuilder>? formals,
       required int startOffset,
       required int nameOffset,
@@ -1624,7 +1640,7 @@
       required TypeBuilder? returnType,
       required Identifier identifier,
       required String name,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<FormalParameterBuilder>? formals,
       required int startOffset,
       required int nameOffset,
@@ -1687,7 +1703,7 @@
       required TypeBuilder? returnType,
       required Identifier identifier,
       required String name,
-      required List<NominalParameterBuilder>? typeParameters,
+      required List<TypeParameterFragment>? typeParameters,
       required List<FormalParameterBuilder>? formals,
       required int startOffset,
       required int nameOffset,
@@ -1732,7 +1748,7 @@
         metadata: metadata,
         modifiers: modifiers,
         returnType: returnType ?? addInferableType(),
-        declaredTypeParameters: typeParameters,
+        declaredTypeParameters: typeParameters?.builders,
         typeParameterNameSpace: typeParameterNameSpace,
         typeParameterScope: typeParameterScope.lookupScope,
         declaredFormals: formals,
@@ -1942,7 +1958,7 @@
   }
 
   @override
-  NominalParameterBuilder addNominalParameter(List<MetadataBuilder>? metadata,
+  TypeParameterFragment addNominalParameter(List<MetadataBuilder>? metadata,
       String name, TypeBuilder? bound, int charOffset, Uri fileUri,
       {required TypeParameterKind kind}) {
     String variableName = name;
@@ -1952,12 +1968,24 @@
       variableName = createWildcardTypeParameterName(wildcardVariableIndex);
       wildcardVariableIndex++;
     }
+    TypeParameterFragment fragment = new TypeParameterFragment(
+        metadata: metadata,
+        name: name,
+        bound: bound,
+        nameOffset: charOffset,
+        fileUri: fileUri,
+        kind: kind,
+        isWildcard: isWildcard,
+        variableName: variableName);
+
     NominalParameterBuilder builder = new NominalParameterBuilder(
         variableName, charOffset, fileUri,
         bound: bound, metadata: metadata, kind: kind, isWildcard: isWildcard);
 
     _unboundNominalParameters.add(builder);
-    return builder;
+
+    fragment.builder = builder;
+    return fragment;
   }
 
   @override
diff --git a/pkg/front_end/lib/src/source/source_extension_builder.dart b/pkg/front_end/lib/src/source/source_extension_builder.dart
index e833461..2c33fa5 100644
--- a/pkg/front_end/lib/src/source/source_extension_builder.dart
+++ b/pkg/front_end/lib/src/source/source_extension_builder.dart
@@ -88,7 +88,7 @@
         parent = enclosingLibraryBuilder,
         _modifiers = fragment.modifiers,
         extensionName = fragment.extensionName,
-        typeParameters = fragment.typeParameters,
+        typeParameters = fragment.typeParameters?.builders,
         typeParameterScope = fragment.typeParameterScope,
         onType = fragment.onType,
         _nameSpaceBuilder = fragment.toDeclarationNameSpaceBuilder() {
diff --git a/pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart b/pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart
index 8b5395d..fedd303 100644
--- a/pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart
+++ b/pkg/front_end/lib/src/source/source_extension_type_declaration_builder.dart
@@ -108,7 +108,7 @@
       : parent = enclosingLibraryBuilder,
         fileOffset = nameOffset,
         _modifiers = fragment.modifiers,
-        typeParameters = fragment.typeParameters,
+        typeParameters = fragment.typeParameters?.builders,
         interfaceBuilders = fragment.interfaces,
         typeParameterScope = fragment.typeParameterScope,
         _introductory = fragment,
@@ -123,7 +123,7 @@
         name: name,
         fileUri: fileUri,
         typeParameters: NominalParameterBuilder.typeParametersFromBuilders(
-            fragment.typeParameters),
+            fragment.typeParameters?.builders),
         reference: indexedContainer?.reference)
       ..fileOffset = nameOffset;
   }
diff --git a/pkg/front_end/lib/src/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/source/source_type_alias_builder.dart
index dcedf3a..cd55668 100644
--- a/pkg/front_end/lib/src/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/source/source_type_alias_builder.dart
@@ -93,7 +93,7 @@
 
   @override
   List<NominalParameterBuilder>? get typeParameters =>
-      _introductory.typeParameters;
+      _introductory.typeParameters?.builders;
 
   @override
   bool get fromDill => false;
diff --git a/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart b/pkg/front_end/lib/src/source/type_parameter_scope_builder.dart
index a74d2cd..ff69493 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
@@ -1236,7 +1236,7 @@
         SourceClassBuilder classBuilder = new SourceClassBuilder(
             modifiers: fragment.modifiers,
             name: fragment.name,
-            typeParameters: fragment.typeParameters,
+            typeParameters: fragment.typeParameters?.builders,
             typeParameterScope: fragment.typeParameterScope,
             nameSpaceBuilder: fragment.toDeclarationNameSpaceBuilder(),
             libraryBuilder: enclosingLibraryBuilder,
@@ -1256,10 +1256,12 @@
       case MixinFragment():
         IndexedClass? indexedClass =
             indexedLibrary?.lookupIndexedClass(fragment.name);
+        List<NominalParameterBuilder>? typeParameters =
+            fragment.typeParameters?.map((p) => p.builder).toList();
         SourceClassBuilder mixinBuilder = new SourceClassBuilder(
             modifiers: fragment.modifiers,
             name: fragment.name,
-            typeParameters: fragment.typeParameters,
+            typeParameters: typeParameters,
             typeParameterScope: fragment.typeParameterScope,
             nameSpaceBuilder: fragment.toDeclarationNameSpaceBuilder(),
             libraryBuilder: enclosingLibraryBuilder,
@@ -1290,13 +1292,13 @@
         }
 
         LookupScope typeParameterScope = TypeParameterScope.fromList(
-            fragment.compilationUnitScope, fragment.typeParameters);
+            fragment.compilationUnitScope, fragment.typeParameters?.builders);
         DeclarationNameSpaceBuilder nameSpaceBuilder =
             new DeclarationNameSpaceBuilder.empty();
         SourceClassBuilder classBuilder = new SourceClassBuilder(
             modifiers: fragment.modifiers | Modifiers.NamedMixinApplication,
             name: name,
-            typeParameters: fragment.typeParameters,
+            typeParameters: fragment.typeParameters?.builders,
             typeParameterScope: typeParameterScope,
             nameSpaceBuilder: nameSpaceBuilder,
             libraryBuilder: enclosingLibraryBuilder,
@@ -1317,9 +1319,11 @@
       case EnumFragment():
         IndexedClass? indexedClass =
             indexedLibrary?.lookupIndexedClass(fragment.name);
+        List<NominalParameterBuilder>? typeParameters =
+            fragment.typeParameters?.map((p) => p.builder).toList();
         SourceEnumBuilder enumBuilder = new SourceEnumBuilder(
             name: fragment.name,
-            typeParameters: fragment.typeParameters,
+            typeParameters: typeParameters,
             underscoreEnumTypeBuilder: loader.target.underscoreEnumType,
             interfaceBuilders: fragment.interfaces,
             enumElements: fragment.enumElements,
@@ -1579,7 +1583,8 @@
               methodBuilder;
         }
       case ConstructorFragment():
-        List<NominalParameterBuilder>? typeParameters = fragment.typeParameters;
+        List<NominalParameterBuilder>? typeParameters =
+            fragment.typeParameters?.builders;
         switch (declarationBuilder!) {
           case ExtensionBuilder():
           case ExtensionTypeDeclarationBuilder():
@@ -2081,7 +2086,7 @@
   final DeclarationBuilderScope bodyScope = new DeclarationBuilderScope();
   final List<Fragment> _fragments = [];
 
-  final List<NominalParameterBuilder>? typeParameters;
+  final List<TypeParameterFragment>? typeParameters;
 
   final NominalParameterNameSpace _nominalParameterNameSpace;
 
diff --git a/pkg/front_end/lib/src/source/value_kinds.dart b/pkg/front_end/lib/src/source/value_kinds.dart
index cd97ec1..3c2ba2b 100644
--- a/pkg/front_end/lib/src/source/value_kinds.dart
+++ b/pkg/front_end/lib/src/source/value_kinds.dart
@@ -28,6 +28,7 @@
 import '../builder/metadata_builder.dart' as type;
 import '../builder/record_type_builder.dart' as type;
 import '../builder/type_builder.dart' as type;
+import '../fragment/fragment.dart' as type;
 import '../kernel/body_builder.dart' as type
     show
         Condition,
@@ -203,6 +204,9 @@
       const SingleValueKind<List<type.TypeBuilder>>();
   static const ValueKind TypeBuilderListOrNull =
       const SingleValueKind<List<type.TypeBuilder>>(NullValues.TypeBuilderList);
+  static const ValueKind TypeParameterFragmentListOrNull =
+      const SingleValueKind<List<type.TypeParameterFragment>>(
+          NullValues.NominalParameters);
   static const ValueKind NominalVariableListOrNull =
       const SingleValueKind<List<type.NominalParameterBuilder>>(
           NullValues.NominalParameters);
diff --git a/pkg/front_end/test/coverage_suite_expected.dart b/pkg/front_end/test/coverage_suite_expected.dart
index d6611b9..438e04e 100644
--- a/pkg/front_end/test/coverage_suite_expected.dart
+++ b/pkg/front_end/test/coverage_suite_expected.dart
@@ -470,7 +470,7 @@
   ),
   // 100.0%.
   "package:front_end/src/fragment/class/declaration.dart": (
-    hitCount: 138,
+    hitCount: 142,
     missCount: 0,
   ),
   // 100.0%.
@@ -554,6 +554,11 @@
     missCount: 0,
   ),
   // 100.0%.
+  "package:front_end/src/fragment/type_parameter.dart": (
+    hitCount: 10,
+    missCount: 0,
+  ),
+  // 100.0%.
   "package:front_end/src/fragment/typedef.dart": (
     hitCount: 4,
     missCount: 0,
@@ -780,7 +785,7 @@
   ),
   // 100.0%.
   "package:front_end/src/kernel/utils.dart": (
-    hitCount: 68,
+    hitCount: 72,
     missCount: 0,
   ),
   // 100.0%.
@@ -825,7 +830,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/outline_builder.dart": (
-    hitCount: 2108,
+    hitCount: 2114,
     missCount: 0,
   ),
   // 100.0%.
@@ -835,7 +840,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/source_builder_factory.dart": (
-    hitCount: 1112,
+    hitCount: 1123,
     missCount: 0,
   ),
   // 100.0%.
@@ -865,13 +870,13 @@
   ),
   // 100.0%.
   "package:front_end/src/source/source_extension_builder.dart": (
-    hitCount: 146,
+    hitCount: 147,
     missCount: 0,
   ),
   // 100.0%.
   "package:front_end/src/source/source_extension_type_declaration_builder.dart":
       (
-    hitCount: 504,
+    hitCount: 506,
     missCount: 0,
   ),
   // 100.0%.
@@ -911,7 +916,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/source_type_alias_builder.dart": (
-    hitCount: 358,
+    hitCount: 359,
     missCount: 0,
   ),
   // 100.0%.
@@ -926,7 +931,7 @@
   ),
   // 100.0%.
   "package:front_end/src/source/type_parameter_scope_builder.dart": (
-    hitCount: 1383,
+    hitCount: 1395,
     missCount: 0,
   ),
   // 100.0%.