Restore 'parameters' and 'typeParameters' for ParameterElementImpl.

This partially reverts https://dart-review.googlesource.com/c/sdk/+/5000
which was done during moving toward integration with Kernel, which
we don't do anymore.

With summary2 the FunctionType of a function type parameter is purely
synthetic, without its original element. However parameters in
function typed parameters still exist as nodes, so they must have
elements.

R=brianwilkerson@google.com

Change-Id: I6689b05459f3989a20839346013c80a86ac8dc7e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99709
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 1c3c7e2..2159a8a 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -7941,6 +7941,16 @@
   /// The unlinked representation of the parameter in the summary.
   final UnlinkedParam unlinkedParam;
 
+  /// A list containing all of the parameters defined by this parameter element.
+  /// There will only be parameters if this parameter is a function typed
+  /// parameter.
+  List<ParameterElement> _parameters;
+
+  /// A list containing all of the type parameters defined for this parameter
+  /// element. There will only be parameters if this parameter is a function
+  /// typed parameter.
+  List<TypeParameterElement> _typeParameters;
+
   /// The kind of this parameter.
   ParameterKind _parameterKind;
 
@@ -8275,7 +8285,39 @@
 
   @override
   List<ParameterElement> get parameters {
-    return const <ParameterElement>[];
+    if (_parameters != null) return _parameters;
+
+    if (linkedNode != null) {
+      var context = enclosingUnit.linkedContext;
+      var formalParameters = context.getFormalParameters(linkedNode);
+      if (formalParameters != null) {
+        var containerRef = reference.getChild('@parameter');
+        return _parameters = ParameterElementImpl.forLinkedNodeList(
+          this,
+          context,
+          containerRef,
+          formalParameters,
+        );
+      } else {
+        return _parameters ??= const <ParameterElement>[];
+      }
+    }
+
+    if (unlinkedParam != null) {
+      _resynthesizeTypeAndParameters();
+      return _parameters ??= const <ParameterElement>[];
+    }
+
+    return _parameters ??= const <ParameterElement>[];
+  }
+
+  /// Set the parameters defined by this executable element to the given
+  /// [parameters].
+  void set parameters(List<ParameterElement> parameters) {
+    for (ParameterElement parameter in parameters) {
+      (parameter as ParameterElementImpl).enclosingElement = this;
+    }
+    this._parameters = parameters;
   }
 
   @override
@@ -8301,7 +8343,18 @@
 
   @override
   List<TypeParameterElement> get typeParameters {
-    return const <TypeParameterElement>[];
+    if (_typeParameters != null) return _typeParameters;
+
+    return _typeParameters ??= const <TypeParameterElement>[];
+  }
+
+  /// Set the type parameters defined by this parameter element to the given
+  /// [typeParameters].
+  void set typeParameters(List<TypeParameterElement> typeParameters) {
+    for (TypeParameterElement parameter in typeParameters) {
+      (parameter as TypeParameterElementImpl).enclosingElement = this;
+    }
+    this._typeParameters = typeParameters;
   }
 
   @override
@@ -8373,9 +8426,10 @@
         var typeElement = new GenericFunctionTypeElementImpl.forOffset(-1);
         typeElement.enclosingElement = this;
 
-        typeElement.parameters = ParameterElementImpl.resynthesizeList(
+        _parameters = ParameterElementImpl.resynthesizeList(
             unlinkedParam.parameters, typeElement,
             synthetic: isSynthetic);
+        typeElement.parameters = _parameters;
 
         typeElement.returnType = enclosingUnit.resynthesizerContext
             .resolveTypeRef(this, unlinkedParam.type);
diff --git a/pkg/analyzer/lib/src/generated/declaration_resolver.dart b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
index 7175395..b956a8a 100644
--- a/pkg/analyzer/lib/src/generated/declaration_resolver.dart
+++ b/pkg/analyzer/lib/src/generated/declaration_resolver.dart
@@ -137,10 +137,7 @@
       });
     }
 
-    bool isFunctionTyped = normalParameter is FunctionTypedFormalParameter ||
-        normalParameter is FieldFormalParameter &&
-            normalParameter.parameters != null;
-    _walk(new ElementWalker.forParameter(element, isFunctionTyped), () {
+    _walk(new ElementWalker.forParameter(element), () {
       normalParameter.accept(this);
     });
 
@@ -202,8 +199,7 @@
     if (node.parent is! DefaultFormalParameter) {
       ParameterElement element =
           _match(node.identifier, _walker.getParameter());
-      bool isFunctionTyped = node.parameters != null;
-      _walk(new ElementWalker.forParameter(element, isFunctionTyped), () {
+      _walk(new ElementWalker.forParameter(element), () {
         super.visitFieldFormalParameter(node);
       });
       resolveMetadata(node, node.metadata, element);
@@ -264,7 +260,7 @@
     if (node.parent is! DefaultFormalParameter) {
       ParameterElement element =
           _match(node.identifier, _walker.getParameter());
-      _walk(new ElementWalker.forParameter(element, true), () {
+      _walk(new ElementWalker.forParameter(element), () {
         super.visitFunctionTypedFormalParameter(node);
       });
       resolveMetadata(node, node.metadata, element);
@@ -405,7 +401,7 @@
           _match(node.identifier, _walker.getParameter());
       (node as SimpleFormalParameterImpl).declaredElement = element;
       _setGenericFunctionType(node.type, element.type);
-      _walk(new ElementWalker.forParameter(element, false), () {
+      _walk(new ElementWalker.forParameter(element), () {
         super.visitSimpleFormalParameter(node);
       });
       resolveMetadata(node, node.metadata, element);
@@ -851,18 +847,10 @@
 
   /// Creates an [ElementWalker] which walks the child elements of a parameter
   /// element.
-  ElementWalker.forParameter(ParameterElement element, bool functionTyped)
+  ElementWalker.forParameter(ParameterElement element)
       : element = element,
         _parameters = element.parameters,
-        _typeParameters = element.typeParameters {
-    // If the parameter node is function typed, extract type parameters and
-    // formal parameters from its generic function type element.
-    if (functionTyped) {
-      GenericFunctionTypeElement typeElement = element.type.element;
-      _typeParameters = typeElement.typeParameters;
-      _parameters = typeElement.parameters;
-    }
-  }
+        _typeParameters = element.typeParameters;
 
   /// Creates an [ElementWalker] which walks the child elements of a typedef
   /// element.
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index 9295e4f..49ba32d 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -5948,8 +5948,7 @@
             new CaughtException(new AnalysisException(), null));
       } else {
         nameScope = new EnclosedScope(nameScope);
-        GenericFunctionTypeElement typeElement = parameterElement.type.element;
-        List<TypeParameterElement> typeParameters = typeElement.typeParameters;
+        var typeParameters = parameterElement.typeParameters;
         int length = typeParameters.length;
         for (int i = 0; i < length; i++) {
           nameScope.define(typeParameters[i]);
@@ -8316,7 +8315,10 @@
       TypeAnnotation returnType, FormalParameterList parameterList) {
     DartType type = parameter.type;
     GenericFunctionTypeElementImpl typeElement = type.element;
-    typeElement.returnType = _computeReturnType(returnType);
+    // With summary2 we use synthetic FunctionType(s).
+    if (typeElement != null) {
+      typeElement.returnType = _computeReturnType(returnType);
+    }
   }
 }
 
diff --git a/pkg/analyzer/lib/src/summary2/lazy_ast.dart b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
index b423a53..773b59f 100644
--- a/pkg/analyzer/lib/src/summary2/lazy_ast.dart
+++ b/pkg/analyzer/lib/src/summary2/lazy_ast.dart
@@ -561,6 +561,7 @@
   final LinkedNode data;
 
   bool _hasDefaultValue = false;
+  bool _hasFormalParameters = false;
   bool _hasMetadata = false;
   bool _hasType = false;
 
@@ -600,6 +601,25 @@
     }
   }
 
+  static void readFormalParameters(
+    AstBinaryReader reader,
+    FormalParameter node,
+  ) {
+    var lazy = get(node);
+    if (lazy != null && !lazy._hasFormalParameters) {
+      if (node is FunctionTypedFormalParameter) {
+        node.parameters = reader.readNode(
+          lazy.data.functionTypedFormalParameter_formalParameters,
+        );
+      } else if (node is FieldFormalParameter) {
+        node.parameters = reader.readNode(
+          lazy.data.fieldFormalParameter_formalParameters,
+        );
+      }
+      lazy._hasFormalParameters = true;
+    }
+  }
+
   static void readMetadata(
     AstBinaryReader reader,
     FormalParameter node,
diff --git a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
index 201d7f0..86bc82a 100644
--- a/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
+++ b/pkg/analyzer/lib/src/summary2/linked_unit_context.dart
@@ -255,6 +255,18 @@
     } else if (node is FunctionExpression) {
       LazyFunctionExpression.readFormalParameters(_astReader, node);
       return node.parameters?.parameters;
+    } else if (node is FormalParameter) {
+      if (node is DefaultFormalParameter) {
+        return getFormalParameters(node.parameter);
+      } else if (node is FieldFormalParameter) {
+        LazyFormalParameter.readFormalParameters(_astReader, node);
+        return node.parameters?.parameters;
+      } else if (node is FunctionTypedFormalParameter) {
+        LazyFormalParameter.readFormalParameters(_astReader, node);
+        return node.parameters.parameters;
+      } else {
+        return null;
+      }
     } else if (node is FunctionTypeAlias) {
       LazyFunctionTypeAlias.readFormalParameters(_astReader, node);
       return node.parameters.parameters;
diff --git a/pkg/analyzer/test/generated/resolver_test.dart b/pkg/analyzer/test/generated/resolver_test.dart
index 3da22d1..9c5be7a 100644
--- a/pkg/analyzer/test/generated/resolver_test.dart
+++ b/pkg/analyzer/test/generated/resolver_test.dart
@@ -1834,6 +1834,7 @@
         AstTestFactory.functionTypedFormalParameter(
             AstTestFactory.typeName4('R'), 'g', [eNode]);
     ParameterElementImpl gElement = ElementFactory.requiredParameter('g');
+    gElement.typeParameters = [elementE];
     gNode.identifier.staticElement = gElement;
 
     FunctionTypeImpl gType =
diff --git a/pkg/analyzer/test/src/summary/element_text.dart b/pkg/analyzer/test/src/summary/element_text.dart
index c383abb..3ca6771 100644
--- a/pkg/analyzer/test/src/summary/element_text.dart
+++ b/pkg/analyzer/test/src/summary/element_text.dart
@@ -726,12 +726,7 @@
     writeIf(e.isCovariant, 'covariant ');
     writeIf(e.isFinal, 'final ');
 
-    if (e.parameters.isNotEmpty) {
-      var type = e.type as FunctionType;
-      writeType2(type.returnType);
-    } else {
-      writeType2(e.type);
-    }
+    writeType2(e.type);
 
     if (e is FieldFormalParameterElement) {
       buffer.write('this.');
@@ -741,8 +736,9 @@
     writeCodeRange(e);
 
     if (e.parameters.isNotEmpty) {
-      writeList('(', ')', e.parameters, ', ', writeParameterElement,
-          includeEmpty: true);
+      buffer.write('/*');
+      writeList('(', ')', e.parameters, ', ', writeParameterElement);
+      buffer.write('*/');
     }
 
     writeVariableTypeInferenceError(e);
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index d87436d..47de718 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -602,7 +602,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C((double) → dynamic this.x);
+  C((double) → dynamic this.x/*(double b)*/);
 }
 ''');
   }
@@ -617,7 +617,7 @@
     checkElementText(library, r'''
 class C {
   dynamic x;
-  C((double) → int this.x);
+  C((double) → int this.x/*(double b)*/);
 }
 ''');
   }
@@ -5793,7 +5793,7 @@
   test_function_parameter_parameters() async {
     var library = await checkLibrary('f(g(x, y)) {}');
     checkElementText(library, r'''
-dynamic f((dynamic, dynamic) → dynamic g) {}
+dynamic f((dynamic, dynamic) → dynamic g/*(dynamic x, dynamic y)*/) {}
 ''');
   }
 
@@ -5856,7 +5856,7 @@
   test_function_type_parameter_with_function_typed_parameter() async {
     var library = await checkLibrary('void f<T, U>(T x(U u)) {}');
     checkElementText(library, r'''
-void f<T, U>((U) → T x) {}
+void f<T, U>((U) → T x/*(U u)*/) {}
 ''');
   }
 
@@ -5955,7 +5955,7 @@
 void f(int Function(int a, String b) p(num c)) => null;
 ''');
     checkElementText(library, r'''
-void f((num) → (int, String) → int p) {}
+void f((num) → (int, String) → int p/*(num c)*/) {}
 ''');
   }
 
@@ -6584,7 +6584,7 @@
 var v = h(/*info:INFERRED_TYPE_CLOSURE*/(y) {});
 ''');
     checkElementText(library, r'''
-typedef F = void Function((String) → int g);
+typedef F = void Function((String) → int g/*(String s)*/);
 dynamic v;
 dynamic h(((String) → int) → void f) {}
 ''');
@@ -6603,7 +6603,7 @@
   void f(int x, (U) → int g) {}
 }
 abstract class D<V, W> {
-  void f(int x, (V) → W g);
+  void f(int x, (V) → W g/*(V s)*/);
 }
 ''');
   }
@@ -6640,7 +6640,7 @@
   void f(int x, (String) → int g) {}
 }
 abstract class D {
-  void f(int x, (String) → int g);
+  void f(int x, (String) → int g/*(String s)*/);
 }
 ''');
   }
@@ -6652,7 +6652,7 @@
 ''');
     checkElementText(library, r'''
 dynamic v;
-dynamic f((int, () → void) → void g) {}
+dynamic f((int, () → void) → void g/*(int x, () → void h)*/) {}
 ''');
   }
 
@@ -6663,7 +6663,7 @@
 ''');
     checkElementText(library, r'''
 dynamic v;
-dynamic f({(int, () → void) → void g}) {}
+dynamic f({(int, () → void) → void g/*(int x, () → void h)*/}) {}
 ''');
   }
 
@@ -6675,7 +6675,7 @@
   void set f((String) → int g) {}
 }
 abstract class D {
-  void set f((String) → int g);
+  void set f((String) → int g/*(String s)*/);
 }
 ''');
   }
@@ -6758,8 +6758,8 @@
 ''');
     checkElementText(library, r'''
 List<((String) → int) → Object> v;
-int f((String) → int x) {}
-String g((String) → int x) {}
+int f((String) → int x/*(String y)*/) {}
+String g((String) → int x/*(String y)*/) {}
 ''');
   }
 
@@ -8121,7 +8121,7 @@
     var library = await checkLibrary('class C { void f<T, U>(T x(U u)) {} }');
     checkElementText(library, r'''
 class C {
-  void f<T, U>((U) → T x) {}
+  void f<T, U>((U) → T x/*(U u)*/) {}
 }
 ''');
   }
@@ -8522,7 +8522,7 @@
     var library = await checkLibrary('class C { f(g(x, y)) {} }');
     checkElementText(library, r'''
 class C {
-  dynamic f((dynamic, dynamic) → dynamic g) {}
+  dynamic f((dynamic, dynamic) → dynamic g/*(dynamic x, dynamic y)*/) {}
 }
 ''');
   }
@@ -8531,7 +8531,7 @@
     var library = await checkLibrary('class C<A, B> { f(A g(B x)) {} }');
     checkElementText(library, r'''
 class C<A, B> {
-  dynamic f((B) → A g) {}
+  dynamic f((B) → A g/*(B x)*/) {}
 }
 ''');
   }
@@ -9501,14 +9501,14 @@
   test_typedef_parameter_parameters() async {
     var library = await checkLibrary('typedef F(g(x, y));');
     checkElementText(library, r'''
-typedef F = dynamic Function((dynamic, dynamic) → dynamic g);
+typedef F = dynamic Function((dynamic, dynamic) → dynamic g/*(dynamic x, dynamic y)*/);
 ''');
   }
 
   test_typedef_parameter_parameters_in_generic_class() async {
     var library = await checkLibrary('typedef F<A, B>(A g(B x));');
     checkElementText(library, r'''
-typedef F<A, B> = dynamic Function((B) → A g);
+typedef F<A, B> = dynamic Function((B) → A g/*(B x)*/);
 ''');
   }