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()) {