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 {