Merge "Add CF backend to KeepAttributesTest."
diff --git a/src/test/java/com/android/tools/r8/shaking/KeepAttributesTest.java b/src/test/java/com/android/tools/r8/shaking/KeepAttributesTest.java
index b518683..96ce54a 100644
--- a/src/test/java/com/android/tools/r8/shaking/KeepAttributesTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/KeepAttributesTest.java
@@ -3,7 +3,7 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
-import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -13,23 +13,36 @@
import com.android.tools.r8.R8Command;
import com.android.tools.r8.TestBase;
import com.android.tools.r8.ToolHelper;
-import com.android.tools.r8.debuginfo.DebugInfoInspector;
-import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.shaking.forceproguardcompatibility.keepattributes.TestKeepAttributes;
import com.android.tools.r8.utils.AndroidApp;
import com.android.tools.r8.utils.AndroidAppConsumers;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
+import com.android.tools.r8.utils.codeinspector.MethodSubject;
import com.google.common.collect.ImmutableList;
import java.io.IOException;
-import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutionException;
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 KeepAttributesTest extends TestBase {
- public static final Class CLASS = TestKeepAttributes.class;
+ private static final Class CLASS = TestKeepAttributes.class;
+
+ @Parameters(name = "{0}")
+ public static Backend[] parameters() {
+ return new Backend[] { Backend.CF, Backend.DEX};
+ }
+
+ private final Backend backend;
+
+ public KeepAttributesTest(Backend backend) {
+ this.backend = backend;
+ }
@Test
public void keepAllAttributesInDebugMode()
@@ -37,10 +50,9 @@
List<String> keepRules = ImmutableList.of(
"-keep class ** { *; }"
);
- CodeInspector inspector = compile(keepRules, CompilationMode.DEBUG);
- DebugInfoInspector debugInfo = debugInfoForMain(inspector);
- checkLineNumbers(true, debugInfo);
- checkLocals(true, debugInfo);
+ MethodSubject mainMethod = compileRunAndGetMain(keepRules, CompilationMode.DEBUG);
+ assertTrue(mainMethod.hasLineNumberTable());
+ assertTrue(mainMethod.hasLocalVariableTable());
}
@Test
@@ -49,10 +61,9 @@
List<String> keepRules = ImmutableList.of(
"-keep class ** { *; }"
);
- CodeInspector inspector = compile(keepRules, CompilationMode.RELEASE);
- DebugInfoInspector debugInfo = debugInfoForMain(inspector);
- checkLineNumbers(false, debugInfo);
- checkLocals(false, debugInfo);
+ MethodSubject mainMethod = compileRunAndGetMain(keepRules, CompilationMode.RELEASE);
+ assertFalse(mainMethod.hasLineNumberTable());
+ assertFalse(mainMethod.hasLocalVariableTable());
}
@Test
@@ -62,10 +73,9 @@
"-keep class ** { *; }",
"-keepattributes " + ProguardKeepAttributes.LINE_NUMBER_TABLE
);
- CodeInspector inspector = compile(keepRules, CompilationMode.RELEASE);
- DebugInfoInspector debugInfo = debugInfoForMain(inspector);
- checkLineNumbers(true, debugInfo);
- checkLocals(false, debugInfo);
+ MethodSubject mainMethod = compileRunAndGetMain(keepRules, CompilationMode.RELEASE);
+ assertTrue(mainMethod.hasLineNumberTable());
+ assertFalse(mainMethod.hasLocalVariableTable());
}
@Test
@@ -78,11 +88,10 @@
+ ", "
+ ProguardKeepAttributes.LOCAL_VARIABLE_TABLE
);
- CodeInspector inspector = compile(keepRules, CompilationMode.RELEASE);
- DebugInfoInspector debugInfo = debugInfoForMain(inspector);
- checkLineNumbers(true, debugInfo);
+ MethodSubject mainMethod = compileRunAndGetMain(keepRules, CompilationMode.RELEASE);
+ assertTrue(mainMethod.hasLineNumberTable());
// Locals are never included in release builds.
- checkLocals(false, debugInfo);
+ assertFalse(mainMethod.hasLocalVariableTable());
}
@Test
@@ -93,7 +102,7 @@
);
// Compiling with a keep rule for locals but no line results in an error in R8.
try {
- compile(keepRules, CompilationMode.RELEASE);
+ compileRunAndGetMain(keepRules, CompilationMode.RELEASE);
} catch (CompilationFailedException e) {
assertTrue(e.getCause().getMessage().contains(ProguardKeepAttributes.LOCAL_VARIABLE_TABLE));
assertTrue(e.getCause().getMessage().contains(ProguardKeepAttributes.LINE_NUMBER_TABLE));
@@ -102,7 +111,7 @@
fail("Expected error");
}
- private CodeInspector compile(List<String> keepRules, CompilationMode mode)
+ private MethodSubject compileRunAndGetMain(List<String> keepRules, CompilationMode mode)
throws CompilationFailedException, IOException, ExecutionException {
AndroidAppConsumers sink = new AndroidAppConsumers();
R8.run(
@@ -111,30 +120,14 @@
.addProgramFiles(
ToolHelper.getClassFilesForTestDirectory(
ToolHelper.getClassFileForTestClass(CLASS).getParent()))
- .addLibraryFiles(ToolHelper.getDefaultAndroidJar())
+ .addLibraryFiles(runtimeJar(backend))
.addProguardConfiguration(keepRules, Origin.unknown())
- .setProgramConsumer(sink.wrapProgramConsumer(emptyConsumer(Backend.DEX)))
+ .setProgramConsumer(sink.wrapProgramConsumer(emptyConsumer(backend)))
.build());
AndroidApp app = sink.build();
CodeInspector codeInspector = new CodeInspector(app);
- runOnArt(app, CLASS.getTypeName());
- return codeInspector;
+ runOnVM(app, CLASS.getTypeName(), backend);
+ return codeInspector.clazz(CLASS).mainMethod();
}
- private DebugInfoInspector debugInfoForMain(CodeInspector inspector) {
- return new DebugInfoInspector(
- inspector,
- CLASS.getTypeName(),
- new MethodSignature("main", "void", Collections.singleton("java.lang.String[]")));
- }
-
- private void checkLineNumbers(boolean expected, DebugInfoInspector debugInfo) {
- assertEquals("Expected " + (expected ? "line entries" : "no line entries"),
- expected, debugInfo.getEntries().stream().anyMatch(e -> e.lineEntry));
- }
-
- private void checkLocals(boolean expected, DebugInfoInspector debugInfo) {
- assertEquals("Expected " + (expected ? "locals" : "no locals"),
- expected, debugInfo.getEntries().stream().anyMatch(e -> !e.locals.isEmpty()));
- }
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
index 1396be9..adee8cf 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/AbsentMethodSubject.java
@@ -78,4 +78,14 @@
public String getFinalSignatureAttribute() {
return null;
}
+
+ @Override
+ public boolean hasLineNumberTable() {
+ return false;
+ }
+
+ @Override
+ public boolean hasLocalVariableTable() {
+ return false;
+ }
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
index 3fe8186..f205594 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/FoundMethodSubject.java
@@ -4,12 +4,22 @@
package com.android.tools.r8.utils.codeinspector;
+import com.android.tools.r8.cf.code.CfInstruction;
+import com.android.tools.r8.cf.code.CfPosition;
+import com.android.tools.r8.errors.Unreachable;
+import com.android.tools.r8.graph.Code;
+import com.android.tools.r8.graph.DexCode;
+import com.android.tools.r8.graph.DexDebugEvent;
import com.android.tools.r8.graph.DexEncodedMethod;
+import com.android.tools.r8.graph.DexString;
import com.android.tools.r8.naming.MemberNaming;
import com.android.tools.r8.naming.MemberNaming.MethodSignature;
import com.android.tools.r8.naming.signature.GenericSignatureParser;
import java.util.Iterator;
+import java.util.ListIterator;
import java.util.function.Predicate;
+import org.objectweb.asm.tree.AbstractInsnNode;
+import org.objectweb.asm.tree.LineNumberNode;
public class FoundMethodSubject extends MethodSubject {
@@ -134,6 +144,69 @@
}
@Override
+ public boolean hasLineNumberTable() {
+ Code code = getMethod().getCode();
+ if (code.isDexCode()) {
+ DexCode dexCode = code.asDexCode();
+ if (dexCode.getDebugInfo() != null) {
+ for (DexDebugEvent event : dexCode.getDebugInfo().events) {
+ if (event instanceof DexDebugEvent.Default) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ if (code.isCfCode()) {
+ for (CfInstruction insn : code.asCfCode().getInstructions()) {
+ if (insn instanceof CfPosition) {
+ return true;
+ }
+ }
+ return false;
+ }
+ if (code.isJarCode()) {
+ ListIterator<AbstractInsnNode> it = code.asJarCode().getNode().instructions.iterator();
+ while (it.hasNext()) {
+ if (it.next() instanceof LineNumberNode) {
+ return true;
+ }
+ }
+ return false;
+ }
+ throw new Unreachable("Unexpected code type: " + code.getClass().getSimpleName());
+ }
+
+ @Override
+ public boolean hasLocalVariableTable() {
+ Code code = getMethod().getCode();
+ if (code.isDexCode()) {
+ DexCode dexCode = code.asDexCode();
+ if (dexCode.getDebugInfo() != null) {
+ for (DexString parameter : dexCode.getDebugInfo().parameters) {
+ if (parameter != null) {
+ return true;
+ }
+ }
+ for (DexDebugEvent event : dexCode.getDebugInfo().events) {
+ if (event instanceof DexDebugEvent.StartLocal) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+ if (code.isCfCode()) {
+ return !code.asCfCode().getLocalVariables().isEmpty();
+ }
+ if (code.isJarCode()) {
+ return code.asJarCode().getNode().localVariables != null
+ && !code.asJarCode().getNode().localVariables.isEmpty();
+ }
+ throw new Unreachable("Unexpected code type: " + code.getClass().getSimpleName());
+ }
+
+ @Override
public String toString() {
return dexMethod.toSourceString();
}
diff --git a/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java b/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
index 6eaaf5f..55030ca 100644
--- a/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
+++ b/src/test/java/com/android/tools/r8/utils/codeinspector/MethodSubject.java
@@ -32,4 +32,8 @@
Predicate<InstructionSubject> filter) {
return null;
}
+
+ public abstract boolean hasLineNumberTable();
+
+ public abstract boolean hasLocalVariableTable();
}