Fix dumping of input files

We would not get the classes that did not have descriptors (from class files)

Change-Id: Iddf96269feddf3e086f4db8f642fb335fa7626a1
diff --git a/src/main/java/com/android/tools/r8/ClassFileConsumer.java b/src/main/java/com/android/tools/r8/ClassFileConsumer.java
index 807fd6e..f940c29 100644
--- a/src/main/java/com/android/tools/r8/ClassFileConsumer.java
+++ b/src/main/java/com/android/tools/r8/ClassFileConsumer.java
@@ -17,6 +17,7 @@
 import java.nio.file.OpenOption;
 import java.nio.file.Path;
 import java.nio.file.StandardOpenOption;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 import java.util.zip.ZipEntry;
@@ -160,12 +161,11 @@
         try (ZipOutputStream out = new ZipOutputStream(Files.newOutputStream(archive, options))) {
           for (ProgramResource resource : resources) {
             assert resource.getClassDescriptors().size() == 1;
-            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);
-            }
+            Iterator<String> iterator = resource.getClassDescriptors().iterator();
+            String className = 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 5629efe..d6a9696 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -7,10 +7,11 @@
 import static com.android.tools.r8.graph.ClassKind.LIBRARY;
 import static com.android.tools.r8.graph.ClassKind.PROGRAM;
 import static com.android.tools.r8.utils.ExceptionUtils.unwrapExecutionException;
+import static com.android.tools.r8.utils.InternalOptions.ASM_VERSION;
 
+import com.android.tools.r8.ClassFileConsumer;
 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;
@@ -41,6 +42,8 @@
 import com.android.tools.r8.utils.StringDiagnostic;
 import com.android.tools.r8.utils.ThreadUtils;
 import com.android.tools.r8.utils.Timing;
+import com.google.common.collect.ImmutableSet;
+import com.google.common.io.ByteStreams;
 import java.io.IOException;
 import java.io.InputStream;
 import java.nio.file.Paths;
@@ -54,6 +57,7 @@
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.stream.Collectors;
+import org.objectweb.asm.ClassVisitor;
 
 public class ApplicationReader {
 
@@ -109,7 +113,7 @@
       throws IOException, ExecutionException {
     assert verifyMainDexOptionsCompatible(inputApp, options);
     if (options.dumpInputToFile != null) {
-      inputApp.writeToZip(Paths.get(options.dumpInputToFile), OutputMode.ClassFile);
+      dumpInputToFile();
       throw options.reporter.fatalError("Dumped compilation inputs to: " + options.dumpInputToFile);
     }
     timing.begin("DexApplication.read");
@@ -146,6 +150,69 @@
     return builder.build();
   }
 
+  private void dumpInputToFile() throws IOException  {
+    List<ProgramResource> programResourcesWithDescriptors = new ArrayList<>();
+    try {
+      for (ProgramResourceProvider programResourceProvider : inputApp
+          .getProgramResourceProviders()) {
+        for (ProgramResource programResource : programResourceProvider.getProgramResources()) {
+          if (programResource.getKind() != Kind.CF) {
+            continue;
+          }
+          try (InputStream inputStream = programResource.getByteStream()) {
+            byte[] bytes = ByteStreams.toByteArray(inputStream);
+            String descriptor = extractClassInternalType(bytes);
+            programResourcesWithDescriptors.add(
+                ProgramResource.fromBytes(
+                    programResource.getOrigin(),
+                    programResource.getKind(),
+                    bytes,
+                    ImmutableSet.of(descriptor)));
+          }
+        }
+      }
+      ClassFileConsumer.ArchiveConsumer.writeResources(
+          Paths.get(options.dumpInputToFile),
+          programResourcesWithDescriptors, inputApp.getDataEntryResourcesForTesting());
+    } catch (ResourceException e) {
+      options.reporter.fatalError("Failed to write input:" + e.getMessage());
+    }
+  }
+
+  private static String extractClassInternalType(byte[] bytes) throws IOException {
+    class ClassNameExtractor extends ClassVisitor {
+      private String className;
+
+      private ClassNameExtractor() {
+        super(ASM_VERSION);
+      }
+
+      @Override
+      public void visit(
+          int version,
+          int access,
+          String name,
+          String signature,
+          String superName,
+          String[] interfaces) {
+        className = name;
+      }
+
+      String getDescriptor() {
+        return "L" + className + ";";
+      }
+    }
+
+    org.objectweb.asm.ClassReader reader = new org.objectweb.asm.ClassReader(bytes);
+    ClassNameExtractor extractor = new ClassNameExtractor();
+    reader.accept(
+        extractor,
+        org.objectweb.asm.ClassReader.SKIP_CODE
+            | org.objectweb.asm.ClassReader.SKIP_DEBUG
+            | org.objectweb.asm.ClassReader.SKIP_FRAMES);
+    return extractor.getDescriptor();
+  }
+
   private static boolean verifyMainDexOptionsCompatible(
       AndroidApp inputApp, InternalOptions options) {
     if (!options.isGeneratingDex()) {