Add a checksum for library desugaring wrappers
Generate the checksum from the name, as their code does not
change between builds.
They are not synthesized from a program class (but rather a
library class), so the existing way of generating checksums for
synthesized classes cannot be used.
Bug: 142352298
Change-Id: I7128f28eb3802f233be1cb76013eb17777dc6572
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
index d7f3861..ad763d8 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationWriter.java
@@ -37,6 +37,7 @@
import com.android.tools.r8.graph.InnerClassAttribute;
import com.android.tools.r8.graph.ObjectToOffsetMapping;
import com.android.tools.r8.graph.ParameterAnnotationsList;
+import com.android.tools.r8.ir.desugar.DesugaredLibraryWrapperSynthesizer;
import com.android.tools.r8.naming.ClassNameMapper;
import com.android.tools.r8.naming.NamingLens;
import com.android.tools.r8.naming.ProguardMapSupplier;
@@ -218,8 +219,18 @@
if (inputChecksums.containsKey(clazz.getType().descriptor.toASCIIString())) {
continue;
} else {
- throw new CompilationError(clazz + " from " + clazz.origin +
- " has no checksum information while checksum encoding is requested");
+ String name = clazz.toSourceString();
+ if (name.contains(DesugaredLibraryWrapperSynthesizer.TYPE_WRAPPER_SUFFIX)
+ || name.contains(DesugaredLibraryWrapperSynthesizer.VIVIFIED_TYPE_WRAPPER_SUFFIX)) {
+ synthesizedChecksums.put(
+ clazz.getType().descriptor.toASCIIString(), (long) name.hashCode());
+ } else {
+ throw new CompilationError(
+ clazz
+ + " from "
+ + clazz.origin
+ + " has no checksum information while checksum encoding is requested");
+ }
}
}
diff --git a/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java b/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
index 30fd9d3..2ddacd7 100644
--- a/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/corelib/JavaUtilFunctionTest.java
@@ -10,6 +10,8 @@
import com.android.tools.r8.NeverInline;
import com.android.tools.r8.TestParameters;
+import com.android.tools.r8.ir.desugar.DesugaredLibraryWrapperSynthesizer;
+import com.android.tools.r8.utils.AndroidApiLevel;
import com.android.tools.r8.utils.BooleanUtils;
import com.android.tools.r8.utils.StringUtils;
import com.android.tools.r8.utils.codeinspector.ClassSubject;
@@ -65,6 +67,7 @@
.addInnerClasses(JavaUtilFunctionTest.class)
.setMinApi(parameters.getApiLevel())
.enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .setIncludeClassesChecksum(true)
.compile()
.inspect(this::checkRewrittenArguments)
.addDesugaredCoreLibraryRunClassPath(
@@ -100,6 +103,40 @@
.assertSuccessWithOutput(expectedOutput);
}
+ @Test
+ public void testWrapperWithChecksum() throws Exception {
+ KeepRuleConsumer keepRuleConsumer = createKeepRuleConsumer(parameters);
+ testForD8()
+ .addInnerClasses(JavaUtilFunctionTest.class)
+ .setMinApi(parameters.getApiLevel())
+ .enableCoreLibraryDesugaring(parameters.getApiLevel(), keepRuleConsumer)
+ .setIncludeClassesChecksum(true) // Compilation fails if some classes are missing checksum.
+ .compile()
+ .inspect(
+ inspector -> {
+ assertEquals(
+ parameters.getApiLevel().getLevel() >= AndroidApiLevel.N.getLevel() ? 0 : 1,
+ inspector.allClasses().stream()
+ .filter(
+ clazz ->
+ clazz
+ .getFinalName()
+ .contains(DesugaredLibraryWrapperSynthesizer.TYPE_WRAPPER_SUFFIX))
+ .count());
+ assertEquals(
+ parameters.getApiLevel().getLevel() >= AndroidApiLevel.N.getLevel() ? 0 : 1,
+ inspector.allClasses().stream()
+ .filter(
+ clazz ->
+ clazz
+ .getFinalName()
+ .contains(
+ DesugaredLibraryWrapperSynthesizer
+ .VIVIFIED_TYPE_WRAPPER_SUFFIX))
+ .count());
+ });
+ }
+
static class TestClass {
@NeverInline