Enable CF for ProxiesTest.
Change-Id: Ib70eed9f2e6a3535992bee63a784c8b1e35f73fa
diff --git a/src/test/java/com/android/tools/r8/shaking/proxy/ProxiesTest.java b/src/test/java/com/android/tools/r8/shaking/proxy/ProxiesTest.java
index 8d38aee..b22dc1e 100644
--- a/src/test/java/com/android/tools/r8/shaking/proxy/ProxiesTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/proxy/ProxiesTest.java
@@ -6,14 +6,11 @@
import static org.junit.Assert.assertEquals;
+import com.android.tools.r8.ClassFileConsumer;
import com.android.tools.r8.DexIndexedConsumer;
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.code.Instruction;
-import com.android.tools.r8.code.InvokeInterface;
-import com.android.tools.r8.code.InvokeVirtual;
-import com.android.tools.r8.graph.DexCode;
import com.android.tools.r8.graph.invokesuper.Consumer;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.origin.Origin;
@@ -24,11 +21,32 @@
import com.android.tools.r8.shaking.proxy.testclasses.TestClass;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
+import com.android.tools.r8.utils.codeinspector.InstructionSubject;
+import com.android.tools.r8.utils.codeinspector.InvokeInstructionSubject;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
+import com.google.common.collect.Streams;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.List;
+import java.util.function.Predicate;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+@RunWith(Parameterized.class)
public class ProxiesTest extends TestBase {
+ private Backend backend;
+
+ @Parameterized.Parameters(name = "Backend: {0}")
+ public static Collection<Backend> data() {
+ return Arrays.asList(Backend.values());
+ }
+
+ public ProxiesTest(Backend backend) {
+ this.backend = backend;
+ }
private void runTest(List<String> additionalKeepRules, Consumer<CodeInspector> inspection,
String expectedResult)
@@ -49,52 +67,89 @@
Origin.unknown()
);
builder.addProguardConfiguration(additionalKeepRules, Origin.unknown());
- builder.setProgramConsumer(DexIndexedConsumer.emptyConsumer());
+ if (backend == Backend.DEX) {
+ builder
+ .setProgramConsumer(DexIndexedConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getDefaultAndroidJar());
+ } else {
+ assert backend == Backend.CF;
+ builder
+ .setProgramConsumer(ClassFileConsumer.emptyConsumer())
+ .addLibraryFiles(ToolHelper.getJava8RuntimeJar());
+ }
AndroidApp app = ToolHelper.runR8(builder.build(), o -> o.enableDevirtualization = false);
- inspection.accept(new CodeInspector(app));
- assertEquals(expectedResult, runOnArt(app, mainClass));
+ inspection.accept(new CodeInspector(app, o -> o.enableCfFrontend = true));
+ assertEquals(
+ expectedResult,
+ backend == Backend.DEX ? runOnArt(app, mainClass) : runOnJava(app, mainClass));
}
- private int countInstructionInX(CodeInspector inspector, Class<? extends Instruction> invoke) {
+ private int countInstructionInX(CodeInspector inspector, Predicate<InstructionSubject> invoke) {
MethodSignature signatureForX =
new MethodSignature("x", "void", ImmutableList.of(BaseInterface.class.getCanonicalName()));
- DexCode x = inspector.clazz(Main.class).method(signatureForX).getMethod().getCode().asDexCode();
- return (int) filterInstructionKind(x, invoke).count();
+ MethodSubject method = inspector.clazz(Main.class).method(signatureForX);
+ assert method instanceof FoundMethodSubject;
+ FoundMethodSubject foundMethod = (FoundMethodSubject) method;
+ return (int) Streams.stream(foundMethod.iterateInstructions(invoke)).count();
}
- private int countInstructionInY(CodeInspector inspector, Class<? extends Instruction> invoke) {
+ private int countInstructionInY(CodeInspector inspector, Predicate<InstructionSubject> invoke) {
MethodSignature signatureForY =
new MethodSignature("y", "void", ImmutableList.of(SubInterface.class.getCanonicalName()));
- DexCode y = inspector.clazz(Main.class).method(signatureForY).getMethod().getCode().asDexCode();
- return (int) filterInstructionKind(y, invoke)
- .filter(instruction -> instruction.getMethod().qualifiedName().endsWith("method"))
- .count();
+ MethodSubject method = inspector.clazz(Main.class).method(signatureForY);
+ assert method instanceof FoundMethodSubject;
+ FoundMethodSubject foundMethod = (FoundMethodSubject) method;
+ return (int)
+ Streams.stream(foundMethod.iterateInstructions(invoke))
+ .filter(
+ instruction -> {
+ InvokeInstructionSubject invokeInstruction =
+ (InvokeInstructionSubject) instruction;
+ return invokeInstruction.invokedMethod().qualifiedName().endsWith("method");
+ })
+ .count();
}
- private int countInstructionInZ(CodeInspector inspector, Class<? extends Instruction> invoke) {
+ private int countInstructionInZ(CodeInspector inspector, Predicate<InstructionSubject> invoke) {
MethodSignature signatureForZ =
new MethodSignature("z", "void", ImmutableList.of(TestClass.class.getCanonicalName()));
- DexCode z = inspector.clazz(Main.class).method(signatureForZ).getMethod().getCode().asDexCode();
- return (int) filterInstructionKind(z, invoke)
- .filter(instruction -> instruction.getMethod().qualifiedName().endsWith("method"))
- .count();
+ MethodSubject method = inspector.clazz(Main.class).method(signatureForZ);
+ assert method instanceof FoundMethodSubject;
+ FoundMethodSubject foundMethod = (FoundMethodSubject) method;
+ return (int)
+ Streams.stream(foundMethod.iterateInstructions(invoke))
+ .filter(
+ instruction -> {
+ InvokeInstructionSubject invokeInstruction =
+ (InvokeInstructionSubject) instruction;
+ return invokeInstruction.invokedMethod().qualifiedName().endsWith("method");
+ })
+ .count();
}
private int countInstructionInZSubClass(
- CodeInspector inspector, Class<? extends Instruction> invoke) {
+ CodeInspector inspector, Predicate<InstructionSubject> invoke) {
MethodSignature signatureForZ =
new MethodSignature("z", "void", ImmutableList.of(SubClass.class.getCanonicalName()));
- DexCode z = inspector.clazz(Main.class).method(signatureForZ).getMethod().getCode().asDexCode();
- return (int) filterInstructionKind(z, invoke)
- .filter(instruction -> instruction.getMethod().qualifiedName().endsWith("method"))
- .count();
+ MethodSubject method = inspector.clazz(Main.class).method(signatureForZ);
+ assert method instanceof FoundMethodSubject;
+ FoundMethodSubject foundMethod = (FoundMethodSubject) method;
+ return (int)
+ Streams.stream(foundMethod.iterateInstructions(invoke))
+ .filter(
+ instruction -> {
+ InvokeInstructionSubject invokeInstruction =
+ (InvokeInstructionSubject) instruction;
+ return invokeInstruction.invokedMethod().qualifiedName().endsWith("method");
+ })
+ .count();
}
private void noInterfaceKept(CodeInspector inspector) {
// Indirectly assert that method is inlined into x, y and z.
- assertEquals(1, countInstructionInX(inspector, InvokeInterface.class));
- assertEquals(1, countInstructionInY(inspector, InvokeInterface.class));
- assertEquals(1, countInstructionInZ(inspector, InvokeVirtual.class));
+ assertEquals(1, countInstructionInX(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(1, countInstructionInY(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(1, countInstructionInZ(inspector, InstructionSubject::isInvokeVirtual));
}
@Test
@@ -106,11 +161,11 @@
private void baseInterfaceKept(CodeInspector inspector) {
// Indirectly assert that method is not inlined into x.
- assertEquals(3, countInstructionInX(inspector, InvokeInterface.class));
+ assertEquals(3, countInstructionInX(inspector, InstructionSubject::isInvokeInterface));
// Indirectly assert that method is inlined into y and z.
- assertEquals(1, countInstructionInY(inspector, InvokeInterface.class));
- assertEquals(1, countInstructionInZ(inspector, InvokeVirtual.class));
- assertEquals(1, countInstructionInZSubClass(inspector, InvokeVirtual.class));
+ assertEquals(1, countInstructionInY(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(1, countInstructionInZ(inspector, InstructionSubject::isInvokeVirtual));
+ assertEquals(1, countInstructionInZSubClass(inspector, InstructionSubject::isInvokeVirtual));
}
@Test
@@ -126,11 +181,11 @@
private void subInterfaceKept(CodeInspector inspector) {
// Indirectly assert that method is not inlined into x or y.
- assertEquals(3, countInstructionInX(inspector, InvokeInterface.class));
- assertEquals(3, countInstructionInY(inspector, InvokeInterface.class));
+ assertEquals(3, countInstructionInX(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(3, countInstructionInY(inspector, InstructionSubject::isInvokeInterface));
// Indirectly assert that method is inlined into z.
- assertEquals(1, countInstructionInZ(inspector, InvokeVirtual.class));
- assertEquals(1, countInstructionInZSubClass(inspector, InvokeVirtual.class));
+ assertEquals(1, countInstructionInZ(inspector, InstructionSubject::isInvokeVirtual));
+ assertEquals(1, countInstructionInZSubClass(inspector, InstructionSubject::isInvokeVirtual));
}
@Test
@@ -148,10 +203,10 @@
private void classKept(CodeInspector inspector) {
// Indirectly assert that method is not inlined into x, y or z.
- assertEquals(3, countInstructionInX(inspector, InvokeInterface.class));
- assertEquals(3, countInstructionInY(inspector, InvokeInterface.class));
- assertEquals(3, countInstructionInZ(inspector, InvokeVirtual.class));
- assertEquals(3, countInstructionInZSubClass(inspector, InvokeVirtual.class));
+ assertEquals(3, countInstructionInX(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(3, countInstructionInY(inspector, InstructionSubject::isInvokeInterface));
+ assertEquals(3, countInstructionInZ(inspector, InstructionSubject::isInvokeVirtual));
+ assertEquals(3, countInstructionInZSubClass(inspector, InstructionSubject::isInvokeVirtual));
}
@Test