[cfe] Add NominalParameterNameSpace

Change-Id: Ia48158f11080368fe7b8c42170d45ef27e81701f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/382581
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/base/scope.dart b/pkg/front_end/lib/src/base/scope.dart
index 1cc4b5f..0a25c81 100644
--- a/pkg/front_end/lib/src/base/scope.dart
+++ b/pkg/front_end/lib/src/base/scope.dart
@@ -294,11 +294,12 @@
       : _parent = parent;
 }
 
-class TypeParameterScope with LookupScopeMixin {
+abstract class AbstractTypeParameterScope implements LookupScope {
   final LookupScope _parent;
-  final Map<String, Builder> _typeParameters;
 
-  TypeParameterScope(this._parent, this._typeParameters);
+  AbstractTypeParameterScope(this._parent);
+
+  Builder? getTypeParameter(String name);
 
   @override
   // Coverage-ignore(suite): Not run.
@@ -306,20 +307,47 @@
 
   @override
   Builder? lookupGetable(String name, int charOffset, Uri fileUri) {
-    return lookupGetableIn(name, charOffset, fileUri, _typeParameters) ??
-        _parent.lookupGetable(name, charOffset, fileUri);
+    Builder? builder = normalizeLookup(
+        getable: getTypeParameter(name),
+        setable: null,
+        name: name,
+        charOffset: charOffset,
+        fileUri: fileUri,
+        classNameOrDebugName: classNameOrDebugName,
+        isSetter: false);
+    return builder ?? _parent.lookupGetable(name, charOffset, fileUri);
   }
 
   @override
   Builder? lookupSetable(String name, int charOffset, Uri fileUri) {
-    Builder? builder =
-        lookupSetableIn(name, charOffset, fileUri, _typeParameters);
+    Builder? builder = normalizeLookup(
+        getable: getTypeParameter(name),
+        setable: null,
+        name: name,
+        charOffset: charOffset,
+        fileUri: fileUri,
+        classNameOrDebugName: classNameOrDebugName,
+        isSetter: true);
     return builder ?? _parent.lookupSetable(name, charOffset, fileUri);
   }
 
-  @override
   String get classNameOrDebugName => "type parameter";
 
+  @override
+  // Coverage-ignore(suite): Not run.
+  void forEachExtension(void Function(ExtensionBuilder) f) {
+    _parent.forEachExtension(f);
+  }
+}
+
+class TypeParameterScope extends AbstractTypeParameterScope {
+  final Map<String, Builder> _typeParameters;
+
+  TypeParameterScope(super._parent, this._typeParameters);
+
+  @override
+  Builder? getTypeParameter(String name) => _typeParameters[name];
+
   static LookupScope fromList(
       LookupScope parent, List<TypeVariableBuilder>? typeVariableBuilders) {
     if (typeVariableBuilders == null) return parent;
@@ -330,12 +358,6 @@
     }
     return new TypeParameterScope(parent, map);
   }
-
-  @override
-  // Coverage-ignore(suite): Not run.
-  void forEachExtension(void Function(ExtensionBuilder) f) {
-    _parent.forEachExtension(f);
-  }
 }
 
 class FixedLookupScope implements LookupScope {
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 5208c2c..b25cfc9 100644
--- a/pkg/front_end/lib/src/source/source_builder_factory.dart
+++ b/pkg/front_end/lib/src/source/source_builder_factory.dart
@@ -146,8 +146,8 @@
 
   final LocalStack<TypeScope> _typeScopes;
 
-  final LocalStack<Map<String, NominalVariableBuilder>>
-      _nominalParameterScopes = new LocalStack([]);
+  final LocalStack<NominalParameterNameSpace> _nominalParameterNameSpaces =
+      new LocalStack([]);
 
   final LocalStack<Map<String, StructuralVariableBuilder>>
       _structuralParameterScopes = new LocalStack([]);
@@ -193,12 +193,13 @@
             TypeParameterScopeKind.classOrNamedMixinApplication,
             "class or mixin application");
 
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.declarationTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -266,7 +267,8 @@
         "Unexpected type scope: $typeParameterScope.");
 
     _declarationBuilderScopes.pop();
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -334,7 +336,8 @@
         "Unexpected type scope: $typeParameterScope.");
 
     _declarationBuilderScopes.pop();
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -383,7 +386,8 @@
         // Coverage-ignore(suite): Not run.
         "Unexpected type scope: $typeParameterScope.");
 
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -391,12 +395,13 @@
   void beginEnumDeclarationHeader(String name) {
     currentTypeParameterScopeBuilder = currentTypeParameterScopeBuilder
         .createNested(TypeParameterScopeKind.enumDeclaration, name);
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.declarationTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -468,7 +473,8 @@
         "Unexpected type scope: $typeParameterScope.");
 
     _declarationBuilderScopes.pop();
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -478,12 +484,13 @@
         currentTypeParameterScopeBuilder.createNested(
             TypeParameterScopeKind.extensionOrExtensionTypeDeclaration,
             "extension");
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.declarationTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -584,12 +591,13 @@
   void beginFactoryMethod() {
     currentTypeParameterScopeBuilder = currentTypeParameterScopeBuilder
         .createNested(TypeParameterScopeKind.factoryMethod, "#factory_method");
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.memberTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -622,19 +630,21 @@
     assert(typeVariableScope.kind == TypeScopeKind.memberTypeParameters,
         "Unexpected type scope: $typeVariableScope.");
 
-    _checkTypeVariables(null, ownerName: null, allowNameConflict: true);
+    _nominalParameterNameSpaces.pop().addTypeVariables(_problemReporting, null,
+        ownerName: null, allowNameConflict: true);
   }
 
   @override
   void beginConstructor() {
     currentTypeParameterScopeBuilder = currentTypeParameterScopeBuilder
         .createNested(TypeParameterScopeKind.constructor, "#method");
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.memberTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -670,7 +680,8 @@
         // Coverage-ignore(suite): Not run.
         "Unexpected type scope: $typeVariableScope.");
 
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -678,12 +689,13 @@
   void beginStaticMethod() {
     currentTypeParameterScopeBuilder = currentTypeParameterScopeBuilder
         .createNested(TypeParameterScopeKind.staticMethod, "#method");
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.memberTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -717,7 +729,8 @@
     assert(typeVariableScope.kind == TypeScopeKind.memberTypeParameters,
         "Unexpected type scope: $typeVariableScope.");
 
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -725,12 +738,13 @@
   void beginInstanceMethod() {
     currentTypeParameterScopeBuilder = currentTypeParameterScopeBuilder
         .createNested(TypeParameterScopeKind.instanceMethod, "#method");
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.memberTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -766,7 +780,8 @@
         // Coverage-ignore(suite): Not run.
         "Unexpected type scope: $typeVariableScope.");
 
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -774,12 +789,13 @@
   void beginTopLevelMethod() {
     currentTypeParameterScopeBuilder = currentTypeParameterScopeBuilder
         .createNested(TypeParameterScopeKind.topLevelMethod, "#method");
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.memberTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -815,7 +831,8 @@
         // Coverage-ignore(suite): Not run.
         "Unexpected type scope: $typeVariableScope.");
 
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -823,12 +840,13 @@
   void beginTypedef() {
     currentTypeParameterScopeBuilder = currentTypeParameterScopeBuilder
         .createNested(TypeParameterScopeKind.typedef, "#typedef");
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.declarationTypeParameters,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -862,7 +880,8 @@
     assert(typeVariableScope.kind == TypeScopeKind.declarationTypeParameters,
         "Unexpected type scope: $typeVariableScope.");
 
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: null, allowNameConflict: true);
   }
 
@@ -900,12 +919,13 @@
         currentTypeParameterScopeBuilder.createNested(
             TypeParameterScopeKind.unnamedMixinApplication,
             "mixin application");
-    Map<String, NominalVariableBuilder> nominalParameterScope = {};
-    _nominalParameterScopes.push(nominalParameterScope);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        new NominalParameterNameSpace();
+    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
     _typeScopes.push(new TypeScope(
         TypeScopeKind.unnamedMixinApplication,
-        new TypeParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterScope),
+        new NominalParameterScope(
+            _typeScopes.current.lookupScope, nominalParameterNameSpace),
         _typeScopes.current));
   }
 
@@ -941,10 +961,10 @@
         "Unexpected declaration builder scope stack: "
         "$_declarationBuilderScopes.");
     assert(
-        _nominalParameterScopes.isEmpty,
+        _nominalParameterNameSpaces.isEmpty,
         // Coverage-ignore(suite): Not run.
-        "Unexpected nominal parameter scope stack : "
-        "$_nominalParameterScopes.");
+        "Unexpected nominal parameter name space stack : "
+        "$_nominalParameterNameSpaces.");
     assert(
         _structuralParameterScopes.isEmpty,
         // Coverage-ignore(suite): Not run.
@@ -1234,15 +1254,16 @@
     }
     // Nested declaration began in `OutlineBuilder.beginEnum`.
     TypeParameterScopeBuilder declaration = endEnumDeclaration(name);
-    Map<String, NominalVariableBuilder>? typeVariablesByName =
-        _checkTypeVariables(typeVariables,
-            ownerName: name, allowNameConflict: false);
 
-    LookupScope typeParameterScope = typeVariablesByName != null
-        ? new TypeParameterScope(_scope, typeVariablesByName)
-        : _scope;
+    NominalParameterNameSpace nominalParameterNameSpace =
+        _nominalParameterNameSpaces.pop();
+    nominalParameterNameSpace.addTypeVariables(_problemReporting, typeVariables,
+        ownerName: name, allowNameConflict: false);
+
+    LookupScope typeParameterScope =
+        new NominalParameterScope(_scope, nominalParameterNameSpace);
     DeclarationNameSpaceBuilder nameSpaceBuilder =
-        declaration.toDeclarationNameSpaceBuilder(typeVariablesByName);
+        declaration.toDeclarationNameSpaceBuilder(nominalParameterNameSpace);
     SourceEnumBuilder enumBuilder = new SourceEnumBuilder(
         metadata,
         name,
@@ -1364,15 +1385,15 @@
     }
     assert(declaration.parent == _libraryTypeParameterScopeBuilder);
 
-    Map<String, NominalVariableBuilder>? typeVariablesByName =
-        _checkTypeVariables(typeVariables,
-            ownerName: className, allowNameConflict: false);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        _nominalParameterNameSpaces.pop();
+    nominalParameterNameSpace.addTypeVariables(_problemReporting, typeVariables,
+        ownerName: className, allowNameConflict: false);
 
-    LookupScope typeParameterScope = typeVariablesByName != null
-        ? new TypeParameterScope(_scope, typeVariablesByName)
-        : _scope;
+    LookupScope typeParameterScope =
+        new NominalParameterScope(_scope, nominalParameterNameSpace);
     DeclarationNameSpaceBuilder nameSpaceBuilder =
-        declaration.toDeclarationNameSpaceBuilder(typeVariablesByName);
+        declaration.toDeclarationNameSpaceBuilder(nominalParameterNameSpace);
 
     if (isMixinDeclaration) {
       modifiers = abstractMask;
@@ -1467,7 +1488,8 @@
         isFinal: isFinal,
         isAugmentation: isAugmentation,
         isMixinClass: isMixinClass)!;
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: supertype.declaration!.name, allowNameConflict: false);
   }
 
@@ -1636,7 +1658,8 @@
                           InstanceTypeVariableAccessState.Allowed);
               applicationTypeArguments.add(applicationTypeArgument);
             }
-            _checkTypeVariables(applicationTypeVariables,
+            _nominalParameterNameSpaces.pop().addTypeVariables(
+                _problemReporting, applicationTypeVariables,
                 ownerName: fullname, allowNameConflict: true);
             if (supertype != null) {
               supertype = new SynthesizedTypeBuilder(
@@ -1741,15 +1764,15 @@
     // `OutlineBuilder.beginExtensionDeclarationPrelude`.
     TypeParameterScopeBuilder declaration = endExtensionDeclaration(name);
     assert(declaration.parent == _libraryTypeParameterScopeBuilder);
-    Map<String, NominalVariableBuilder>? typeVariablesByName =
-        _checkTypeVariables(typeVariables,
-            ownerName: name, allowNameConflict: false);
+    NominalParameterNameSpace nominalParameterNameSpace =
+        _nominalParameterNameSpaces.pop();
+    nominalParameterNameSpace.addTypeVariables(_problemReporting, typeVariables,
+        ownerName: name, allowNameConflict: false);
 
-    LookupScope typeParameterScope = typeVariablesByName != null
-        ? new TypeParameterScope(_scope, typeVariablesByName)
-        : _scope;
-    DeclarationNameSpaceBuilder extensionNameSpace =
-        declaration.toDeclarationNameSpaceBuilder(typeVariablesByName);
+    LookupScope typeParameterScope =
+        new NominalParameterScope(_scope, nominalParameterNameSpace);
+    DeclarationNameSpaceBuilder nameSpaceBuilder =
+        declaration.toDeclarationNameSpaceBuilder(nominalParameterNameSpace);
 
     Extension? referenceFrom;
     ExtensionName extensionName = declaration.extensionName!;
@@ -1764,7 +1787,7 @@
         typeVariables,
         type,
         typeParameterScope,
-        extensionNameSpace,
+        nameSpaceBuilder,
         _parent,
         startOffset,
         nameOffset,
@@ -1796,15 +1819,16 @@
     // Nested declaration began in `OutlineBuilder.beginExtensionDeclaration`.
     TypeParameterScopeBuilder declaration = endExtensionTypeDeclaration(name);
     assert(declaration.parent == _libraryTypeParameterScopeBuilder);
-    Map<String, NominalVariableBuilder>? typeVariablesByName =
-        _checkTypeVariables(typeVariables,
-            ownerName: name, allowNameConflict: false);
 
-    LookupScope typeParameterScope = typeVariablesByName != null
-        ? new TypeParameterScope(_scope, typeVariablesByName)
-        : _scope;
+    NominalParameterNameSpace nominalParameterNameSpace =
+        _nominalParameterNameSpaces.pop();
+    nominalParameterNameSpace.addTypeVariables(_problemReporting, typeVariables,
+        ownerName: name, allowNameConflict: false);
+
+    LookupScope typeParameterScope =
+        new NominalParameterScope(_scope, nominalParameterNameSpace);
     DeclarationNameSpaceBuilder nameSpaceBuilder =
-        declaration.toDeclarationNameSpaceBuilder(typeVariablesByName);
+        declaration.toDeclarationNameSpaceBuilder(nominalParameterNameSpace);
 
     IndexedContainer? indexedContainer =
         indexedLibrary?.lookupIndexedExtensionTypeDeclaration(name);
@@ -1861,7 +1885,8 @@
     TypeAliasBuilder typedefBuilder = new SourceTypeAliasBuilder(
         metadata, name, typeVariables, type, _parent, charOffset,
         referenceFrom: referenceFrom);
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: name, allowNameConflict: true);
     // Nested declaration began in `OutlineBuilder.beginFunctionTypeAlias`.
     endTypedef();
@@ -2022,7 +2047,8 @@
           nativeMethodName: nativeMethodName,
           forAbstractClassOrEnumOrMixin: forAbstractClassOrMixin);
     }
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: constructorBuilder.name, allowNameConflict: true);
     // TODO(johnniwinther): There is no way to pass the tear off reference here.
     _addBuilderInternal(constructorName, constructorBuilder, charOffset,
@@ -2194,7 +2220,8 @@
     // Nested declaration began in `OutlineBuilder.beginFactoryMethod`.
     endFactoryMethod();
 
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: identifier.name, allowNameConflict: true);
 
     _addBuilderInternal(procedureName, procedureBuilder, charOffset,
@@ -2352,7 +2379,8 @@
         asyncModifier,
         nameScheme,
         nativeMethodName: nativeMethodName);
-    _checkTypeVariables(typeVariables,
+    _nominalParameterNameSpaces.pop().addTypeVariables(
+        _problemReporting, typeVariables,
         ownerName: procedureBuilder.name, allowNameConflict: true);
     _addBuilderInternal(name, procedureBuilder, charOffset,
         getterReference: procedureReference);
@@ -2716,47 +2744,6 @@
     return builder;
   }
 
-  Map<String, NominalVariableBuilder>? _checkTypeVariables(
-      List<NominalVariableBuilder>? typeVariables,
-      {required String? ownerName,
-      required bool allowNameConflict}) {
-    Map<String, NominalVariableBuilder> typeVariablesByName =
-        _nominalParameterScopes.pop();
-    if (typeVariables == null || typeVariables.isEmpty) return null;
-    for (NominalVariableBuilder tv in typeVariables) {
-      NominalVariableBuilder? existing = typeVariablesByName[tv.name];
-      if (tv.isWildcard) continue;
-      if (existing != null) {
-        if (existing.kind == TypeVariableKind.extensionSynthesized) {
-          // The type parameter from the extension is shadowed by the type
-          // parameter from the member. Rename the shadowed type parameter.
-          existing.parameter.name = '#${existing.name}';
-          typeVariablesByName[tv.name] = tv;
-        } else {
-          _problemReporting.addProblem(messageTypeVariableDuplicatedName,
-              tv.charOffset, tv.name.length, _compilationUnit.fileUri,
-              context: [
-                templateTypeVariableDuplicatedNameCause
-                    .withArguments(tv.name)
-                    .withLocation(_compilationUnit.fileUri, existing.charOffset,
-                        existing.name.length)
-              ]);
-        }
-      } else {
-        typeVariablesByName[tv.name] = tv;
-        // Only classes and extension types and type variables can't have the
-        // same name. See
-        // [#29555](https://github.com/dart-lang/sdk/issues/29555) and
-        // [#54602](https://github.com/dart-lang/sdk/issues/54602).
-        if (tv.name == ownerName && !allowNameConflict) {
-          _problemReporting.addProblem(messageTypeVariableSameNameAsEnclosing,
-              tv.charOffset, tv.name.length, _compilationUnit.fileUri);
-        }
-      }
-    }
-    return typeVariablesByName;
-  }
-
   @override
   NominalVariableCopy? copyTypeVariables(
       List<NominalVariableBuilder>? oldVariableBuilders,
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 7d342da..c115a47 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
@@ -324,12 +324,12 @@
   }
 
   DeclarationNameSpaceBuilder toDeclarationNameSpaceBuilder(
-      Map<String, NominalVariableBuilder>? typeVariables) {
+      NominalParameterNameSpace? nominalParameterNameSpace) {
     assert(members == null);
     assert(setters == null);
     assert(extensions == null);
     return new DeclarationNameSpaceBuilder._(
-        name, typeVariables, _addedBuilders);
+        name, nominalParameterNameSpace, _addedBuilders);
   }
 
   void addBuilderToDeclaration(
@@ -341,6 +341,59 @@
   String toString() => 'DeclarationBuilder(${hashCode}:kind=$kind,name=$name)';
 }
 
+class NominalParameterScope extends AbstractTypeParameterScope {
+  final NominalParameterNameSpace _nameSpace;
+
+  NominalParameterScope(super._parent, this._nameSpace);
+
+  @override
+  Builder? getTypeParameter(String name) => _nameSpace.getTypeParameter(name);
+}
+
+class NominalParameterNameSpace {
+  Map<String, NominalVariableBuilder> _typeParametersByName = {};
+
+  NominalVariableBuilder? getTypeParameter(String name) =>
+      _typeParametersByName[name];
+
+  void addTypeVariables(ProblemReporting _problemReporting,
+      List<NominalVariableBuilder>? typeVariables,
+      {required String? ownerName, required bool allowNameConflict}) {
+    if (typeVariables == null || typeVariables.isEmpty) return;
+    for (NominalVariableBuilder tv in typeVariables) {
+      NominalVariableBuilder? existing = _typeParametersByName[tv.name];
+      if (tv.isWildcard) continue;
+      if (existing != null) {
+        if (existing.kind == TypeVariableKind.extensionSynthesized) {
+          // The type parameter from the extension is shadowed by the type
+          // parameter from the member. Rename the shadowed type parameter.
+          existing.parameter.name = '#${existing.name}';
+          _typeParametersByName[tv.name] = tv;
+        } else {
+          _problemReporting.addProblem(messageTypeVariableDuplicatedName,
+              tv.charOffset, tv.name.length, tv.fileUri,
+              context: [
+                templateTypeVariableDuplicatedNameCause
+                    .withArguments(tv.name)
+                    .withLocation(existing.fileUri!, existing.charOffset,
+                        existing.name.length)
+              ]);
+        }
+      } else {
+        _typeParametersByName[tv.name] = tv;
+        // Only classes and extension types and type variables can't have the
+        // same name. See
+        // [#29555](https://github.com/dart-lang/sdk/issues/29555) and
+        // [#54602](https://github.com/dart-lang/sdk/issues/54602).
+        if (tv.name == ownerName && !allowNameConflict) {
+          _problemReporting.addProblem(messageTypeVariableSameNameAsEnclosing,
+              tv.charOffset, tv.name.length, tv.fileUri);
+        }
+      }
+    }
+  }
+}
+
 class _AddBuilder {
   final String name;
   final Builder declaration;
@@ -352,16 +405,16 @@
 
 class DeclarationNameSpaceBuilder {
   final String _name;
-  final Map<String, NominalVariableBuilder>? _typeVariables;
+  final NominalParameterNameSpace? _nominalParameterNameSpace;
   final List<_AddBuilder> _addedBuilders;
 
   DeclarationNameSpaceBuilder.empty()
       : _name = '',
-        _typeVariables = null,
+        _nominalParameterNameSpace = null,
         _addedBuilders = const [];
 
   DeclarationNameSpaceBuilder._(
-      this._name, this._typeVariables, this._addedBuilders);
+      this._name, this._nominalParameterNameSpace, this._addedBuilders);
 
   void _addBuilder(
       ProblemReporting problemReporting,
@@ -435,8 +488,9 @@
 
   void checkTypeVariableConflict(ProblemReporting _problemReporting,
       String name, Builder member, Uri fileUri) {
-    if (_typeVariables != null) {
-      NominalVariableBuilder? tv = _typeVariables![name];
+    if (_nominalParameterNameSpace != null) {
+      NominalVariableBuilder? tv =
+          _nominalParameterNameSpace.getTypeParameter(name);
       if (tv != null) {
         _problemReporting.addProblem(
             templateConflictsWithTypeVariable.withArguments(name),