Refactor inlinable field predicates and ensure it is cleared.
Bug: 204845971
Change-Id: I1fecfb963635bcaa27946c96af1d775481d6540a
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 4d7fe69..41181b1 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardConfigurationRule.java
@@ -7,7 +7,6 @@
import com.android.tools.r8.graph.AppView;
import com.android.tools.r8.graph.DexClass;
import com.android.tools.r8.graph.DexDefinitionSupplier;
-import com.android.tools.r8.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexProgramClass;
import com.android.tools.r8.graph.DexType;
@@ -19,16 +18,12 @@
import com.google.common.collect.Iterables;
import java.util.Collections;
import java.util.List;
-import java.util.Map;
import java.util.Objects;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.StreamSupport;
public abstract class ProguardConfigurationRule extends ProguardClassSpecification {
private boolean used = false;
- private Map<DexField, DexField> inlinableFieldsInPrecondition = new ConcurrentHashMap<>();
// TODO(b/164019179): Since we are using the rule language for tracing main dex we can end up in
// a situation where the references to types are dead.
private boolean canReferenceDeadTypes = false;
@@ -71,18 +66,6 @@
used = true;
}
- public boolean hasInlinableFieldsMatchingPrecondition() {
- return !inlinableFieldsInPrecondition.isEmpty();
- }
-
- public Set<DexField> getInlinableFieldsMatchingPrecondition() {
- return inlinableFieldsInPrecondition.keySet();
- }
-
- public void addInlinableFieldMatchingPrecondition(DexField field) {
- inlinableFieldsInPrecondition.put(field, field);
- }
-
public boolean isProguardCheckDiscardRule() {
return false;
}
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 8313325..f61b4ee 100644
--- a/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.java
+++ b/src/main/java/com/android/tools/r8/shaking/ProguardIfRule.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.graph.DexField;
import com.android.tools.r8.graph.DexItemFactory;
import com.android.tools.r8.graph.DexReference;
import com.android.tools.r8.origin.Origin;
@@ -10,7 +11,9 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
import java.util.List;
+import java.util.Map;
import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;
public class ProguardIfRule extends ProguardKeepRuleBase {
@@ -34,6 +37,8 @@
private final Set<DexReference> preconditions;
final ProguardKeepRule subsequentRule;
+ private Map<DexField, DexField> inlinableFieldsInPrecondition = new ConcurrentHashMap<>();
+
public Set<DexReference> getPreconditions() {
return preconditions;
}
@@ -42,6 +47,16 @@
return subsequentRule;
}
+ public void addInlinableFieldMatchingPrecondition(DexField field) {
+ inlinableFieldsInPrecondition.put(field, field);
+ }
+
+ public Set<DexField> getAndClearInlinableFieldsMatchingPrecondition() {
+ Set<DexField> fields = inlinableFieldsInPrecondition.keySet();
+ inlinableFieldsInPrecondition = null;
+ return fields;
+ }
+
public static class Builder extends ProguardKeepRuleBase.Builder<ProguardIfRule, Builder> {
ProguardKeepRule subsequentRule = null;
diff --git a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
index 7eb31b4..bda331a 100644
--- a/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
+++ b/src/main/java/com/android/tools/r8/shaking/RootSetUtils.java
@@ -1684,12 +1684,18 @@
return;
}
for (ProguardConfigurationRule rule : rules) {
- if (rule.isProguardIfRule() && rule.hasInlinableFieldsMatchingPrecondition()) {
- List<DexField> fields = new ArrayList<>(rule.getInlinableFieldsMatchingPrecondition());
- fields.sort(DexField::compareTo);
- options.reporter.warning(
- new InlinableStaticFinalFieldPreconditionDiagnostic(rule.asProguardIfRule(), fields));
- } else if (!rule.isUsed() && options.testing.reportUnusedProguardConfigurationRules) {
+ if (rule.isProguardIfRule()) {
+ ProguardIfRule ifRule = rule.asProguardIfRule();
+ Set<DexField> unorderedFields = ifRule.getAndClearInlinableFieldsMatchingPrecondition();
+ if (!unorderedFields.isEmpty()) {
+ List<DexField> fields = new ArrayList<>(unorderedFields);
+ fields.sort(DexField::compareTo);
+ options.reporter.warning(
+ new InlinableStaticFinalFieldPreconditionDiagnostic(ifRule, fields));
+ continue;
+ }
+ }
+ if (!rule.isUsed() && options.testing.reportUnusedProguardConfigurationRules) {
String message = "Proguard configuration rule does not match anything: `" + rule + "`";
StringDiagnostic diagnostic = new StringDiagnostic(message, rule.getOrigin());
options.reporter.info(diagnostic);