Forward D8 output classes to R8 compilation in R8 partial

Change-Id: I84a70a6af6bf55629e684a21af972ff80c87256f
diff --git a/src/main/java/com/android/tools/r8/R8Partial.java b/src/main/java/com/android/tools/r8/R8Partial.java
index 281fa12..b8bef68 100644
--- a/src/main/java/com/android/tools/r8/R8Partial.java
+++ b/src/main/java/com/android/tools/r8/R8Partial.java
@@ -7,11 +7,12 @@
 import com.android.tools.r8.diagnostic.R8VersionDiagnostic;
 import com.android.tools.r8.errors.Unreachable;
 import com.android.tools.r8.features.FeatureSplitConfiguration;
+import com.android.tools.r8.graph.DexClasspathClass;
 import com.android.tools.r8.graph.DirectMappedDexApplication;
 import com.android.tools.r8.graph.LazyLoadedDexApplication;
 import com.android.tools.r8.keepanno.ast.KeepDeclaration;
+import com.android.tools.r8.partial.R8PartialD8Input;
 import com.android.tools.r8.partial.R8PartialD8Result;
-import com.android.tools.r8.partial.R8PartialInput;
 import com.android.tools.r8.partial.R8PartialProgramPartioning;
 import com.android.tools.r8.partial.R8PartialSubCompilationConfiguration.R8PartialD8SubCompilationConfiguration;
 import com.android.tools.r8.partial.R8PartialSubCompilationConfiguration.R8PartialR8SubCompilationConfiguration;
@@ -21,6 +22,7 @@
 import com.android.tools.r8.utils.ExceptionUtils;
 import com.android.tools.r8.utils.FeatureSplitConsumers;
 import com.android.tools.r8.utils.ForwardingDiagnosticsHandler;
+import com.android.tools.r8.utils.InternalClasspathOrLibraryClassProvider;
 import com.android.tools.r8.utils.InternalOptions;
 import com.android.tools.r8.utils.InternalProgramClassProvider;
 import com.android.tools.r8.utils.ListUtils;
@@ -67,7 +69,7 @@
         getAndClearFeatureSplitConsumers();
 
     timing.begin("Process input");
-    R8PartialInput input = runProcessInputStep(app, executor);
+    R8PartialD8Input input = runProcessInputStep(app, executor);
 
     timing.end().begin("Run D8");
     R8PartialD8Result d8Result = runD8Step(input, executor);
@@ -77,7 +79,7 @@
     lockFeatureSplitProgramResourceProviders();
 
     timing.begin("Run R8");
-    runR8Step(app, input, d8Result, executor);
+    runR8Step(app, d8Result, executor);
     timing.end();
 
     if (options.isPrintTimesReportingEnabled()) {
@@ -85,14 +87,14 @@
     }
   }
 
-  private R8PartialInput runProcessInputStep(AndroidApp androidApp, ExecutorService executor)
+  private R8PartialD8Input runProcessInputStep(AndroidApp androidApp, ExecutorService executor)
       throws IOException {
     LazyLoadedDexApplication lazyApp =
         new ApplicationReader(androidApp, options, timing).read(executor);
     List<KeepDeclaration> keepDeclarations = lazyApp.getKeepDeclarations();
     DirectMappedDexApplication app = lazyApp.toDirect();
     R8PartialProgramPartioning partioning = R8PartialProgramPartioning.create(app);
-    return new R8PartialInput(
+    return new R8PartialD8Input(
         partioning.getD8Classes(),
         partioning.getR8Classes(),
         app.classpathClasses(),
@@ -100,7 +102,7 @@
         keepDeclarations);
   }
 
-  private R8PartialD8Result runD8Step(R8PartialInput input, ExecutorService executor)
+  private R8PartialD8Result runD8Step(R8PartialD8Input input, ExecutorService executor)
       throws IOException {
     // TODO(b/389039057): This will desugar the entire R8 part. For build speed, look into if some
     //  desugarings can be postponed to the R8 compilation, since we do not desugar dead code in R8.
@@ -130,11 +132,13 @@
         subCompilationConfiguration.getClassToFeatureSplitMap(),
         subCompilationConfiguration.getDexedOutputClasses(),
         subCompilationConfiguration.getDesugaredOutputClasses(),
+        input.getKeepDeclarations(),
+        subCompilationConfiguration.getOutputClasspathClasses(),
+        subCompilationConfiguration.getOutputLibraryClasses(),
         subCompilationConfiguration.getStartupProfile());
   }
 
-  private void runR8Step(
-      AndroidApp app, R8PartialInput input, R8PartialD8Result d8Result, ExecutorService executor)
+  private void runR8Step(AndroidApp app, R8PartialD8Result d8Result, ExecutorService executor)
       throws IOException {
     // Compile R8 input with R8 using the keep rules from trace references.
     DiagnosticsHandler r8DiagnosticsHandler =
@@ -154,6 +158,13 @@
         R8Command.builder(r8DiagnosticsHandler)
             .addProgramResourceProvider(
                 new InternalProgramClassProvider(d8Result.getDesugaredClasses()))
+            .addClasspathResourceProvider(
+                new InternalClasspathOrLibraryClassProvider<>(
+                    DexClasspathClass.toClasspathClasses(d8Result.getDexedClasses())))
+            .addClasspathResourceProvider(
+                new InternalClasspathOrLibraryClassProvider<>(d8Result.getOutputClasspathClasses()))
+            .addLibraryResourceProvider(
+                new InternalClasspathOrLibraryClassProvider<>(d8Result.getOutputLibraryClasses()))
             .enableLegacyFullModeForKeepRules(true)
             .setMinApiLevel(options.getMinApiLevel().getLevel())
             .setMode(options.getCompilationMode())
@@ -185,7 +196,6 @@
             });
       }
     }
-    input.configure(r8Builder);
     r8Builder.validate();
     // TODO(b/391572031): Configure library desugaring.
     R8Command r8Command =
@@ -198,7 +208,7 @@
             d8Result.getArtProfiles(),
             d8Result.getClassToFeatureSplitMap(),
             d8Result.getDexedClasses(),
-            input.getKeepDeclarations(),
+            d8Result.getKeepDeclarations(),
             d8Result.getStartupProfile(),
             timing);
     r8Options.setArtProfileOptions(
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialInput.java b/src/main/java/com/android/tools/r8/partial/R8PartialD8Input.java
similarity index 98%
rename from src/main/java/com/android/tools/r8/partial/R8PartialInput.java
rename to src/main/java/com/android/tools/r8/partial/R8PartialD8Input.java
index 07b713c..5d15c6c 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialInput.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialD8Input.java
@@ -23,7 +23,7 @@
 import java.util.Map;
 import java.util.Set;
 
-public class R8PartialInput {
+public class R8PartialD8Input {
 
   private final Collection<DexProgramClass> d8Classes;
   private final Collection<DexProgramClass> r8Classes;
@@ -31,7 +31,7 @@
   private final Map<DexType, DexLibraryClass> libraryClasses;
   private final List<KeepDeclaration> keepDeclarations;
 
-  public R8PartialInput(
+  public R8PartialD8Input(
       Collection<DexProgramClass> d8Classes,
       Collection<DexProgramClass> r8Classes,
       Collection<DexClasspathClass> classpathClasses,
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialD8Result.java b/src/main/java/com/android/tools/r8/partial/R8PartialD8Result.java
index c4994e7..9ab729a 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialD8Result.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialD8Result.java
@@ -4,10 +4,14 @@
 package com.android.tools.r8.partial;
 
 import com.android.tools.r8.features.ClassToFeatureSplitMap;
+import com.android.tools.r8.graph.DexClasspathClass;
+import com.android.tools.r8.graph.DexLibraryClass;
 import com.android.tools.r8.graph.DexProgramClass;
+import com.android.tools.r8.keepanno.ast.KeepDeclaration;
 import com.android.tools.r8.profile.art.ArtProfileCollection;
 import com.android.tools.r8.profile.startup.profile.StartupProfile;
 import java.util.Collection;
+import java.util.List;
 
 public class R8PartialD8Result {
 
@@ -15,6 +19,9 @@
   private final ClassToFeatureSplitMap classToFeatureSplitMap;
   private final Collection<DexProgramClass> dexedClasses;
   private final Collection<DexProgramClass> desugaredClasses;
+  private final List<KeepDeclaration> keepDeclarations;
+  private final Collection<DexClasspathClass> outputClasspathClasses;
+  private final Collection<DexLibraryClass> outputLibraryClasses;
   private final StartupProfile startupProfile;
 
   public R8PartialD8Result(
@@ -22,11 +29,17 @@
       ClassToFeatureSplitMap classToFeatureSplitMap,
       Collection<DexProgramClass> dexedClasses,
       Collection<DexProgramClass> desugaredClasses,
+      List<KeepDeclaration> keepDeclarations,
+      Collection<DexClasspathClass> outputClasspathClasses,
+      Collection<DexLibraryClass> outputLibraryClasses,
       StartupProfile startupProfile) {
     this.artProfiles = artProfiles;
     this.classToFeatureSplitMap = classToFeatureSplitMap;
     this.dexedClasses = dexedClasses;
     this.desugaredClasses = desugaredClasses;
+    this.keepDeclarations = keepDeclarations;
+    this.outputClasspathClasses = outputClasspathClasses;
+    this.outputLibraryClasses = outputLibraryClasses;
     this.startupProfile = startupProfile;
   }
 
@@ -46,6 +59,18 @@
     return desugaredClasses;
   }
 
+  public List<KeepDeclaration> getKeepDeclarations() {
+    return keepDeclarations;
+  }
+
+  public Collection<DexClasspathClass> getOutputClasspathClasses() {
+    return outputClasspathClasses;
+  }
+
+  public Collection<DexLibraryClass> getOutputLibraryClasses() {
+    return outputLibraryClasses;
+  }
+
   public StartupProfile getStartupProfile() {
     return startupProfile;
   }
diff --git a/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java b/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
index 2e1582d..a0cc036 100644
--- a/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
+++ b/src/main/java/com/android/tools/r8/partial/R8PartialSubCompilationConfiguration.java
@@ -8,6 +8,8 @@
 import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
 import com.android.tools.r8.graph.AppView;
 import com.android.tools.r8.graph.DexClass;
+import com.android.tools.r8.graph.DexClasspathClass;
+import com.android.tools.r8.graph.DexLibraryClass;
 import com.android.tools.r8.graph.DexMember;
 import com.android.tools.r8.graph.DexProgramClass;
 import com.android.tools.r8.graph.DexReference;
@@ -68,6 +70,8 @@
     private ClassToFeatureSplitMap classToFeatureSplitMap;
     private Collection<DexProgramClass> dexedOutputClasses;
     private Collection<DexProgramClass> desugaredOutputClasses;
+    private Collection<DexClasspathClass> outputClasspathClasses;
+    private Collection<DexLibraryClass> outputLibraryClasses;
     private StartupProfile startupProfile;
 
     public R8PartialD8SubCompilationConfiguration(
@@ -96,6 +100,16 @@
       return desugaredOutputClasses;
     }
 
+    public Collection<DexClasspathClass> getOutputClasspathClasses() {
+      assert outputClasspathClasses != null;
+      return outputClasspathClasses;
+    }
+
+    public Collection<DexLibraryClass> getOutputLibraryClasses() {
+      assert outputLibraryClasses != null;
+      return outputLibraryClasses;
+    }
+
     public StartupProfile getStartupProfile() {
       assert startupProfile != null;
       return startupProfile;
@@ -147,6 +161,9 @@
           desugaredOutputClasses.add(clazz);
         }
       }
+      DirectMappedDexApplication app = appView.app().toDirect();
+      outputClasspathClasses = app.classpathClasses();
+      outputLibraryClasses = app.libraryClasses();
       startupProfile = appView.getStartupProfile();
     }
   }
diff --git a/src/main/java/com/android/tools/r8/utils/InternalClasspathOrLibraryClassProvider.java b/src/main/java/com/android/tools/r8/utils/InternalClasspathOrLibraryClassProvider.java
index cb002a6..5229dd4 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalClasspathOrLibraryClassProvider.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalClasspathOrLibraryClassProvider.java
@@ -9,6 +9,7 @@
 import com.android.tools.r8.graph.DexClass;
 import com.android.tools.r8.graph.DexType;
 import java.util.Collection;
+import java.util.IdentityHashMap;
 import java.util.Map;
 import java.util.Set;
 
@@ -17,6 +18,10 @@
 
   private final Map<DexType, T> classes;
 
+  public InternalClasspathOrLibraryClassProvider(Collection<T> classes) {
+    this(MapUtils.transform(classes, IdentityHashMap::new, DexClass::getType));
+  }
+
   public InternalClasspathOrLibraryClassProvider(Map<DexType, T> classes) {
     this.classes = classes;
   }