Misc. prerequisites for merging subsequent if rules
Change-Id: I256d835d64ae8655c0d6d8a8043de00f308dc7b9
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 25c9cbf..37c0cf3 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardClassNameList.java
@@ -3,20 +3,22 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
+import static com.google.common.base.Predicates.alwaysTrue;
+
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexType;
import com.android.tools.r8.utils.IterableUtils;
-import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.TraversalContinuation;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
+import com.google.common.collect.Sets;
import it.unimi.dsi.fastutil.objects.Object2BooleanArrayMap;
import it.unimi.dsi.fastutil.objects.Object2BooleanMap;
import it.unimi.dsi.fastutil.objects.Object2BooleanMap.Entry;
import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -85,20 +87,26 @@
public abstract boolean hasSpecificTypes();
- public abstract List<DexType> getSpecificTypes();
+ public abstract Set<DexType> getSpecificTypes();
public abstract boolean matches(DexType type);
- protected Iterable<ProguardWildcard> getWildcards() {
- return Collections::emptyIterator;
+ protected final Iterable<ProguardWildcard> getWildcards() {
+ return getWildcardsThatMatches(alwaysTrue());
+ }
+
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return IterableUtils.empty();
}
public boolean hasWildcards() {
return getWildcards().iterator().hasNext();
}
- static Iterable<ProguardWildcard> getWildcardsOrEmpty(ProguardClassNameList nameList) {
- return nameList == null ? Collections::emptyIterator : nameList.getWildcards();
+ static <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatchesOrEmpty(
+ ProguardClassNameList nameList, Predicate<? super ProguardWildcard> predicate) {
+ return nameList != null ? nameList.getWildcardsThatMatches(predicate) : IterableUtils.empty();
}
protected ProguardClassNameList materialize(DexItemFactory dexItemFactory) {
@@ -162,7 +170,7 @@
}
@Override
- public List<DexType> getSpecificTypes() {
+ public Set<DexType> getSpecificTypes() {
return null;
}
@@ -220,14 +228,18 @@
@Override
public boolean hasSpecificTypes() {
- return className.hasSpecificType();
+ return className.hasSpecificType() || className.hasSpecificTypes();
}
@Override
- public List<DexType> getSpecificTypes() {
- return className.hasSpecificType()
- ? Collections.singletonList(className.getSpecificType())
- : null;
+ public Set<DexType> getSpecificTypes() {
+ if (className.hasSpecificType()) {
+ return Collections.singleton(className.getSpecificType());
+ }
+ if (className.hasSpecificTypes()) {
+ return className.getSpecificTypes();
+ }
+ return null;
}
@Override
@@ -236,8 +248,9 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return className.getWildcards();
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return className.getWildcardsThatMatches(predicate);
}
@Override
@@ -261,7 +274,7 @@
private final ImmutableList<ProguardTypeMatcher> classNames;
- private List<DexType> specificTypes;
+ private Set<DexType> specificTypes;
private PositiveClassNameList(Collection<ProguardTypeMatcher> classNames) {
this.classNames = ImmutableList.copyOf(classNames);
@@ -308,12 +321,22 @@
}
@Override
- public List<DexType> getSpecificTypes() {
+ public Set<DexType> getSpecificTypes() {
if (specificTypes == null) {
- specificTypes =
- classNames.stream().allMatch(ProguardTypeMatcher::hasSpecificType)
- ? ListUtils.map(classNames, ProguardTypeMatcher::getSpecificType)
- : Collections.emptyList();
+ if (Iterables.all(
+ classNames, className -> className.hasSpecificType() || className.hasSpecificTypes())) {
+ specificTypes = Sets.newIdentityHashSet();
+ for (var className : classNames) {
+ if (className.hasSpecificType()) {
+ specificTypes.add(className.getSpecificType());
+ } else {
+ assert className.hasSpecificTypes();
+ specificTypes.addAll(className.getSpecificTypes());
+ }
+ }
+ } else {
+ specificTypes = Collections.emptySet();
+ }
}
return specificTypes.isEmpty() ? null : specificTypes;
}
@@ -325,8 +348,10 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return IterableUtils.flatMap(classNames, ProguardTypeMatcher::getWildcards);
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return IterableUtils.flatMap(
+ classNames, className -> className.getWildcardsThatMatches(predicate));
}
@Override
@@ -406,7 +431,7 @@
}
@Override
- public List<DexType> getSpecificTypes() {
+ public Set<DexType> getSpecificTypes() {
return null;
}
@@ -424,8 +449,10 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return IterableUtils.flatMap(classNames.keySet(), ProguardTypeMatcher::getWildcards);
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return IterableUtils.flatMap(
+ classNames.keySet(), className -> className.getWildcardsThatMatches(predicate));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java b/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
index 0700049..63e6b5a 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardClassSpecification.java
@@ -252,6 +252,14 @@
return source;
}
+ public boolean hasMemberRules() {
+ return memberRules != null && !memberRules.isEmpty();
+ }
+
+ public ProguardMemberRule getMemberRule(int index) {
+ return memberRules.get(index);
+ }
+
public List<ProguardMemberRule> getMemberRules() {
return memberRules;
}
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 5b11df3..ceb9671 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationParser.java
@@ -1358,8 +1358,7 @@
if (acceptString("<init>")) {
ProguardTypeMatcher typeMatcher =
ProguardTypeMatcher.create(first, ClassOrType.TYPE, dexItemFactory);
- if (!typeMatcher.matchesSpecificType()
- || !typeMatcher.getSpecificType().isVoidType()) {
+ if (!typeMatcher.hasSpecificType() || !typeMatcher.getSpecificType().isVoidType()) {
throw parseError("Expected [access-flag]* void <init>");
}
ruleBuilder.setRuleType(ProguardMemberType.INIT);
@@ -1369,8 +1368,7 @@
} else if (acceptString("<clinit>")) {
ProguardTypeMatcher typeMatcher =
ProguardTypeMatcher.create(first, ClassOrType.TYPE, dexItemFactory);
- if (!typeMatcher.matchesSpecificType()
- || !typeMatcher.getSpecificType().isVoidType()) {
+ if (!typeMatcher.hasSpecificType() || !typeMatcher.getSpecificType().isVoidType()) {
throw parseError("Expected [access-flag]* void <clinit>");
}
ruleBuilder.setRuleType(ProguardMemberType.CLINIT);
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
index 4e80401..29933a5 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.shaking;
import static com.android.tools.r8.graph.DexProgramClass.asProgramClassOrNull;
+import static com.google.common.base.Predicates.alwaysTrue;
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppInfoWithClassHierarchy;
@@ -16,11 +17,11 @@
import com.android.tools.r8.graph.SubtypingInfo;
import com.android.tools.r8.origin.Origin;
import com.android.tools.r8.position.Position;
+import com.android.tools.r8.shaking.ProguardWildcard.BackReference;
import com.android.tools.r8.utils.BooleanBox;
import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.StringUtils;
import com.google.common.collect.Iterables;
-import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
@@ -213,16 +214,29 @@
return false;
}
- protected Iterable<ProguardWildcard> getWildcards() {
- List<ProguardMemberRule> memberRules = getMemberRules();
+ protected boolean hasBackReferences() {
+ return !Iterables.isEmpty(getBackReferences());
+ }
+
+ public Iterable<BackReference> getBackReferences() {
+ return getWildcardsThatMatches(ProguardWildcard::isBackReference);
+ }
+
+ protected final Iterable<ProguardWildcard> getWildcards() {
+ return getWildcardsThatMatches(alwaysTrue());
+ }
+
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
return Iterables.concat(
- ProguardTypeMatcher.getWildcardsOrEmpty(getClassAnnotations()),
- ProguardClassNameList.getWildcardsOrEmpty(getClassNames()),
- ProguardTypeMatcher.getWildcardsOrEmpty(getInheritanceAnnotations()),
- ProguardTypeMatcher.getWildcardsOrEmpty(getInheritanceClassName()),
- memberRules == null
- ? Collections::emptyIterator
- : IterableUtils.flatMap(memberRules, ProguardMemberRule::getWildcards));
+ ProguardTypeMatcher.getWildcardsThatMatchesOrEmpty(getClassAnnotations(), predicate),
+ ProguardClassNameList.getWildcardsThatMatchesOrEmpty(getClassNames(), predicate),
+ ProguardTypeMatcher.getWildcardsThatMatchesOrEmpty(getInheritanceAnnotations(), predicate),
+ ProguardTypeMatcher.getWildcardsThatMatchesOrEmpty(getInheritanceClassName(), predicate),
+ hasMemberRules()
+ ? IterableUtils.flatMap(
+ getMemberRules(), memberRule -> memberRule.getWildcardsThatMatches(predicate))
+ : IterableUtils.empty());
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java
index cb3757c..4953a20 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java
@@ -14,6 +14,7 @@
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
public class ProguardIfRule extends ProguardKeepRuleBase {
@@ -132,8 +133,11 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return Iterables.concat(super.getWildcards(), subsequentRule.getWildcards());
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return Iterables.concat(
+ super.getWildcardsThatMatches(predicate),
+ subsequentRule.getWildcardsThatMatches(predicate));
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
index 326a95e..85a96c2 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardKeepRule.java
@@ -44,7 +44,7 @@
}
}
- protected ProguardKeepRule(
+ public ProguardKeepRule(
Origin origin,
Position position,
String source,
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
index 0720337..5ee286d 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardMemberRule.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
+import static com.google.common.base.Predicates.alwaysTrue;
+
import com.android.tools.r8.errors.Unreachable;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClassAndField;
@@ -19,6 +21,7 @@
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
public class ProguardMemberRule {
@@ -114,7 +117,7 @@
private final List<ProguardTypeMatcher> arguments;
private final ProguardMemberRuleReturnValue returnValue;
- private ProguardMemberRule(
+ public ProguardMemberRule(
List<ProguardTypeMatcher> annotations,
ProguardAccessFlags accessFlags,
ProguardAccessFlags negatedAccessFlags,
@@ -156,6 +159,10 @@
return ruleType;
}
+ public boolean hasType() {
+ return type != null;
+ }
+
public ProguardTypeMatcher getType() {
return type;
}
@@ -176,10 +183,6 @@
return returnValue;
}
- public ProguardTypeMatcher getTypeMatcher() {
- return type;
- }
-
public boolean matches(
DexClassAndField field,
AppView<?> appView,
@@ -322,14 +325,24 @@
}
}
- Iterable<ProguardWildcard> getWildcards() {
+ public boolean hasBackReference() {
+ return IterableUtils.hasNext(getWildcardsThatMatches(ProguardWildcard::isBackReference));
+ }
+
+ final Iterable<ProguardWildcard> getWildcards() {
+ return getWildcardsThatMatches(alwaysTrue());
+ }
+
+ <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
return Iterables.concat(
- ProguardTypeMatcher.getWildcardsOrEmpty(annotations),
- ProguardTypeMatcher.getWildcardsOrEmpty(type),
- ProguardNameMatcher.getWildcardsOrEmpty(name),
+ ProguardTypeMatcher.getWildcardsThatMatchesOrEmpty(annotations, predicate),
+ ProguardTypeMatcher.getWildcardsThatMatchesOrEmpty(type, predicate),
+ ProguardNameMatcher.getWildcardsThatMatchesOrEmpty(name, predicate),
arguments == null
- ? Collections::emptyIterator
- : IterableUtils.flatMap(arguments, ProguardTypeMatcher::getWildcards));
+ ? IterableUtils.empty()
+ : IterableUtils.flatMap(
+ arguments, argument -> argument.getWildcardsThatMatches(predicate)));
}
ProguardMemberRule materialize(DexItemFactory dexItemFactory) {
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardNameMatcher.java b/src/main/java/com/android/tools/r8/shaking/ProguardNameMatcher.java
index c217d45..ecd43b1 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardNameMatcher.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardNameMatcher.java
@@ -3,12 +3,15 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.shaking;
+import static com.google.common.base.Predicates.alwaysTrue;
+
import com.android.tools.r8.shaking.ProguardConfigurationParser.IdentifierPatternWithWildcards;
import com.android.tools.r8.shaking.ProguardWildcard.BackReference;
import com.android.tools.r8.shaking.ProguardWildcard.Pattern;
-import com.google.common.collect.ImmutableList;
+import com.android.tools.r8.utils.IterableUtils;
import java.util.Collections;
import java.util.List;
+import java.util.function.Predicate;
import java.util.stream.Collectors;
public abstract class ProguardNameMatcher {
@@ -89,12 +92,20 @@
public abstract boolean matches(String name);
- protected Iterable<ProguardWildcard> getWildcards() {
- return Collections::emptyIterator;
+ protected final Iterable<ProguardWildcard> getWildcards() {
+ return getWildcardsThatMatches(alwaysTrue());
}
- static Iterable<ProguardWildcard> getWildcardsOrEmpty(ProguardNameMatcher nameMatcher) {
- return nameMatcher == null ? Collections::emptyIterator : nameMatcher.getWildcards();
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return IterableUtils.empty();
+ }
+
+ static <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatchesOrEmpty(
+ ProguardNameMatcher nameMatcher, Predicate<? super ProguardWildcard> predicate) {
+ return nameMatcher != null
+ ? nameMatcher.getWildcardsThatMatches(predicate)
+ : IterableUtils.empty();
}
protected ProguardNameMatcher materialize() {
@@ -119,8 +130,9 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return ImmutableList.of(wildcard);
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return predicate.test(wildcard) ? Collections.singleton((T) wildcard) : IterableUtils.empty();
}
@Override
@@ -129,6 +141,16 @@
}
@Override
+ public boolean equals(Object obj) {
+ return obj instanceof MatchAllNames;
+ }
+
+ @Override
+ public int hashCode() {
+ return getClass().hashCode();
+ }
+
+ @Override
public String toString() {
return "*";
}
@@ -154,8 +176,9 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return wildcards;
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return IterableUtils.filter(wildcards, predicate);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java b/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java
index f9aef9b..62b82f8 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardTypeMatcher.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.shaking;
import static com.android.tools.r8.utils.DescriptorUtils.javaTypeToDescriptor;
+import static com.google.common.base.Predicates.alwaysTrue;
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexItemFactory;
@@ -12,13 +13,18 @@
import com.android.tools.r8.shaking.ProguardWildcard.BackReference;
import com.android.tools.r8.shaking.ProguardWildcard.Pattern;
import com.android.tools.r8.utils.DescriptorUtils;
+import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.StringUtils;
+import com.android.tools.r8.utils.StringUtils.BraceType;
import com.google.common.collect.ImmutableList;
import it.unimi.dsi.fastutil.ints.Int2ReferenceMap;
import it.unimi.dsi.fastutil.ints.Int2ReferenceOpenHashMap;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
+import java.util.Set;
+import java.util.function.Consumer;
+import java.util.function.Predicate;
public abstract class ProguardTypeMatcher {
@@ -60,18 +66,41 @@
return false;
}
- protected Iterable<ProguardWildcard> getWildcards() {
- return Collections::emptyIterator;
+ protected void forEachWildcard(Consumer<? super ProguardWildcard> consumer) {
+ // Intentionally empty.
}
- static Iterable<ProguardWildcard> getWildcardsOrEmpty(ProguardTypeMatcher typeMatcher) {
- return typeMatcher == null ? Collections::emptyIterator : typeMatcher.getWildcards();
+ protected final Iterable<ProguardWildcard> getWildcards() {
+ return getWildcardsThatMatches(alwaysTrue());
}
- static Iterable<ProguardWildcard> getWildcardsOrEmpty(List<ProguardTypeMatcher> typeMatchers) {
- List<ProguardWildcard> result = new ArrayList<>();
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return IterableUtils.empty();
+ }
+
+ protected static <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatchesOrEmpty(
+ ProguardTypeMatcher typeMatcher, Predicate<? super ProguardWildcard> predicate) {
+ return typeMatcher != null
+ ? typeMatcher.getWildcardsThatMatches(predicate)
+ : IterableUtils.empty();
+ }
+
+ @SuppressWarnings("unchecked")
+ static <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatchesOrEmpty(
+ List<ProguardTypeMatcher> typeMatchers, Predicate<? super ProguardWildcard> predicate) {
+ if (typeMatchers.isEmpty()) {
+ return IterableUtils.empty();
+ }
+ List<T> result = new ArrayList<>();
+ Consumer<ProguardWildcard> fn =
+ wildcard -> {
+ if (predicate.test(wildcard)) {
+ result.add((T) wildcard);
+ }
+ };
for (ProguardTypeMatcher typeMatcher : typeMatchers) {
- typeMatcher.getWildcards().forEach(result::add);
+ typeMatcher.forEachWildcard(fn);
}
return result;
}
@@ -149,11 +178,17 @@
}
public DexType getSpecificType() {
+ assert false;
return null;
}
- public final boolean matchesSpecificType() {
- return getSpecificType() != null;
+ public boolean hasSpecificTypes() {
+ return false;
+ }
+
+ public Set<DexType> getSpecificTypes() {
+ assert false;
+ return null;
}
private static class MatchAllTypes extends ProguardTypeMatcher {
@@ -182,8 +217,15 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return ImmutableList.of(wildcard);
+ protected void forEachWildcard(Consumer<? super ProguardWildcard> consumer) {
+ consumer.accept(wildcard);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return predicate.test(wildcard) ? Collections.singleton((T) wildcard) : IterableUtils.empty();
}
@Override
@@ -272,8 +314,15 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return ImmutableList.of(wildcard);
+ protected void forEachWildcard(Consumer<? super ProguardWildcard> consumer) {
+ consumer.accept(wildcard);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return predicate.test(wildcard) ? Collections.singleton((T) wildcard) : IterableUtils.empty();
}
@Override
@@ -321,8 +370,15 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return ImmutableList.of(wildcard);
+ protected void forEachWildcard(Consumer<? super ProguardWildcard> consumer) {
+ consumer.accept(wildcard);
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return predicate.test(wildcard) ? Collections.singleton((T) wildcard) : IterableUtils.empty();
}
@Override
@@ -394,6 +450,52 @@
}
}
+ public static class MatchSpecificTypes extends ProguardTypeMatcher {
+
+ public final Set<DexType> types;
+
+ public MatchSpecificTypes(Set<DexType> types) {
+ this.types = types;
+ }
+
+ @Override
+ public boolean hasSpecificTypes() {
+ return true;
+ }
+
+ @Override
+ public Set<DexType> getSpecificTypes() {
+ return types;
+ }
+
+ @Override
+ public boolean matches(DexType type) {
+ return types.contains(type);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (!(obj instanceof MatchSpecificTypes)) {
+ return false;
+ }
+ MatchSpecificTypes other = (MatchSpecificTypes) obj;
+ return types.equals(other.types);
+ }
+
+ @Override
+ public int hashCode() {
+ return types.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return StringUtils.join(", ", types, DexType::getTypeName, BraceType.TUBORG);
+ }
+ }
+
private static class MatchTypePattern extends ProguardTypeMatcher {
private final String pattern;
@@ -419,8 +521,14 @@
}
@Override
- protected Iterable<ProguardWildcard> getWildcards() {
- return wildcards;
+ protected void forEachWildcard(Consumer<? super ProguardWildcard> consumer) {
+ wildcards.forEach(consumer);
+ }
+
+ @Override
+ protected <T extends ProguardWildcard> Iterable<T> getWildcardsThatMatches(
+ Predicate<? super ProguardWildcard> predicate) {
+ return IterableUtils.filter(wildcards, predicate);
}
@Override
diff --git a/src/main/java/com/android/tools/r8/shaking/ProguardWildcard.java b/src/main/java/com/android/tools/r8/shaking/ProguardWildcard.java
index b6cb8e5..a672c96 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardWildcard.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardWildcard.java
@@ -77,7 +77,7 @@
}
}
- static class BackReference extends ProguardWildcard {
+ public static class BackReference extends ProguardWildcard {
// Back-reference is not referable, hence the other type, Pattern, here.
Pattern reference;
final int referenceIndex;
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 9b6bc09..c94ce9c 100644
--- a/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
+++ b/src/test/java/com/android/tools/r8/shaking/ProguardConfigurationParserTest.java
@@ -37,6 +37,7 @@
import com.android.tools.r8.utils.AbortException;
import com.android.tools.r8.utils.FileUtils;
import com.android.tools.r8.utils.InternalOptions.PackageObfuscationMode;
+import com.android.tools.r8.utils.IterableUtils;
import com.android.tools.r8.utils.KeepingDiagnosticHandler;
import com.android.tools.r8.utils.ListUtils;
import com.android.tools.r8.utils.Reporter;
@@ -55,6 +56,7 @@
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.Set;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.function.Predicate;
@@ -258,9 +260,11 @@
assertEquals(1, rules.size());
assertEquals(ProguardClassType.CLASS, rules.get(0).getClassType());
assertEquals(1, rules.get(0).getClassNames().size());
- List<DexType> classTypes = rules.get(0).getClassNames().getSpecificTypes();
+ Set<DexType> classTypes = rules.get(0).getClassNames().getSpecificTypes();
assertEquals(1, classTypes.size());
- assertSame(dexItemFactory.createType("L-package-/-ClassNameWithDash-;"), classTypes.get(0));
+ assertSame(
+ dexItemFactory.createType("L-package-/-ClassNameWithDash-;"),
+ IterableUtils.first(classTypes));
ProguardConfigurationRule rule = rules.get(0);
assertEquals(2, rule.getMemberRules().size());
int matches = 0;