Fix order of resolving / writing / reading of function / method declarations.

Now that we assign indexes to occurred GenericFunctionType nodes, we
need to make the order consistent across all visitors.

R=brianwilkerson@google.com

Change-Id: Ifc9c7bfa35612cef235f000f30130d36116067e5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/103340
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
index ce98e5d..95d761c 100644
--- a/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
+++ b/pkg/analyzer/lib/src/summary2/ast_binary_writer.dart
@@ -636,9 +636,9 @@
       bodyToStore = null;
     }
     var builder = LinkedNodeBuilder.functionExpression(
-      functionExpression_body: bodyToStore?.accept(this),
-      functionExpression_formalParameters: node.parameters?.accept(this),
       functionExpression_typeParameters: node.typeParameters?.accept(this),
+      functionExpression_formalParameters: node.parameters?.accept(this),
+      functionExpression_body: bodyToStore?.accept(this),
     );
     builder.flags = AstBinaryFlags.encode(
       isAsync: node.body?.isAsynchronous ?? false,
@@ -699,10 +699,10 @@
     genericFunctionTypes.add(null);
 
     var builder = LinkedNodeBuilder.genericFunctionType(
-      genericFunctionType_formalParameters: node.parameters.accept(this),
       genericFunctionType_returnType: node.returnType?.accept(this),
-      genericFunctionType_type: _writeType(node.type),
       genericFunctionType_typeParameters: node.typeParameters?.accept(this),
+      genericFunctionType_formalParameters: node.parameters.accept(this),
+      genericFunctionType_type: _writeType(node.type),
     );
     builder.flags = AstBinaryFlags.encode(
       hasQuestion: node.question != null,
@@ -917,9 +917,9 @@
   @override
   LinkedNodeBuilder visitMethodDeclaration(MethodDeclaration node) {
     var builder = LinkedNodeBuilder.methodDeclaration(
-      methodDeclaration_formalParameters: node.parameters?.accept(this),
       methodDeclaration_returnType: node.returnType?.accept(this),
       methodDeclaration_typeParameters: node.typeParameters?.accept(this),
+      methodDeclaration_formalParameters: node.parameters?.accept(this),
     );
     builder
       ..name = node.name.name
diff --git a/pkg/analyzer/lib/src/summary2/reference_resolver.dart b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
index e54f0a3..cdc7508 100644
--- a/pkg/analyzer/lib/src/summary2/reference_resolver.dart
+++ b/pkg/analyzer/lib/src/summary2/reference_resolver.dart
@@ -359,8 +359,8 @@
     LinkingNodeContext(node, scope);
 
     node.returnType?.accept(this);
-    node.parameters?.accept(this);
     node.typeParameters?.accept(this);
+    node.parameters?.accept(this);
     nodesToBuildType.addDeclaration(node);
 
     scope = outerScope;
diff --git a/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart b/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart
index 59062c6..7bd3aac 100644
--- a/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/generic_function_type_test.dart
@@ -46,4 +46,73 @@
 int Function(int a) y;
 ''');
   }
+
+  /// Test that when multiple [GenericFunctionType]s are used in a
+  /// [FunctionDeclaration], all of them are resolved correctly.
+  test_typeAnnotation_function() async {
+    await assertNoErrorsInCode('''
+void Function() f<T extends bool Function()>(int Function() a) {
+  return null;
+}
+
+double Function() x;
+''');
+    assertType(
+      findNode.genericFunctionType('void Function()'),
+      '() → void',
+    );
+    assertType(
+      findNode.genericFunctionType('bool Function()'),
+      '() → bool',
+    );
+    assertType(
+      findNode.genericFunctionType('int Function()'),
+      '() → int',
+    );
+    assertType(
+      findNode.genericFunctionType('double Function()'),
+      '() → double',
+    );
+  }
+
+  /// Test that when multiple [GenericFunctionType]s are used in a
+  /// [GenericFunctionType], all of them are resolved correctly.
+  test_typeAnnotation_genericFunctionType() async {
+    await assertNoErrorsInCode('''
+void f(
+  void Function() a,
+  bool Function() Function(int Function()) b,
+) {}
+''');
+  }
+
+  /// Test that when multiple [GenericFunctionType]s are used in a
+  /// [FunctionDeclaration], all of them are resolved correctly.
+  test_typeAnnotation_method() async {
+    await assertNoErrorsInCode('''
+class C {
+  void Function() m<T extends bool Function()>(int Function() a) {
+    return null;
+  }
+}
+
+double Function() x;
+''');
+    assertType(
+      findNode.genericFunctionType('void Function()'),
+      '() → void',
+    );
+    assertType(
+      findNode.genericFunctionType('bool Function()'),
+      '() → bool',
+    );
+    assertType(
+      findNode.genericFunctionType('int Function()'),
+      '() → int',
+    );
+    assertType(
+      findNode.genericFunctionType('double Function()'),
+      '() → double',
+    );
+  }
 }