[analyzer] Use FormalParameterElementOrMember when interfacing with shared code.

Change the analyzer's use of the following shared generic types so
that it supplies the type parameter `FormalParameterElementOrMember`
instead of `ParameterElementMixin` as the type it uses to represent
parameters of function types:

- `SharedFunctionTypeStructure`
- `TypeConstraintGenerator`
- `TypeConstraintGeneratorMixin`

`FormalParameterElementOrMember` is a new interface class that acts as
a common private base class for all the concrete subtypes of the
public API class `FormalParameterElement`.

This required adding a type cast in one place (in
`FunctionTypeImpl.sortedNamedParametersShared`). In other places, I
avoided type casts by tightening up some return types (for example,
`FieldFormalParameterElementImpl.element` now returns
`FieldFormalParameterElementImpl2` instead of
`FieldFormalParameterElement2`). The analyzer public API is unchanged,
though (for example, `FieldFormalParameterFragment.element` still has
a return type of `FieldFormalParameterElement2`), so clients should be
unaffected.

As a result of this change, it is no longer necessary for
`ParameterElementMixin` to implement the shared interface
`SharedNamedFunctionParameterStructure`. This interface is now
implemented by `FormalParameterElementOrMember`.

This is part of a larger arc of work to use types from the new
analyzer element model when interfacing with shared code.

Change-Id: I1ab5bf0607a80cbe30f4814bd5444487099825ee
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/402341
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 7b0002d..acf5f3b 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -4400,8 +4400,8 @@
   });
 
   @override
-  FieldFormalParameterElement2 get element =>
-      super.element as FieldFormalParameterElement2;
+  FieldFormalParameterElementImpl2 get element =>
+      super.element as FieldFormalParameterElementImpl2;
 
   /// Initializing formals are visible only in the "formal parameter
   /// initializer scope", which is the current scope of the initializer list
@@ -4428,7 +4428,7 @@
       visitor.visitFieldFormalParameterElement(this);
 
   @override
-  FormalParameterElement _createElement(
+  FieldFormalParameterElementImpl2 _createElement(
           FormalParameterFragment firstFragment) =>
       FieldFormalParameterElementImpl2(firstFragment as ParameterElementImpl);
 }
@@ -4453,7 +4453,7 @@
         FragmentedAnnotatableElementMixin<FormalParameterFragment>,
         FragmentedElementMixin<FormalParameterFragment>,
         _NonTopLevelVariableOrParameter
-    implements FormalParameterElement {
+    implements FormalParameterElementOrMember {
   final ParameterElementImpl wrappedElement;
 
   FormalParameterElementImpl(this.wrappedElement) {
@@ -4552,6 +4552,9 @@
   String? get name3 => wrappedElement.name;
 
   @override
+  String get nameShared => wrappedElement.name;
+
+  @override
   // TODO(augmentations): Implement the merge of formal parameters.
   DartType get type => wrappedElement.type;
 
@@ -4588,6 +4591,11 @@
   //     .toList();
 }
 
+abstract class FormalParameterElementOrMember
+    implements
+        FormalParameterElement,
+        SharedNamedFunctionParameterStructure<DartType> {}
+
 mixin FragmentedAnnotatableElementMixin<E extends Fragment>
     implements FragmentedElementMixin<E> {
   String? get documentationComment {
@@ -9029,7 +9037,7 @@
   bool inheritsCovariant = false;
 
   /// The element corresponding to this fragment.
-  FormalParameterElement? _element;
+  FormalParameterElementImpl? _element;
 
   /// Initialize a newly created parameter element to have the given [name] and
   /// [nameOffset].
@@ -9065,7 +9073,7 @@
   ParameterElement get declaration => this;
 
   @override
-  FormalParameterElement get element {
+  FormalParameterElementImpl get element {
     if (_element != null) {
       return _element!;
     }
@@ -9080,7 +9088,7 @@
     return _createElement(firstFragment);
   }
 
-  set element(FormalParameterElement element) => _element = element;
+  set element(FormalParameterElementImpl element) => _element = element;
 
   @override
   Fragment? get enclosingFragment => enclosingElement3 as Fragment?;
@@ -9170,7 +9178,7 @@
     builder.writeFormalParameter(this);
   }
 
-  FormalParameterElement _createElement(
+  FormalParameterElementImpl _createElement(
           FormalParameterFragment firstFragment) =>
       FormalParameterElementImpl(firstFragment as ParameterElementImpl);
 }
@@ -9241,10 +9249,7 @@
 
 /// A mixin that provides a common implementation for methods defined in
 /// [ParameterElement].
-mixin ParameterElementMixin
-    implements
-        ParameterElement,
-        SharedNamedFunctionParameterStructure<DartType> {
+mixin ParameterElementMixin implements ParameterElement {
   @override
   bool get isNamed => parameterKind.isNamed;
 
@@ -9270,9 +9275,6 @@
   bool get isRequiredPositional => parameterKind.isRequiredPositional;
 
   @override
-  String get nameShared => name;
-
-  @override
   // Overridden to remove the 'deprecated' annotation.
   ParameterKind get parameterKind;
 
@@ -10274,8 +10276,8 @@
   });
 
   @override
-  SuperFormalParameterElement2 get element =>
-      super.element as SuperFormalParameterElement2;
+  SuperFormalParameterElementImpl2 get element =>
+      super.element as SuperFormalParameterElementImpl2;
 
   /// Super parameters are visible only in the initializer list scope,
   /// and introduce final variables.
@@ -10329,7 +10331,7 @@
   }
 
   @override
-  FormalParameterElement _createElement(
+  FormalParameterElementImpl _createElement(
           FormalParameterFragment firstFragment) =>
       SuperFormalParameterElementImpl2(firstFragment as ParameterElementImpl);
 }
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 9d6ac84..9f50ea0 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -1079,7 +1079,7 @@
 /// type parameters are known.
 class ParameterMember extends VariableMember
     with ParameterElementMixin
-    implements ParameterElement, FormalParameterElement {
+    implements ParameterElement, FormalParameterElementOrMember {
   @override
   final List<TypeParameterElement> typeParameters;
 
@@ -1168,6 +1168,9 @@
   String? get name3 => _element2.name3;
 
   @override
+  String get nameShared => name;
+
+  @override
   Element2 get nonSynthetic2 => _element2;
 
   @deprecated
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index f541df5..c621481 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -90,7 +90,7 @@
     implements
         FunctionType,
         SharedFunctionTypeStructure<DartType, TypeParameterElementImpl2,
-            ParameterElementMixin> {
+            FormalParameterElementOrMember> {
   @override
   late int hashCode = _computeHashCode();
 
@@ -234,8 +234,13 @@
       positionalParameterTypes.sublist(requiredPositionalParameterCount);
 
   @override
-  List<ParameterElementMixin> get sortedNamedParametersShared =>
-      sortedNamedParameters;
+  // TODO(paulberry): see if this type can be changed to
+  // `List<FormalParameterElementImpl>`. See
+  // https://dart-review.googlesource.com/c/sdk/+/402341/comment/b1669e20_15938fcd/.
+  List<FormalParameterElementOrMember> get sortedNamedParametersShared =>
+      sortedNamedParameters
+          .map((p) => p.asElement2 as FormalParameterElementOrMember)
+          .toList();
 
   @override
   List<TypeParameterElementImpl2> get typeParameters => typeFormals
diff --git a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
index 95faa67..02d08a5 100644
--- a/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_constraint_gatherer.dart
@@ -94,7 +94,7 @@
 /// attempt to make one type schema a subtype of another.
 class TypeConstraintGatherer extends shared.TypeConstraintGenerator<
         DartType,
-        ParameterElementMixin,
+        FormalParameterElementOrMember,
         PromotableElementImpl2,
         TypeParameterElementImpl2,
         InterfaceType,
@@ -103,7 +103,7 @@
     with
         shared.TypeConstraintGeneratorMixin<
             DartType,
-            ParameterElementMixin,
+            FormalParameterElementOrMember,
             PromotableElementImpl2,
             TypeParameterElementImpl2,
             InterfaceType,
diff --git a/pkg/analyzer/test/generated/non_error_resolver_test.dart b/pkg/analyzer/test/generated/non_error_resolver_test.dart
index ea80ad6..170b723 100644
--- a/pkg/analyzer/test/generated/non_error_resolver_test.dart
+++ b/pkg/analyzer/test/generated/non_error_resolver_test.dart
@@ -1890,6 +1890,20 @@
     ]);
   }
 
+  test_instantiateGenericFunctionWithNamedParameterAsGenericArg() async {
+    // This test case reproduces the problem encountered in
+    // https://dart-review.googlesource.com/c/sdk/+/402341/comment/b1669e20_15938fcd/.
+    await assertNoErrorsInCode(r'''
+abstract class C<T> {
+  S f<S>(S Function(C<T>) g);
+}
+
+T h<T>(C<T> c, {bool b = false}) => throw '';
+
+T test<T>(C<T> c) => c.f(h);
+''');
+  }
+
   test_integerLiteralOutOfRange_negative_leadingZeros() async {
     await assertNoErrorsInCode('''
 int x = -000923372036854775809;