[KeepAnno] Add support of adding to the default constraints
Bug: b/248408342
Change-Id: Ibd6b97c537354c06db38893dd9fdc80bd25a8637
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/annotations/KeepTarget.java b/src/keepanno/java/com/android/tools/r8/keepanno/annotations/KeepTarget.java
index d18f91d..3d055d0 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/annotations/KeepTarget.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/annotations/KeepTarget.java
@@ -75,6 +75,7 @@
* <p>Mutually exclusive with the following other properties defining constraints:
*
* <ul>
+ * <li>constraintAdditions
* <li>allow
* <li>disallow
* </ul>
@@ -86,6 +87,28 @@
KeepConstraint[] constraints() default {};
/**
+ * Add additional usage constraints of the target.
+ *
+ * <p>The specified constraints must remain valid for the target in addition to the default
+ * constraints.
+ *
+ * <p>The default constraints are documented in {@link #constraints}
+ *
+ * <p>Mutually exclusive with the following other properties defining constraints:
+ *
+ * <ul>
+ * <li>constraints
+ * <li>allow
+ * <li>disallow
+ * </ul>
+ *
+ * <p>If nothing is specified for constraints the default is the default for {@link #constraints}.
+ *
+ * @return Additional usage constraints for the target.
+ */
+ KeepConstraint[] constraintAdditions() default {};
+
+ /**
* Define the constraints that are allowed to be modified.
*
* <p>The specified option constraints do not need to be preserved for the target.
@@ -94,6 +117,7 @@
*
* <ul>
* <li>constraints
+ * <li>constraintAdditions
* <li>disallow
* </ul>
*
@@ -114,6 +138,7 @@
*
* <ul>
* <li>constraints
+ * <li>constraintAdditions
* <li>allow
* </ul>
*
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConstraintsParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConstraintsParser.java
index 981c480..05b9fe8 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConstraintsParser.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConstraintsParser.java
@@ -16,6 +16,7 @@
public enum ConstraintsProperty {
CONSTRAINTS,
+ ADDITIONS,
ALLOW,
DISALLOW
}
@@ -27,19 +28,24 @@
@Override
AnnotationVisitor tryPropertyArray(
ConstraintsProperty property, String name, Consumer<KeepConstraints> setValue) {
+ ParsingContext parsingContext = getParsingContext().property(name);
switch (property) {
+ case ADDITIONS:
+ return new KeepConstraintsVisitor(
+ parsingContext,
+ constraints -> setValue.accept(KeepConstraints.defaultAdditions(constraints)));
case CONSTRAINTS:
- return new KeepConstraintsVisitor(getParsingContext(), setValue::accept);
+ return new KeepConstraintsVisitor(parsingContext, setValue::accept);
case ALLOW:
return new KeepOptionsVisitor(
- getParsingContext(),
+ parsingContext,
options ->
setValue.accept(
KeepConstraints.fromLegacyOptions(
KeepOptions.allowBuilder().addAll(options).build())));
case DISALLOW:
return new KeepOptionsVisitor(
- getParsingContext(),
+ parsingContext,
options ->
setValue.accept(
KeepConstraints.fromLegacyOptions(
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 c0d6087..b37f18f 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
@@ -747,6 +747,7 @@
visit(Item.className, className);
constraintsParser = new ConstraintsParser(parsingContext);
constraintsParser.setProperty(Target.constraints, ConstraintsProperty.CONSTRAINTS);
+ constraintsParser.setProperty(Target.constraintAdditions, ConstraintsProperty.ADDITIONS);
constraintsParser.setProperty(Target.allow, ConstraintsProperty.ALLOW);
constraintsParser.setProperty(Target.disallow, ConstraintsProperty.DISALLOW);
}
@@ -857,6 +858,7 @@
addContext.accept(metaInfoBuilder);
constraintsParser = new ConstraintsParser(parsingContext);
constraintsParser.setProperty(Target.constraints, ConstraintsProperty.CONSTRAINTS);
+ constraintsParser.setProperty(Target.constraintAdditions, ConstraintsProperty.ADDITIONS);
constraintsParser.setProperty(Target.allow, ConstraintsProperty.ALLOW);
constraintsParser.setProperty(Target.disallow, ConstraintsProperty.DISALLOW);
}
@@ -1809,6 +1811,7 @@
this.bindingsHelper = bindingsHelper;
optionsParser = new ConstraintsParser(parsingContext);
optionsParser.setProperty(Target.constraints, ConstraintsProperty.CONSTRAINTS);
+ optionsParser.setProperty(Target.constraintAdditions, ConstraintsProperty.ADDITIONS);
optionsParser.setProperty(Target.allow, ConstraintsProperty.ALLOW);
optionsParser.setProperty(Target.disallow, ConstraintsProperty.DISALLOW);
}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/AnnotationConstants.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/AnnotationConstants.java
index 85082de..a03cb6c 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/AnnotationConstants.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/AnnotationConstants.java
@@ -140,6 +140,7 @@
public static final String kind = "kind";
public static final String constraintsGroup = "constraints";
public static final String constraints = "constraints";
+ public static final String constraintAdditions = "constraintAdditions";
public static final String allow = "allow";
public static final String disallow = "disallow";
}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepConstraints.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepConstraints.java
index 65673ec..a4be849 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepConstraints.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepConstraints.java
@@ -4,6 +4,7 @@
package com.android.tools.r8.keepanno.ast;
+import com.android.tools.r8.keepanno.ast.KeepOptions.KeepOption;
import com.google.common.collect.ImmutableSet;
import java.util.Collections;
import java.util.HashSet;
@@ -21,6 +22,10 @@
return Defaults.INSTANCE;
}
+ public static KeepConstraints defaultAdditions(KeepConstraints additionalConstraints) {
+ return new Additions(additionalConstraints);
+ }
+
public static Builder builder() {
return new Builder();
}
@@ -87,6 +92,32 @@
}
}
+ private static class Additions extends KeepConstraints {
+
+ private final KeepConstraints additions;
+
+ public Additions(KeepConstraints additions) {
+ this.additions = additions;
+ }
+
+ @Override
+ public KeepOptions convertToKeepOptions(KeepOptions defaultOptions) {
+ KeepOptions additionalOptions = additions.convertToKeepOptions(defaultOptions);
+ KeepOptions.Builder builder = KeepOptions.disallowBuilder();
+ for (KeepOption option : KeepOption.values()) {
+ if (!additionalOptions.isAllowed(option) || !defaultOptions.isAllowed(option)) {
+ builder.add(option);
+ }
+ }
+ return builder.build();
+ }
+
+ @Override
+ public Set<KeepAttribute> getRequiredKeepAttributes() {
+ return additions.getRequiredKeepAttributes();
+ }
+ }
+
private static class Constraints extends KeepConstraints {
private final Set<KeepConstraint> constraints;
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepAccessVisibilityFlagsTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepAccessVisibilityFlagsTest.java
index 2454356..afa1871 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepAccessVisibilityFlagsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepAccessVisibilityFlagsTest.java
@@ -187,29 +187,17 @@
@KeepTarget(
kind = KeepItemKind.CLASS_AND_MEMBERS,
classConstant = FieldRuleTarget.class,
- constraints = {
- KeepConstraint.LOOKUP,
- KeepConstraint.NAME,
- KeepConstraint.VISIBILITY_INVARIANT
- },
+ constraintAdditions = {KeepConstraint.VISIBILITY_INVARIANT},
fieldAccess = {FieldAccessFlags.NON_PRIVATE}),
@KeepTarget(
kind = KeepItemKind.CLASS_AND_MEMBERS,
classConstant = MethodRuleTarget.class,
- constraints = {
- KeepConstraint.LOOKUP,
- KeepConstraint.NAME,
- KeepConstraint.VISIBILITY_INVARIANT
- },
+ constraintAdditions = {KeepConstraint.VISIBILITY_INVARIANT},
methodAccess = {MethodAccessFlags.NON_PACKAGE_PRIVATE}),
@KeepTarget(
kind = KeepItemKind.CLASS_AND_MEMBERS,
classConstant = MemberRuleTarget.class,
- constraints = {
- KeepConstraint.LOOKUP,
- KeepConstraint.NAME,
- KeepConstraint.VISIBILITY_INVARIANT
- },
+ constraintAdditions = {KeepConstraint.VISIBILITY_INVARIANT},
memberAccess = {MemberAccessFlags.PACKAGE_PRIVATE, MemberAccessFlags.PRIVATE}),
})
void foo() {
diff --git a/src/test/java/com/android/tools/r8/keepanno/MembersAnnotatedByPatternsTest.java b/src/test/java/com/android/tools/r8/keepanno/MembersAnnotatedByPatternsTest.java
index 18d8d6d..642e269 100644
--- a/src/test/java/com/android/tools/r8/keepanno/MembersAnnotatedByPatternsTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/MembersAnnotatedByPatternsTest.java
@@ -122,19 +122,19 @@
classConstant = OnMembers.class,
kind = KeepItemKind.CLASS_AND_MEMBERS,
memberAnnotatedByClassConstant = A.class,
- constraints = {KeepConstraint.LOOKUP, KeepConstraint.ANNOTATIONS, KeepConstraint.NAME}),
+ constraintAdditions = {KeepConstraint.ANNOTATIONS}),
@KeepTarget(
classConstant = OnFields.class,
kind = KeepItemKind.CLASS_AND_FIELDS,
fieldAnnotatedByClassName =
"com.android.tools.r8.keepanno.MembersAnnotatedByPatternsTest$B",
- constraints = {KeepConstraint.LOOKUP, KeepConstraint.ANNOTATIONS, KeepConstraint.NAME}),
+ constraintAdditions = {KeepConstraint.ANNOTATIONS}),
@KeepTarget(
classConstant = OnMethods.class,
kind = KeepItemKind.CLASS_AND_METHODS,
methodAnnotatedByClassNamePattern =
@ClassNamePattern(simpleName = "MembersAnnotatedByPatternsTest$C"),
- constraints = {KeepConstraint.LOOKUP, KeepConstraint.ANNOTATIONS, KeepConstraint.NAME})
+ constraintAdditions = {KeepConstraint.ANNOTATIONS})
})
public void foo(Class<?> clazz) throws Exception {
for (Field field : clazz.getDeclaredFields()) {
diff --git a/src/test/java/com/android/tools/r8/keepanno/utils/KeepItemAnnotationGenerator.java b/src/test/java/com/android/tools/r8/keepanno/utils/KeepItemAnnotationGenerator.java
index b12f190..6344760 100644
--- a/src/test/java/com/android/tools/r8/keepanno/utils/KeepItemAnnotationGenerator.java
+++ b/src/test/java/com/android/tools/r8/keepanno/utils/KeepItemAnnotationGenerator.java
@@ -490,6 +490,7 @@
private Group getKeepConstraintsGroup() {
return new Group(CONSTRAINTS_GROUP)
.addMember(constraints())
+ .addMember(constraintAdditions())
.addMember(
new GroupMember("allow")
.setDeprecated("Use " + docLink(constraints()) + " instead.")
@@ -543,6 +544,17 @@
.defaultArrayEmpty(KeepConstraint.class);
}
+ private static GroupMember constraintAdditions() {
+ return new GroupMember("constraintAdditions")
+ .setDocTitle("Add additional usage constraints of the target.")
+ .addParagraph(
+ "The specified constraints must remain valid for the target",
+ "in addition to the default constraints.")
+ .addParagraph("The default constraints are documented in " + docLink(constraints()))
+ .setDocReturn("Additional usage constraints for the target.")
+ .defaultArrayEmpty(KeepConstraint.class);
+ }
+
private GroupMember bindingName() {
return new GroupMember("bindingName")
.setDocTitle(