Ensure that we can merge desugared java8 classes
We do create a single class for each method, but when merging we did
not take into account that we allow multiple instances of these.
Bug: 123242448
Change-Id: If4ec57e9d3172c6fe6fe8facaf6efb7916e1aa49
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java b/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
index c0a7569..9e2e9ab 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/Java8MethodRewriter.java
@@ -84,6 +84,10 @@
return null;
}
+ public static boolean hasJava8MethodRewritePrefix(DexType clazz) {
+ return clazz.descriptor.toString().startsWith(UTILITY_CLASS_DESCRIPTOR_PREFIX);
+ }
+
public void synthesizeUtilityClass(Builder<?> builder, InternalOptions options) {
if (holders.isEmpty()) {
return;
diff --git a/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java b/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
index 3b2b878..1cf61c0 100644
--- a/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
+++ b/src/main/java/com/android/tools/r8/utils/ProgramClassCollection.java
@@ -9,6 +9,7 @@
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.ir.desugar.InterfaceMethodRewriter;
+import com.android.tools.r8.ir.desugar.Java8MethodRewriter;
import com.android.tools.r8.ir.desugar.LambdaRewriter;
import com.android.tools.r8.ir.desugar.TwrCloseResourceRewriter;
import java.util.List;
@@ -68,6 +69,7 @@
private static boolean assumeClassesAreEqual(DexProgramClass a) {
return LambdaRewriter.hasLambdaClassPrefix(a.type)
+ || Java8MethodRewriter.hasJava8MethodRewritePrefix(a.type)
|| InterfaceMethodRewriter.hasDispatchClassSuffix(a.type)
|| a.type.descriptor.toString().equals(TwrCloseResourceRewriter.UTILITY_CLASS_DESCRIPTOR);
}
diff --git a/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java b/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
index f94d5a5..053ac5c 100644
--- a/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/Java8MethodsTest.java
@@ -4,7 +4,10 @@
package com.android.tools.r8.desugar;
+import com.android.tools.r8.D8TestCompileResult;
import com.android.tools.r8.TestBase;
+import com.android.tools.r8.utils.AndroidApiLevel;
+import java.nio.file.Path;
import org.junit.Before;
import org.junit.Test;
@@ -26,6 +29,62 @@
.assertSuccessWithOutput(expectedOutput);
}
+ @Test
+ public void testD8Merge() throws Exception {
+ String jvmOutput = testForJvm()
+ .addTestClasspath()
+ .run(MergeRun.class).getStdOut();
+
+ // See b/123242448
+ Path zip1 = temp.newFile("first.zip").toPath();
+ Path zip2 = temp.newFile("second.zip").toPath();
+ Path zip3 = temp.newFile("third.zip").toPath();
+
+ D8TestCompileResult result1 =
+ testForD8()
+ .setMinApi(AndroidApiLevel.L)
+ .addProgramClasses(MergeRun.class, MergeInputB.class)
+ .compile()
+ .writeToZip(zip1);
+ D8TestCompileResult result2 =
+ testForD8()
+ .setMinApi(AndroidApiLevel.L)
+ .addProgramClasses(MergeInputA.class)
+ .compile()
+ .writeToZip(zip2);
+
+ testForD8()
+ .addProgramFiles(zip1, zip2)
+ .setMinApi(AndroidApiLevel.L)
+ .compile()
+ .run(MergeRun.class)
+ .assertSuccessWithOutput(jvmOutput);
+ }
+
+
+ static class MergeInputA {
+ public void foo() {
+ System.out.println(Integer.hashCode(42));
+ System.out.println(Double.hashCode(42.0));
+ }
+ }
+
+ static class MergeInputB {
+ public void foo() {
+ System.out.println(Integer.hashCode(43));
+ System.out.println(Double.hashCode(43.0));
+ }
+ }
+
+ static class MergeRun {
+ public static void main(String[] args) {
+ MergeInputA a = new MergeInputA();
+ MergeInputB b = new MergeInputB();
+ a.foo();
+ b.foo();
+ }
+ }
+
static class Java8Methods {
public static void main(String[] args) {
byte[] aBytes = new byte[]{42, 1, -1, Byte.MAX_VALUE, Byte.MIN_VALUE};