Allow R8 to dump all of the input to a zipfile

This enables us to easily get inputs for an app from a gradle invocation

Change-Id: I5dc2042d71ec563fd84e6427ff2d1fe1174f1d85
diff --git a/src/main/java/com/android/tools/r8/ClassFileConsumer.java b/src/main/java/com/android/tools/r8/ClassFileConsumer.java
index e124571..807fd6e 100644
--- a/src/main/java/com/android/tools/r8/ClassFileConsumer.java
+++ b/src/main/java/com/android/tools/r8/ClassFileConsumer.java
@@ -160,10 +160,12 @@
         try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(archive, options))) {
           for (ProgramResource resource : resources) {
             assert resource.getClassDescriptors().size() == 1;
-            String className = resource.getClassDescriptors().iterator().next();
-            String entryName = getClassFileName(className);
-            byte[] bytes = ByteStreams.toByteArray(closer.register(resource.getByteStream()));
-            ZipUtils.writeToZipStream(out, entryName, bytes, ZipEntry.DEFLATED);
+            if (resource.getClassDescriptors() != null) {
+              String className = resource.getClassDescriptors().iterator().next();
+              String entryName = getClassFileName(className);
+              byte[] bytes = ByteStreams.toByteArray(closer.register(resource.getByteStream()));
+              ZipUtils.writeToZipStream(out, entryName, bytes, ZipEntry.DEFLATED);
+            }
           }
           for (DataEntryResource dataResource : dataResources) {
             String entryName = dataResource.getName();
diff --git a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
index cfe4d9f..6fddedd 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -10,6 +10,7 @@
 
 import com.android.tools.r8.ClassFileResourceProvider;
 import com.android.tools.r8.DataResourceProvider;
+import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.ProgramResource;
 import com.android.tools.r8.ProgramResource.Kind;
 import com.android.tools.r8.ProgramResourceProvider;
@@ -42,6 +43,7 @@
 import com.android.tools.r8.utils.Timing;
 import java.io.IOException;
 import java.io.InputStream;
+import java.nio.file.Paths;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.List;
@@ -107,6 +109,10 @@
       ProgramClassConflictResolver resolver)
       throws IOException, ExecutionException {
     assert verifyMainDexOptionsCompatible(inputApp, options);
+    if (options.dumpInputToFile != null) {
+      inputApp.writeToZip(Paths.get(options.dumpInputToFile), OutputMode.ClassFile);
+      throw options.reporter.fatalError("Dumped compilation inputs to: " + options.dumpInputToFile);
+    }
     timing.begin("DexApplication.read");
     final LazyLoadedDexApplication.Builder builder =
         DexApplication.builder(options, timing, resolver);
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 687e7da..aaee831 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -68,7 +68,6 @@
   // Set to true to run compilation in a single thread and without randomly shuffling the input.
   // This makes life easier when running R8 in a debugger.
   public static final boolean DETERMINISTIC_DEBUGGING = false;
-
   public enum LineNumberOptimization {
     OFF,
     ON
@@ -176,6 +175,8 @@
   // To print memory one also have to enable printtimes.
   public boolean printMemory = System.getProperty("com.android.tools.r8.printmemory") != null;
 
+  public String dumpInputToFile = System.getProperty("com.android.tools.r8.dumpinputtofile");
+
   // Flag to toggle if DEX code objects should pass-through without IR processing.
   public boolean passthroughDexCode = false;
   // TODO(b/134705306): Currently allow merging dex files resulting from Java 8 library