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