[KeepAnno] Add bindings to check declarations
This change aligns checks with edges and allows more uniform
parsing. Follow-up CLs will start normalizing the AST to only
allow references in the precondition and consequence sets.
Bug: b/343389186
Change-Id: I541709dd01717633f4d2024945a7e7ec1d23523e
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
index c6b6f64..f28d5c8 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReader.java
@@ -49,6 +49,7 @@
import com.android.tools.r8.keepanno.ast.KeepMemberAccessPattern;
import com.android.tools.r8.keepanno.ast.KeepMemberAccessPattern.BuilderBase;
import com.android.tools.r8.keepanno.ast.KeepMemberItemPattern;
+import com.android.tools.r8.keepanno.ast.KeepMemberItemReference;
import com.android.tools.r8.keepanno.ast.KeepMemberPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodAccessPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodNamePattern;
@@ -829,15 +830,30 @@
"Invalid extracted annotation, must specify either an edge, a removed check, or an"
+ " optimized-out check.");
}
+ KeepEdgeMetaInfo metaInfo = context.applyToMetadata(KeepEdgeMetaInfo.builder()).build();
KeepCheckKind kind = isCheckRemoved ? KeepCheckKind.REMOVED : KeepCheckKind.OPTIMIZED_OUT;
- parent.accept(
- KeepCheck.builder()
- .setMetaInfo(context.applyToMetadata(KeepEdgeMetaInfo.builder()).build())
- .setKind(kind)
- .setItemPattern(context.toItemPattern())
- .build());
+ KeepItemPattern itemPattern = context.toItemPattern();
+ parent.accept(buildKeepCheckFromItem(metaInfo, kind, itemPattern));
super.visitEnd();
}
+
+ private static KeepCheck buildKeepCheckFromItem(
+ KeepEdgeMetaInfo metaInfo, KeepCheckKind kind, KeepItemPattern itemPattern) {
+ KeepBindings.Builder bindingsBuilder = KeepBindings.builder();
+ KeepBindingSymbol symbol = bindingsBuilder.generateFreshSymbol("CHECK");
+ bindingsBuilder.addBinding(symbol, itemPattern);
+ KeepItemReference itemReference =
+ itemPattern.isClassItemPattern()
+ ? KeepClassItemReference.fromBindingReference(KeepBindingReference.forClass(symbol))
+ : KeepMemberItemReference.fromBindingReference(
+ KeepBindingReference.forMember(symbol));
+ return KeepCheck.builder()
+ .setMetaInfo(metaInfo)
+ .setKind(kind)
+ .setBindings(bindingsBuilder.build())
+ .setItemReference(itemReference)
+ .build();
+ }
}
private static class KeepEdgeVisitor extends AnnotationVisitorBase {
@@ -1531,11 +1547,12 @@
@Override
public void visitEnd() {
+ UserBindingsHelper bindingsHelper = new UserBindingsHelper();
KeepItemVisitorBase itemVisitor =
new KeepItemVisitorBase(parsingContext) {
@Override
public UserBindingsHelper getBindingsHelper() {
- throw parsingContext.error("bindings not supported");
+ return bindingsHelper;
}
};
itemVisitor.visit(Item.className, className);
@@ -1544,7 +1561,8 @@
KeepCheck.builder()
.setMetaInfo(metaInfoBuilder.build())
.setKind(kind)
- .setItemPattern(itemVisitor.getItemReference().asItemPattern())
+ .setBindings(itemVisitor.getBindingsHelper().build())
+ .setItemReference(itemVisitor.getItemReference())
.build());
}
}
@@ -1583,11 +1601,8 @@
public void visitEnd() {
super.visitEnd();
parent.accept(
- KeepCheck.builder()
- .setMetaInfo(metaInfoBuilder.build())
- .setKind(kind)
- .setItemPattern(context)
- .build());
+ ExtractedAnnotationVisitor.buildKeepCheckFromItem(
+ metaInfoBuilder.build(), kind, context));
}
}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepBindings.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepBindings.java
index df6a224..fbc429a 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepBindings.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepBindings.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.keepanno.ast;
+import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.IdentityHashMap;
@@ -57,6 +59,28 @@
.collect(Collectors.joining(", "));
}
+ public void verify(KeepItemReference... references) {
+ verify(Arrays.asList(references));
+ }
+
+ public void verify(Collection<KeepItemReference> references) {
+ for (KeepItemReference reference : references) {
+ if (reference.isBindingReference()) {
+ KeepBindingReference bindingReference = reference.asBindingReference();
+ if (!bindings.containsKey(bindingReference.getName())) {
+ throw new KeepEdgeException("Unbound reference to " + bindingReference);
+ }
+ } else {
+ KeepItemPattern itemPattern = reference.asItemPattern();
+ for (KeepBindingReference bindingReference : itemPattern.getBindingReferences()) {
+ if (!bindings.containsKey(bindingReference.getName())) {
+ throw new KeepEdgeException("Unbound reference to " + bindingReference);
+ }
+ }
+ }
+ }
+ }
+
/**
* A unique binding.
*
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepCheck.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepCheck.java
index 1b2e42d..50f5c7c 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepCheck.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepCheck.java
@@ -14,7 +14,8 @@
private KeepEdgeMetaInfo metaInfo = KeepEdgeMetaInfo.none();
private KeepCheckKind kind = KeepCheckKind.REMOVED;
- private KeepItemPattern itemPattern;
+ private KeepBindings bindings = KeepBindings.none();
+ private KeepItemReference itemReference;
public Builder setMetaInfo(KeepEdgeMetaInfo metaInfo) {
this.metaInfo = metaInfo;
@@ -26,16 +27,22 @@
return this;
}
- public Builder setItemPattern(KeepItemPattern itemPattern) {
- this.itemPattern = itemPattern;
+ public Builder setBindings(KeepBindings bindings) {
+ this.bindings = bindings;
+ return this;
+ }
+
+ public Builder setItemReference(KeepItemReference itemReference) {
+ this.itemReference = itemReference;
return this;
}
public KeepCheck build() {
- if (itemPattern == null) {
+ if (itemReference == null) {
throw new KeepEdgeException("KeepCheck must have an item pattern.");
}
- return new KeepCheck(metaInfo, kind, itemPattern);
+ bindings.verify(itemReference);
+ return new KeepCheck(metaInfo, kind, bindings, itemReference);
}
}
@@ -45,12 +52,18 @@
private final KeepEdgeMetaInfo metaInfo;
private final KeepCheckKind kind;
- private final KeepItemPattern itemPattern;
+ private final KeepBindings bindings;
+ private final KeepItemReference itemReference;
- private KeepCheck(KeepEdgeMetaInfo metaInfo, KeepCheckKind kind, KeepItemPattern itemPattern) {
+ private KeepCheck(
+ KeepEdgeMetaInfo metaInfo,
+ KeepCheckKind kind,
+ KeepBindings bindings,
+ KeepItemReference itemReference) {
this.metaInfo = metaInfo;
this.kind = kind;
- this.itemPattern = itemPattern;
+ this.bindings = bindings;
+ this.itemReference = itemReference;
}
@Override
@@ -66,12 +79,23 @@
return kind;
}
+ public KeepBindings getBindings() {
+ return bindings;
+ }
+
+ public KeepItemReference getItemReference() {
+ return itemReference;
+ }
+
public KeepItemPattern getItemPattern() {
- return itemPattern;
+ if (itemReference.isBindingReference()) {
+ return bindings.get(itemReference.asBindingReference()).getItem();
+ }
+ return itemReference.asItemPattern();
}
@Override
public String toString() {
- return "KeepCheck{kind=" + kind + ", item=" + itemPattern + "}";
+ return "KeepCheck{kind=" + kind + ", item=" + itemReference + "}";
}
}