Extend callback test to run desugaring twice
Bug: 171867367
Bug: 172433489
Change-Id: I4ea79d9c1a3dfda1f9a603693289288791efdfb2
diff --git a/src/main/java/com/android/tools/r8/utils/ZipUtils.java b/src/main/java/com/android/tools/r8/utils/ZipUtils.java
index f33ed6f..400ef0c 100644
--- a/src/main/java/com/android/tools/r8/utils/ZipUtils.java
+++ b/src/main/java/com/android/tools/r8/utils/ZipUtils.java
@@ -23,6 +23,7 @@
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
+import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
@@ -68,7 +69,11 @@
}
public static void iter(String zipFileStr, OnEntryHandler handler) throws IOException {
- try (ZipFile zipFile = new ZipFile(zipFileStr, StandardCharsets.UTF_8)) {
+ iter(Paths.get(zipFileStr), handler);
+ }
+
+ public static void iter(Path zipFilePath, OnEntryHandler handler) throws IOException {
+ try (ZipFile zipFile = new ZipFile(zipFilePath.toFile(), StandardCharsets.UTF_8)) {
final Enumeration<? extends ZipEntry> entries = zipFile.entries();
while (entries.hasMoreElements()) {
ZipEntry entry = entries.nextElement();
@@ -79,6 +84,12 @@
}
}
+ public static byte[] readSingleEntry(Path zipFilePath, String name) throws IOException {
+ try (ZipFile zipFile = new ZipFile(zipFilePath.toFile(), StandardCharsets.UTF_8)) {
+ return ByteStreams.toByteArray(zipFile.getInputStream(zipFile.getEntry(name)));
+ }
+ }
+
public static void zip(Path zipFile, Path inputDirectory) throws IOException {
List<Path> files =
Files.walk(inputDirectory)
@@ -226,4 +237,8 @@
return zipFile;
}
}
+
+ public static String zipEntryNameForClass(Class<?> clazz) {
+ return DescriptorUtils.getClassBinaryName(clazz) + CLASS_EXTENSION;
+ }
}
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/CallBackConversionTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/CallBackConversionTest.java
index 92d2394..241f4a0 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/CallBackConversionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/conversiontests/CallBackConversionTest.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.desugar.desugaredlibrary.conversiontests;
+import static com.android.tools.r8.utils.InternalOptions.ASM_VERSION;
import static junit.framework.TestCase.assertEquals;
import static junit.framework.TestCase.assertTrue;
@@ -11,10 +12,13 @@
import com.android.tools.r8.desugar.desugaredlibrary.DesugaredLibraryTestBase;
import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
+import com.android.tools.r8.utils.DescriptorUtils;
import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.ZipUtils;
import com.android.tools.r8.utils.codeinspector.CodeInspector;
import com.android.tools.r8.utils.codeinspector.FoundMethodSubject;
import java.nio.file.Path;
+import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
import org.junit.BeforeClass;
@@ -22,6 +26,9 @@
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
+import org.objectweb.asm.ClassReader;
+import org.objectweb.asm.ClassVisitor;
+import org.objectweb.asm.MethodVisitor;
@RunWith(Parameterized.class)
public class CallBackConversionTest extends DesugaredLibraryTestBase {
@@ -101,10 +108,68 @@
.assertSuccessWithOutput(EXPECTED_RESULT);
}
+ private static class ClassInfo {
+ private final String classBinaryName;
+ private final List<String> methodNames;
+
+ ClassInfo(String classBinaryNamename, List<String> methodNames) {
+ this.classBinaryName = classBinaryNamename;
+ this.methodNames = methodNames;
+ }
+
+ public String getClassBinaryName() {
+ return classBinaryName;
+ }
+
+ public List<String> getMethodNames() {
+ return methodNames;
+ }
+ }
+
+ private static ClassInfo extractClassInfo(byte[] ccc) {
+ class ClassNameExtractor extends ClassVisitor {
+ private String classBinaryName;
+ private final List<String> methodNames = new ArrayList<>();
+
+ private ClassNameExtractor() {
+ super(ASM_VERSION);
+ }
+
+ @Override
+ public void visit(
+ int version,
+ int access,
+ String name,
+ String signature,
+ String superName,
+ String[] interfaces) {
+ classBinaryName = name;
+ super.visit(version, access, name, signature, superName, interfaces);
+ }
+
+ @Override
+ public MethodVisitor visitMethod(
+ int access, String name, String desc, String signature, String[] exceptions) {
+ methodNames.add(name);
+ return null;
+ }
+
+ ClassInfo getClassInfo() {
+ return new ClassInfo(classBinaryName, methodNames);
+ }
+ }
+
+ ClassReader reader = new ClassReader(ccc);
+ ClassNameExtractor extractor = new ClassNameExtractor();
+ reader.accept(
+ extractor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
+ return extractor.getClassInfo();
+ }
+
@Test
public void testCallBackD8Cf() throws Exception {
// Use D8 to desugar with Java classfile output.
- Path jar =
+ Path firstJar =
testForD8(Backend.CF)
.setMinApi(parameters.getApiLevel())
.addProgramClasses(Impl.class)
@@ -114,9 +179,37 @@
.inspect(CallBackConversionTest::assertDuplicatedAPI)
.writeToZip();
+ ClassInfo info =
+ extractClassInfo(
+ ZipUtils.readSingleEntry(firstJar, ZipUtils.zipEntryNameForClass(Impl.class)));
+ assertEquals(
+ Impl.class.getTypeName(),
+ DescriptorUtils.getJavaTypeFromBinaryName(info.getClassBinaryName()));
+ assertEquals(2, info.methodNames.stream().filter(name -> name.equals("foo")).count());
+
+ // Use D8 to desugar with Java classfile output.
+ Path secondJar =
+ testForD8(Backend.CF)
+ .setMinApi(parameters.getApiLevel())
+ .addProgramFiles(firstJar)
+ .addLibraryClasses(CustomLibClass.class)
+ .enableCoreLibraryDesugaring(parameters.getApiLevel(), new AbsentKeepRuleConsumer())
+ .compile()
+ .inspect(CallBackConversionTest::assertDuplicatedAPI)
+ .writeToZip();
+
+ info =
+ extractClassInfo(
+ ZipUtils.readSingleEntry(secondJar, ZipUtils.zipEntryNameForClass(Impl.class)));
+ assertEquals(
+ Impl.class.getTypeName(),
+ DescriptorUtils.getJavaTypeFromBinaryName(info.getClassBinaryName()));
+ // TODO(b/171867367): This should only be 2.
+ assertEquals(3, info.getMethodNames().stream().filter(name -> name.equals("foo")).count());
+
// Convert to DEX without desugaring and run.
testForD8()
- .addProgramFiles(jar)
+ .addProgramFiles(firstJar)
.setMinApi(parameters.getApiLevel())
.disableDesugaring()
.compile()
@@ -125,7 +218,7 @@
this::buildDesugaredLibrary,
parameters.getApiLevel(),
collectKeepRulesWithTraceReferences(
- jar, buildDesugaredLibraryClassFile(parameters.getApiLevel())),
+ firstJar, buildDesugaredLibraryClassFile(parameters.getApiLevel())),
shrinkDesugaredLibrary)
.addRunClasspathFiles(CUSTOM_LIB)
.run(parameters.getRuntime(), Impl.class)