Merge "Parse Proguard flag -useuniqueclassmembernames"
diff --git a/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java b/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
index 76d7d56..dd15f32 100644
--- a/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
+++ b/src/main/java/com/android/tools/r8/GenerateMainDexListCommand.java
@@ -104,10 +104,10 @@
         ProguardConfigurationParser parser = new ProguardConfigurationParser(factory);
         try {
           parser.parse(mainDexRules);
+          mainDexKeepRules = parser.getConfig().getRules();
         } catch (ProguardRuleParserException e) {
           throw new CompilationException(e.getMessage(), e.getCause());
         }
-        mainDexKeepRules = parser.getConfig().getRules();
       }
 
       return new GenerateMainDexListCommand(
diff --git a/src/main/java/com/android/tools/r8/R8Command.java b/src/main/java/com/android/tools/r8/R8Command.java
index e237cf6..b860de4 100644
--- a/src/main/java/com/android/tools/r8/R8Command.java
+++ b/src/main/java/com/android/tools/r8/R8Command.java
@@ -205,10 +205,10 @@
         ProguardConfigurationParser parser = new ProguardConfigurationParser(factory);
         try {
           parser.parse(mainDexRules);
+          mainDexKeepRules = parser.getConfig().getRules();
         } catch (ProguardRuleParserException e) {
           throw new CompilationException(e.getMessage(), e.getCause());
         }
-        mainDexKeepRules = parser.getConfig().getRules();
       }
       ProguardConfiguration configuration;
       if (proguardConfigs.isEmpty()) {
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 d0c5478..c3436c7 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
@@ -42,6 +42,7 @@
     private Path obfuscationDictionary;
     private Path classObfuscationDictionary;
     private Path packageObfuscationDictionary;
+    private boolean useUniqueClassMemberNames;
 
     private Builder(DexItemFactory dexItemFactory) {
       this.dexItemFactory = dexItemFactory;
@@ -85,6 +86,10 @@
       this.obfuscating = obfuscate;
     }
 
+    boolean isObfuscating() {
+      return obfuscating;
+    }
+
     public void setShrinking(boolean shrinking) {
       this.shrinking = shrinking;
     }
@@ -145,6 +150,14 @@
       this.packageObfuscationDictionary = packageObfuscationDictionary;
     }
 
+    public void setUseUniqueClassMemberNames(boolean useUniqueClassMemberNames) {
+      this.useUniqueClassMemberNames = useUniqueClassMemberNames;
+    }
+
+    boolean isUseUniqueClassMemberNames() {
+      return useUniqueClassMemberNames;
+    }
+
     public ProguardConfiguration build() {
       return new ProguardConfiguration(
           dexItemFactory,
@@ -169,7 +182,8 @@
           seedFile,
           DictionaryReader.readAllNames(obfuscationDictionary),
           DictionaryReader.readAllNames(classObfuscationDictionary),
-          DictionaryReader.readAllNames(packageObfuscationDictionary));
+          DictionaryReader.readAllNames(packageObfuscationDictionary),
+          useUniqueClassMemberNames);
     }
   }
 
@@ -196,6 +210,7 @@
   private final ImmutableList<String> obfuscationDictionary;
   private final ImmutableList<String> classObfuscationDictionary;
   private final ImmutableList<String> packageObfuscationDictionary;
+  private boolean useUniqueClassMemberNames;
 
   private ProguardConfiguration(
       DexItemFactory factory,
@@ -220,7 +235,8 @@
       Path seedFile,
       ImmutableList<String> obfuscationDictionary,
       ImmutableList<String> classObfuscationDictionary,
-      ImmutableList<String> packageObfuscationDictionary) {
+      ImmutableList<String> packageObfuscationDictionary,
+      boolean useUniqueClassMemberNames) {
     this.dexItemFactory = factory;
     this.injars = ImmutableList.copyOf(injars);
     this.libraryjars = ImmutableList.copyOf(libraryjars);
@@ -244,6 +260,7 @@
     this.obfuscationDictionary = obfuscationDictionary;
     this.classObfuscationDictionary = classObfuscationDictionary;
     this.packageObfuscationDictionary = packageObfuscationDictionary;
+    this.useUniqueClassMemberNames = useUniqueClassMemberNames;
   }
 
   /**
@@ -345,6 +362,10 @@
     return packageObfuscationDictionary;
   }
 
+  public boolean isUseUniqueClassMemberNames() {
+    return useUniqueClassMemberNames;
+  }
+
   public static ProguardConfiguration defaultConfiguration(DexItemFactory dexItemFactory) {
     return new DefaultProguardConfiguration(dexItemFactory);
   }
@@ -372,9 +393,10 @@
           ImmutableList.of(ProguardKeepRule.defaultKeepAllRule()),
           false                 /* printSeeds */,
           null                  /* seedFile */,
-          ImmutableList.of()     /* obfuscationDictionary */,
-          ImmutableList.of()     /* classObfuscationDictionary */,
-          ImmutableList.of()     /* packageObfuscationDictionary */);
+          ImmutableList.of()    /* obfuscationDictionary */,
+          ImmutableList.of()    /* classObfuscationDictionary */,
+          ImmutableList.of()    /* packageObfuscationDictionary */,
+          false                 /* useUniqueClassMemberNames*/);
     }
 
     @Override
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 cc1120c..aacf129 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -77,7 +77,14 @@
     return configurationBuilder;
   }
 
-  public ProguardConfiguration getConfig() {
+  public ProguardConfiguration getConfig() throws ProguardRuleParserException {
+    if (configurationBuilder.isUseUniqueClassMemberNames()
+        && configurationBuilder.isObfuscating()) {
+      // The flag -useuniqueulassmembernames has only effect when minifying, so ignore it if we
+      // are not.
+      throw new ProguardRuleParserException("-useuniqueulassmembernames is not supported");
+    }
+
     return configurationBuilder.build();
   }
 
@@ -252,6 +259,8 @@
       } else if (acceptString("alwaysinline")) {
         ProguardAlwaysInlineRule rule = parseAlwaysInlineRule();
         configurationBuilder.addRule(rule);
+      } else if (acceptString("useuniqueclassmembernames")) {
+        configurationBuilder.setUseUniqueClassMemberNames(true);
       } else {
         throw parseError("Unknown option");
       }
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardRuleParserException.java b/src/main/java/com/android/tools/r8/shaking/ProguardRuleParserException.java
index 0fb2787..23c0c2e 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardRuleParserException.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardRuleParserException.java
@@ -4,6 +4,10 @@
 package com.android.tools.r8.shaking;
 
 public class ProguardRuleParserException extends Exception {
+  public ProguardRuleParserException(String message) {
+    super(message);
+  }
+
   public ProguardRuleParserException(String message, String snippet) {
     this(message, snippet, null);
   }
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 a47ee57..31e0556 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -621,4 +621,39 @@
       assertTrue(e.getMessage().contains("Expected list element at "));
     }
   }
+
+  @Test
+  public void parseUseUniqueClassMemberNames() throws Exception {
+    try {
+      ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
+      parser.parse(new ProguardConfigurationSourceStrings(ImmutableList.of(
+          "-useuniqueclassmembernames"
+      )));
+      parser.getConfig();
+      fail();
+    } catch (ProguardRuleParserException e) {
+      assertTrue(e.getMessage().contains("-useuniqueulassmembernames is not supported"));
+    }
+  }
+
+  @Test
+  public void parseUseUniqueClassMemberNamesWithoutMinification() throws Exception {
+    ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
+    parser.parse(new ProguardConfigurationSourceStrings(ImmutableList.of(
+        "-useuniqueclassmembernames",
+        "-dontobfuscate"
+    )));
+    ProguardConfiguration config = parser.getConfig();
+    assertTrue(config.isUseUniqueClassMemberNames());
+
+    parser = new ProguardConfigurationParser(new DexItemFactory());
+    parser.parse(new ProguardConfigurationSourceStrings(ImmutableList.of(
+        "-useuniqueclassmembernames"
+    )));
+    parser.parse(new ProguardConfigurationSourceStrings(ImmutableList.of(
+        "-dontobfuscate"
+    )));
+    config = parser.getConfig();
+    assertTrue(config.isUseUniqueClassMemberNames());
+  }
 }