Vary Java 8 rewriting using InternalOptions methods

This removes the need to ensure that the highest-supported version is reported in InternalOptions and instead defers to InternalOptions for whether each semantic group of methods requires rewriting.

Bug: 130408977
Test: Java8MethodsTest
Change-Id: I28e8d64d2c36647cc1a8d235a4fe0a77b4928227
diff --git a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
index bfdbd88..2c768116 100644
--- a/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/conversion/IRConverter.java
@@ -179,7 +179,7 @@
             ? new TwrCloseResourceRewriter(appView, this)
             : null;
     this.java8MethodRewriter =
-        (options.enableDesugaring && !options.canUseJava8Methods())
+        options.enableDesugaring
             ? new Java8MethodRewriter(appView, this)
             : null;
     this.lambdaMerger = options.enableLambdaMerging ? new LambdaMerger(appView) : null;
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 36eabbe..1998f12 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
@@ -30,7 +30,6 @@
 import com.android.tools.r8.ir.desugar.Java8MethodRewriter.RewritableMethods.MethodGenerator;
 import com.android.tools.r8.ir.synthetic.TemplateMethodCode;
 import com.android.tools.r8.origin.SynthesizedOrigin;
-import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.DescriptorUtils;
 import com.android.tools.r8.utils.InternalOptions;
 import com.google.common.collect.Sets;
@@ -60,10 +59,14 @@
     this.appView = appView;
     this.converter = converter;
     this.factory = appView.dexItemFactory();
-    this.rewritableMethods = new RewritableMethods(factory, appView.options().minApiLevel);
+    this.rewritableMethods = new RewritableMethods(factory, appView.options());
   }
 
   public void desugar(IRCode code) {
+    if (rewritableMethods.isEmpty()) {
+      return; // Nothing to do!
+    }
+
     InstructionIterator iterator = code.instructionIterator();
     while (iterator.hasNext()) {
       Instruction instruction = iterator.next();
@@ -497,16 +500,20 @@
     private final Map<DexString, Map<DexString, Map<DexProto, MethodGenerator>>> rewritable =
         new HashMap<>();
 
-    public RewritableMethods(DexItemFactory factory, int minApiLevel) {
-      if (minApiLevel < AndroidApiLevel.N.getLevel()) {
-        initializeAndroidNMethods(factory);
+    public RewritableMethods(DexItemFactory factory, InternalOptions options) {
+      if (!options.canUseJava8SignedOperations()) {
+        initializeJava8SignedOperations(factory);
       }
-      if (minApiLevel < AndroidApiLevel.O.getLevel()) {
-        initializeAndroidOMethods(factory);
+      if (!options.canUseJava8UnsignedOperations()) {
+        initializeJava8UnsignedOperations(factory);
       }
     }
 
-    private void initializeAndroidNMethods(DexItemFactory factory) {
+    boolean isEmpty() {
+      return rewritable.isEmpty();
+    }
+
+    private void initializeJava8SignedOperations(DexItemFactory factory) {
       // Byte
       DexString clazz = factory.boxedByteDescriptor;
       // int Byte.hashCode(byte i)
@@ -680,7 +687,7 @@
           .put(proto, new MethodGenerator(CharacterMethods::hashCodeCode, clazz, method, proto));
     }
 
-    private void initializeAndroidOMethods(DexItemFactory factory) {
+    private void initializeJava8UnsignedOperations(DexItemFactory factory) {
       DexString clazz = factory.boxedLongDescriptor;
 
       // long Long.divideUnsigned(long a, long b)
diff --git a/src/main/java/com/android/tools/r8/utils/InternalOptions.java b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
index 29d2bcf..d227afd 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -666,9 +666,11 @@
     return isGeneratingClassFiles() || hasMinApi(AndroidApiLevel.K);
   }
 
-  public boolean canUseJava8Methods() {
-    // This value must be set to the highest API level of all methods we desugar. The implementation
-    // will conditionally desugar based on the specified minimum API level.
+  public boolean canUseJava8SignedOperations() {
+    return hasMinApi(AndroidApiLevel.N);
+  }
+
+  public boolean canUseJava8UnsignedOperations() {
     return hasMinApi(AndroidApiLevel.O);
   }