Throw exception when Dictionary cannot be read

I think it makes more sense to fail when there's a problem with a
dictionary, and it avoids a message that was printed to stderr.

Change-Id: I5f13b9ec4bc54ac174db25c5a6b9baffd8b6c544
diff --git a/src/main/java/com/android/tools/r8/naming/DictionaryReader.java b/src/main/java/com/android/tools/r8/naming/DictionaryReader.java
index 1d05d25..0b26acd 100644
--- a/src/main/java/com/android/tools/r8/naming/DictionaryReader.java
+++ b/src/main/java/com/android/tools/r8/naming/DictionaryReader.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.naming;
 
+import com.android.tools.r8.CompilationException;
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableList.Builder;
 import java.io.BufferedReader;
@@ -51,7 +52,7 @@
     }
   }
 
-  public static ImmutableList<String> readAllNames(Path path) {
+  public static ImmutableList<String> readAllNames(Path path) throws CompilationException {
     if (path != null) {
       Builder<String> namesBuilder = new ImmutableList.Builder<String>();
       try (DictionaryReader reader = new DictionaryReader(path);) {
@@ -61,7 +62,8 @@
           name = reader.readName();
         }
       } catch (IOException e) {
-        System.err.println("Unable to create dictionary from file " + path.toString());
+        throw new CompilationException(
+            "Unable to create dictionary from file " + path.toString(), e);
       }
       return namesBuilder.build();
     } else {
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
index 10daea7..fd08f51 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.shaking;
 
+import com.android.tools.r8.CompilationException;
 import com.android.tools.r8.graph.DexItemFactory;
 import com.android.tools.r8.naming.DictionaryReader;
 import com.android.tools.r8.utils.InternalOptions.KeepAttributeOptions;
@@ -170,7 +171,7 @@
       return keepParameterNames;
     }
 
-    public ProguardConfiguration build() {
+    public ProguardConfiguration build() throws CompilationException {
       return new ProguardConfiguration(
           dexItemFactory,
           injars,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
index 06fa9ed..a6e5703 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.shaking;
 
+import com.android.tools.r8.CompilationException;
 import com.android.tools.r8.dex.Constants;
 import com.android.tools.r8.graph.DexAccessFlags;
 import com.android.tools.r8.graph.DexField;
@@ -76,7 +77,8 @@
     return configurationBuilder;
   }
 
-  public ProguardConfiguration getConfig() throws ProguardRuleParserException {
+  public ProguardConfiguration getConfig()
+      throws ProguardRuleParserException, CompilationException {
     if (configurationBuilder.isKeepParameterNames()
         && configurationBuilder.isObfuscating()) {
       // The flag -keepparameternames has only effect when minifying, so ignore it if we
diff --git a/src/test/java/com/android/tools/r8/ToolHelper.java b/src/test/java/com/android/tools/r8/ToolHelper.java
index 9947e97..a5d0322 100644
--- a/src/test/java/com/android/tools/r8/ToolHelper.java
+++ b/src/test/java/com/android/tools/r8/ToolHelper.java
@@ -586,7 +586,7 @@
 
   public static ProguardConfiguration loadProguardConfiguration(
       DexItemFactory factory, List<Path> configPaths)
-      throws IOException, ProguardRuleParserException {
+      throws IOException, ProguardRuleParserException, CompilationException {
     if (configPaths.isEmpty()) {
       return ProguardConfiguration.defaultConfiguration(factory);
     }
diff --git a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
index f049102..3d65e0d 100644
--- a/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
+++ b/src/test/java/com/android/tools/r8/naming/NamingTestBase.java
@@ -3,6 +3,7 @@
 // BSD-style license that can be found in the LICENSE file.
 package com.android.tools.r8.naming;
 
+import com.android.tools.r8.CompilationException;
 import com.android.tools.r8.ToolHelper;
 import com.android.tools.r8.graph.AppInfoWithSubtyping;
 import com.android.tools.r8.graph.ClassAndMemberPublicizer;
@@ -61,7 +62,7 @@
   }
 
   NamingLens runMinifier(List<Path> configPaths)
-      throws IOException, ProguardRuleParserException, ExecutionException {
+      throws IOException, ProguardRuleParserException, ExecutionException, CompilationException {
     ProguardConfiguration configuration =
         ToolHelper.loadProguardConfiguration(dexItemFactory, configPaths);
     InternalOptions options = new InternalOptions(configuration);
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
index 78fbc8e..fe0b6f6 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -105,7 +105,7 @@
       VALID_PROGUARD_DIR + "target.flags";
 
   @Test
-  public void parse() throws IOException, ProguardRuleParserException {
+  public void parse() throws Exception {
     ProguardConfigurationParser parser;
 
     // Parse from file.
@@ -125,7 +125,7 @@
   }
 
   @Test
-  public void parseMultipleNamePatterns() throws IOException, ProguardRuleParserException {
+  public void parseMultipleNamePatterns() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(MULTIPLE_NAME_PATTERNS_FILE));
     List<ProguardConfigurationRule> rules = parser.getConfig().getRules();
@@ -190,7 +190,7 @@
   }
 
   @Test
-  public void parseAccessFlags() throws IOException, ProguardRuleParserException {
+  public void parseAccessFlags() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(ACCESS_FLAGS_FILE));
     List<ProguardConfigurationRule> rules = parser.getConfig().getRules();
@@ -228,7 +228,7 @@
   }
 
   @Test
-  public void parseWhyAreYouKeeping() throws IOException, ProguardRuleParserException {
+  public void parseWhyAreYouKeeping() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(WHY_ARE_YOU_KEEPING_FILE));
     List<ProguardConfigurationRule> rules = parser.getConfig().getRules();
@@ -241,7 +241,7 @@
   }
 
   @Test
-  public void parseAssumeNoSideEffects() throws IOException, ProguardRuleParserException {
+  public void parseAssumeNoSideEffects() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(ASSUME_NO_SIDE_EFFECTS));
     List<ProguardConfigurationRule> assumeNoSideEffects = parser.getConfig().getRules();
@@ -252,8 +252,7 @@
   }
 
   @Test
-  public void parseAssumeNoSideEffectsWithReturnValue()
-      throws IOException, ProguardRuleParserException {
+  public void parseAssumeNoSideEffectsWithReturnValue() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(ASSUME_NO_SIDE_EFFECTS_WITH_RETURN_VALUE));
     List<ProguardConfigurationRule> assumeNoSideEffects = parser.getConfig().getRules();
@@ -292,8 +291,7 @@
   }
 
   @Test
-  public void parseAssumeValuesWithReturnValue()
-      throws IOException, ProguardRuleParserException {
+  public void parseAssumeValuesWithReturnValue() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(ASSUME_VALUES_WITH_RETURN_VALUE));
     List<ProguardConfigurationRule> assumeValues = parser.getConfig().getRules();
@@ -376,7 +374,7 @@
   }
 
   @Test
-  public void parseDontobfuscate() throws IOException, ProguardRuleParserException {
+  public void parseDontobfuscate() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(DONT_OBFUSCATE));
     ProguardConfiguration config = parser.getConfig();
@@ -384,7 +382,7 @@
   }
 
   @Test
-  public void parseRepackageClassesEmpty() throws IOException, ProguardRuleParserException {
+  public void parseRepackageClassesEmpty() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PACKAGE_OBFUSCATION_1));
     ProguardConfiguration config = parser.getConfig();
@@ -394,7 +392,7 @@
   }
 
   @Test
-  public void parseRepackageClassesNonEmpty() throws IOException, ProguardRuleParserException {
+  public void parseRepackageClassesNonEmpty() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PACKAGE_OBFUSCATION_2));
     ProguardConfiguration config = parser.getConfig();
@@ -404,7 +402,7 @@
   }
 
   @Test
-  public void parseFlattenPackageHierarchyEmpty() throws IOException, ProguardRuleParserException {
+  public void parseFlattenPackageHierarchyEmpty() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PACKAGE_OBFUSCATION_3));
     ProguardConfiguration config = parser.getConfig();
@@ -414,7 +412,7 @@
   }
 
   @Test
-  public void parseFlattenPackageHierarchyNonEmpty() throws IOException, ProguardRuleParserException {
+  public void parseFlattenPackageHierarchyNonEmpty() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PACKAGE_OBFUSCATION_4));
     ProguardConfiguration config = parser.getConfig();
@@ -425,7 +423,7 @@
 
   @Test
   public void flattenPackageHierarchyCannotOverrideRepackageClasses()
-      throws IOException, ProguardRuleParserException {
+      throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PACKAGE_OBFUSCATION_5));
     ProguardConfiguration config = parser.getConfig();
@@ -436,7 +434,7 @@
 
   @Test
   public void repackageClassesOverridesFlattenPackageHierarchy()
-      throws IOException, ProguardRuleParserException {
+      throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PACKAGE_OBFUSCATION_6));
     ProguardConfiguration config = parser.getConfig();
@@ -446,7 +444,7 @@
   }
 
   @Test
-  public void parseApplyMapping() throws IOException, ProguardRuleParserException {
+  public void parseApplyMapping() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(APPLY_MAPPING));
     ProguardConfiguration config = parser.getConfig();
@@ -454,7 +452,7 @@
   }
 
   @Test
-  public void parseApplyMappingWithoutFile() throws IOException, ProguardRuleParserException {
+  public void parseApplyMappingWithoutFile() throws Exception {
     try {
       ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
       parser.parse(Paths.get(APPLY_MAPPING_WITHOUT_FILE));
@@ -465,7 +463,7 @@
   }
 
   @Test
-  public void parseIncluding() throws IOException, ProguardRuleParserException {
+  public void parseIncluding() throws Exception {
     new ProguardConfigurationParser(new DexItemFactory()).parse(Paths.get(INCLUDING));
   }
 
@@ -495,7 +493,7 @@
   }
 
   @Test
-  public void parseLibraryJars() throws IOException, ProguardRuleParserException {
+  public void parseLibraryJars() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     if (!ToolHelper.isLinux() && !ToolHelper.isMac()) {
       parser.parse(Paths.get(LIBRARY_JARS_WIN));
@@ -518,7 +516,7 @@
   }
 
   @Test
-  public void parseSeeds() throws IOException, ProguardRuleParserException {
+  public void parseSeeds() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(SEEDS));
     ProguardConfiguration config = parser.getConfig();
@@ -527,7 +525,7 @@
   }
 
   @Test
-  public void parseSeeds2() throws IOException, ProguardRuleParserException {
+  public void parseSeeds2() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(SEEDS_2));
     ProguardConfiguration config = parser.getConfig();
@@ -536,7 +534,7 @@
   }
 
   @Test
-  public void parseVerbose() throws IOException, ProguardRuleParserException {
+  public void parseVerbose() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(VERBOSE));
     ProguardConfiguration config = parser.getConfig();
@@ -544,13 +542,13 @@
   }
 
   @Test
-  public void parseKeepdirectories() throws IOException, ProguardRuleParserException {
+  public void parseKeepdirectories() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(KEEPDIRECTORIES));
   }
 
   @Test
-  public void parseDontshrink() throws IOException, ProguardRuleParserException {
+  public void parseDontshrink() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(DONT_SHRINK));
     ProguardConfiguration config = parser.getConfig();
@@ -558,49 +556,46 @@
   }
 
   @Test
-  public void parseDontSkipNonPublicLibraryClasses()
-      throws IOException, ProguardRuleParserException {
+  public void parseDontSkipNonPublicLibraryClasses() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(DONT_SKIP_NON_PUBLIC_LIBRARY_CLASSES));
   }
 
   @Test
-  public void parseDontskipnonpubliclibraryclassmembers()
-      throws IOException, ProguardRuleParserException {
+  public void parseDontskipnonpubliclibraryclassmembers() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(DONT_SKIP_NON_PUBLIC_LIBRARY_CLASS_MEMBERS));
   }
 
   @Test
-  public void parseOverloadAggressively()
-      throws IOException, ProguardRuleParserException {
+  public void parseOverloadAggressively() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(OVERLOAD_AGGRESIVELY));
   }
 
   @Test
-  public void parseDontOptimize() throws IOException, ProguardRuleParserException {
+  public void parseDontOptimize() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(DONT_OPTIMIZE));
     ProguardConfiguration config = parser.getConfig();
   }
 
   @Test
-  public void parseDontOptimizeOverridesPasses() throws IOException, ProguardRuleParserException {
+  public void parseDontOptimizeOverridesPasses() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(DONT_OPTIMIZE_OVERRIDES_PASSES));
     ProguardConfiguration config = parser.getConfig();
   }
 
   @Test
-  public void parseOptimizationPasses() throws IOException, ProguardRuleParserException {
+  public void parseOptimizationPasses() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(OPTIMIZATION_PASSES));
     ProguardConfiguration config = parser.getConfig();
   }
 
   @Test
-  public void parseOptimizationPassesError() throws IOException, ProguardRuleParserException {
+  public void parseOptimizationPassesError() throws Exception {
     try {
       ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
       parser.parse(Paths.get(OPTIMIZATION_PASSES_WITHOUT_N));
@@ -622,13 +617,13 @@
   }
 
   @Test
-  public void parseAndskipSingleArgument() throws IOException, ProguardRuleParserException {
+  public void parseAndskipSingleArgument() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PARSE_AND_SKIP_SINGLE_ARGUMENT));
   }
 
   @Test
-  public void parsePrintUsage() throws IOException, ProguardRuleParserException {
+  public void parsePrintUsage() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PRINT_USAGE));
     ProguardConfiguration config = parser.getConfig();
@@ -637,7 +632,7 @@
   }
 
   @Test
-  public void parsePrintUsageToFile() throws IOException, ProguardRuleParserException {
+  public void parsePrintUsageToFile() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(PRINT_USAGE_TO_FILE));
     ProguardConfiguration config = parser.getConfig();
@@ -646,14 +641,13 @@
   }
 
   @Test
-  public void parseTarget()
-      throws IOException, ProguardRuleParserException {
+  public void parseTarget() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     parser.parse(Paths.get(TARGET));
   }
 
   @Test
-  public void parseInvalidKeepClassOption() throws IOException, ProguardRuleParserException {
+  public void parseInvalidKeepClassOption() throws Exception {
     try {
       ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
       Path proguardConfig = writeTextToTempFile(
@@ -680,7 +674,7 @@
   }
 
   @Test
-  public void testRenameSourceFileAttribute() throws IOException, ProguardRuleParserException {
+  public void testRenameSourceFileAttribute() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     String config1 = "-renamesourcefileattribute PG\n";
     String config2 = "-keepattributes SourceFile,SourceDir\n";
@@ -692,7 +686,7 @@
   }
 
   @Test
-  public void testRenameSourceFileAttributeEmpty() throws IOException, ProguardRuleParserException {
+  public void testRenameSourceFileAttributeEmpty() throws Exception {
     ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
     String config1 = "-renamesourcefileattribute\n";
     String config2 = "-keepattributes SourceFile\n";