[vm/debugger] fix order of type arguments in debugger

Debugger will build array of type param(BuildParameters()) in an order that type param starts with type params of ancestor function and ends up with child function. But function with multiple type arguments is supposed to keep the same order instead of inserting reversely.

Bug: https://github.com/dart-lang/sdk/issues/35581
Change-Id: I861d8cf08ed90738dcaf18551eb1e5abd67067a3
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99721
Commit-Queue: Zichang Guo <zichangguo@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
diff --git a/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart b/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart
index 9648807..9e63186 100644
--- a/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart
+++ b/runtime/observatory/tests/service/evaluate_function_type_parameters_test.dart
@@ -11,11 +11,11 @@
 topLevel<S>() {
   debugger();
 
-  void inner1<T>(T x) {
+  void inner1<TBool, TString, TDouble, TInt>(TInt x) {
     debugger();
   }
 
-  inner1<int>(3);
+  inner1<bool, String, double, int>(3);
 
   void inner2() {
     debugger();
@@ -25,7 +25,7 @@
 }
 
 class A {
-  foo<T>() {
+  foo<T, S>() {
     debugger();
   }
 
@@ -36,7 +36,7 @@
 
 void testMain() {
   topLevel<String>();
-  (new A()).foo<int>();
+  (new A()).foo<int, bool>();
   (new A()).bar<dynamic>(42);
 }
 
@@ -62,7 +62,19 @@
     expect(stack.type, equals('Stack'));
     expect(await stack['frames'][topFrame].location.getLine(), 16);
 
-    Instance result = await isolate.evalFrame(topFrame, "T.toString()");
+    Instance result = await isolate.evalFrame(topFrame, "TBool.toString()");
+    print(result);
+    expect(result.valueAsString, equals("bool"));
+
+    result = await isolate.evalFrame(topFrame, "TString.toString()");
+    print(result);
+    expect(result.valueAsString, equals("String"));
+
+    result = await isolate.evalFrame(topFrame, "TDouble.toString()");
+    print(result);
+    expect(result.valueAsString, equals("double"));
+
+    result = await isolate.evalFrame(topFrame, "TInt.toString()");
     print(result);
     expect(result.valueAsString, equals("int"));
 
@@ -99,6 +111,10 @@
     Instance result = await isolate.evalFrame(topFrame, "T.toString()");
     print(result);
     expect(result.valueAsString, equals("int"));
+
+    result = await isolate.evalFrame(topFrame, "S.toString()");
+    print(result);
+    expect(result.valueAsString, equals("bool"));
   },
   resumeIsolate,
   hasStoppedAtBreakpoint,
diff --git a/runtime/vm/debugger.cc b/runtime/vm/debugger.cc
index fa6eaec..9eb8294 100644
--- a/runtime/vm/debugger.cc
+++ b/runtime/vm/debugger.cc
@@ -1367,15 +1367,21 @@
     TypeArguments& type_params = TypeArguments::Handle();
     TypeParameter& type_param = TypeParameter::Handle();
     Function& current = Function::Handle(function().raw());
+    intptr_t mapping_offset = num_vars;
     for (intptr_t i = 0; !current.IsNull(); i += current.NumTypeParameters(),
                   current = current.parent_function()) {
       type_params = current.type_parameters();
-      for (intptr_t j = 0; j < current.NumTypeParameters(); ++j) {
+      intptr_t size = current.NumTypeParameters();
+      mapping_offset -= size;
+      for (intptr_t j = 0; j < size; ++j) {
         type_param = TypeParameter::RawCast(type_params.TypeAt(j));
         name = type_param.Name();
-        // Write the names in backwards so they match up with the order of the
-        // types in 'type_arguments'.
-        type_params_names.SetAt(num_vars - (i + j) - 1, name);
+        // Write the names in backwards in terms of chain of functions.
+        // But keep the order of names within the same function. so they
+        // match up with the order of the types in 'type_arguments'.
+        // Index:0 1 2 3 ...
+        //       |Names in Grandparent| |Names in Parent| ..|Names in Child|
+        type_params_names.SetAt(mapping_offset + j, name);
       }
     }
     if (!type_arguments.IsNull()) {