Dump Options

dump now dumps various additional settings, including:
- intermediate flag
- no-data-resource flag
- optimizeMulitDexforLinearAlloc flag
- no-desugaring
- main-dex-resources
- proguard-input-map

Change-Id: Id1a8a8de7bb77e2e874e5abf1b2021d38505d303
diff --git a/src/main/java/com/android/tools/r8/BaseCommand.java b/src/main/java/com/android/tools/r8/BaseCommand.java
index 036dd57..893bc64 100644
--- a/src/main/java/com/android/tools/r8/BaseCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCommand.java
@@ -275,14 +275,16 @@
      * @see #addMainDexListFiles(Path...)
      */
     public B addMainDexListFiles(Collection<Path> files) {
-      guard(() -> {
-        try {
-          app.addMainDexListFiles(files);
-        } catch (NoSuchFileException e) {
-          reporter.error(new StringDiagnostic(
-              "Main-dex-ist file does not exist", new PathOrigin(Paths.get(e.getFile()))));
-        }
-      });
+      guard(
+          () -> {
+            try {
+              app.addMainDexListFiles(files);
+            } catch (NoSuchFileException e) {
+              reporter.error(
+                  new StringDiagnostic(
+                      "Main-dex-list file does not exist", new PathOrigin(Paths.get(e.getFile()))));
+            }
+          });
       return self();
     }
 
diff --git a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
index 80dcf13..b12b467 100644
--- a/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
+++ b/src/main/java/com/android/tools/r8/BaseCompilerCommand.java
@@ -109,6 +109,15 @@
     return minApiLevel;
   }
 
+  void dumpBaseCommandOptions(DumpOptions.Builder builder) {
+    builder
+        .setCompilationMode(getMode())
+        .setMinApi(getMinApiLevel())
+        .setOptimizeMultidexForLinearAlloc(isOptimizeMultidexForLinearAlloc())
+        .setThreadCount(getThreadCount())
+        .setDesugarState(getDesugarState());
+  }
+
   /**
    * Get the program consumer that will receive the compilation output.
    *
diff --git a/src/main/java/com/android/tools/r8/D8Command.java b/src/main/java/com/android/tools/r8/D8Command.java
index 3372bc9..501d4ae 100644
--- a/src/main/java/com/android/tools/r8/D8Command.java
+++ b/src/main/java/com/android/tools/r8/D8Command.java
@@ -6,6 +6,7 @@
 import static com.android.tools.r8.utils.InternalOptions.DETERMINISTIC_DEBUGGING;
 
 import com.android.tools.r8.AssertionsConfiguration.AssertionTransformation;
+import com.android.tools.r8.dex.Marker.Tool;
 import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.inspector.Inspector;
@@ -449,7 +450,17 @@
       internal.dumpInputToDirectory = null;
       internal.dumpInputToFile = null;
     }
+    internal.dumpOptions = dumpOptions();
 
     return internal;
   }
+
+  private DumpOptions dumpOptions() {
+    DumpOptions.Builder builder = DumpOptions.builder(Tool.D8);
+    dumpBaseCommandOptions(builder);
+    return builder
+        .setIntermediate(intermediate)
+        .setDesugaredLibraryConfiguration(libraryConfiguration)
+        .build();
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/DumpOptions.java b/src/main/java/com/android/tools/r8/DumpOptions.java
new file mode 100644
index 0000000..cd2ac79
--- /dev/null
+++ b/src/main/java/com/android/tools/r8/DumpOptions.java
@@ -0,0 +1,263 @@
+// Copyright (c) 2020, 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;
+
+import com.android.tools.r8.dex.Marker.Tool;
+import com.android.tools.r8.features.FeatureSplitConfiguration;
+import com.android.tools.r8.ir.desugar.DesugaredLibraryConfiguration;
+import com.android.tools.r8.shaking.ProguardConfiguration;
+import com.android.tools.r8.utils.InternalOptions.DesugarState;
+import com.android.tools.r8.utils.ThreadUtils;
+import java.util.Optional;
+
+@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
+public class DumpOptions {
+
+  // The following keys and values should not be changed to keep the dump utility backward
+  // compatible with previous versions. They are also used by the python script compileDump and
+  // the corresponding CompileDumpCompatR8 java class.
+  private static final String TOOL_KEY = "tool";
+  private static final String MODE_KEY = "mode";
+  private static final String DEBUG_MODE_VALUE = "debug";
+  private static final String RELEASE_MODE_VALUE = "release";
+  private static final String MIN_API_KEY = "min-api";
+  private static final String OPTIMIZE_MULTIDEX_FOR_LINEAR_ALLOC_KEY =
+      "optimize-multidex-for-linear-alloc";
+  private static final String THREAD_COUNT_KEY = "thread-count";
+  private static final String DESUGAR_STATE_KEY = "desugar-state";
+  private static final String INTERMEDIATE_KEY = "intermediate";
+  private static final String INCLUDE_DATA_RESOURCES_KEY = "include-data-resources";
+  private static final String TREE_SHAKING_KEY = "tree-shaking";
+  private static final String MINIFICATION_KEY = "minification";
+  private static final String FORCE_PROGUARD_COMPATIBILITY_KEY = "force-proguard-compatibility";
+
+  private final Tool tool;
+  private final CompilationMode compilationMode;
+  private final int minApi;
+  private final boolean optimizeMultidexForLinearAlloc;
+  private final int threadCount;
+  private final DesugarState desugarState;
+  private final Optional<Boolean> intermediate;
+  private final Optional<Boolean> includeDataResources;
+  private final Optional<Boolean> treeShaking;
+  private final Optional<Boolean> minification;
+  private final Optional<Boolean> forceProguardCompatibility;
+
+  // Dump if present.
+  private final DesugaredLibraryConfiguration desugaredLibraryConfiguration;
+  private final FeatureSplitConfiguration featureSplitConfiguration;
+  private final ProguardConfiguration proguardConfiguration;
+
+  // Reporting only.
+  private final boolean dumpInputToFile;
+
+  private DumpOptions(
+      Tool tool,
+      CompilationMode compilationMode,
+      int minAPI,
+      DesugaredLibraryConfiguration desugaredLibraryConfiguration,
+      boolean optimizeMultidexForLinearAlloc,
+      int threadCount,
+      DesugarState desugarState,
+      Optional<Boolean> intermediate,
+      Optional<Boolean> includeDataResources,
+      Optional<Boolean> treeShaking,
+      Optional<Boolean> minification,
+      Optional<Boolean> forceProguardCompatibility,
+      FeatureSplitConfiguration featureSplitConfiguration,
+      ProguardConfiguration proguardConfiguration,
+      boolean dumpInputToFile) {
+    this.tool = tool;
+    this.compilationMode = compilationMode;
+    this.minApi = minAPI;
+    this.desugaredLibraryConfiguration = desugaredLibraryConfiguration;
+    this.optimizeMultidexForLinearAlloc = optimizeMultidexForLinearAlloc;
+    this.threadCount = threadCount;
+    this.desugarState = desugarState;
+    this.intermediate = intermediate;
+    this.includeDataResources = includeDataResources;
+    this.treeShaking = treeShaking;
+    this.minification = minification;
+    this.forceProguardCompatibility = forceProguardCompatibility;
+    this.featureSplitConfiguration = featureSplitConfiguration;
+    this.proguardConfiguration = proguardConfiguration;
+    this.dumpInputToFile = dumpInputToFile;
+  }
+
+  public String dumpOptions() {
+    StringBuilder builder = new StringBuilder();
+    addDumpEntry(builder, TOOL_KEY, tool.name());
+    // We keep the following values for backward compatibility.
+    addDumpEntry(
+        builder,
+        MODE_KEY,
+        compilationMode == CompilationMode.DEBUG ? DEBUG_MODE_VALUE : RELEASE_MODE_VALUE);
+    addDumpEntry(builder, MIN_API_KEY, minApi);
+    addDumpEntry(builder, OPTIMIZE_MULTIDEX_FOR_LINEAR_ALLOC_KEY, optimizeMultidexForLinearAlloc);
+    if (threadCount != ThreadUtils.NOT_SPECIFIED) {
+      addDumpEntry(builder, THREAD_COUNT_KEY, threadCount);
+    }
+    addDumpEntry(builder, DESUGAR_STATE_KEY, desugarState);
+    addOptionalDumpEntry(builder, INTERMEDIATE_KEY, intermediate);
+    addOptionalDumpEntry(builder, INCLUDE_DATA_RESOURCES_KEY, includeDataResources);
+    addOptionalDumpEntry(builder, TREE_SHAKING_KEY, treeShaking);
+    addOptionalDumpEntry(builder, MINIFICATION_KEY, minification);
+    addOptionalDumpEntry(builder, FORCE_PROGUARD_COMPATIBILITY_KEY, forceProguardCompatibility);
+    return builder.toString();
+  }
+
+  private void addOptionalDumpEntry(StringBuilder builder, String key, Optional<?> optionalValue) {
+    optionalValue.ifPresent(bool -> addDumpEntry(builder, key, bool));
+  }
+
+  private void addDumpEntry(StringBuilder builder, String key, Object value) {
+    builder.append(key).append("=").append(value).append("\n");
+  }
+
+  private boolean hasDesugaredLibraryConfiguration() {
+    return desugaredLibraryConfiguration != null
+        && desugaredLibraryConfiguration
+            != DesugaredLibraryConfiguration.EMPTY_DESUGARED_LIBRARY_CONFIGURATION;
+  }
+
+  public String getDesugaredLibraryJsonSource() {
+    if (hasDesugaredLibraryConfiguration()) {
+      return desugaredLibraryConfiguration.getJsonSource();
+    }
+    return null;
+  }
+
+  public FeatureSplitConfiguration getFeatureSplitConfiguration() {
+    return featureSplitConfiguration;
+  }
+
+  public String getParsedProguardConfiguration() {
+    return proguardConfiguration == null ? null : proguardConfiguration.getParsedConfiguration();
+  }
+
+  public boolean dumpInputToFile() {
+    return dumpInputToFile;
+  }
+
+  public static Builder builder(Tool tool) {
+    return new Builder(tool);
+  }
+
+  public static class Builder {
+    private final Tool tool;
+    private CompilationMode compilationMode;
+    private int minApi;
+    private boolean optimizeMultidexForLinearAlloc;
+    private int threadCount;
+    private DesugarState desugarState;
+    private Optional<Boolean> intermediate = Optional.empty();
+    private Optional<Boolean> includeDataResources = Optional.empty();
+    private Optional<Boolean> treeShaking = Optional.empty();
+    private Optional<Boolean> minification = Optional.empty();
+    private Optional<Boolean> forceProguardCompatibility = Optional.empty();
+    // Dump if present.
+    private DesugaredLibraryConfiguration desugaredLibraryConfiguration;
+    private FeatureSplitConfiguration featureSplitConfiguration;
+    private ProguardConfiguration proguardConfiguration;
+
+    // Reporting only.
+    private boolean dumpInputToFile;
+
+    public Builder(Tool tool) {
+      this.tool = tool;
+    }
+
+    public Builder setCompilationMode(CompilationMode compilationMode) {
+      this.compilationMode = compilationMode;
+      return this;
+    }
+
+    public Builder setMinApi(int minAPI) {
+      this.minApi = minAPI;
+      return this;
+    }
+
+    public Builder setDesugaredLibraryConfiguration(
+        DesugaredLibraryConfiguration desugaredLibraryConfiguration) {
+      this.desugaredLibraryConfiguration = desugaredLibraryConfiguration;
+      return this;
+    }
+
+    public Builder setOptimizeMultidexForLinearAlloc(boolean optimizeMultidexForLinearAlloc) {
+      this.optimizeMultidexForLinearAlloc = optimizeMultidexForLinearAlloc;
+      return this;
+    }
+
+    public Builder setThreadCount(int threadCount) {
+      this.threadCount = threadCount;
+      return this;
+    }
+
+    public Builder setDesugarState(DesugarState desugarState) {
+      this.desugarState = desugarState;
+      return this;
+    }
+
+    public Builder setIntermediate(boolean intermediate) {
+      this.intermediate = Optional.of(intermediate);
+      return this;
+    }
+
+    public Builder setIncludeDataResources(Optional<Boolean> includeDataResources) {
+      this.includeDataResources = includeDataResources;
+      return this;
+    }
+
+    public Builder setForceProguardCompatibility(boolean forceProguardCompatibility) {
+      this.forceProguardCompatibility = Optional.of(forceProguardCompatibility);
+      return this;
+    }
+
+    public Builder setMinification(boolean minification) {
+      this.minification = Optional.of(minification);
+      return this;
+    }
+
+    public Builder setTreeShaking(boolean treeShaking) {
+      this.treeShaking = Optional.of(treeShaking);
+      return this;
+    }
+
+    public Builder setDumpInputToFile(boolean dumpInputToFile) {
+      this.dumpInputToFile = dumpInputToFile;
+      return this;
+    }
+
+    public Builder setFeatureSplitConfiguration(
+        FeatureSplitConfiguration featureSplitConfiguration) {
+      this.featureSplitConfiguration = featureSplitConfiguration;
+      return this;
+    }
+
+    public Builder setProguardConfiguration(ProguardConfiguration proguardConfiguration) {
+      this.proguardConfiguration = proguardConfiguration;
+      return this;
+    }
+
+    public DumpOptions build() {
+      return new DumpOptions(
+          tool,
+          compilationMode,
+          minApi,
+          desugaredLibraryConfiguration,
+          optimizeMultidexForLinearAlloc,
+          threadCount,
+          desugarState,
+          intermediate,
+          includeDataResources,
+          treeShaking,
+          minification,
+          forceProguardCompatibility,
+          featureSplitConfiguration,
+          proguardConfiguration,
+          dumpInputToFile);
+    }
+  }
+}
diff --git a/src/main/java/com/android/tools/r8/L8Command.java b/src/main/java/com/android/tools/r8/L8Command.java
index 8e4bb2a..dce2b21 100644
--- a/src/main/java/com/android/tools/r8/L8Command.java
+++ b/src/main/java/com/android/tools/r8/L8Command.java
@@ -7,6 +7,7 @@
 
 import com.android.tools.r8.AssertionsConfiguration.AssertionTransformation;
 import com.android.tools.r8.ProgramResource.Kind;
+import com.android.tools.r8.dex.Marker.Tool;
 import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.inspector.Inspector;
@@ -196,6 +197,7 @@
       assert internal.threadCount == ThreadUtils.NOT_SPECIFIED;
       internal.threadCount = getThreadCount();
     }
+    internal.dumpOptions = dumpOptions();
 
     return internal;
   }
@@ -383,4 +385,10 @@
     @Override
     public void finished(DiagnosticsHandler handler) {}
   }
+
+  private DumpOptions dumpOptions() {
+    DumpOptions.Builder builder = DumpOptions.builder(Tool.L8);
+    dumpBaseCommandOptions(builder);
+    return builder.setDesugaredLibraryConfiguration(libraryConfiguration).build();
+  }
 }
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index 4a68964..40be618 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -7,6 +7,7 @@
 
 import com.android.tools.r8.AssertionsConfiguration.AssertionTransformation;
 import com.android.tools.r8.ProgramResource.Kind;
+import com.android.tools.r8.dex.Marker.Tool;
 import com.android.tools.r8.errors.DexFileOverflowDiagnostic;
 import com.android.tools.r8.experimental.graphinfo.GraphConsumer;
 import com.android.tools.r8.features.FeatureSplitConfiguration;
@@ -42,6 +43,7 @@
 import java.util.Collection;
 import java.util.List;
 import java.util.Objects;
+import java.util.Optional;
 import java.util.function.BiFunction;
 import java.util.function.BiPredicate;
 import java.util.function.Consumer;
@@ -98,6 +100,7 @@
     private boolean disableMinification = false;
     private boolean disableVerticalClassMerging = false;
     private boolean forceProguardCompatibility = false;
+    private Optional<Boolean> includeDataResources = Optional.empty();
     private StringConsumer proguardMapConsumer = null;
     private StringConsumer proguardUsageConsumer = null;
     private StringConsumer proguardSeedsConsumer = null;
@@ -368,6 +371,7 @@
      */
     @Override
     public Builder setOutput(Path outputPath, OutputMode outputMode, boolean includeDataResources) {
+      this.includeDataResources = Optional.of(includeDataResources);
       return super.setOutput(outputPath, outputMode, includeDataResources);
     }
 
@@ -578,6 +582,7 @@
               configuration.isObfuscating(),
               disableVerticalClassMerging,
               forceProguardCompatibility,
+              includeDataResources,
               proguardMapConsumer,
               proguardUsageConsumer,
               proguardSeedsConsumer,
@@ -667,6 +672,7 @@
   private final boolean enableMinification;
   private final boolean disableVerticalClassMerging;
   private final boolean forceProguardCompatibility;
+  private final Optional<Boolean> includeDataResources;
   private final StringConsumer proguardMapConsumer;
   private final StringConsumer proguardUsageConsumer;
   private final StringConsumer proguardSeedsConsumer;
@@ -741,6 +747,7 @@
       boolean enableMinification,
       boolean disableVerticalClassMerging,
       boolean forceProguardCompatibility,
+      Optional<Boolean> includeDataResources,
       StringConsumer proguardMapConsumer,
       StringConsumer proguardUsageConsumer,
       StringConsumer proguardSeedsConsumer,
@@ -781,6 +788,7 @@
     this.enableMinification = enableMinification;
     this.disableVerticalClassMerging = disableVerticalClassMerging;
     this.forceProguardCompatibility = forceProguardCompatibility;
+    this.includeDataResources = includeDataResources;
     this.proguardMapConsumer = proguardMapConsumer;
     this.proguardUsageConsumer = proguardUsageConsumer;
     this.proguardSeedsConsumer = proguardSeedsConsumer;
@@ -803,6 +811,7 @@
     enableMinification = false;
     disableVerticalClassMerging = false;
     forceProguardCompatibility = false;
+    includeDataResources = null;
     proguardMapConsumer = null;
     proguardUsageConsumer = null;
     proguardSeedsConsumer = null;
@@ -974,6 +983,7 @@
       internal.dumpInputToDirectory = null;
       internal.dumpInputToFile = null;
     }
+    internal.dumpOptions = dumpOptions();
 
     return internal;
   }
@@ -1002,4 +1012,18 @@
       System.out.print(string);
     }
   }
+
+  private DumpOptions dumpOptions() {
+    DumpOptions.Builder builder = DumpOptions.builder(Tool.R8);
+    dumpBaseCommandOptions(builder);
+    return builder
+        .setIncludeDataResources(includeDataResources)
+        .setTreeShaking(getEnableTreeShaking())
+        .setMinification(getEnableMinification())
+        .setForceProguardCompatibility(forceProguardCompatibility)
+        .setFeatureSplitConfiguration(featureSplitConfiguration)
+        .setProguardConfiguration(proguardConfiguration)
+        .setDesugaredLibraryConfiguration(libraryConfiguration)
+        .build();
+  }
 }
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 2f3c56e..b46cd9b 100644
--- a/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
+++ b/src/main/java/com/android/tools/r8/dex/ApplicationReader.java
@@ -184,7 +184,7 @@
     }
     if (dumpOutput != null) {
       timing.begin("ApplicationReader.dump");
-      dumpInputToFile(inputApp, dumpOutput, options);
+      inputApp.dump(dumpOutput, options.dumpOptions, options.reporter, options.dexItemFactory());
       if (cleanDump) {
         Files.delete(dumpOutput);
       }
@@ -230,10 +230,6 @@
     }
   }
 
-  private static void dumpInputToFile(AndroidApp app, Path output, InternalOptions options) {
-    app.dump(output, options);
-  }
-
   private static boolean verifyMainDexOptionsCompatible(
       AndroidApp inputApp, InternalOptions options) {
     if (!options.isGeneratingDex()) {
diff --git a/src/main/java/com/android/tools/r8/features/ClassToFeatureSplitMap.java b/src/main/java/com/android/tools/r8/features/ClassToFeatureSplitMap.java
index 519bd27..b6588df 100644
--- a/src/main/java/com/android/tools/r8/features/ClassToFeatureSplitMap.java
+++ b/src/main/java/com/android/tools/r8/features/ClassToFeatureSplitMap.java
@@ -17,6 +17,7 @@
 import com.android.tools.r8.graph.ProgramDefinition;
 import com.android.tools.r8.graph.ProgramMethod;
 import com.android.tools.r8.utils.InternalOptions;
+import com.android.tools.r8.utils.Reporter;
 import com.google.common.collect.Sets;
 import java.util.IdentityHashMap;
 import java.util.Map;
@@ -39,8 +40,14 @@
 
   public static ClassToFeatureSplitMap createInitialClassToFeatureSplitMap(
       InternalOptions options) {
-    DexItemFactory dexItemFactory = options.dexItemFactory();
-    FeatureSplitConfiguration featureSplitConfiguration = options.featureSplitConfiguration;
+    return createInitialClassToFeatureSplitMap(
+        options.dexItemFactory(), options.featureSplitConfiguration, options.reporter);
+  }
+
+  public static ClassToFeatureSplitMap createInitialClassToFeatureSplitMap(
+      DexItemFactory dexItemFactory,
+      FeatureSplitConfiguration featureSplitConfiguration,
+      Reporter reporter) {
 
     ClassToFeatureSplitMap result = new ClassToFeatureSplitMap();
     if (featureSplitConfiguration == null) {
@@ -58,7 +65,7 @@
             }
           }
         } catch (ResourceException e) {
-          throw options.reporter.fatalError(e.getMessage());
+          throw reporter.fatalError(e.getMessage());
         }
       }
     }
diff --git a/src/main/java/com/android/tools/r8/utils/AndroidApp.java b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
index c426a09..dd80deb 100644
--- a/src/main/java/com/android/tools/r8/utils/AndroidApp.java
+++ b/src/main/java/com/android/tools/r8/utils/AndroidApp.java
@@ -20,6 +20,7 @@
 import com.android.tools.r8.DexFilePerClassFileConsumer;
 import com.android.tools.r8.DexIndexedConsumer;
 import com.android.tools.r8.DirectoryClassFileProvider;
+import com.android.tools.r8.DumpOptions;
 import com.android.tools.r8.FeatureSplit;
 import com.android.tools.r8.OutputMode;
 import com.android.tools.r8.ProgramResource;
@@ -81,13 +82,16 @@
  */
 public class AndroidApp {
 
+  // TODO(b/172887664): Move to DumpOptions and capitalize.
   private static final String dumpVersionFileName = "r8-version";
   private static final String dumpBuildPropertiesFileName = "build.properties";
   private static final String dumpDesugaredLibraryFileName = "desugared-library.json";
+  private static final String dumpMainDexListResourceFileName = "main-dex-list.txt";
   private static final String dumpProgramFileName = "program.jar";
   private static final String dumpClasspathFileName = "classpath.jar";
   private static final String dumpLibraryFileName = "library.jar";
   private static final String dumpConfigFileName = "proguard.config";
+  private static final String dumpInputConfigFileName = "proguard_input.config";
 
   private static Map<FeatureSplit, String> dumpFeatureSplitFileNames(
       FeatureSplitConfiguration featureSplitConfiguration) {
@@ -454,7 +458,7 @@
     return programResourcesMainDescriptor.get(resource);
   }
 
-  public void dump(Path output, InternalOptions options) {
+  public void dump(Path output, DumpOptions options, Reporter reporter, DexItemFactory factory) {
     int nextDexIndex = 0;
     OpenOption[] openOptions =
         new OpenOption[] {StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING};
@@ -462,50 +466,60 @@
       writeToZipStream(
           out, dumpVersionFileName, Version.getVersionString().getBytes(), ZipEntry.DEFLATED);
       writeToZipStream(
-          out,
-          dumpBuildPropertiesFileName,
-          getBuildPropertiesContents(options).getBytes(),
-          ZipEntry.DEFLATED);
-      if (options.desugaredLibraryConfiguration.getJsonSource() != null) {
+          out, dumpBuildPropertiesFileName, options.dumpOptions().getBytes(), ZipEntry.DEFLATED);
+      if (options.getDesugaredLibraryJsonSource() != null) {
         writeToZipStream(
             out,
             dumpDesugaredLibraryFileName,
-            options.desugaredLibraryConfiguration.getJsonSource().getBytes(),
+            options.getDesugaredLibraryJsonSource().getBytes(),
             ZipEntry.DEFLATED);
-        if (options.dumpInputToFile != null) {
-          options.reporter.warning(
+        if (options.dumpInputToFile()) {
+          reporter.warning(
               "Dumping a compilation with desugared library on a file may prevent reproduction,"
                   + " use dumpInputToDirectory property instead.");
         }
       }
-      if (options.getProguardConfiguration() != null) {
-        String proguardConfig = options.getProguardConfiguration().getParsedConfiguration();
+      if (options.getParsedProguardConfiguration() != null) {
+        String proguardConfig = options.getParsedProguardConfiguration();
         writeToZipStream(out, dumpConfigFileName, proguardConfig.getBytes(), ZipEntry.DEFLATED);
       }
+      if (proguardMapInputData != null) {
+        reporter.warning(
+            "Dumping proguard map input data may have side effects due to I/O on Paths.");
+        writeToZipStream(
+            out,
+            dumpInputConfigFileName,
+            proguardMapInputData.getString().getBytes(),
+            ZipEntry.DEFLATED);
+      }
+      if (hasMainDexList()) {
+        List<String> mainDexList = new ArrayList<>();
+        if (hasMainDexListResources()) {
+          reporter.warning(
+              "Dumping main dex list resources may have side effects due to I/O on Paths.");
+          for (StringResource mainDexListResource : getMainDexListResources()) {
+            mainDexList.add(mainDexListResource.getString());
+          }
+        }
+        mainDexList.addAll(getMainDexClasses());
+        String join = StringUtils.join(mainDexList, "\n");
+        writeToZipStream(out, dumpMainDexListResourceFileName, join.getBytes(), ZipEntry.DEFLATED);
+      }
       nextDexIndex =
           dumpProgramResources(
               dumpProgramFileName,
-              dumpFeatureSplitFileNames(options.featureSplitConfiguration),
+              options.getFeatureSplitConfiguration(),
               nextDexIndex,
               out,
-              options);
+              reporter,
+              factory);
       nextDexIndex = dumpClasspathResources(nextDexIndex, out);
       nextDexIndex = dumpLibraryResources(nextDexIndex, out);
     } catch (IOException | ResourceException e) {
-      throw options.reporter.fatalError(new ExceptionDiagnostic(e));
+      throw reporter.fatalError(new ExceptionDiagnostic(e));
     }
   }
 
-  private String getBuildPropertiesContents(InternalOptions options) {
-    return String.join(
-        "\n",
-        ImmutableList.of(
-            "mode=" + (options.debug ? "debug" : "release"),
-            "min-api=" + options.minApiLevel,
-            "tree-shaking=" + options.isTreeShakingEnabled(),
-            "minification=" + options.isMinificationEnabled()));
-  }
-
   private int dumpLibraryResources(int nextDexIndex, ZipOutputStream out)
       throws IOException, ResourceException {
     nextDexIndex =
@@ -547,19 +561,22 @@
 
   private int dumpProgramResources(
       String archiveName,
-      Map<FeatureSplit, String> featureSplitArchiveNames,
+      FeatureSplitConfiguration featureSplitConfiguration,
       int nextDexIndex,
       ZipOutputStream out,
-      InternalOptions options)
+      Reporter reporter,
+      DexItemFactory dexItemFactory)
       throws IOException, ResourceException {
+
+    Map<FeatureSplit, String> featureSplitArchiveNames =
+        dumpFeatureSplitFileNames(featureSplitConfiguration);
     Map<FeatureSplit, ByteArrayOutputStream> featureSplitArchiveByteStreams =
         new IdentityHashMap<>();
     Map<FeatureSplit, ZipOutputStream> featureSplitArchiveOutputStreams = new IdentityHashMap<>();
     try {
-      DexItemFactory dexItemFactory = options.dexItemFactory();
-      FeatureSplitConfiguration featureSplitConfiguration = options.featureSplitConfiguration;
       ClassToFeatureSplitMap classToFeatureSplitMap =
-          ClassToFeatureSplitMap.createInitialClassToFeatureSplitMap(options);
+          ClassToFeatureSplitMap.createInitialClassToFeatureSplitMap(
+              dexItemFactory, featureSplitConfiguration, reporter);
       if (featureSplitConfiguration != null) {
         for (FeatureSplit featureSplit : featureSplitConfiguration.getFeatureSplits()) {
           ByteArrayOutputStream archiveByteStream = new ByteArrayOutputStream();
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 7a3f0d0..c5320a1 100644
--- a/src/main/java/com/android/tools/r8/utils/InternalOptions.java
+++ b/src/main/java/com/android/tools/r8/utils/InternalOptions.java
@@ -11,6 +11,7 @@
 import com.android.tools.r8.DesugarGraphConsumer;
 import com.android.tools.r8.DexFilePerClassFileConsumer;
 import com.android.tools.r8.DexIndexedConsumer;
+import com.android.tools.r8.DumpOptions;
 import com.android.tools.r8.FeatureSplit;
 import com.android.tools.r8.ProgramConsumer;
 import com.android.tools.r8.StringConsumer;
@@ -335,6 +336,9 @@
   // Boolean value indicating that byte code pass through may be enabled.
   public boolean enableCfByteCodePassThrough = false;
 
+  // Contain the contents of the build properties file from the compiler command.
+  public DumpOptions dumpOptions;
+
   // Hidden marker for classes.dex
   private boolean hasMarker = false;
   private Marker marker;
diff --git a/src/test/java/com/android/tools/r8/AndroidAppDumpsTest.java b/src/test/java/com/android/tools/r8/AndroidAppDumpsTest.java
index 441be7c..e144bdc 100644
--- a/src/test/java/com/android/tools/r8/AndroidAppDumpsTest.java
+++ b/src/test/java/com/android/tools/r8/AndroidAppDumpsTest.java
@@ -67,7 +67,7 @@
             .build();
 
     Path dumpFile = temp.newFolder().toPath().resolve("dump.zip");
-    appIn.dump(dumpFile, options);
+    appIn.dump(dumpFile, options.dumpOptions, options.reporter, options.dexItemFactory());
 
     AndroidApp appOut = AndroidApp.builder(options.reporter).addDump(dumpFile).build();
     assertEquals(1, appOut.getClassProgramResourcesForTesting().size());
diff --git a/tools/compiledump.py b/tools/compiledump.py
index 5919e3f..797019b 100755
--- a/tools/compiledump.py
+++ b/tools/compiledump.py
@@ -132,6 +132,14 @@
   def desugared_library_json(self):
     return self.if_exists('desugared-library.json')
 
+  def proguard_input_map(self):
+    if self.if_exists('proguard_input.config'):
+      print "Unimplemented: proguard_input configuration."
+
+  def main_dex_resource(self):
+    if self.if_exists('main-dex-list.txt'):
+      print "Unimplemented: main-dex-list."
+
   def build_properties_file(self):
     return self.if_exists('build.properties')