R8 assistant api surface covering jacoco

Change-Id: I2f00d9603c760e9f07eddfe2d0df327b7270f904
diff --git a/src/assistant/java/com/android/tools/r8/assistant/runtime/EmptyReflectiveOperationReceiver.java b/src/assistant/java/com/android/tools/r8/assistant/runtime/EmptyReflectiveOperationReceiver.java
index 1c747a6..6f874f5 100644
--- a/src/assistant/java/com/android/tools/r8/assistant/runtime/EmptyReflectiveOperationReceiver.java
+++ b/src/assistant/java/com/android/tools/r8/assistant/runtime/EmptyReflectiveOperationReceiver.java
@@ -36,6 +36,16 @@
   public void onClassGetDeclaredMethods(Stack stack, Class<?> clazz) {}
 
   @Override
+  public void onClassGetMethod(
+      Stack stack, Class<?> clazz, String method, Class<?>... parameters) {}
+
+  @Override
+  public void onClassGetField(Stack stack, Class<?> clazz, String fieldName) {}
+
+  @Override
+  public void onClassGetMethods(Stack stack, Class<?> clazz) {}
+
+  @Override
   public void onClassGetName(Stack stack, Class<?> clazz, NameLookupType lookupType) {}
 
   @Override
diff --git a/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOperationLogger.java b/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOperationLogger.java
index bbda127..76684c7 100644
--- a/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOperationLogger.java
+++ b/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOperationLogger.java
@@ -32,6 +32,21 @@
   }
 
   @Override
+  public void onClassGetMethod(Stack stack, Class<?> clazz, String method, Class<?>... parameters) {
+    System.out.println("Reflectively got method " + method + " on " + clazz.getName());
+  }
+
+  @Override
+  public void onClassGetField(Stack stack, Class<?> clazz, String fieldName) {
+    System.out.println("Reflectively got field " + fieldName + " on " + clazz.getName());
+  }
+
+  @Override
+  public void onClassGetMethods(Stack stack, Class<?> clazz) {
+    System.out.println("Reflectively got methods on " + clazz.getName());
+  }
+
+  @Override
   public void onClassGetName(Stack stack, Class<?> clazz, NameLookupType lookupType) {
     System.out.println(
         "Reflectively got name on " + clazz.getName() + "(" + lookupType.toString() + ")");
diff --git a/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOperationReceiver.java b/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOperationReceiver.java
index c298422..d4c43b8 100644
--- a/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOperationReceiver.java
+++ b/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOperationReceiver.java
@@ -23,6 +23,12 @@
 
   void onClassGetDeclaredMethods(Stack stack, Class<?> clazz);
 
+  void onClassGetMethod(Stack stack, Class<?> clazz, String method, Class<?>... parameters);
+
+  void onClassGetField(Stack stack, Class<?> clazz, String fieldName);
+
+  void onClassGetMethods(Stack stack, Class<?> clazz);
+
   void onClassGetName(Stack stack, Class<?> clazz, NameLookupType lookupType);
 
   void onClassGetSuperclass(Stack stack, Class<?> clazz);
diff --git a/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOracle.java b/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOracle.java
index 1582bcd..3188493 100644
--- a/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOracle.java
+++ b/src/assistant/java/com/android/tools/r8/assistant/runtime/ReflectiveOracle.java
@@ -170,4 +170,16 @@
   public static void onClassIsSynthetic(Class<?> clazz) {
     getInstance().onClassFlag(Stack.createStack(), clazz, ClassFlag.SYNTHETIC);
   }
+
+  public static void onClassGetMethods(Class<?> clazz) {
+    getInstance().onClassGetMethods(Stack.createStack(), clazz);
+  }
+
+  public static void onClassGetMethod(Class<?> clazz, String name, Class<?>[] parameterTypes) {
+    getInstance().onClassGetMethod(Stack.createStack(), clazz, name, parameterTypes);
+  }
+
+  public static void onClassGetField(Class<?> clazz, String name) {
+    getInstance().onClassGetField(Stack.createStack(), clazz, name);
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/assistant/InstrumentedReflectiveMethodList.java b/src/main/java/com/android/tools/r8/assistant/InstrumentedReflectiveMethodList.java
index 1ff6b34..9b9203a 100644
--- a/src/main/java/com/android/tools/r8/assistant/InstrumentedReflectiveMethodList.java
+++ b/src/main/java/com/android/tools/r8/assistant/InstrumentedReflectiveMethodList.java
@@ -28,6 +28,8 @@
   Map<DexMethod, DexMethod> getInstrumentedMethodsAndTargets() {
     ImmutableMap.Builder<DexMethod, DexMethod> builder = ImmutableMap.builder();
 
+    // java.lang.Class methods
+
     builder.put(
         factory.classMethods.newInstance,
         getMethodReferenceWithClassParameter("onClassNewInstance"));
@@ -76,7 +78,6 @@
             "isAssignableFrom"),
         getMethodReferenceWithParameterTypes(
             "onClassIsAssignableFrom", factory.classType, factory.classType));
-
     DexProto toBoolean = factory.createProto(factory.booleanType);
     builder.put(
         factory.createMethod(factory.classType, toBoolean, "isAnnotation"),
@@ -114,6 +115,20 @@
     builder.put(
         factory.createMethod(factory.classType, toBoolean, "isSynthetic"),
         getMethodReferenceWithClassParameter("onClassIsSynthetic"));
+    builder.put(
+        factory.classMethods.getMethod,
+        getMethodReferenceWithParameterTypes(
+            "onClassGetMethod", factory.classType, factory.stringType, factory.classArrayType));
+    builder.put(
+        factory.classMethods.getField,
+        getMethodReferenceWithParameterTypes(
+            "onClassGetField", factory.classType, factory.stringType));
+    builder.put(
+        factory.createMethod(
+            factory.classType,
+            factory.createProto(factory.createArrayType(1, factory.methodType)),
+            "getMethods"),
+        getMethodReferenceWithClassParameter("onClassGetMethods"));
 
     return builder.build();
   }
diff --git a/src/test/java/com/android/tools/r8/assistant/JavaLangClassTest.java b/src/test/java/com/android/tools/r8/assistant/JavaLangClassTest.java
index f4b1c12..c7a5d13 100644
--- a/src/test/java/com/android/tools/r8/assistant/JavaLangClassTest.java
+++ b/src/test/java/com/android/tools/r8/assistant/JavaLangClassTest.java
@@ -6,6 +6,7 @@
 import com.android.tools.r8.TestBase;
 import com.android.tools.r8.TestParameters;
 import com.android.tools.r8.TestParametersCollection;
+import com.android.tools.r8.assistant.JavaLangClassTestClass.Bar;
 import com.android.tools.r8.assistant.JavaLangClassTestClass.Foo;
 import com.android.tools.r8.assistant.runtime.EmptyReflectiveOperationReceiver;
 import com.android.tools.r8.assistant.runtime.ReflectiveOracle.Stack;
@@ -29,14 +30,15 @@
   @Test
   public void testInstrumentationWithCustomOracle() throws Exception {
     testForAssistant()
-        .addProgramClasses(JavaLangClassTestClass.class, Foo.class)
+        .addProgramClasses(JavaLangClassTestClass.class, Foo.class, Bar.class)
         .addInstrumentationClasses(Instrumentation.class)
         .setCustomReflectiveOperationReceiver(Instrumentation.class)
         .setMinApi(parameters)
         .compile()
         .run(parameters.getRuntime(), JavaLangClassTestClass.class)
         .assertSuccessWithOutputLines(
-            "5", "1", "9", "2", "3", "3", "4", "5", "6", "7", "8", "5", "1", "12", "13", "15");
+            "5", "1", "9", "2", "3", "3", "4", "5", "6", "7", "8", "5", "1", "12", "13", "15", "22",
+            "20", "21");
   }
 
   public static class Instrumentation extends EmptyReflectiveOperationReceiver {
@@ -112,5 +114,21 @@
     public void onClassGetSuperclass(Stack stack, Class<?> clazz) {
       printNumIfTrue(clazz.getName().endsWith("Foo"), 9);
     }
+
+    @Override
+    public void onClassGetMethod(
+        Stack stack, Class<?> clazz, String method, Class<?>... parameters) {
+      printNumIfTrue(clazz.getName().endsWith("Bar"), 20);
+    }
+
+    @Override
+    public void onClassGetField(Stack stack, Class<?> clazz, String fieldName) {
+      printNumIfTrue(clazz.getName().endsWith("Bar"), 21);
+    }
+
+    @Override
+    public void onClassGetMethods(Stack stack, Class<?> clazz) {
+      printNumIfTrue(clazz.getName().endsWith("Bar"), 22);
+    }
   }
 }
diff --git a/src/test/java/com/android/tools/r8/assistant/JavaLangClassTestClass.java b/src/test/java/com/android/tools/r8/assistant/JavaLangClassTestClass.java
index 1e84ec1..2ced001 100644
--- a/src/test/java/com/android/tools/r8/assistant/JavaLangClassTestClass.java
+++ b/src/test/java/com/android/tools/r8/assistant/JavaLangClassTestClass.java
@@ -4,6 +4,7 @@
 package com.android.tools.r8.assistant;
 
 import java.io.InputStream;
+import java.lang.reflect.Field;
 import java.lang.reflect.Method;
 
 // Top level file since the getXName methods relies on nest members being available for lookup.
@@ -33,6 +34,11 @@
       Package pack = clazz2.getPackage();
       InputStream resStream = clazz2.getResourceAsStream("res");
       boolean ass = clazz2.isAssignableFrom(Object.class);
+
+      Class<?> barClass = Bar.class;
+      Method[] methods = barClass.getMethods();
+      Method bar = barClass.getMethod("bar");
+      Field i = barClass.getField("i");
     } catch (ClassNotFoundException | NoSuchFieldException | NoSuchMethodException e) {
       throw new RuntimeException(e);
     }
@@ -48,4 +54,12 @@
 
     public abstract void fooBar();
   }
+
+  public static class Bar {
+    public int i;
+
+    public int bar() {
+      return 11;
+    }
+  }
 }
diff --git a/src/test/java/com/android/tools/r8/assistant/ReflectiveCallExtractor.java b/src/test/java/com/android/tools/r8/assistant/ReflectiveCallExtractor.java
index ec05467..3f59460 100644
--- a/src/test/java/com/android/tools/r8/assistant/ReflectiveCallExtractor.java
+++ b/src/test/java/com/android/tools/r8/assistant/ReflectiveCallExtractor.java
@@ -70,7 +70,6 @@
     }
     return methods;
   }
-
   private static boolean isReflective(DexMethod method, DexItemFactory factory) {
     DexType type = method.getHolderType();
     if (type.isIdenticalTo(factory.classType)) {
diff --git a/src/test/java/com/android/tools/r8/assistant/ReflectiveCallExtractorTest.java b/src/test/java/com/android/tools/r8/assistant/ReflectiveCallExtractorTest.java
index 4e1e18d..04611ad 100644
--- a/src/test/java/com/android/tools/r8/assistant/ReflectiveCallExtractorTest.java
+++ b/src/test/java/com/android/tools/r8/assistant/ReflectiveCallExtractorTest.java
@@ -38,17 +38,17 @@
 
   @Test
   public void testGson() throws Exception {
-    test(ToolHelper.GSON, 15, 17);
+    test(ToolHelper.GSON, 16, 16);
   }
 
   @Test
   public void testGuava() throws Exception {
-    test(ToolHelper.GUAVA_JRE, 15, 25);
+    test(ToolHelper.GUAVA_JRE, 18, 22);
   }
 
   @Test
   public void testJacoco() throws Exception {
-    test(ToolHelper.JACOCO_AGENT, 10, 2);
+    test(ToolHelper.JACOCO_AGENT, 12, 0);
   }
 
   private void test(Path jar, int success, int failure) throws Exception {