[cfe] Make applyMixins and copyTypeVariables static in BuilderFactoryImpl

This is done in preparation for moving the creation of class builders to
after outline building.

Change-Id: I3a6e06ff68055b9e4c915fbe8c44227b492cdf63
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384702
Reviewed-by: Jens Johansen <jensj@google.com>
diff --git a/pkg/front_end/lib/src/source/builder_factory.dart b/pkg/front_end/lib/src/source/builder_factory.dart
index a74813e..ff2c9f3 100644
--- a/pkg/front_end/lib/src/source/builder_factory.dart
+++ b/pkg/front_end/lib/src/source/builder_factory.dart
@@ -483,17 +483,6 @@
       int charOffset,
       Uri fileUri);
 
-  /// Creates a [NominalVariableCopy] object containing a copy of
-  /// [oldVariableBuilders] into the scope of [declaration].
-  ///
-  /// This is used for adding copies of class type parameters to factory
-  /// methods and unnamed mixin applications, and for adding copies of
-  /// extension type parameters to extension instance methods.
-  NominalVariableCopy? copyTypeVariables(
-      List<NominalVariableBuilder>? oldVariableBuilders,
-      {required TypeVariableKind kind,
-      required InstanceTypeVariableAccessState instanceTypeVariableAccess});
-
   void registerUnboundStructuralVariables(
       List<StructuralVariableBuilder> variableBuilders);
 }
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 f678a02..e15ae4c 100644
--- a/pkg/front_end/lib/src/source/source_builder_factory.dart
+++ b/pkg/front_end/lib/src/source/source_builder_factory.dart
@@ -114,6 +114,10 @@
   /// inferred types in the original code.
   final Map<String, Builder>? _omittedTypeDeclarationBuilders;
 
+  /// Map from mixin application classes to their mixin types.
+  ///
+  /// This is used to check that super access in mixin declarations have a
+  /// concrete target.
   Map<SourceClassBuilder, TypeBuilder>? _mixinApplications = {};
 
   final List<NominalVariableBuilder> _unboundNominalVariables = [];
@@ -124,7 +128,7 @@
 
   final LibraryName libraryName;
 
-  final LookupScope _scope;
+  final LookupScope _compilationUnitScope;
 
   /// Index for building unique lowered names for wildcard variables.
   int wildcardVariableIndex = 0;
@@ -155,7 +159,7 @@
         _libraryNameSpaceBuilder = libraryNameSpaceBuilder,
         _problemReporting = problemReporting,
         _parent = parent,
-        _scope = scope,
+        _compilationUnitScope = scope,
         libraryName = libraryName,
         indexedLibrary = indexedLibrary,
         _omittedTypeDeclarationBuilders = omittedTypeDeclarationBuilders,
@@ -675,28 +679,6 @@
         "Unexpected type scope: $typeVariableScope.");
   }
 
-  void beginUnnamedMixinApplication() {
-    NominalParameterNameSpace nominalParameterNameSpace =
-        new NominalParameterNameSpace();
-    _nominalParameterNameSpaces.push(nominalParameterNameSpace);
-    _typeScopes.push(new TypeScope(
-        TypeScopeKind.unnamedMixinApplication,
-        new NominalParameterScope(
-            _typeScopes.current.lookupScope, nominalParameterNameSpace),
-        _typeScopes.current));
-  }
-
-  void endUnnamedMixinApplication() {
-    TypeScope typeVariableScope = _typeScopes.pop();
-    assert(
-        typeVariableScope.kind == TypeScopeKind.unnamedMixinApplication,
-        // Coverage-ignore(suite): Not run.
-        "Unexpected type scope: $typeVariableScope.");
-    assert(
-        typeVariableScope.isEmpty, // Coverage-ignore(suite): Not run.
-        "Unexpected type scope: $typeVariableScope");
-  }
-
   @override
   void checkStacks() {
     assert(
@@ -1016,20 +998,31 @@
     LookupScope typeParameterScope = declarationFragment.typeParameterScope;
     DeclarationNameSpaceBuilder nameSpaceBuilder =
         declarationFragment.toDeclarationNameSpaceBuilder();
+
+    assert(
+        _mixinApplications != null, "Late registration of mixin application.");
+
     SourceEnumBuilder enumBuilder = new SourceEnumBuilder(
         metadata,
         name,
         typeVariables,
         loader.target.underscoreEnumType,
-        _applyMixins(
-            loader.target.underscoreEnumType,
-            supertypeBuilder,
-            startCharOffset,
-            charOffset,
-            charEndOffset,
-            name,
-            /* isMixinDeclaration = */
-            false,
+        applyMixins(
+            unboundNominalVariables: _unboundNominalVariables,
+            compilationUnitScope: _compilationUnitScope,
+            problemReporting: _problemReporting,
+            objectTypeBuilder: loader.target.objectType,
+            enclosingLibraryBuilder: _parent,
+            fileUri: _compilationUnit.fileUri,
+            indexedLibrary: indexedLibrary,
+            supertype: loader.target.underscoreEnumType,
+            mixinApplicationBuilder: supertypeBuilder,
+            mixinApplications: _mixinApplications!,
+            startCharOffset: startCharOffset,
+            charOffset: charOffset,
+            charEndOffset: charEndOffset,
+            subclassName: name,
+            isMixinDeclaration: false,
             typeVariables: typeVariables,
             isMacro: false,
             isSealed: false,
@@ -1037,7 +1030,8 @@
             isInterface: false,
             isFinal: false,
             isAugmentation: false,
-            isMixinClass: false),
+            isMixinClass: false,
+            addBuilder: _addBuilder),
         interfaceBuilders,
         enumConstantInfos,
         _parent,
@@ -1153,13 +1147,31 @@
     if (declarationFragment.declaresConstConstructor) {
       modifiers |= declaresConstConstructorMask;
     }
+
+    assert(
+        _mixinApplications != null, "Late registration of mixin application.");
+
     SourceClassBuilder classBuilder = new SourceClassBuilder(
         metadata,
         modifiers,
         className,
         typeVariables,
-        _applyMixins(supertype, mixins, startOffset, nameOffset, endOffset,
-            className, isMixinDeclaration,
+        applyMixins(
+            unboundNominalVariables: _unboundNominalVariables,
+            compilationUnitScope: _compilationUnitScope,
+            problemReporting: _problemReporting,
+            objectTypeBuilder: loader.target.objectType,
+            enclosingLibraryBuilder: _parent,
+            fileUri: _compilationUnit.fileUri,
+            indexedLibrary: indexedLibrary,
+            supertype: supertype,
+            mixinApplicationBuilder: mixins,
+            mixinApplications: _mixinApplications!,
+            startCharOffset: startOffset,
+            charOffset: nameOffset,
+            charEndOffset: endOffset,
+            subclassName: className,
+            isMixinDeclaration: isMixinDeclaration,
             typeVariables: typeVariables,
             isMacro: false,
             isSealed: false,
@@ -1168,7 +1180,8 @@
             isFinal: false,
             // TODO(johnniwinther): How can we support class with mixins?
             isAugmentation: false,
-            isMixinClass: false),
+            isMixinClass: false,
+            addBuilder: _addBuilder),
         interfaces,
         // TODO(johnniwinther): Add the `on` clause types of a mixin declaration
         // here.
@@ -1226,8 +1239,26 @@
       required bool isMixinClass}) {
     // Nested declaration began in `OutlineBuilder.beginNamedMixinApplication`.
     endNamedMixinApplication(name);
-    supertype = _applyMixins(supertype, mixinApplication, startCharOffset,
-        charOffset, charEndOffset, name, false,
+
+    assert(
+        _mixinApplications != null, "Late registration of mixin application.");
+
+    supertype = applyMixins(
+        unboundNominalVariables: _unboundNominalVariables,
+        compilationUnitScope: _compilationUnitScope,
+        problemReporting: _problemReporting,
+        objectTypeBuilder: loader.target.objectType,
+        enclosingLibraryBuilder: _parent,
+        fileUri: _compilationUnit.fileUri,
+        indexedLibrary: indexedLibrary,
+        supertype: supertype,
+        mixinApplicationBuilder: mixinApplication,
+        mixinApplications: _mixinApplications!,
+        startCharOffset: startCharOffset,
+        charOffset: charOffset,
+        charEndOffset: charEndOffset,
+        subclassName: name,
+        isMixinDeclaration: false,
         metadata: metadata,
         name: name,
         typeVariables: typeVariables,
@@ -1239,21 +1270,29 @@
         isInterface: isInterface,
         isFinal: isFinal,
         isAugmentation: isAugmentation,
-        isMixinClass: isMixinClass)!;
+        isMixinClass: isMixinClass,
+        addBuilder: _addBuilder)!;
     _nominalParameterNameSpaces.pop().addTypeVariables(
         _problemReporting, typeVariables,
         ownerName: supertype.declaration!.name, allowNameConflict: false);
   }
 
-  TypeBuilder? _applyMixins(
-      TypeBuilder? supertype,
-      MixinApplicationBuilder? mixinApplications,
-      int startCharOffset,
-      int charOffset,
-      int charEndOffset,
-      String subclassName,
-      bool isMixinDeclaration,
-      {List<MetadataBuilder>? metadata,
+  static TypeBuilder? applyMixins(
+      {required ProblemReporting problemReporting,
+      required SourceLibraryBuilder enclosingLibraryBuilder,
+      required List<NominalVariableBuilder> unboundNominalVariables,
+      required TypeBuilder? supertype,
+      required MixinApplicationBuilder? mixinApplicationBuilder,
+      required int startCharOffset,
+      required int charOffset,
+      required int charEndOffset,
+      required String subclassName,
+      required bool isMixinDeclaration,
+      required IndexedLibrary? indexedLibrary,
+      required LookupScope compilationUnitScope,
+      required Map<SourceClassBuilder, TypeBuilder> mixinApplications,
+      required Uri fileUri,
+      List<MetadataBuilder>? metadata,
       String? name,
       List<NominalVariableBuilder>? typeVariables,
       int modifiers = 0,
@@ -1264,19 +1303,22 @@
       required bool isInterface,
       required bool isFinal,
       required bool isAugmentation,
-      required bool isMixinClass}) {
+      required bool isMixinClass,
+      required TypeBuilder objectTypeBuilder,
+      required void Function(String name, Builder declaration, int charOffset,
+              {Reference? getterReference})
+          addBuilder}) {
     if (name == null) {
       // The following parameters should only be used when building a named
       // mixin application.
       if (metadata != null) {
-        unhandled("metadata", "unnamed mixin application", charOffset,
-            _compilationUnit.fileUri);
+        unhandled("metadata", "unnamed mixin application", charOffset, fileUri);
       } else if (interfaces != null) {
-        unhandled("interfaces", "unnamed mixin application", charOffset,
-            _compilationUnit.fileUri);
+        unhandled(
+            "interfaces", "unnamed mixin application", charOffset, fileUri);
       }
     }
-    if (mixinApplications != null) {
+    if (mixinApplicationBuilder != null) {
       // Documentation below assumes the given mixin application is in one of
       // these forms:
       //
@@ -1293,7 +1335,7 @@
       /// 1. `S with M1`.
       /// 2. `(S with M1) with M2`.
       /// 3. `((S with M1) with M2) with M3`.
-      supertype ??= loader.target.objectType;
+      supertype ??= objectTypeBuilder;
 
       /// The variable part of the mixin application's synthetic name. It
       /// starts out as the name of the superclass, but is only used after it
@@ -1347,10 +1389,10 @@
       /// Iterate over the mixins from left to right. At the end of each
       /// iteration, a new [supertype] is computed that is the mixin
       /// application of [supertype] with the current mixin.
-      for (int i = 0; i < mixinApplications.mixins.length; i++) {
-        TypeBuilder mixin = mixinApplications.mixins[i];
+      for (int i = 0; i < mixinApplicationBuilder.mixins.length; i++) {
+        TypeBuilder mixin = mixinApplicationBuilder.mixins[i];
         isNamedMixinApplication =
-            name != null && mixin == mixinApplications.mixins.last;
+            name != null && mixin == mixinApplicationBuilder.mixins.last;
         bool isGeneric = false;
         if (!isNamedMixinApplication) {
           if (typeVariableNames != null) {
@@ -1377,10 +1419,11 @@
           // Otherwise, we pass the fresh type variables to the mixin
           // application in the same order as they're declared on the subclass.
           if (isGeneric) {
-            beginUnnamedMixinApplication();
+            NominalParameterNameSpace nominalParameterNameSpace =
+                new NominalParameterNameSpace();
 
             NominalVariableCopy nominalVariableCopy = copyTypeVariables(
-                typeVariables,
+                enclosingLibraryBuilder, unboundNominalVariables, typeVariables,
                 kind: TypeVariableKind.extensionSynthesized,
                 instanceTypeVariableAccess:
                     InstanceTypeVariableAccessState.Allowed)!;
@@ -1392,8 +1435,6 @@
             Map<NominalVariableBuilder, TypeBuilder> substitutionMap =
                 nominalVariableCopy.substitutionMap;
 
-            endUnnamedMixinApplication();
-
             applicationTypeArguments = [];
             for (NominalVariableBuilder typeVariable in typeVariables!) {
               TypeBuilder applicationTypeArgument =
@@ -1404,14 +1445,14 @@
                       // the class that extend the anonymous mixin application.
                       typeVariable,
                       const NullabilityBuilder.omitted(),
-                      fileUri: _compilationUnit.fileUri,
+                      fileUri: fileUri,
                       charOffset: charOffset,
                       instanceTypeVariableAccess:
                           InstanceTypeVariableAccessState.Allowed);
               applicationTypeArguments.add(applicationTypeArgument);
             }
-            _nominalParameterNameSpaces.pop().addTypeVariables(
-                _problemReporting, applicationTypeVariables,
+            nominalParameterNameSpace.addTypeVariables(
+                problemReporting, applicationTypeVariables,
                 ownerName: fullname, allowNameConflict: true);
             if (supertype != null) {
               supertype = new SynthesizedTypeBuilder(
@@ -1429,11 +1470,11 @@
         IndexedClass? referencesFromIndexedClass;
         if (indexedLibrary != null) {
           referencesFromIndexedClass =
-              indexedLibrary!.lookupIndexedClass(fullname);
+              indexedLibrary.lookupIndexedClass(fullname);
         }
 
         LookupScope typeParameterScope =
-            TypeParameterScope.fromList(_scope, typeVariables);
+            TypeParameterScope.fromList(compilationUnitScope, typeVariables);
         DeclarationNameSpaceBuilder nameSpaceBuilder =
             new DeclarationNameSpaceBuilder.empty();
         SourceClassBuilder application = new SourceClassBuilder(
@@ -1453,7 +1494,7 @@
             // No `on` clause types.
             typeParameterScope,
             nameSpaceBuilder,
-            _parent,
+            enclosingLibraryBuilder,
             <ConstructorReferenceBuilder>[],
             computedStartCharOffset,
             charOffset,
@@ -1471,16 +1512,16 @@
         // pkg/analyzer/test/src/summary/resynthesize_kernel_test.dart can't
         // handle that :(
         application.cls.isAnonymousMixin = !isNamedMixinApplication;
-        _addBuilder(fullname, application, charOffset,
+        addBuilder(fullname, application, charOffset,
             getterReference: referencesFromIndexedClass?.cls.reference);
         supertype = new NamedTypeBuilderImpl.fromTypeDeclarationBuilder(
             application, const NullabilityBuilder.omitted(),
             arguments: applicationTypeArguments,
-            fileUri: _compilationUnit.fileUri,
+            fileUri: fileUri,
             charOffset: charOffset,
             instanceTypeVariableAccess:
                 InstanceTypeVariableAccessState.Allowed);
-        _registerMixinApplication(application, mixin);
+        mixinApplications[application] = mixin;
       }
       return supertype;
     } else {
@@ -1488,18 +1529,6 @@
     }
   }
 
-  /// Registers that [mixinApplication] is a mixin application introduced by
-  /// the [mixedInType] in a with-clause.
-  ///
-  /// This is used to check that super access in mixin declarations have a
-  /// concrete target.
-  void _registerMixinApplication(
-      SourceClassBuilder mixinApplication, TypeBuilder mixedInType) {
-    assert(
-        _mixinApplications != null, "Late registration of mixin application.");
-    _mixinApplications![mixinApplication] = mixedInType;
-  }
-
   @override
   void addExtensionDeclaration(
       OffsetMap offsetMap,
@@ -1661,8 +1690,8 @@
       switch (declarationFragment) {
         case ExtensionFragment():
         case ExtensionTypeFragment():
-          NominalVariableCopy? nominalVariableCopy = copyTypeVariables(
-              declarationFragment.typeParameters,
+          NominalVariableCopy? nominalVariableCopy = copyTypeVariables(_parent,
+              _unboundNominalVariables, declarationFragment.typeParameters,
               kind: TypeVariableKind.extensionSynthesized,
               instanceTypeVariableAccess:
                   InstanceTypeVariableAccessState.Allowed);
@@ -1683,8 +1712,8 @@
     } else if (!isStatic) {
       switch (declarationFragment) {
         case ExtensionFragment():
-          NominalVariableCopy? nominalVariableCopy = copyTypeVariables(
-              declarationFragment.typeParameters,
+          NominalVariableCopy? nominalVariableCopy = copyTypeVariables(_parent,
+              _unboundNominalVariables, declarationFragment.typeParameters,
               kind: TypeVariableKind.extensionSynthesized,
               instanceTypeVariableAccess:
                   InstanceTypeVariableAccessState.Allowed);
@@ -1717,8 +1746,8 @@
           }
           formals = synthesizedFormals;
         case ExtensionTypeFragment():
-          NominalVariableCopy? nominalVariableCopy = copyTypeVariables(
-              declarationFragment.typeParameters,
+          NominalVariableCopy? nominalVariableCopy = copyTypeVariables(_parent,
+              _unboundNominalVariables, declarationFragment.typeParameters,
               kind: TypeVariableKind.extensionSynthesized,
               instanceTypeVariableAccess:
                   InstanceTypeVariableAccessState.Allowed);
@@ -1856,8 +1885,8 @@
       required bool isConst}) {
     beginConstructor();
     endConstructor();
-    NominalVariableCopy? nominalVariableCopy = copyTypeVariables(
-        _declarationFragments.current.typeParameters,
+    NominalVariableCopy? nominalVariableCopy = copyTypeVariables(_parent,
+        _unboundNominalVariables, _declarationFragments.current.typeParameters,
         kind: TypeVariableKind.extensionSynthesized,
         instanceTypeVariableAccess: InstanceTypeVariableAccessState.Allowed);
     List<NominalVariableBuilder>? typeVariables =
@@ -2099,7 +2128,8 @@
           staticMask | modifiers,
           returnType,
           procedureName,
-          typeVariables = copyTypeVariables(enclosingDeclaration.typeParameters,
+          typeVariables = copyTypeVariables(_parent, _unboundNominalVariables,
+                  enclosingDeclaration.typeParameters,
                   kind: TypeVariableKind.function,
                   instanceTypeVariableAccess:
                       InstanceTypeVariableAccessState.Allowed)
@@ -2123,7 +2153,8 @@
           staticMask | modifiers,
           returnType,
           procedureName,
-          typeVariables = copyTypeVariables(enclosingDeclaration.typeParameters,
+          typeVariables = copyTypeVariables(_parent, _unboundNominalVariables,
+                  enclosingDeclaration.typeParameters,
                   kind: TypeVariableKind.function,
                   instanceTypeVariableAccess:
                       InstanceTypeVariableAccessState.Allowed)
@@ -2719,8 +2750,15 @@
     return builder;
   }
 
-  @override
-  NominalVariableCopy? copyTypeVariables(
+  /// Creates a [NominalVariableCopy] object containing a copy of
+  /// [oldVariableBuilders] into the scope of [declaration].
+  ///
+  /// This is used for adding copies of class type parameters to factory
+  /// methods and unnamed mixin applications, and for adding copies of
+  /// extension type parameters to extension instance methods.
+  static NominalVariableCopy? copyTypeVariables(
+      Builder _parent,
+      List<NominalVariableBuilder> _unboundNominalVariables,
       List<NominalVariableBuilder>? oldVariableBuilders,
       {required TypeVariableKind kind,
       required InstanceTypeVariableAccessState instanceTypeVariableAccess}) {
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 4abe40f..ea5867b 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
@@ -698,6 +698,7 @@
     return typeCount;
   }
 
+  // Coverage-ignore(suite): Not run.
   bool get isEmpty => _unresolvedNamedTypes.isEmpty && _childScopes.isEmpty;
 
   @override