Normalize keep options as "allow" options.
Bug: b/248408342
Change-Id: I4d1d2be9295c2e2f3f80302eb81617a92af0744d
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepOptions.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepOptions.java
index 573a482..539ae71 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepOptions.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepOptions.java
@@ -3,17 +3,16 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.experimental.keepanno.ast;
+import com.google.common.collect.ImmutableSet;
import java.util.Arrays;
import java.util.Collection;
-import java.util.Collections;
import java.util.HashSet;
-import java.util.Objects;
import java.util.Set;
public final class KeepOptions {
public boolean isKeepAll() {
- return allowIfSet ? options.isEmpty() : options.size() == KeepOption.values().length;
+ return allowedOptions.isEmpty();
}
public enum KeepOption {
@@ -25,7 +24,7 @@
public static KeepOptions keepAll() {
if (ALLOW_NONE_INSTANCE == null) {
- ALLOW_NONE_INSTANCE = new KeepOptions(true, Collections.emptySet());
+ ALLOW_NONE_INSTANCE = new KeepOptions(ImmutableSet.of());
}
return ALLOW_NONE_INSTANCE;
}
@@ -69,6 +68,7 @@
}
public KeepOptions build() {
+ // Fast path check for the two variants of "keep all".
if (options.isEmpty()) {
if (allowIfSet) {
return keepAll();
@@ -81,22 +81,30 @@
}
throw new KeepEdgeException("Invalid keep options that allow everything.");
}
- return new KeepOptions(allowIfSet, Collections.unmodifiableSet(options));
+ // The normalized options is the "allow variant", if not of that form invert it on build.
+ if (allowIfSet) {
+ return new KeepOptions(ImmutableSet.copyOf(options));
+ }
+ ImmutableSet.Builder<KeepOption> invertedOptions = ImmutableSet.builder();
+ for (KeepOption option : KeepOption.values()) {
+ if (!options.contains(option)) {
+ invertedOptions.add(option);
+ }
+ }
+ return new KeepOptions(invertedOptions.build());
}
}
private static KeepOptions ALLOW_NONE_INSTANCE = null;
- private final boolean allowIfSet;
- private final Set<KeepOption> options;
+ private final ImmutableSet<KeepOption> allowedOptions;
- private KeepOptions(boolean allowIfSet, Set<KeepOption> options) {
- this.allowIfSet = allowIfSet;
- this.options = options;
+ private KeepOptions(ImmutableSet<KeepOption> options) {
+ this.allowedOptions = options;
}
public boolean isAllowed(KeepOption option) {
- return options.contains(option) == allowIfSet;
+ return allowedOptions.contains(option);
}
@Override
@@ -107,14 +115,12 @@
if (o == null || getClass() != o.getClass()) {
return false;
}
- // This does not actually capture equivalence. We should normalize the builder the 'allow'
- // variant always.
KeepOptions that = (KeepOptions) o;
- return allowIfSet == that.allowIfSet && options.equals(that.options);
+ return allowedOptions.equals(that.allowedOptions);
}
@Override
public int hashCode() {
- return Objects.hash(allowIfSet, options);
+ return allowedOptions.hashCode();
}
}