Revise -dontwarn [class_filter] to use ProguardClassNameList.
Bug: 36799092
Change-Id: Ib700430c35651bb2b9c5ebb810da94d2c90d043d
diff --git a/src/main/java/com/android/tools/r8/R8.java b/src/main/java/com/android/tools/r8/R8.java
index c6fcc22..39e0342 100644
--- a/src/main/java/com/android/tools/r8/R8.java
+++ b/src/main/java/com/android/tools/r8/R8.java
@@ -31,8 +31,8 @@
import com.android.tools.r8.shaking.DiscardedChecker;
import com.android.tools.r8.shaking.Enqueuer;
import com.android.tools.r8.shaking.MainDexListBuilder;
+import com.android.tools.r8.shaking.ProguardClassNameList;
import com.android.tools.r8.shaking.ProguardRuleParserException;
-import com.android.tools.r8.shaking.ProguardTypeMatcher;
import com.android.tools.r8.shaking.ProguardTypeMatcher.MatchSpecificType;
import com.android.tools.r8.shaking.ReasonPrinter;
import com.android.tools.r8.shaking.RootSetBuilder;
@@ -153,15 +153,15 @@
}
private Set<DexType> filterMissingClasses(Set<DexType> missingClasses,
- Set<ProguardTypeMatcher> dontWarnPatterns) {
+ ProguardClassNameList dontWarnPatterns) {
Set<DexType> result = new HashSet<>(missingClasses);
- for (ProguardTypeMatcher matcher : dontWarnPatterns) {
+ dontWarnPatterns.forEachTypeMatcher(matcher -> {
if (matcher instanceof MatchSpecificType) {
result.remove(((MatchSpecificType) matcher).type);
} else {
result.removeIf(matcher::matches);
}
- }
+ });
return result;
}
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java b/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java
index cd1c5fc..979d238 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java
@@ -12,6 +12,7 @@
import java.util.Collection;
import java.util.Collections;
import java.util.List;
+import java.util.function.Consumer;
import java.util.stream.Collectors;
public abstract class ProguardClassNameList {
@@ -20,6 +21,10 @@
return new Builder();
}
+ public static ProguardClassNameList emptyList() {
+ return new EmptyClassNameList();
+ }
+
public static ProguardClassNameList singletonList(ProguardTypeMatcher matcher) {
return new SingleClassNameList(matcher);
}
@@ -69,6 +74,37 @@
public abstract boolean matches(DexType type);
+ public abstract void forEachTypeMatcher(Consumer<ProguardTypeMatcher> consumer);
+
+ private static class EmptyClassNameList extends ProguardClassNameList {
+
+ private EmptyClassNameList() {
+ }
+
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ @Override
+ public void writeTo(StringBuilder builder) {
+ }
+
+ @Override
+ public List<DexType> asSpecificDexTypes() {
+ return null;
+ }
+
+ @Override
+ public boolean matches(DexType type) {
+ return false;
+ }
+
+ @Override
+ public void forEachTypeMatcher(Consumer<ProguardTypeMatcher> consumer) {
+ }
+ }
+
private static class SingleClassNameList extends ProguardClassNameList {
private final ProguardTypeMatcher className;
@@ -97,6 +133,11 @@
public boolean matches(DexType type) {
return className.matches(type);
}
+
+ @Override
+ public void forEachTypeMatcher(Consumer<ProguardTypeMatcher> consumer) {
+ consumer.accept(className);
+ }
}
private static class PositiveClassNameList extends ProguardClassNameList {
@@ -137,6 +178,11 @@
public boolean matches(DexType type) {
return classNames.stream().anyMatch(name -> name.matches(type));
}
+
+ @Override
+ public void forEachTypeMatcher(Consumer<ProguardTypeMatcher> consumer) {
+ classNames.forEach(consumer);
+ }
}
private static class MixedClassNameList extends ProguardClassNameList {
@@ -182,5 +228,10 @@
}
return false;
}
+
+ @Override
+ public void forEachTypeMatcher(Consumer<ProguardTypeMatcher> consumer) {
+ classNames.object2BooleanEntrySet().forEach(entry -> consumer.accept(entry.getKey()));
+ }
}
}
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 239f9bc..10daea7 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfiguration.java
@@ -8,12 +8,9 @@
import com.android.tools.r8.utils.InternalOptions.KeepAttributeOptions;
import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
import com.google.common.collect.ImmutableList;
-import com.google.common.collect.ImmutableSet;
import java.nio.file.Path;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
-import java.util.Set;
public class ProguardConfiguration {
@@ -36,7 +33,7 @@
private boolean verbose = false;
private String renameSourceFileAttribute = null;
private final List<String> keepAttributePatterns = new ArrayList<>();
- private final Set<ProguardTypeMatcher> dontWarnPatterns = new HashSet<>();
+ private ProguardClassNameList dontWarnPatterns = ProguardClassNameList.emptyList();
protected final List<ProguardConfigurationRule> rules = new ArrayList<>();
private final DexItemFactory dexItemFactory;
private boolean printSeeds;
@@ -133,8 +130,8 @@
this.rules.add(rule);
}
- public void addDontWarnPattern(ProguardTypeMatcher pattern) {
- dontWarnPatterns.add(pattern);
+ public void setDontWarnPatterns(ProguardClassNameList patterns) {
+ dontWarnPatterns = patterns;
}
public void setSeedFile(Path seedFile) {
@@ -223,7 +220,7 @@
private final boolean verbose;
private final String renameSourceFileAttribute;
private final ImmutableList<String> keepAttributesPatterns;
- private final ImmutableSet<ProguardTypeMatcher> dontWarnPatterns;
+ private final ProguardClassNameList dontWarnPatterns;
protected final ImmutableList<ProguardConfigurationRule> rules;
private final boolean printSeeds;
private final Path seedFile;
@@ -252,7 +249,7 @@
boolean verbose,
String renameSourceFileAttribute,
List<String> keepAttributesPatterns,
- Set<ProguardTypeMatcher> dontWarnPatterns,
+ ProguardClassNameList dontWarnPatterns,
List<ProguardConfigurationRule> rules,
boolean printSeeds,
Path seedFile,
@@ -279,7 +276,7 @@
this.verbose = verbose;
this.renameSourceFileAttribute = renameSourceFileAttribute;
this.keepAttributesPatterns = ImmutableList.copyOf(keepAttributesPatterns);
- this.dontWarnPatterns = ImmutableSet.copyOf(dontWarnPatterns);
+ this.dontWarnPatterns = dontWarnPatterns;
this.rules = ImmutableList.copyOf(rules);
this.printSeeds = printSeeds;
this.seedFile = seedFile;
@@ -377,7 +374,7 @@
return keepAttributesPatterns;
}
- public ImmutableSet<ProguardTypeMatcher> getDontWarnPatterns() {
+ public ProguardClassNameList getDontWarnPatterns() {
return dontWarnPatterns;
}
@@ -430,7 +427,7 @@
false /* verbose */,
null /* renameSourceFileAttribute */,
KeepAttributeOptions.KEEP_ALL,
- ImmutableSet.of() /* dontWarnPatterns */,
+ ProguardClassNameList.emptyList(),
ImmutableList.of(ProguardKeepRule.defaultKeepAllRule()),
false /* printSeeds */,
null /* seedFile */,
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 08a7eca..70bad56 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -198,11 +198,12 @@
} else if (acceptString("ignorewarnings")) {
configurationBuilder.setIgnoreWarnings(true);
} else if (acceptString("dontwarn")) {
- do {
- ProguardTypeMatcher pattern = ProguardTypeMatcher.create(parseClassName(),
- ClassOrType.CLASS, dexItemFactory);
- configurationBuilder.addDontWarnPattern(pattern);
- } while (acceptChar(','));
+ if (isOptionalArgumentGiven()) {
+ configurationBuilder.setDontWarnPatterns(parseClassNames());
+ } else {
+ configurationBuilder.setDontWarnPatterns(
+ ProguardClassNameList.singletonList(ProguardTypeMatcher.defaultAllMatcher()));
+ }
} else if (acceptString("repackageclasses")) {
if (configurationBuilder.getPackageObfuscationMode() == PackageObfuscationMode.FLATTEN) {
warnOverridingOptions("repackageclasses", "flattenpackagehierarchy");
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 3f44025..c0121db 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -145,6 +145,51 @@
}
@Test
+ public void testDontWarn() throws Exception {
+ DexItemFactory dexItemFactory = new DexItemFactory();
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(dexItemFactory);
+ String dontwarn = "-dontwarn !foobar,*bar";
+ parser.parse(new ProguardConfigurationSourceStrings(ImmutableList.of(dontwarn)));
+ ProguardConfiguration config = parser.getConfig();
+ assertFalse(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lboobaz;")));
+ assertTrue(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lboobar;")));
+ assertFalse(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lfoobar;")));
+ }
+
+ @Test
+ public void testDontWarnAllExplicitly() throws Exception {
+ DexItemFactory dexItemFactory = new DexItemFactory();
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(dexItemFactory);
+ String dontwarnAll = "-dontwarn *";
+ parser.parse(new ProguardConfigurationSourceStrings(ImmutableList.of(dontwarnAll)));
+ ProguardConfiguration config = parser.getConfig();
+ assertTrue(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lboobaz;")));
+ assertTrue(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lboobar;")));
+ assertTrue(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lfoobar;")));
+ }
+
+ @Test
+ public void testDontWarnAllImplicitly() throws Exception {
+ DexItemFactory dexItemFactory = new DexItemFactory();
+ ProguardConfigurationParser parser = new ProguardConfigurationParser(dexItemFactory);
+ String dontwarnAll = "-dontwarn";
+ parser.parse(new ProguardConfigurationSourceStrings(ImmutableList.of(dontwarnAll)));
+ ProguardConfiguration config = parser.getConfig();
+ assertTrue(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lboobaz;")));
+ assertTrue(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lboobar;")));
+ assertTrue(
+ config.getDontWarnPatterns().matches(dexItemFactory.createType("Lfoobar;")));
+ }
+
+ @Test
public void parseAccessFlags() throws IOException, ProguardRuleParserException {
ProguardConfigurationParser parser = new ProguardConfigurationParser(new DexItemFactory());
parser.parse(Paths.get(ACCESS_FLAGS_FILE));
diff --git a/src/test/java/com/android/tools/r8/shaking/ProguardNameMatchingTest.java b/src/test/java/com/android/tools/r8/shaking/ProguardNameMatchingTest.java
index af87086..2737971 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardNameMatchingTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardNameMatchingTest.java
@@ -62,6 +62,9 @@
assertTrue(matchClassName("java.lang.Object", "!java.util.**", "java**"));
assertFalse(matchClassName("java.lang.Object", "!java.**", "java.lang.*"));
assertTrue(matchClassName("java.lang.Object", "java.lang.*", "!java.**"));
+
+ assertTrue(matchClassName("boobar", "!foobar", "*bar"));
+ assertFalse(matchClassName("foobar", "!foobar", "*bar"));
}
private void assertMatchesBasicTypes(String pattern) {