Backport Method#getParameterCount

Bug: b/273107245
Change-Id: I9b58da39014a2cdeedf432cd8b023ece9d1e4309
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
index 508c314..47d762c 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/BackportedMethodRewriter.java
@@ -1015,6 +1015,20 @@
               BackportedMethods::LongMethods_toUnsignedStringWithRadix,
               "toUnsignedStringWithRadix"));
 
+      // Method
+      type = factory.methodType;
+
+      // int Method.getParameterCount()
+      name = factory.createString("getParameterCount");
+      proto = factory.createProto(factory.intType);
+      method = factory.createMethod(type, proto, name);
+      addProvider(
+          new StatifyingMethodGenerator(
+              method,
+              BackportedMethods::MethodMethods_getParameterCount,
+              "getParameterCount",
+              type));
+
       // String
       type = factory.stringType;
 
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java b/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
index 99392e1..7d65007 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/backports/BackportedMethods.java
@@ -5773,6 +5773,30 @@
         ImmutableList.of());
   }
 
+  public static CfCode MethodMethods_getParameterCount(DexItemFactory factory, DexMethod method) {
+    CfLabel label0 = new CfLabel();
+    CfLabel label1 = new CfLabel();
+    return new CfCode(
+        method.holder,
+        1,
+        1,
+        ImmutableList.of(
+            label0,
+            new CfLoad(ValueType.OBJECT, 0),
+            new CfInvoke(
+                182,
+                factory.createMethod(
+                    factory.createType("Ljava/lang/reflect/Method;"),
+                    factory.createProto(factory.createType("[Ljava/lang/Class;")),
+                    factory.createString("getParameterTypes")),
+                false),
+            new CfArrayLength(),
+            new CfReturn(ValueType.INT),
+            label1),
+        ImmutableList.of(),
+        ImmutableList.of());
+  }
+
   public static CfCode ObjectsMethods_checkFromIndexSize(DexItemFactory factory, DexMethod method) {
     CfLabel label0 = new CfLabel();
     CfLabel label1 = new CfLabel();
diff --git a/src/test/java/com/android/tools/r8/desugar/backports/MethodBackportTest.java b/src/test/java/com/android/tools/r8/desugar/backports/MethodBackportTest.java
new file mode 100644
index 0000000..78c2770
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/desugar/backports/MethodBackportTest.java
@@ -0,0 +1,39 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.desugar.backports;
+
+import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public final class MethodBackportTest extends AbstractBackportTest {
+  @Parameters(name = "{0}")
+  public static Iterable<?> data() {
+    return getTestParameters().withAllRuntimesAndApiLevels().build();
+  }
+
+  public MethodBackportTest(TestParameters parameters) {
+    super(parameters, String.class, Main.class);
+    registerTarget(AndroidApiLevel.O, 0);
+  }
+
+  static final class Main extends MiniAssert {
+    public static void main(String[] args) throws NoSuchMethodException {
+      assertEquals(0, Main.class.getMethod("empty").getParameterCount());
+      assertEquals(
+          2, Main.class.getMethod("wideArgs", long.class, double.class).getParameterCount());
+      assertEquals(1, Main.class.getMethod("args", Object[].class).getParameterCount());
+    }
+
+    public static void empty() {}
+
+    public static void wideArgs(long l, double d) {}
+
+    public static void args(Object... o) {}
+  }
+}
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
index 429f2be..3a7cb1e 100644
--- a/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/GenerateBackportMethods.java
@@ -50,6 +50,7 @@
           IntegerMethods.class,
           LongMethods.class,
           MathMethods.class,
+          MethodMethods.class,
           ObjectsMethods.class,
           OptionalMethods.class,
           PredicateMethods.class,
diff --git a/src/test/java/com/android/tools/r8/ir/desugar/backports/MethodMethods.java b/src/test/java/com/android/tools/r8/ir/desugar/backports/MethodMethods.java
new file mode 100644
index 0000000..0c03f1f
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/ir/desugar/backports/MethodMethods.java
@@ -0,0 +1,14 @@
+// Copyright (c) 2023, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.desugar.backports;
+
+import java.lang.reflect.Method;
+
+public class MethodMethods {
+
+  public static int getParameterCount(Method method) {
+    return method.getParameterTypes().length;
+  }
+}