Elements. Stop implementing VariableElementOrMember and ParameterElementMixin by members.

The test changes are intentional, because `typeParameters2`
in `FormalParameterElementImpl` now returns elements.

Change-Id: Idd4696f6b69d4f4d84f7f5678d1476044512dfaf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/437700
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
index 1ae8187..fa45e15 100644
--- a/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
+++ b/pkg/analyzer/lib/src/dart/element/display_string_builder.dart
@@ -209,6 +209,20 @@
     }
   }
 
+  void writeFormalParameter2(FormalParameterElementMixin element) {
+    if (element.isRequiredPositional) {
+      _writeWithoutDelimiters2(element, forElement: true);
+    } else if (element.isOptionalPositional) {
+      _write('[');
+      _writeWithoutDelimiters2(element, forElement: true);
+      _write(']');
+    } else if (element.isNamed) {
+      _write('{');
+      _writeWithoutDelimiters2(element, forElement: true);
+      _write('}');
+    }
+  }
+
   void writeFunctionType(FunctionTypeImpl type) {
     if (_maybeWriteTypeAlias(type)) {
       return;
@@ -219,10 +233,7 @@
     _writeType(type.returnType);
     _write(' Function');
     _writeTypeParameters2(type.typeParameters);
-    _writeFormalParameters(
-      type.parameters.map((e) => e.asElement).toList(),
-      forElement: false,
-    );
+    _writeFormalParameters2(type.parameters, forElement: false);
     _writeNullability(type.nullabilitySuffix);
   }
 
@@ -425,6 +436,12 @@
     _write(element.displayName);
   }
 
+  void writeVariableElement2(VariableElement2OrMember element) {
+    _writeType(element.type);
+    _write(' ');
+    _write(element.displayName);
+  }
+
   void writeVoidType() {
     _write('void');
   }
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 7705ffa..b1be2b9 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -3111,7 +3111,8 @@
 
   @override
   // TODO(augmentations): Implement the merge of formal parameters.
-  List<TypeParameterElement> get typeParameters2 => const [];
+  List<TypeParameterElement> get typeParameters2 =>
+      firstFragment.typeParameters.map((fragment) => fragment.element).toList();
 
   @override
   TypeImpl get typeShared => type;
diff --git a/pkg/analyzer/lib/src/dart/element/member.dart b/pkg/analyzer/lib/src/dart/element/member.dart
index 9db02b6..bd402f4 100644
--- a/pkg/analyzer/lib/src/dart/element/member.dart
+++ b/pkg/analyzer/lib/src/dart/element/member.dart
@@ -926,9 +926,8 @@
 
 /// A parameter element defined in a parameterized type where the values of the
 /// type parameters are known.
-class ParameterMember extends VariableMember
-    with ParameterElementMixin, FormalParameterElementMixin {
-  @override
+class ParameterMember extends VariableMember with FormalParameterElementMixin {
+  // TODO(scheglov): replace with TypeParameterElementImpl(s)
   final List<TypeParameterFragmentImpl> typeParameters;
 
   factory ParameterMember({
@@ -1013,6 +1012,30 @@
   bool get isInitializingFormal => declaration.isInitializingFormal;
 
   @override
+  bool get isNamed => baseElement.isNamed;
+
+  @override
+  bool get isOptional => baseElement.isOptional;
+
+  @override
+  bool get isOptionalNamed => baseElement.isOptionalNamed;
+
+  @override
+  bool get isOptionalPositional => baseElement.isOptionalPositional;
+
+  @override
+  bool get isPositional => baseElement.isPositional;
+
+  @override
+  bool get isRequired => baseElement.isRequired;
+
+  @override
+  bool get isRequiredNamed => baseElement.isRequiredNamed;
+
+  @override
+  bool get isRequiredPositional => baseElement.isRequiredPositional;
+
+  @override
   bool get isSuperFormal => declaration.isSuperFormal;
 
   @override
@@ -1052,15 +1075,6 @@
   }
 
   @override
-  List<ParameterElementMixin> get parameters {
-    var type = this.type;
-    if (type is FunctionTypeImpl) {
-      return type.parameters.map((element) => element.asElement).toList();
-    }
-    return const <ParameterElementMixin>[];
-  }
-
-  @override
   Source? get source => _declaration.source;
 
   @override
@@ -1083,7 +1097,7 @@
 
   @override
   void appendTo(ElementDisplayStringBuilder builder) {
-    builder.writeFormalParameter(this);
+    builder.writeFormalParameter2(this);
   }
 
   @override
@@ -1121,32 +1135,6 @@
     _element2.visitChildren2(visitor);
   }
 
-  static ParameterElementMixin from(
-    ParameterElementMixin element,
-    MapSubstitution substitution,
-  ) {
-    FormalParameterFragmentImpl declaration;
-    var combined = substitution;
-    if (element is ParameterMember) {
-      var member = element;
-      declaration = member.declaration;
-
-      var map = <TypeParameterElement, DartType>{
-        for (var MapEntry(:key, :value) in member.substitution.map.entries)
-          key: substitution.substituteType(value),
-      };
-      combined = Substitution.fromMap2(map);
-    } else {
-      declaration = element as FormalParameterFragmentImpl;
-    }
-
-    if (combined.map.isEmpty) {
-      return element;
-    }
-
-    return ParameterMember(declaration: declaration, substitution: combined);
-  }
-
   static FormalParameterElementMixin from2(
     FormalParameterElementMixin element,
     MapSubstitution substitution,
@@ -1398,7 +1386,7 @@
 /// A variable element defined in a parameterized type where the values of the
 /// type parameters are known.
 abstract class VariableMember extends Member
-    implements VariableElementOrMember {
+    implements VariableElement2OrMember {
   TypeImpl? _type;
 
   /// Initialize a newly created element to represent a variable, based on the
@@ -1437,7 +1425,7 @@
 
   @override
   void appendTo(ElementDisplayStringBuilder builder) {
-    builder.writeVariableElement(this);
+    builder.writeVariableElement2(this);
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary2/bundle_writer.dart b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
index 2efdfa1..b505537 100644
--- a/pkg/analyzer/lib/src/summary2/bundle_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/bundle_writer.dart
@@ -991,6 +991,10 @@
     }
   }
 
+  void _writeElementName(Element element) {
+    _writeOptionalStringReference(element.name3);
+  }
+
   void _writeFormalParameters(
     List<ParameterElementMixin> parameters, {
     required bool withAnnotations,
@@ -1014,6 +1018,29 @@
     }
   }
 
+  void _writeFormalParameters2(
+    List<FormalParameterElementMixin> parameters, {
+    required bool withAnnotations,
+  }) {
+    writeUInt30(parameters.length);
+    for (var parameter in parameters) {
+      _writeFormalParameterKind2(parameter);
+      writeBool(parameter.hasImplicitType);
+      writeBool(parameter.isInitializingFormal);
+      _writeTypeParameters2(parameter.typeParameters2.cast(), () {
+        writeType(parameter.type);
+        _writeElementName(parameter);
+        _writeFormalParameters2(
+          parameter.formalParameters.cast(),
+          withAnnotations: withAnnotations,
+        );
+      }, withAnnotations: withAnnotations);
+      if (withAnnotations) {
+        _writeMetadata(parameter.metadata as MetadataImpl);
+      }
+    }
+  }
+
   void _writeFragmentName(Fragment fragment) {
     _writeOptionalStringReference(fragment.name2);
   }
@@ -1025,10 +1052,7 @@
 
     _writeTypeParameters(type.typeFormals, () {
       writeType(type.returnType);
-      _writeFormalParameters(
-        type.parameters.map((e) => e.asElement).toList(),
-        withAnnotations: false,
-      );
+      _writeFormalParameters2(type.formalParameters, withAnnotations: false);
     }, withAnnotations: false);
     _writeNullabilitySuffix(type.nullabilitySuffix);
   }
@@ -1115,6 +1139,26 @@
     });
   }
 
+  void _writeTypeParameters2(
+    List<TypeParameterElementImpl> typeParameters,
+    void Function() f, {
+    required bool withAnnotations,
+  }) {
+    localElements.withElements(typeParameters, () {
+      writeUInt30(typeParameters.length);
+      for (var typeParameter in typeParameters) {
+        _writeElementName(typeParameter);
+      }
+      for (var typeParameter in typeParameters) {
+        writeType(typeParameter.bound);
+        if (withAnnotations) {
+          _writeMetadata(typeParameter.metadata);
+        }
+      }
+      f();
+    });
+  }
+
   static List<DartType> _enclosingClassTypeArguments(
     Element declaration,
     Map<TypeParameterElement, DartType> substitution,
@@ -1320,6 +1364,20 @@
     }
   }
 
+  void _writeFormalParameterKind2(FormalParameterElementMixin p) {
+    if (p.isRequiredPositional) {
+      writeByte(Tag.ParameterKindRequiredPositional);
+    } else if (p.isOptionalPositional) {
+      writeByte(Tag.ParameterKindOptionalPositional);
+    } else if (p.isRequiredNamed) {
+      writeByte(Tag.ParameterKindRequiredNamed);
+    } else if (p.isOptionalNamed) {
+      writeByte(Tag.ParameterKindOptionalNamed);
+    } else {
+      throw StateError('Unexpected parameter kind: $p');
+    }
+  }
+
   void _writeOptionalStringReference(String? value) {
     if (value != null) {
       writeBool(true);
diff --git a/pkg/analyzer/lib/src/utilities/extensions/element.dart b/pkg/analyzer/lib/src/utilities/extensions/element.dart
index fa0b19c..ac608c1 100644
--- a/pkg/analyzer/lib/src/utilities/extensions/element.dart
+++ b/pkg/analyzer/lib/src/utilities/extensions/element.dart
@@ -274,16 +274,6 @@
   }
 }
 
-extension FormalParameterElementMixinExtension on FormalParameterElementMixin {
-  ParameterElementMixin get asElement {
-    return switch (this) {
-      FormalParameterElementImpl(:var firstFragment) => firstFragment,
-      ParameterMember member => member,
-      _ => throw UnsupportedError('Unsupported type: $runtimeType'),
-    };
-  }
-}
-
 extension GetterElementImplExtension on GetterElementImpl {
   PropertyAccessorFragmentImpl get asElement {
     return lastFragment;
diff --git a/pkg/analyzer/test/src/summary/elements/class_test.dart b/pkg/analyzer/test/src/summary/elements/class_test.dart
index 56194d1..22f6702 100644
--- a/pkg/analyzer/test/src/summary/elements/class_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/class_test.dart
@@ -728,9 +728,14 @@
             requiredPositional final f
               firstFragment: #F4
               type: List<U> Function<T, U>(T)
+              typeParameters
+                #E0 T
+                  firstFragment: #F8
+                #E1 U
+                  firstFragment: #F9
               formalParameters
                 requiredPositional t
-                  firstFragment: #F8
+                  firstFragment: #F10
                   type: T
       getters
         synthetic f
@@ -2917,9 +2922,13 @@
             requiredPositional final a
               firstFragment: #F6
               type: int Function<T extends num>(T)?
+              typeParameters
+                #E0 T
+                  firstFragment: #F7
+                  bound: num
               formalParameters
                 requiredPositional d
-                  firstFragment: #F7
+                  firstFragment: #F8
                   type: T
           superConstructor: <testLibrary>::@class::A::@constructor::new
 ''');
diff --git a/pkg/analyzer/test/src/summary/elements/formal_parameter_test.dart b/pkg/analyzer/test/src/summary/elements/formal_parameter_test.dart
index 68cd062..858e690 100644
--- a/pkg/analyzer/test/src/summary/elements/formal_parameter_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/formal_parameter_test.dart
@@ -559,9 +559,14 @@
         requiredPositional a
           firstFragment: #F2
           type: T Function<T, U>(U)
+          typeParameters
+            #E0 T
+              firstFragment: #F3
+            #E1 U
+              firstFragment: #F4
           formalParameters
             requiredPositional u
-              firstFragment: #F3
+              firstFragment: #F5
               type: U
       returnType: void
 ''');
diff --git a/pkg/analyzer/test/src/summary/elements/offsets_test.dart b/pkg/analyzer/test/src/summary/elements/offsets_test.dart
index 56a2b407..ae777de 100644
--- a/pkg/analyzer/test/src/summary/elements/offsets_test.dart
+++ b/pkg/analyzer/test/src/summary/elements/offsets_test.dart
@@ -3037,9 +3037,12 @@
         requiredPositional f
           firstFragment: #F2
           type: void Function<U>(int)
+          typeParameters
+            #E0 U
+              firstFragment: #F3
           formalParameters
             requiredPositional a
-              firstFragment: #F3
+              firstFragment: #F4
               type: int
       returnType: void
 ''');
@@ -3069,9 +3072,12 @@
         requiredNamed f
           firstFragment: #F2
           type: void Function<U>(int)
+          typeParameters
+            #E0 U
+              firstFragment: #F3
           formalParameters
             requiredPositional a
-              firstFragment: #F3
+              firstFragment: #F4
               type: int
       returnType: void
 ''');