Extend InstructionSubject classes to CF, enable CF on ApplyMappingTest.
Change-Id: Ia5efcc468836db0f34a9f00c054fd2d0f5239eee
diff --git a/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java b/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
index 876a758..39d7f0b 100644
--- a/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
+++ b/src/test/java/com/android/tools/r8/naming/ApplyMappingTest.java
@@ -6,6 +6,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -15,8 +16,6 @@
import com.android.tools.r8.StringConsumer;
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.NewInstance;
import com.android.tools.r8.graph.DexMethod;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.shaking.ProguardRuleParserException;
@@ -26,14 +25,21 @@
import com.android.tools.r8.utils.dexinspector.InstructionSubject;
import com.android.tools.r8.utils.dexinspector.InvokeInstructionSubject;
import com.android.tools.r8.utils.dexinspector.MethodSubject;
+import com.android.tools.r8.utils.dexinspector.NewInstanceInstructionSubject;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Iterator;
import java.util.concurrent.ExecutionException;
import org.junit.Before;
import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+@RunWith(Parameterized.class)
public class ApplyMappingTest extends TestBase {
private static final String MAPPING = "test-mapping.txt";
@@ -52,9 +58,20 @@
private Path out;
+ private Backend backend;
+
+ @Parameters(name = "Backend: {0}")
+ public static Collection<Backend> data() {
+ return Arrays.asList(Backend.values());
+ }
+
+ public ApplyMappingTest(Backend backend) {
+ this.backend = backend;
+ }
+
@Before
public void setup() throws IOException {
- out = temp.newFolder("outdex").toPath();
+ out = temp.newFolder("out").toPath();
}
@Test
@@ -97,7 +114,7 @@
pgConfig -> pgConfig.setApplyMappingFile(proguardMap))
.build());
- DexInspector inspector = new DexInspector(instrApp);
+ DexInspector inspector = createDexInspector(instrApp);
MethodSubject main = inspector.clazz("applymapping044.Main").method(DexInspector.MAIN);
Iterator<InvokeInstructionSubject> iterator =
main.iterateInstructions(InstructionSubject::isInvoke);
@@ -152,7 +169,7 @@
.build());
// Make sure the given proguard map is indeed applied.
- DexInspector inspector = new DexInspector(outputApp);
+ DexInspector inspector = createDexInspector(outputApp);
MethodSubject main = inspector.clazz("applymapping044.Main").method(DexInspector.MAIN);
Iterator<InvokeInstructionSubject> iterator =
main.iterateInstructions(InstructionSubject::isInvoke);
@@ -194,6 +211,15 @@
assertEquals("p", original_f.invokedMethod().name.toString());
}
+ private static DexInspector createDexInspector(AndroidApp outputApp)
+ throws IOException, ExecutionException {
+ return new DexInspector(
+ outputApp,
+ o -> {
+ o.enableCfFrontend = true;
+ });
+ }
+
@Test
public void test_naming001_rule105() throws Exception {
// keep rules to reserve D and E, along with a proguard map.
@@ -210,7 +236,7 @@
.build());
// Make sure the given proguard map is indeed applied.
- DexInspector inspector = new DexInspector(outputApp);
+ DexInspector inspector = createDexInspector(outputApp);
MethodSubject main = inspector.clazz("naming001.D").method(DexInspector.MAIN);
Iterator<InvokeInstructionSubject> iterator =
main.iterateInstructions(InstructionSubject::isInvoke);
@@ -242,13 +268,20 @@
.build());
// Make sure the given proguard map is indeed applied.
- DexInspector inspector = new DexInspector(outputApp);
+ DexInspector inspector = createDexInspector(outputApp);
MethodSubject main = inspector.clazz("naming001.D").method(DexInspector.MAIN);
+ Iterator<InstructionSubject> iterator = main.iterateInstructions();
// naming001.E is renamed to a.a, so first instruction must be: new-instance La/a;
- Instruction[] instructions = main.getMethod().getCode().asDexCode().instructions;
- assertTrue(instructions[0] instanceof NewInstance);
- NewInstance newInstance = (NewInstance) instructions[0];
+ NewInstanceInstructionSubject newInstance = null;
+ while (iterator.hasNext()) {
+ InstructionSubject instruction = iterator.next();
+ if (instruction.isNewInstance()) {
+ newInstance = (NewInstanceInstructionSubject) instruction;
+ break;
+ }
+ }
+ assertNotNull(newInstance);
assertEquals( "La/a;", newInstance.getType().toSmaliString());
}
@@ -269,7 +302,7 @@
return R8Command.builder()
.addLibraryFiles(ToolHelper.getDefaultAndroidJar(), mainApp)
.addProgramFiles(instrApp)
- .setOutput(out, OutputMode.DexIndexed)
+ .setOutput(out, backend == Backend.DEX ? OutputMode.DexIndexed : OutputMode.ClassFile)
.addProguardConfigurationFiles(flag);
}
@@ -278,15 +311,17 @@
return R8Command.builder()
.addLibraryFiles(ToolHelper.getDefaultAndroidJar())
.addProgramFiles(jars)
- .setOutput(out, OutputMode.DexIndexed)
+ .setOutput(out, backend == Backend.DEX ? OutputMode.DexIndexed : OutputMode.ClassFile)
.addProguardConfigurationFiles(flag);
}
private static AndroidApp runR8(R8Command command)
throws ProguardRuleParserException, ExecutionException, IOException {
- return ToolHelper.runR8(command, options -> {
- // Disable inlining to make this test not depend on inlining decisions.
- options.enableInlining = false;
- });
+ return ToolHelper.runR8(
+ command,
+ options -> {
+ // Disable inlining to make this test not depend on inlining decisions.
+ options.enableInlining = false;
+ });
}
}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/AbsentClassSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/AbsentClassSubject.java
index 7213a54..e2fa906 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/AbsentClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/AbsentClassSubject.java
@@ -10,12 +10,6 @@
public class AbsentClassSubject extends ClassSubject {
- private DexInspector dexInspector;
-
- public AbsentClassSubject(DexInspector dexInspector) {
- this.dexInspector = dexInspector;
- }
-
@Override
public boolean isPresent() {
return false;
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionIterator.java b/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionIterator.java
new file mode 100644
index 0000000..d000250
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionIterator.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2018, 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.utils.dexinspector;
+
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.graph.Code;
+import java.util.Iterator;
+
+class CfInstructionIterator implements InstructionIterator {
+
+ private final DexInspector dexInspector;
+ private final Iterator<CfInstruction> iterator;
+
+ CfInstructionIterator(DexInspector dexInspector, MethodSubject method) {
+ this.dexInspector = dexInspector;
+ assert method.isPresent();
+ Code code = method.getMethod().getCode();
+ assert code != null && code.isCfCode();
+ iterator = code.asCfCode().getInstructions().iterator();
+ }
+
+ @Override
+ public boolean hasNext() {
+ return iterator.hasNext();
+ }
+
+ @Override
+ public InstructionSubject next() {
+ return dexInspector.createInstructionSubject(iterator.next());
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java
new file mode 100644
index 0000000..ae900f3
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/CfInstructionSubject.java
@@ -0,0 +1,118 @@
+// Copyright (c) 2018, 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.utils.dexinspector;
+
+import com.android.tools.r8.cf.code.CfConstString;
+import com.android.tools.r8.cf.code.CfFieldInstruction;
+import com.android.tools.r8.cf.code.CfGoto;
+import com.android.tools.r8.cf.code.CfIf;
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.cf.code.CfInvoke;
+import com.android.tools.r8.cf.code.CfInvokeDynamic;
+import com.android.tools.r8.cf.code.CfLabel;
+import com.android.tools.r8.cf.code.CfNew;
+import com.android.tools.r8.cf.code.CfNop;
+import com.android.tools.r8.cf.code.CfPosition;
+import com.android.tools.r8.cf.code.CfReturnVoid;
+import com.android.tools.r8.cf.code.CfThrow;
+import org.objectweb.asm.Opcodes;
+
+public class CfInstructionSubject implements InstructionSubject {
+ protected final CfInstruction instruction;
+
+ public CfInstructionSubject(CfInstruction instruction) {
+ this.instruction = instruction;
+ }
+
+ @Override
+ public boolean isFieldAccess() {
+ return instruction instanceof CfFieldInstruction;
+ }
+
+ @Override
+ public boolean isInvokeVirtual() {
+ return instruction instanceof CfInvoke
+ && ((CfInvoke) instruction).getOpcode() == Opcodes.INVOKEVIRTUAL;
+ }
+
+ @Override
+ public boolean isInvokeInterface() {
+ return instruction instanceof CfInvoke
+ && ((CfInvoke) instruction).getOpcode() == Opcodes.INVOKEINTERFACE;
+ }
+
+ @Override
+ public boolean isInvokeStatic() {
+ return instruction instanceof CfInvoke
+ && ((CfInvoke) instruction).getOpcode() == Opcodes.INVOKESTATIC;
+ }
+
+ @Override
+ public boolean isNop() {
+ return instruction instanceof CfNop;
+ }
+
+ @Override
+ public boolean isConstString() {
+ return instruction instanceof CfConstString;
+ }
+
+ @Override
+ public boolean isConstString(String value) {
+ return isConstString() && ((CfConstString) instruction).getString().toString().equals(value);
+ }
+
+ @Override
+ public boolean isGoto() {
+ return instruction instanceof CfGoto;
+ }
+
+ @Override
+ public boolean isIfNez() {
+ return instruction instanceof CfIf && ((CfIf) instruction).getOpcode() == Opcodes.IFNE;
+ }
+
+ @Override
+ public boolean isIfEqz() {
+ return instruction instanceof CfIf && ((CfIf) instruction).getOpcode() == Opcodes.IFEQ;
+ }
+
+ @Override
+ public boolean isReturnVoid() {
+ return instruction instanceof CfReturnVoid;
+ }
+
+ @Override
+ public boolean isThrow() {
+ return instruction instanceof CfThrow;
+ }
+
+ @Override
+ public boolean isInvoke() {
+ return instruction instanceof CfInvoke || instruction instanceof CfInvokeDynamic;
+ }
+
+ @Override
+ public boolean isNewInstance() {
+ return instruction instanceof CfNew;
+ }
+
+ public boolean isInvokeSpecial() {
+ return instruction instanceof CfInvoke
+ && ((CfInvoke) instruction).getOpcode() == Opcodes.INVOKESPECIAL;
+ }
+
+ public boolean isInvokeDynamic() {
+ return instruction instanceof CfInvokeDynamic;
+ }
+
+ public boolean isLabel() {
+ return instruction instanceof CfLabel;
+ }
+
+ public boolean isPosition() {
+ return instruction instanceof CfPosition;
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInspector.java b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInspector.java
index 51e4ce2..c67a560 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInspector.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInspector.java
@@ -6,8 +6,10 @@
import static org.junit.Assert.assertTrue;
import com.android.tools.r8.StringResource;
+import com.android.tools.r8.cf.code.CfInstruction;
import com.android.tools.r8.code.Instruction;
import com.android.tools.r8.dex.ApplicationReader;
+import com.android.tools.r8.errors.Unimplemented;
import com.android.tools.r8.graph.Code;
import com.android.tools.r8.graph.DexAnnotation;
import com.android.tools.r8.graph.DexAnnotationElement;
@@ -205,7 +207,7 @@
}
DexClass clazz = application.definitionFor(toDexTypeIgnorePrimitives(name));
if (clazz == null) {
- return new AbsentClassSubject(this);
+ return new AbsentClassSubject();
}
return new FoundClassSubject(this, clazz, naming);
}
@@ -250,15 +252,36 @@
return new InvokeDexInstructionSubject(this, instruction);
} else if (dexInst.isFieldAccess()) {
return new FieldAccessDexInstructionSubject(this, instruction);
+ } else if (dexInst.isNewInstance()) {
+ return new NewInstanceDexInstructionSubject(instruction);
} else {
return dexInst;
}
}
+ InstructionSubject createInstructionSubject(CfInstruction instruction) {
+ CfInstructionSubject cfInst = new CfInstructionSubject(instruction);
+ if (cfInst.isInvoke()) {
+ return new InvokeCfInstructionSubject(this, instruction);
+ } else if (cfInst.isFieldAccess()) {
+ return new FieldAccessCfInstructionSubject(this, instruction);
+ } else if (cfInst.isNewInstance()) {
+ return new NewInstanceCfInstructionSubject(instruction);
+ } else {
+ return cfInst;
+ }
+ }
+
InstructionIterator createInstructionIterator(MethodSubject method) {
Code code = method.getMethod().getCode();
- assert code != null && code.isDexCode();
- return new DexInstructionIterator(this, method);
+ assert code != null;
+ if (code.isDexCode()) {
+ return new DexInstructionIterator(this, method);
+ } else if (code.isCfCode()) {
+ return new CfInstructionIterator(this, method);
+ } else {
+ throw new Unimplemented("InstructionIterator is implemented for DexCode and CfCode only.");
+ }
}
// Build the generic signature using the current mapping if any.
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionIterator.java b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionIterator.java
index eaff010..9ed4de1 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionIterator.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionIterator.java
@@ -10,7 +10,7 @@
class DexInstructionIterator implements InstructionIterator {
- private DexInspector dexInspector;
+ private final DexInspector dexInspector;
private final DexCode code;
private int index;
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionSubject.java
index b2320d3..82d725a 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/DexInstructionSubject.java
@@ -34,6 +34,7 @@
import com.android.tools.r8.code.IputObject;
import com.android.tools.r8.code.IputShort;
import com.android.tools.r8.code.IputWide;
+import com.android.tools.r8.code.NewInstance;
import com.android.tools.r8.code.Nop;
import com.android.tools.r8.code.ReturnVoid;
import com.android.tools.r8.code.Sget;
@@ -53,7 +54,7 @@
import com.android.tools.r8.code.Throw;
public class DexInstructionSubject implements InstructionSubject {
- protected Instruction instruction;
+ protected final Instruction instruction;
public DexInstructionSubject(Instruction instruction) {
this.instruction = instruction;
@@ -75,16 +76,6 @@
}
@Override
- public boolean isInvokeDirect() {
- return instruction instanceof InvokeDirect || instruction instanceof InvokeDirectRange;
- }
-
- @Override
- public boolean isInvokeSuper() {
- return instruction instanceof InvokeSuper || instruction instanceof InvokeSuperRange;
- }
-
- @Override
public boolean isInvokeStatic() {
return instruction instanceof InvokeStatic || instruction instanceof InvokeStaticRange;
}
@@ -131,6 +122,28 @@
return instruction instanceof Throw;
}
+ @Override
+ public boolean isInvoke() {
+ return isInvokeVirtual()
+ || isInvokeInterface()
+ || isInvokeDirect()
+ || isInvokeSuper()
+ || isInvokeStatic();
+ }
+
+ @Override
+ public boolean isNewInstance() {
+ return instruction instanceof NewInstance;
+ }
+
+ public boolean isInvokeSuper() {
+ return instruction instanceof InvokeSuper || instruction instanceof InvokeSuperRange;
+ }
+
+ public boolean isInvokeDirect() {
+ return instruction instanceof InvokeDirect || instruction instanceof InvokeDirectRange;
+ }
+
public boolean isConst4() {
return instruction instanceof Const4;
}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessCfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessCfInstructionSubject.java
new file mode 100644
index 0000000..a2103e6
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessCfInstructionSubject.java
@@ -0,0 +1,23 @@
+// Copyright (c) 2018, 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.utils.dexinspector;
+
+import com.android.tools.r8.cf.code.CfFieldInstruction;
+import com.android.tools.r8.cf.code.CfInstruction;
+
+public class FieldAccessCfInstructionSubject extends CfInstructionSubject
+ implements FieldAccessInstructionSubject {
+ private final DexInspector dexInspector;
+
+ public FieldAccessCfInstructionSubject(DexInspector dexInspector, CfInstruction instruction) {
+ super(instruction);
+ this.dexInspector = dexInspector;
+ assert isFieldAccess();
+ }
+
+ public TypeSubject holder() {
+ return new TypeSubject(dexInspector, ((CfFieldInstruction) instruction).getField().getHolder());
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessDexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessDexInstructionSubject.java
index c3ea3fc..ed54f90 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessDexInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/FieldAccessDexInstructionSubject.java
@@ -9,7 +9,7 @@
public class FieldAccessDexInstructionSubject extends DexInstructionSubject
implements FieldAccessInstructionSubject {
- private DexInspector dexInspector;
+ private final DexInspector dexInspector;
public FieldAccessDexInstructionSubject(DexInspector dexInspector, Instruction instruction) {
super(instruction);
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/FilteredInstructionIterator.java b/src/test/java/com/android/tools/r8/utils/dexinspector/FilteredInstructionIterator.java
index 33ac77f..5f3c078 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/FilteredInstructionIterator.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/FilteredInstructionIterator.java
@@ -10,14 +10,12 @@
class FilteredInstructionIterator<T extends InstructionSubject> implements Iterator<T> {
- private DexInspector dexInspector;
private final InstructionIterator iterator;
private final Predicate<InstructionSubject> predicate;
private InstructionSubject pendingNext = null;
FilteredInstructionIterator(
DexInspector dexInspector, MethodSubject method, Predicate<InstructionSubject> predicate) {
- this.dexInspector = dexInspector;
this.iterator = dexInspector.createInstructionIterator(method);
this.predicate = predicate;
hasNext();
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/FoundClassSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/FoundClassSubject.java
index 12dbaeb..2202f89 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/FoundClassSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/FoundClassSubject.java
@@ -25,7 +25,7 @@
public class FoundClassSubject extends ClassSubject {
- private DexInspector dexInspector;
+ private final DexInspector dexInspector;
private final DexClass dexClass;
final ClassNamingForNameMapper naming;
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/FoundFieldSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/FoundFieldSubject.java
index 52aa0ce..5dfa4f1 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/FoundFieldSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/FoundFieldSubject.java
@@ -12,7 +12,7 @@
public class FoundFieldSubject extends FieldSubject {
- private DexInspector dexInspector;
+ private final DexInspector dexInspector;
private final FoundClassSubject clazz;
private final DexEncodedField dexField;
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/FoundMethodSubject.java
index e245258..6eb3858 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/FoundMethodSubject.java
@@ -13,7 +13,7 @@
public class FoundMethodSubject extends MethodSubject {
- private DexInspector dexInspector;
+ private final DexInspector dexInspector;
private final FoundClassSubject clazz;
private final DexEncodedMethod dexMethod;
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/InstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/InstructionSubject.java
index 00102e5..b6f1e52 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/InstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/InstructionSubject.java
@@ -11,10 +11,6 @@
boolean isInvokeInterface();
- boolean isInvokeDirect();
-
- boolean isInvokeSuper();
-
boolean isInvokeStatic();
boolean isNop();
@@ -33,11 +29,7 @@
boolean isThrow();
- default boolean isInvoke() {
- return isInvokeVirtual()
- || isInvokeInterface()
- || isInvokeDirect()
- || isInvokeSuper()
- || isInvokeStatic();
- }
+ boolean isInvoke();
+
+ boolean isNewInstance();
}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeCfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeCfInstructionSubject.java
new file mode 100644
index 0000000..4d245b2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeCfInstructionSubject.java
@@ -0,0 +1,33 @@
+// Copyright (c) 2018, 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.utils.dexinspector;
+
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.cf.code.CfInvoke;
+import com.android.tools.r8.errors.Unimplemented;
+import com.android.tools.r8.graph.DexMethod;
+
+public class InvokeCfInstructionSubject extends CfInstructionSubject
+ implements InvokeInstructionSubject {
+ private final DexInspector dexInspector;
+
+ public InvokeCfInstructionSubject(DexInspector dexInspector, CfInstruction instruction) {
+ super(instruction);
+ assert isInvoke();
+ this.dexInspector = dexInspector;
+ }
+
+ public TypeSubject holder() {
+ return new TypeSubject(dexInspector, invokedMethod().getHolder());
+ }
+
+ public DexMethod invokedMethod() {
+ if (isInvokeDynamic()) {
+ throw new Unimplemented(
+ "invokeMethod is not implemented for the INVOKEDYNAMIC CF instruction.");
+ }
+ return ((CfInvoke) instruction).getMethod();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeDexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeDexInstructionSubject.java
index a4f5636..51d0767 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeDexInstructionSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/InvokeDexInstructionSubject.java
@@ -10,7 +10,7 @@
public class InvokeDexInstructionSubject extends DexInstructionSubject
implements InvokeInstructionSubject {
- private DexInspector dexInspector;
+ private final DexInspector dexInspector;
public InvokeDexInstructionSubject(DexInspector dexInspector, Instruction instruction) {
super(instruction);
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceCfInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceCfInstructionSubject.java
new file mode 100644
index 0000000..71a1dfc
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceCfInstructionSubject.java
@@ -0,0 +1,17 @@
+package com.android.tools.r8.utils.dexinspector;
+
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.cf.code.CfNew;
+import com.android.tools.r8.graph.DexType;
+
+public class NewInstanceCfInstructionSubject extends CfInstructionSubject
+ implements NewInstanceInstructionSubject {
+ public NewInstanceCfInstructionSubject(CfInstruction instruction) {
+ super(instruction);
+ }
+
+ @Override
+ public DexType getType() {
+ return ((CfNew) instruction).getType();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceDexInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceDexInstructionSubject.java
new file mode 100644
index 0000000..675ded2
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceDexInstructionSubject.java
@@ -0,0 +1,17 @@
+package com.android.tools.r8.utils.dexinspector;
+
+import com.android.tools.r8.code.Instruction;
+import com.android.tools.r8.code.NewInstance;
+import com.android.tools.r8.graph.DexType;
+
+public class NewInstanceDexInstructionSubject extends DexInstructionSubject
+ implements NewInstanceInstructionSubject {
+ public NewInstanceDexInstructionSubject(Instruction instruction) {
+ super(instruction);
+ }
+
+ @Override
+ public DexType getType() {
+ return ((NewInstance) instruction).getType();
+ }
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceInstructionSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceInstructionSubject.java
new file mode 100644
index 0000000..98a10ec
--- /dev/null
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/NewInstanceInstructionSubject.java
@@ -0,0 +1,7 @@
+package com.android.tools.r8.utils.dexinspector;
+
+import com.android.tools.r8.graph.DexType;
+
+public interface NewInstanceInstructionSubject extends InstructionSubject {
+ DexType getType();
+}
diff --git a/src/test/java/com/android/tools/r8/utils/dexinspector/TypeSubject.java b/src/test/java/com/android/tools/r8/utils/dexinspector/TypeSubject.java
index 6a911eb..5b21c41 100644
--- a/src/test/java/com/android/tools/r8/utils/dexinspector/TypeSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/dexinspector/TypeSubject.java
@@ -8,7 +8,7 @@
public class TypeSubject extends Subject {
- private DexInspector dexInspector;
+ private final DexInspector dexInspector;
private final DexType dexType;
TypeSubject(DexInspector dexInspector, DexType dexType) {