Read the app once while converting specification

- Remove appView creation
- Remove a lot of dead code

Bug: 221224178
Change-Id: I69a982c9a8fbdad87b908f1c426829492cce9b62
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAmender.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAmender.java
index bd146e9..62f6e56 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAmender.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibraryAmender.java
@@ -4,11 +4,14 @@
 
 package com.android.tools.r8.ir.desugar.desugaredlibrary;
 
+import com.android.tools.r8.androidapi.ComputedApiLevel;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexDefinitionSupplier;
 import com.android.tools.r8.graph.DexEncodedMethod;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.MethodAccessFlags;
+import com.android.tools.r8.utils.Reporter;
 import java.util.Map;
 
 /**
@@ -18,21 +21,34 @@
  */
 public class DesugaredLibraryAmender {
 
-  private final AppView<?> appView;
+  private final DexDefinitionSupplier definitions;
+  private final Reporter reporter;
+  private final ComputedApiLevel minAPILevel;
 
   public static void run(AppView<?> appView) {
-    run(appView, appView.options().machineDesugaredLibrarySpecification.getAmendLibraryMethods());
+    run(
+        appView,
+        appView.options().reporter,
+        appView.computedMinApiLevel(),
+        appView.options().machineDesugaredLibrarySpecification.getAmendLibraryMethods());
   }
 
-  public static void run(AppView<?> appView, Map<DexMethod, MethodAccessFlags> amendLibrary) {
+  public static void run(
+      DexDefinitionSupplier definitions,
+      Reporter reporter,
+      ComputedApiLevel minAPILevel,
+      Map<DexMethod, MethodAccessFlags> amendLibrary) {
     if (amendLibrary.isEmpty()) {
       return;
     }
-    new DesugaredLibraryAmender(appView).run(amendLibrary);
+    new DesugaredLibraryAmender(definitions, reporter, minAPILevel).run(amendLibrary);
   }
 
-  private DesugaredLibraryAmender(AppView<?> appView) {
-    this.appView = appView;
+  private DesugaredLibraryAmender(
+      DexDefinitionSupplier definitions, Reporter reporter, ComputedApiLevel minAPILevel) {
+    this.definitions = definitions;
+    this.reporter = reporter;
+    this.minAPILevel = minAPILevel;
   }
 
   private void run(Map<DexMethod, MethodAccessFlags> amendLibrary) {
@@ -40,17 +56,14 @@
   }
 
   private void amendLibraryMethod(DexMethod method, MethodAccessFlags methodAccessFlags) {
-    DexClass dexClass = appView.contextIndependentDefinitionFor(method.getHolderType());
+    DexClass dexClass = definitions.contextIndependentDefinitionFor(method.getHolderType());
     if (dexClass == null || !dexClass.isLibraryClass()) {
       // Consider just throwing an error.
-      appView
-          .options()
-          .reporter
-          .warning(
-              "Desugared library: Cannot amend library method "
-                  + method
-                  + " because the holder is not a library class"
-                  + (dexClass == null ? "(null)." : "."));
+      reporter.warning(
+          "Desugared library: Cannot amend library method "
+              + method
+              + " because the holder is not a library class"
+              + (dexClass == null ? "(null)." : "."));
       return;
     }
     if (dexClass.lookupMethod(method) != null) {
@@ -61,7 +74,7 @@
             .setMethod(method)
             .setAccessFlags(methodAccessFlags)
             .setCode(null)
-            .setApiLevelForDefinition(appView.computedMinApiLevel())
+            .setApiLevelForDefinition(minAPILevel)
             .build();
     dexClass.getMethodCollection().addMethod(encodedMethod);
   }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibrarySpecification.java
index e284e54..a76d426 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/DesugaredLibrarySpecification.java
@@ -4,8 +4,6 @@
 
 package com.android.tools.r8.ir.desugar.desugaredlibrary;
 
-import com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification.HumanDesugaredLibrarySpecification;
-import com.android.tools.r8.ir.desugar.desugaredlibrary.legacyspecification.LegacyDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
@@ -25,14 +23,6 @@
     return false;
   }
 
-  default LegacyDesugaredLibrarySpecification asLegacyDesugaredLibrarySpecification() {
-    return null;
-  }
-
-  default HumanDesugaredLibrarySpecification asHumanDesugaredLibrarySpecification() {
-    return null;
-  }
-
   boolean isEmpty();
 
   boolean isLibraryCompilation();
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecification.java
index 5f08201..f9aadb2 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/humanspecification/HumanDesugaredLibrarySpecification.java
@@ -3,11 +3,6 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.ir.desugar.desugaredlibrary.humanspecification;
 
-import com.android.tools.r8.graph.AppView;
-import com.android.tools.r8.graph.DexClassAndMethod;
-import com.android.tools.r8.graph.DexEncodedMethod;
-import com.android.tools.r8.graph.DexMethod;
-import com.android.tools.r8.graph.DexType;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.DesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineDesugaredLibrarySpecification;
 import com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion.HumanToMachineSpecificationConverter;
@@ -18,8 +13,6 @@
 import java.io.IOException;
 import java.nio.file.Path;
 import java.util.List;
-import java.util.Map;
-import java.util.Set;
 
 public class HumanDesugaredLibrarySpecification implements DesugaredLibrarySpecification {
 
@@ -51,11 +44,6 @@
     return true;
   }
 
-  @Override
-  public HumanDesugaredLibrarySpecification asHumanDesugaredLibrarySpecification() {
-    return this;
-  }
-
   public boolean supportAllCallbacksFromLibrary() {
     return topLevelFlags.supportAllCallbacksFromLibrary();
   }
@@ -87,61 +75,6 @@
     return topLevelFlags.getIdentifier();
   }
 
-  public Map<String, String> getRewritePrefix() {
-    return rewritingFlags.getRewritePrefix();
-  }
-
-  public boolean hasEmulatedLibraryInterfaces() {
-    return !getEmulateLibraryInterface().isEmpty();
-  }
-
-  public Map<DexType, DexType> getEmulateLibraryInterface() {
-    return rewritingFlags.getEmulatedInterfaces();
-  }
-
-  // If the method is retargeted, answers the retargeted method, else null.
-  public DexMethod retargetMethod(DexEncodedMethod method, AppView<?> appView) {
-    Map<DexMethod, DexType> retargetCoreLibMember = rewritingFlags.getRetargetMethod();
-    DexType dexType = retargetCoreLibMember.get(method.getReference());
-    if (dexType != null) {
-      return appView
-          .dexItemFactory()
-          .createMethod(
-              dexType,
-              appView.dexItemFactory().prependHolderToProto(method.getReference()),
-              method.getName());
-    }
-    return null;
-  }
-
-  public DexMethod retargetMethod(DexClassAndMethod method, AppView<?> appView) {
-    return retargetMethod(method.getDefinition(), appView);
-  }
-
-  public Map<DexMethod, DexType> getRetargetCoreLibMember() {
-    return rewritingFlags.getRetargetMethod();
-  }
-
-  public Map<DexType, DexType> getBackportCoreLibraryMember() {
-    return rewritingFlags.getLegacyBackport();
-  }
-
-  public Map<DexType, DexType> getCustomConversions() {
-    return rewritingFlags.getCustomConversions();
-  }
-
-  public Set<DexType> getWrapperConversions() {
-    return rewritingFlags.getWrapperConversions();
-  }
-
-  public Set<DexMethod> getDontRewriteInvocation() {
-    return rewritingFlags.getDontRewriteInvocation();
-  }
-
-  public Set<DexType> getDontRetargetLibMember() {
-    return rewritingFlags.getDontRetarget();
-  }
-
   @Override
   public List<String> getExtraKeepRules() {
     return topLevelFlags.getExtraKeepRules();
@@ -159,12 +92,7 @@
   @Override
   public MachineDesugaredLibrarySpecification toMachineSpecification(
       InternalOptions options, AndroidApp app, Timing timing) throws IOException {
-    return new HumanToMachineSpecificationConverter(timing)
-        .convert(
-            this,
-            isLibraryCompilation() ? app.getProgramResourceProviders() : null,
-            app.getLibraryResourceProviders(),
-            options);
+    return new HumanToMachineSpecificationConverter(timing).convert(this, app, options);
   }
 
   @Override
@@ -172,6 +100,6 @@
       InternalOptions options, Path library, Path desugaredJDKLib, Timing timing)
       throws IOException {
     return new HumanToMachineSpecificationConverter(timing)
-        .convert(this, isLibraryCompilation() ? desugaredJDKLib : null, library, options);
+        .convertForTesting(this, desugaredJDKLib, library, options);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/legacyspecification/LegacyDesugaredLibrarySpecification.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/legacyspecification/LegacyDesugaredLibrarySpecification.java
index e48a6d0..6db6566 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/legacyspecification/LegacyDesugaredLibrarySpecification.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/legacyspecification/LegacyDesugaredLibrarySpecification.java
@@ -15,7 +15,6 @@
 import com.android.tools.r8.utils.AndroidApiLevel;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.Pair;
 import com.android.tools.r8.utils.Timing;
 import java.io.IOException;
 import java.nio.file.Path;
@@ -48,11 +47,6 @@
     return true;
   }
 
-  @Override
-  public LegacyDesugaredLibrarySpecification asLegacyDesugaredLibrarySpecification() {
-    return this;
-  }
-
   public LegacyTopLevelFlags getTopLevelFlags() {
     return topLevelFlags;
   }
@@ -84,18 +78,6 @@
     return topLevelFlags.getIdentifier();
   }
 
-  public Map<String, String> getRewritePrefix() {
-    return rewritingFlags.getRewritePrefix();
-  }
-
-  public boolean hasEmulatedLibraryInterfaces() {
-    return !getEmulateLibraryInterface().isEmpty();
-  }
-
-  public Map<DexType, DexType> getEmulateLibraryInterface() {
-    return rewritingFlags.getEmulateLibraryInterface();
-  }
-
   // If the method is retargeted, answers the retargeted method, else null.
   public DexMethod retargetMethod(DexEncodedMethod method, AppView<?> appView) {
     Map<DexString, Map<DexType, DexType>> retargetCoreLibMember =
@@ -116,14 +98,6 @@
     return retargetMethod(method.getDefinition(), appView);
   }
 
-  public Map<DexString, Map<DexType, DexType>> getRetargetCoreLibMember() {
-    return rewritingFlags.getRetargetCoreLibMember();
-  }
-
-  public Map<DexType, DexType> getBackportCoreLibraryMember() {
-    return rewritingFlags.getBackportCoreLibraryMember();
-  }
-
   public Map<DexType, DexType> getCustomConversions() {
     return rewritingFlags.getCustomConversions();
   }
@@ -132,13 +106,6 @@
     return rewritingFlags.getWrapperConversions();
   }
 
-  public List<Pair<DexType, DexString>> getDontRewriteInvocation() {
-    return rewritingFlags.getDontRewriteInvocation();
-  }
-
-  public Set<DexType> getDontRetargetLibMember() {
-    return rewritingFlags.getDontRetargetLibMember();
-  }
 
   @Override
   public List<String> getExtraKeepRules() {
@@ -154,7 +121,7 @@
   public MachineDesugaredLibrarySpecification toMachineSpecification(
       InternalOptions options, AndroidApp app, Timing timing) throws IOException {
     return new LegacyToHumanSpecificationConverter(timing)
-        .convert(this, app.getLibraryResourceProviders(), options)
+        .convert(this, app, options)
         .toMachineSpecification(options, app, timing);
   }
 
@@ -163,7 +130,7 @@
       InternalOptions options, Path library, Path desugaredJDKLib, Timing timing)
       throws IOException {
     return new LegacyToHumanSpecificationConverter(timing)
-        .convert(this, library, options)
+        .convertForTesting(this, desugaredJDKLib, library, options)
         .toMachineSpecification(options, library, desugaredJDKLib, timing);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/AppForSpecConversion.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/AppForSpecConversion.java
new file mode 100644
index 0000000..45f9dae
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/AppForSpecConversion.java
@@ -0,0 +1,71 @@
+// Copyright (c) 2022, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion;
+
+import com.android.tools.r8.ClassFileResourceProvider;
+import com.android.tools.r8.ProgramResourceProvider;
+import com.android.tools.r8.dex.ApplicationReader;
+import com.android.tools.r8.graph.DexApplication;
+import com.android.tools.r8.utils.AndroidApp;
+import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.ThreadUtils;
+import com.android.tools.r8.utils.Timing;
+import java.io.IOException;
+import java.nio.file.Path;
+import java.util.concurrent.ExecutorService;
+
+public class AppForSpecConversion {
+  static DexApplication readApp(
+      AndroidApp inputApp, InternalOptions options, boolean libraryCompilation, Timing timing)
+      throws IOException {
+    timing.begin("Read App");
+    AndroidApp.Builder builder = AndroidApp.builder();
+    for (ClassFileResourceProvider classFileResourceProvider :
+        inputApp.getLibraryResourceProviders()) {
+      builder.addLibraryResourceProvider(classFileResourceProvider);
+    }
+    if (libraryCompilation) {
+      for (ProgramResourceProvider programResourceProvider :
+          inputApp.getProgramResourceProviders()) {
+        builder.addProgramResourceProvider(programResourceProvider);
+      }
+    }
+    DexApplication app = internalReadApp(builder.build(), options, timing);
+    timing.end();
+    return app;
+  }
+
+  static DexApplication readAppForTesting(
+      Path desugaredJDKLib,
+      Path androidLib,
+      InternalOptions options,
+      boolean libraryCompilation,
+      Timing timing)
+      throws IOException {
+    timing.begin("Read App for testing");
+    assert !libraryCompilation || desugaredJDKLib != null;
+    AndroidApp.Builder builder = AndroidApp.builder();
+    if (libraryCompilation) {
+      builder.addProgramFile(desugaredJDKLib);
+    }
+    AndroidApp inputApp = builder.addLibraryFile(androidLib).build();
+    DexApplication app = internalReadApp(inputApp, options, timing);
+    timing.end();
+    return app;
+  }
+
+  private static DexApplication internalReadApp(
+      AndroidApp inputApp, InternalOptions options, Timing timing) throws IOException {
+    timing.begin("Internal Read App");
+    ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
+    ExecutorService executorService = ThreadUtils.getExecutorService(options);
+    assert !options.ignoreJavaLibraryOverride;
+    options.ignoreJavaLibraryOverride = true;
+    DexApplication app = applicationReader.read(executorService);
+    options.ignoreJavaLibraryOverride = false;
+    timing.end();
+    return app;
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
index f7189fb..32c2400 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/HumanToMachineSpecificationConverter.java
@@ -4,12 +4,9 @@
 
 package com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion;
 
-import com.android.tools.r8.ClassFileResourceProvider;
-import com.android.tools.r8.ProgramResourceProvider;
-import com.android.tools.r8.dex.ApplicationReader;
+import com.android.tools.r8.androidapi.ComputedApiLevel;
 import com.android.tools.r8.graph.AppInfo;
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
-import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexMethod;
 import com.android.tools.r8.graph.DexProto;
@@ -26,7 +23,7 @@
 import com.android.tools.r8.ir.desugar.desugaredlibrary.machinespecification.MachineTopLevelFlags;
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
-import com.android.tools.r8.utils.ThreadUtils;
+import com.android.tools.r8.utils.Reporter;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.Sets;
 import java.io.IOException;
@@ -34,11 +31,11 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Set;
-import java.util.concurrent.ExecutorService;
 
 public class HumanToMachineSpecificationConverter {
 
-  private AppView<?> appView;
+  private AppInfoWithClassHierarchy appInfo;
+  private Reporter reporter;
   private final Set<DexType> missingCustomConversions = Sets.newIdentityHashSet();
   private final Timing timing;
 
@@ -47,55 +44,30 @@
   }
 
   public MachineDesugaredLibrarySpecification convert(
-      HumanDesugaredLibrarySpecification humanSpec,
-      List<ProgramResourceProvider> desugaredJDKLib,
-      List<ClassFileResourceProvider> library,
-      InternalOptions options)
+      HumanDesugaredLibrarySpecification humanSpec, AndroidApp inputApp, InternalOptions options)
       throws IOException {
-    timing.begin("Human to machine convert");
-    assert !humanSpec.isLibraryCompilation() || desugaredJDKLib != null;
-    AndroidApp.Builder builder = AndroidApp.builder();
-    for (ClassFileResourceProvider classFileResourceProvider : library) {
-      builder.addLibraryResourceProvider(classFileResourceProvider);
-    }
-    if (humanSpec.isLibraryCompilation()) {
-      for (ProgramResourceProvider programResourceProvider : desugaredJDKLib) {
-        builder.addProgramResourceProvider(programResourceProvider);
-      }
-    }
-    MachineDesugaredLibrarySpecification machineSpec =
-        internalConvert(humanSpec, builder.build(), options);
-    timing.end();
-    return machineSpec;
+    DexApplication app =
+        AppForSpecConversion.readApp(inputApp, options, humanSpec.isLibraryCompilation(), timing);
+    return convert(humanSpec, app);
   }
 
-  public MachineDesugaredLibrarySpecification convert(
+  public MachineDesugaredLibrarySpecification convertForTesting(
       HumanDesugaredLibrarySpecification humanSpec,
       Path desugaredJDKLib,
       Path androidLib,
       InternalOptions options)
       throws IOException {
-    timing.begin("Human to machine convert");
-    assert !humanSpec.isLibraryCompilation() || desugaredJDKLib != null;
-    AndroidApp.Builder builder = AndroidApp.builder();
-    if (humanSpec.isLibraryCompilation()) {
-      builder.addProgramFile(desugaredJDKLib);
-    }
-    AndroidApp inputApp = builder.addLibraryFile(androidLib).build();
-    MachineDesugaredLibrarySpecification machineSpec =
-        internalConvert(humanSpec, inputApp, options);
-    timing.end();
-    return machineSpec;
+    DexApplication app =
+        AppForSpecConversion.readAppForTesting(
+            desugaredJDKLib, androidLib, options, humanSpec.isLibraryCompilation(), timing);
+    return convert(humanSpec, app);
   }
 
-  private MachineDesugaredLibrarySpecification internalConvert(
-      HumanDesugaredLibrarySpecification humanSpec, AndroidApp inputApp, InternalOptions options)
-      throws IOException {
-    timing.begin("internal convert");
-    DexApplication app = readApp(inputApp, options);
-    timing.begin("appView creation");
-    appView = AppView.createForD8(AppInfo.createInitialAppInfo(app));
-    timing.end();
+  private MachineDesugaredLibrarySpecification convert(
+      HumanDesugaredLibrarySpecification humanSpec, DexApplication app) {
+    timing.begin("Human to machine convert");
+    reporter = app.options.reporter;
+    appInfo = AppInfoWithClassHierarchy.createForDesugaring(AppInfo.createInitialAppInfo(app));
     LibraryValidator.validate(
         app,
         humanSpec.isLibraryCompilation(),
@@ -122,9 +94,9 @@
   private MachineRewritingFlags convertRewritingFlags(
       String synthesizedPrefix, HumanRewritingFlags rewritingFlags) {
     timing.begin("convert rewriting flags");
-    AppInfoWithClassHierarchy appInfo = appView.appInfoForDesugaring();
     MachineRewritingFlags.Builder builder = MachineRewritingFlags.builder();
-    DesugaredLibraryAmender.run(appView, rewritingFlags.getAmendLibraryMethod());
+    DesugaredLibraryAmender.run(
+        appInfo, reporter, ComputedApiLevel.unknown(), rewritingFlags.getAmendLibraryMethod());
     rewritingFlags.getAmendLibraryMethod().forEach(builder::amendLibraryMethod);
     new HumanToMachineRetargetConverter(appInfo)
         .convertRetargetFlags(rewritingFlags, builder, this::warnMissingReferences);
@@ -171,18 +143,6 @@
     builder.putCustomConversion(type, new CustomConversionDescriptor(toMethod, fromMethod));
   }
 
-  private DexApplication readApp(AndroidApp inputApp, InternalOptions options) throws IOException {
-    timing.begin("Read app");
-    ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
-    ExecutorService executorService = ThreadUtils.getExecutorService(options);
-    assert !options.ignoreJavaLibraryOverride;
-    options.ignoreJavaLibraryOverride = true;
-    DexApplication app = applicationReader.read(executorService);
-    options.ignoreJavaLibraryOverride = false;
-    timing.end();
-    return app;
-  }
-
   void warnMissingReferences(String message, Set<? extends DexReference> missingReferences) {
     List<DexReference> memberList = new ArrayList<>(missingReferences);
     memberList.sort(DexReference::compareTo);
@@ -199,6 +159,6 @@
     if (memberList.isEmpty()) {
       return;
     }
-    appView.options().reporter.warning("Specification conversion: " + message + memberList);
+    reporter.warning("Specification conversion: " + message + memberList);
   }
 }
diff --git a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
index 13306e4..47ef9e3 100644
--- a/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
+++ b/src/main/java/com/android/tools/r8/ir/desugar/desugaredlibrary/specificationconversion/LegacyToHumanSpecificationConverter.java
@@ -4,10 +4,8 @@
 
 package com.android.tools.r8.ir.desugar.desugaredlibrary.specificationconversion;
 
-import com.android.tools.r8.ClassFileResourceProvider;
 import com.android.tools.r8.StringConsumer;
 import com.android.tools.r8.StringResource;
-import com.android.tools.r8.dex.ApplicationReader;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.DexApplication;
 import com.android.tools.r8.graph.DexClass;
@@ -35,7 +33,6 @@
 import com.android.tools.r8.utils.AndroidApp;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.Pair;
-import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.Timing;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableMap;
@@ -46,7 +43,6 @@
 import java.util.ArrayList;
 import java.util.List;
 import java.util.Map;
-import java.util.concurrent.ExecutorService;
 
 public class LegacyToHumanSpecificationConverter {
 
@@ -59,7 +55,10 @@
   }
 
   public void convertAllAPILevels(
-      StringResource inputSpecification, Path androidLib, StringConsumer output)
+      StringResource inputSpecification,
+      Path desugaredJDKLib,
+      Path androidLib,
+      StringConsumer output)
       throws IOException {
     InternalOptions options = new InternalOptions();
     MultiAPILevelLegacyDesugaredLibrarySpecification legacySpec =
@@ -67,19 +66,21 @@
                 options.dexItemFactory(), options.reporter)
             .parseMultiLevelConfiguration(inputSpecification);
     MultiAPILevelHumanDesugaredLibrarySpecification humanSpec =
-        convertAllAPILevels(legacySpec, androidLib, options);
+        convertAllAPILevels(legacySpec, desugaredJDKLib, androidLib, options);
     MultiAPILevelHumanDesugaredLibrarySpecificationJsonExporter.export(humanSpec, output);
   }
 
   public MultiAPILevelHumanDesugaredLibrarySpecification convertAllAPILevels(
       MultiAPILevelLegacyDesugaredLibrarySpecification legacySpec,
+      Path desugaredJDKLib,
       Path androidLib,
       InternalOptions options)
       throws IOException {
     timing.begin("Legacy to human all API convert");
     Origin origin = legacySpec.getOrigin();
-    AndroidApp androidApp = AndroidApp.builder().addLibraryFile(androidLib).build();
-    DexApplication app = readApp(androidApp, options);
+    DexApplication app =
+        AppForSpecConversion.readAppForTesting(desugaredJDKLib, androidLib, options, true, timing);
+
     HumanTopLevelFlags humanTopLevelFlags = convertTopLevelFlags(legacySpec.getTopLevelFlags());
     Int2ObjectArrayMap<HumanRewritingFlags> commonFlags =
         convertRewritingFlagMap(legacySpec.getCommonFlags(), app, origin);
@@ -100,36 +101,29 @@
   }
 
   public HumanDesugaredLibrarySpecification convert(
+      LegacyDesugaredLibrarySpecification legacySpec, AndroidApp inputApp, InternalOptions options)
+      throws IOException {
+    DexApplication app =
+        AppForSpecConversion.readApp(inputApp, options, legacySpec.isLegacy(), timing);
+    return convert(legacySpec, app, options);
+  }
+
+  public HumanDesugaredLibrarySpecification convertForTesting(
       LegacyDesugaredLibrarySpecification legacySpec,
-      List<ClassFileResourceProvider> library,
+      Path desugaredJDKLib,
+      Path androidLib,
       InternalOptions options)
       throws IOException {
-    timing.begin("Legacy to human convert");
-    AndroidApp.Builder builder = AndroidApp.builder();
-    for (ClassFileResourceProvider classFileResourceProvider : library) {
-      builder.addLibraryResourceProvider(classFileResourceProvider);
-    }
-    HumanDesugaredLibrarySpecification humanSpec =
-        internalConvert(legacySpec, builder.build(), options);
-    timing.end();
-    return humanSpec;
+    DexApplication app =
+        AppForSpecConversion.readAppForTesting(
+            desugaredJDKLib, androidLib, options, legacySpec.isLibraryCompilation(), timing);
+    return convert(legacySpec, app, options);
   }
 
   public HumanDesugaredLibrarySpecification convert(
-      LegacyDesugaredLibrarySpecification legacySpec, Path androidLib, InternalOptions options)
+      LegacyDesugaredLibrarySpecification legacySpec, DexApplication app, InternalOptions options)
       throws IOException {
-    timing.begin("Legacy to human convert");
-    AndroidApp androidApp = AndroidApp.builder().addLibraryFile(androidLib).build();
-    HumanDesugaredLibrarySpecification humanSpec = internalConvert(legacySpec, androidApp, options);
-    timing.end();
-    return humanSpec;
-  }
-
-  public HumanDesugaredLibrarySpecification internalConvert(
-      LegacyDesugaredLibrarySpecification legacySpec, AndroidApp inputApp, InternalOptions options)
-      throws IOException {
-    timing.begin("internal convert");
-    DexApplication app = readApp(inputApp, options);
+    timing.begin("Legacy to Human convert");
     LibraryValidator.validate(
         app,
         legacySpec.isLibraryCompilation(),
@@ -202,15 +196,6 @@
     builder.retargetMethod(source, target);
   }
 
-  private DexApplication readApp(AndroidApp inputApp, InternalOptions options) throws IOException {
-    timing.begin("Read app");
-    ApplicationReader applicationReader = new ApplicationReader(inputApp, options, timing);
-    ExecutorService executorService = ThreadUtils.getExecutorService(options);
-    DexApplication app = applicationReader.read(executorService);
-    timing.end();
-    return app;
-  }
-
   private Int2ObjectArrayMap<HumanRewritingFlags> convertRewritingFlagMap(
       Int2ObjectMap<LegacyRewritingFlags> libFlags, DexApplication app, Origin origin) {
     Int2ObjectArrayMap<HumanRewritingFlags> map = new Int2ObjectArrayMap<>();
@@ -222,7 +207,6 @@
       LegacyRewritingFlags flags, DexApplication app, Origin origin) {
     timing.begin("Convert rewriting flags");
     HumanRewritingFlags.Builder builder = HumanRewritingFlags.builder(app.options.reporter, origin);
-
     flags
         .getRewritePrefix()
         .forEach((prefix, rewritten) -> rewritePrefix(builder, prefix, rewritten));
@@ -231,11 +215,9 @@
     flags.getCustomConversions().forEach(builder::putCustomConversion);
     flags.getDontRetargetLibMember().forEach(builder::addDontRetargetLibMember);
     flags.getWrapperConversions().forEach(builder::addWrapperConversion);
-    timing.begin("Convert retarget");
     flags
         .getRetargetCoreLibMember()
         .forEach((name, typeMap) -> convertRetargetCoreLibMember(builder, app, name, typeMap));
-    timing.end();
     flags
         .getDontRewriteInvocation()
         .forEach(pair -> convertDontRewriteInvocation(builder, app, pair));
diff --git a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
index df07564..f107b2a 100644
--- a/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
+++ b/src/test/java/com/android/tools/r8/desugar/desugaredlibrary/specification/ConvertExportReadTest.java
@@ -59,7 +59,11 @@
                 StringResource.fromFile(ToolHelper.getDesugarLibJsonForTesting()));
 
     MultiAPILevelHumanDesugaredLibrarySpecification humanSpec1 =
-        converter.convertAllAPILevels(spec, ToolHelper.getAndroidJar(31), options);
+        converter.convertAllAPILevels(
+            spec,
+            ToolHelper.getDesugarJDKLibs(),
+            ToolHelper.getAndroidJar(getRequiredCompilationAPILevel()),
+            options);
 
     Box<String> json = new Box<>();
     MultiAPILevelHumanDesugaredLibrarySpecificationJsonExporter.export(