Specify API surface of DexSplitter

DexSplitter and FeatureClassMapping are public API and should be
annotated with @Keep and marked final.

DexSplitter.Options is public API, but DexSplitter.FeatureJar is not.
As a result, make addFeatureJar(FeatureJar) private and getFeatureJars()
package-private.

FeatureClassMapping.fromJarFiles() takes a List<FeatureJar> and is
needed from a different package of R8, but is not public API, and
therefore it is placed in a static inner FeatureClassMapping.Internal
class (which is not annotated with @Keep).

Also replace DexSplitter.Reporter by DefaultDiagnosticsHandler.

Change-Id: I7fc53083968763de285fadb83f2f50b8f7c479da
diff --git a/src/main/java/com/android/tools/r8/dexsplitter/DexSplitter.java b/src/main/java/com/android/tools/r8/dexsplitter/DexSplitter.java
index f452cf1..b0a5a3c 100644
--- a/src/main/java/com/android/tools/r8/dexsplitter/DexSplitter.java
+++ b/src/main/java/com/android/tools/r8/dexsplitter/DexSplitter.java
@@ -8,8 +8,8 @@
 import com.android.tools.r8.D8Command;
 import com.android.tools.r8.DexIndexedConsumer;
 import com.android.tools.r8.DexSplitterHelper;
-import com.android.tools.r8.Diagnostic;
 import com.android.tools.r8.DiagnosticsHandler;
+import com.android.tools.r8.Keep;
 import com.android.tools.r8.utils.AbortException;
 import com.android.tools.r8.utils.DefaultDiagnosticsHandler;
 import com.android.tools.r8.utils.ExceptionUtils;
@@ -24,44 +24,14 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public class DexSplitter {
+@Keep
+public final class DexSplitter {
 
   private static final String DEFAULT_OUTPUT_DIR = "output";
   private static final String DEFAULT_BASE_NAME = "base";
 
   private static final boolean PRINT_ARGS = false;
 
-  public static class Reporter implements DiagnosticsHandler {
-
-    private final DiagnosticsHandler handler = new DefaultDiagnosticsHandler();
-    private boolean reportedErrors = false;
-
-    public RuntimeException fatal(Diagnostic error) {
-      error(error);
-      throw new AbortException();
-    }
-
-    public boolean hasReportedErrors() {
-      return reportedErrors;
-    }
-
-    @Override
-    public void error(Diagnostic error) {
-      handler.error(error);
-      reportedErrors = true;
-    }
-
-    @Override
-    public void warning(Diagnostic warning) {
-      handler.warning(warning);
-    }
-
-    @Override
-    public void info(Diagnostic info) {
-      handler.info(info);
-    }
-  }
-
   public static class FeatureJar {
     private String jar;
     private String outputName;
@@ -94,8 +64,9 @@
 
   }
 
-  public static class Options {
-    private final Reporter reporter = new Reporter();
+  @Keep
+  public static final class Options {
+    private final DiagnosticsHandler diagnosticsHandler = new DefaultDiagnosticsHandler();
     private List<String> inputArchives = new ArrayList<>();
     private List<FeatureJar> featureJars = new ArrayList<>();
     private String baseOutputName = DEFAULT_BASE_NAME;
@@ -103,8 +74,8 @@
     private String featureSplitMapping;
     private String proguardMap;
 
-    public Reporter getReporter() {
-      return reporter;
+    public DiagnosticsHandler getDiagnosticsHandler() {
+      return diagnosticsHandler;
     }
 
     public String getOutput() {
@@ -143,7 +114,7 @@
       inputArchives.add(inputArchive);
     }
 
-    protected void addFeatureJar(FeatureJar featureJar) {
+    private void addFeatureJar(FeatureJar featureJar) {
       featureJars.add(featureJar);
     }
 
@@ -159,13 +130,13 @@
       return ImmutableList.copyOf(inputArchives);
     }
 
-    public ImmutableList<FeatureJar> getFeatureJars() {
+    ImmutableList<FeatureJar> getFeatureJars() {
       return ImmutableList.copyOf(featureJars);
     }
 
     // Shorthand error messages.
     public void error(String msg) {
-      reporter.error(new StringDiagnostic(msg));
+      diagnosticsHandler.error(new StringDiagnostic(msg));
     }
   }
 
@@ -231,11 +202,11 @@
       throws FeatureMappingException {
     if (options.getFeatureSplitMapping() != null) {
       return FeatureClassMapping.fromSpecification(
-          Paths.get(options.getFeatureSplitMapping()), options.getReporter());
+          Paths.get(options.getFeatureSplitMapping()), options.getDiagnosticsHandler());
     }
     assert !options.getFeatureJars().isEmpty();
-    return FeatureClassMapping.fromJarFiles(
-        options.getFeatureJars(), options.getBaseOutputName(), options.getReporter());
+    return FeatureClassMapping.Internal.fromJarFiles(
+        options.getFeatureJars(), options.getBaseOutputName(), options.getDiagnosticsHandler());
   }
 
   private static void run(String[] args)
@@ -246,16 +217,20 @@
 
   public static void run(Options options)
       throws FeatureMappingException, CompilationFailedException {
+    boolean errors = false;
     if (options.getInputArchives().isEmpty()) {
+      errors = true;
       options.error("Need at least one --input");
     }
     if (options.getFeatureSplitMapping() == null && options.getFeatureJars().isEmpty()) {
+      errors = true;
       options.error("You must supply a feature split mapping or feature jars");
     }
     if (options.getFeatureSplitMapping() != null && !options.getFeatureJars().isEmpty()) {
+      errors = true;
       options.error("You can't supply both a feature split mapping and feature jars");
     }
-    if (options.getReporter().hasReportedErrors()) {
+    if (errors) {
       throw new AbortException();
     }
 
diff --git a/src/main/java/com/android/tools/r8/utils/FeatureClassMapping.java b/src/main/java/com/android/tools/r8/utils/FeatureClassMapping.java
index 8e84935..31dc439 100644
--- a/src/main/java/com/android/tools/r8/utils/FeatureClassMapping.java
+++ b/src/main/java/com/android/tools/r8/utils/FeatureClassMapping.java
@@ -4,8 +4,8 @@
 package com.android.tools.r8.utils;
 
 import com.android.tools.r8.ArchiveClassFileProvider;
+import com.android.tools.r8.DiagnosticsHandler;
 import com.android.tools.r8.Keep;
-import com.android.tools.r8.dexsplitter.DexSplitter;
 import com.android.tools.r8.dexsplitter.DexSplitter.FeatureJar;
 import com.android.tools.r8.origin.PathOrigin;
 import java.io.IOException;
@@ -40,7 +40,7 @@
  * placement tool.
  */
 @Keep
-public class FeatureClassMapping {
+public final class FeatureClassMapping {
 
   HashMap<String, String> parsedRules = new HashMap<>(); // Already parsed rules.
   boolean usesOnlyExactMappings = true;
@@ -80,17 +80,18 @@
   }
 
   public static FeatureClassMapping fromSpecification(Path file) throws FeatureMappingException {
-    return fromSpecification(file, new DexSplitter.Reporter());
+    return fromSpecification(file, new DefaultDiagnosticsHandler());
   }
 
-  public static FeatureClassMapping fromSpecification(Path file, DexSplitter.Reporter reporter)
+  public static FeatureClassMapping fromSpecification(Path file, DiagnosticsHandler reporter)
       throws FeatureMappingException {
     FeatureClassMapping mapping = new FeatureClassMapping();
     List<String> lines = null;
     try {
       lines = FileUtils.readAllLines(file);
     } catch (IOException e) {
-      throw reporter.fatal(new ExceptionDiagnostic(e, new SpecificationOrigin(file)));
+      reporter.error(new ExceptionDiagnostic(e, new SpecificationOrigin(file)));
+      throw new AbortException();
     }
     for (int i = 0; i < lines.size(); i++) {
       String line = lines.get(i);
@@ -99,33 +100,33 @@
     return mapping;
   }
 
-  public static FeatureClassMapping fromJarFiles(List<FeatureJar> featureJars, String baseName)
-      throws FeatureMappingException {
-    return fromJarFiles(featureJars, baseName, new DexSplitter.Reporter());
-  }
+  public static class Internal {
 
-  public static FeatureClassMapping fromJarFiles(
-      List<FeatureJar> featureJars, String baseName, DexSplitter.Reporter reporter)
-      throws FeatureMappingException {
-    FeatureClassMapping mapping = new FeatureClassMapping();
-    if (mapping.baseName != null) {
-      mapping.baseName = baseName;
-    }
-    for (FeatureJar featureJar : featureJars) {
-      Path jarPath = Paths.get(featureJar.getJar());
-      ArchiveClassFileProvider provider = null;
-      try {
-        provider = new ArchiveClassFileProvider(jarPath);
-      } catch (IOException e) {
-        throw reporter.fatal(new ExceptionDiagnostic(e, new JarFileOrigin(jarPath)));
+    public static FeatureClassMapping fromJarFiles(
+        List<FeatureJar> featureJars, String baseName, DiagnosticsHandler reporter)
+        throws FeatureMappingException {
+      FeatureClassMapping mapping = new FeatureClassMapping();
+      if (mapping.baseName != null) {
+        mapping.baseName = baseName;
       }
-      for (String javaDescriptor : provider.getClassDescriptors()) {
+      for (FeatureJar featureJar : featureJars) {
+        Path jarPath = Paths.get(featureJar.getJar());
+        ArchiveClassFileProvider provider = null;
+        try {
+          provider = new ArchiveClassFileProvider(jarPath);
+        } catch (IOException e) {
+          reporter.error(new ExceptionDiagnostic(e, new JarFileOrigin(jarPath)));
+          throw new AbortException();
+        }
+        for (String javaDescriptor : provider.getClassDescriptors()) {
           String javaType = DescriptorUtils.descriptorToJavaType(javaDescriptor);
           mapping.addMapping(javaType, featureJar.getOutputName());
+        }
       }
+      assert mapping.usesOnlyExactMappings;
+      return mapping;
     }
-    assert mapping.usesOnlyExactMappings;
-    return mapping;
+
   }
 
   private FeatureClassMapping() {}