[KeepAnno] Migrate remaining "single declarations" to new parsers
Bug: b/248408342
Change-Id: I9e4fca0b693831dcf003b6f0e6baf4d0a2762111
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/InstanceOfParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/InstanceOfParser.java
new file mode 100644
index 0000000..a34915b
--- /dev/null
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/InstanceOfParser.java
@@ -0,0 +1,67 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.keepanno.asm;
+
+import com.android.tools.r8.keepanno.asm.InstanceOfParser.InstanceOfProperties;
+import com.android.tools.r8.keepanno.ast.AnnotationConstants.Item;
+import com.android.tools.r8.keepanno.ast.KeepInstanceOfPattern;
+import com.android.tools.r8.keepanno.ast.KeepQualifiedClassNamePattern;
+import com.android.tools.r8.keepanno.ast.ParsingContext;
+import java.util.function.Consumer;
+import org.objectweb.asm.Type;
+
+public class InstanceOfParser
+ extends PropertyParserBase<KeepInstanceOfPattern, InstanceOfProperties> {
+
+ public enum InstanceOfProperties {
+ NAME,
+ NAME_EXCL,
+ CONSTANT,
+ CONSTANT_EXCL
+ }
+
+ public InstanceOfParser(ParsingContext parsingContext) {
+ super(parsingContext.group(Item.instanceOfGroup));
+ }
+
+ @Override
+ public boolean tryProperty(
+ InstanceOfProperties property,
+ String name,
+ Object value,
+ Consumer<KeepInstanceOfPattern> setValue) {
+ KeepInstanceOfPattern result = parse(property, value);
+ if (result != null) {
+ setValue.accept(result);
+ return true;
+ }
+ return super.tryProperty(property, name, value, setValue);
+ }
+
+ private KeepInstanceOfPattern parse(InstanceOfProperties property, Object value) {
+ switch (property) {
+ case NAME:
+ return KeepInstanceOfPattern.builder()
+ .classPattern(KeepQualifiedClassNamePattern.exact(((String) value)))
+ .build();
+ case NAME_EXCL:
+ return KeepInstanceOfPattern.builder()
+ .classPattern(KeepQualifiedClassNamePattern.exact(((String) value)))
+ .setInclusive(false)
+ .build();
+ case CONSTANT:
+ return KeepInstanceOfPattern.builder()
+ .classPattern(KeepQualifiedClassNamePattern.exact(((Type) value).getClassName()))
+ .build();
+ case CONSTANT_EXCL:
+ return KeepInstanceOfPattern.builder()
+ .classPattern(KeepQualifiedClassNamePattern.exact(((Type) value).getClassName()))
+ .setInclusive(false)
+ .build();
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepConstraintsVisitor.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepConstraintsVisitor.java
new file mode 100644
index 0000000..9012458
--- /dev/null
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepConstraintsVisitor.java
@@ -0,0 +1,77 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.keepanno.asm;
+
+import com.android.tools.r8.keepanno.asm.KeepEdgeReader.Parent;
+import com.android.tools.r8.keepanno.ast.AnnotationConstants;
+import com.android.tools.r8.keepanno.ast.AnnotationConstants.Constraints;
+import com.android.tools.r8.keepanno.ast.KeepOptions.KeepOption;
+import com.android.tools.r8.keepanno.ast.ParsingContext;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class KeepConstraintsVisitor extends AnnotationVisitorBase {
+
+ private final Parent<Collection<KeepOption>> parent;
+ private final Set<KeepOption> options = new HashSet<>();
+
+ public KeepConstraintsVisitor(
+ ParsingContext parsingContext, Parent<Collection<KeepOption>> parent) {
+ super(parsingContext);
+ this.parent = parent;
+ }
+
+ @Override
+ public void visitEnum(String ignore, String descriptor, String value) {
+ if (!descriptor.equals(AnnotationConstants.Constraints.DESCRIPTOR)) {
+ super.visitEnum(ignore, descriptor, value);
+ }
+ switch (value) {
+ case Constraints.LOOKUP:
+ options.add(KeepOption.SHRINKING);
+ break;
+ case Constraints.NAME:
+ options.add(KeepOption.OBFUSCATING);
+ break;
+ case Constraints.VISIBILITY_RELAX:
+ // The compiler currently satisfies that access is never restricted.
+ break;
+ case Constraints.VISIBILITY_RESTRICT:
+ // We don't have directional rules so this prohibits any modification.
+ options.add(KeepOption.ACCESS_MODIFICATION);
+ break;
+ case Constraints.CLASS_INSTANTIATE:
+ case Constraints.METHOD_INVOKE:
+ case Constraints.FIELD_GET:
+ case Constraints.FIELD_SET:
+ // These options are the item-specific actual uses of the items.
+ // Allocating, invoking and read/writing all imply that the item cannot be "optimized"
+ // at compile time. It would be natural to refine the field specific uses but that is
+ // not expressible as keep options.
+ options.add(KeepOption.OPTIMIZING);
+ break;
+ case Constraints.METHOD_REPLACE:
+ case Constraints.FIELD_REPLACE:
+ case Constraints.NEVER_INLINE:
+ case Constraints.CLASS_OPEN_HIERARCHY:
+ options.add(KeepOption.OPTIMIZING);
+ break;
+ case Constraints.ANNOTATIONS:
+ // The annotation constrain only implies that annotations should remain, no restrictions
+ // are on the item otherwise.
+ options.add(KeepOption.ANNOTATION_REMOVAL);
+ break;
+ default:
+ super.visitEnum(ignore, descriptor, value);
+ }
+ }
+
+ @Override
+ public void visitEnd() {
+ parent.accept(options);
+ super.visitEnd();
+ }
+}
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 37829fb..7f0d34d 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
@@ -4,13 +4,14 @@
package com.android.tools.r8.keepanno.asm;
import com.android.tools.r8.keepanno.asm.ClassNameParser.ClassNameProperty;
+import com.android.tools.r8.keepanno.asm.InstanceOfParser.InstanceOfProperties;
+import com.android.tools.r8.keepanno.asm.OptionsParser.OptionsProperty;
import com.android.tools.r8.keepanno.asm.StringPatternParser.StringProperty;
import com.android.tools.r8.keepanno.asm.TypeParser.TypeProperty;
import com.android.tools.r8.keepanno.ast.AccessVisibility;
import com.android.tools.r8.keepanno.ast.AnnotationConstants;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Binding;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Condition;
-import com.android.tools.r8.keepanno.ast.AnnotationConstants.Constraints;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Edge;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.FieldAccess;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.ForApi;
@@ -18,7 +19,6 @@
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Kind;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.MemberAccess;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.MethodAccess;
-import com.android.tools.r8.keepanno.ast.AnnotationConstants.Option;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.Target;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.UsedByReflection;
import com.android.tools.r8.keepanno.ast.KeepBindingReference;
@@ -60,17 +60,14 @@
import com.android.tools.r8.keepanno.ast.ParsingContext.AnnotationParsingContext;
import com.android.tools.r8.keepanno.ast.ParsingContext.ClassParsingContext;
import com.android.tools.r8.keepanno.ast.ParsingContext.FieldParsingContext;
-import com.android.tools.r8.keepanno.ast.ParsingContext.GroupParsingContext;
import com.android.tools.r8.keepanno.ast.ParsingContext.MethodParsingContext;
import com.google.common.collect.ImmutableList;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
import java.util.Map;
-import java.util.Set;
import java.util.function.BiPredicate;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -478,7 +475,7 @@
}
// Interface for providing AST result(s) for a sub-tree back up to its parent.
- private interface Parent<T> {
+ public interface Parent<T> {
void accept(T result);
}
@@ -748,7 +745,7 @@
private final KeepConsequences.Builder consequences = KeepConsequences.builder();
private final KeepEdgeMetaInfo.Builder metaInfoBuilder = KeepEdgeMetaInfo.builder();
private final UserBindingsHelper bindingsHelper = new UserBindingsHelper();
- private final OptionsDeclaration optionsDeclaration;
+ private final OptionsParser optionsParser;
UsedByReflectionClassVisitor(
AnnotationParsingContext parsingContext,
@@ -762,7 +759,10 @@
addContext.accept(metaInfoBuilder);
// The class context/holder is the annotated class.
visit(Item.className, className);
- optionsDeclaration = new OptionsDeclaration(parsingContext);
+ optionsParser = new OptionsParser(parsingContext);
+ optionsParser.setProperty(Target.constraints, OptionsProperty.CONSTRAINTS);
+ optionsParser.setProperty(Target.allow, OptionsProperty.ALLOW);
+ optionsParser.setProperty(Target.disallow, OptionsProperty.DISALLOW);
}
@Override
@@ -793,7 +793,7 @@
},
bindingsHelper);
}
- AnnotationVisitor visitor = optionsDeclaration.tryParseArray(name);
+ AnnotationVisitor visitor = optionsParser.tryParseArray(name, unused -> {});
if (visitor != null) {
return visitor;
}
@@ -829,7 +829,7 @@
consequences.addTarget(
KeepTarget.builder()
.setItemPattern(itemPattern)
- .setOptions(getKeepOptionsOrDefault(optionsDeclaration.getValue()))
+ .setOptions(getKeepOptionsOrDefault(optionsParser.getValue()))
.build());
}
parent.accept(
@@ -856,7 +856,7 @@
private final UserBindingsHelper bindingsHelper = new UserBindingsHelper();
private final KeepConsequences.Builder consequences = KeepConsequences.builder();
private ItemKind kind = KeepEdgeReader.ItemKind.ONLY_MEMBERS;
- private final OptionsDeclaration optionsDeclaration;
+ private final OptionsParser optionsParser;
UsedByReflectionMemberVisitor(
AnnotationParsingContext parsingContext,
@@ -868,7 +868,10 @@
this.parent = parent;
this.context = context;
addContext.accept(metaInfoBuilder);
- optionsDeclaration = new OptionsDeclaration(parsingContext);
+ optionsParser = new OptionsParser(parsingContext);
+ optionsParser.setProperty(Target.constraints, OptionsProperty.CONSTRAINTS);
+ optionsParser.setProperty(Target.allow, OptionsProperty.ALLOW);
+ optionsParser.setProperty(Target.disallow, OptionsProperty.DISALLOW);
}
@Override
@@ -907,7 +910,7 @@
},
bindingsHelper);
}
- AnnotationVisitor visitor = optionsDeclaration.tryParseArray(name);
+ AnnotationVisitor visitor = optionsParser.tryParseArray(name, unused -> {});
if (visitor != null) {
return visitor;
}
@@ -928,7 +931,7 @@
validateConsistentKind(memberContext.getMemberPattern());
consequences.addTarget(
KeepTarget.builder()
- .setOptions(getKeepOptionsOrDefault(optionsDeclaration.getValue()))
+ .setOptions(getKeepOptionsOrDefault(optionsParser.getValue()))
.setItemPattern(context)
.build());
parent.accept(
@@ -1185,10 +1188,10 @@
}
}
- abstract static class Declaration<T> {
+ abstract static class Declaration {
boolean isDefault() {
- for (Declaration<?> declaration : declarations()) {
+ for (Declaration declaration : declarations()) {
if (!declaration.isDefault()) {
return false;
}
@@ -1196,7 +1199,7 @@
return true;
}
- List<Declaration<?>> declarations() {
+ List<Declaration> declarations() {
return Collections.emptyList();
}
@@ -1207,7 +1210,7 @@
private void ignore(Object arg) {}
boolean tryParse(String name, Object value) {
- for (Declaration<?> declaration : declarations()) {
+ for (Declaration declaration : declarations()) {
if (declaration.tryParse(name, value)) {
return true;
}
@@ -1221,7 +1224,7 @@
}
AnnotationVisitor tryParseArray(String name) {
- for (Declaration<?> declaration : declarations()) {
+ for (Declaration declaration : declarations()) {
AnnotationVisitor visitor = declaration.tryParseArray(name);
if (visitor != null) {
return visitor;
@@ -1237,7 +1240,7 @@
}
AnnotationVisitor tryParseAnnotation(String name, String descriptor) {
- for (Declaration<?> declaration : declarations()) {
+ for (Declaration declaration : declarations()) {
AnnotationVisitor visitor = declaration.tryParseAnnotation(name, descriptor);
if (visitor != null) {
return visitor;
@@ -1253,145 +1256,7 @@
}
}
- private abstract static class SingleDeclaration<T> extends Declaration<T> {
- private final ParsingContext parsingContext;
- private String declarationName = null;
- private T declarationValue = null;
- private AnnotationVisitor declarationVisitor = null;
-
- private SingleDeclaration(GroupParsingContext parsingContext) {
- this.parsingContext = parsingContext;
- }
-
- public ParsingContext getParsingContext() {
- return parsingContext;
- }
-
- abstract T getDefaultValue();
-
- abstract T parse(String name, Object value);
-
- AnnotationVisitor parseArray(String name, Consumer<T> setValue) {
- return null;
- }
-
- AnnotationVisitor parseAnnotation(String name, String descriptor, Consumer<T> setValue) {
- return null;
- }
-
- @Override
- boolean isDefault() {
- return !hasDeclaration();
- }
-
- private boolean hasDeclaration() {
- return declarationValue != null || declarationVisitor != null;
- }
-
- private void error(String name) {
- throw parsingContext.error(
- "Multiple properties: '" + declarationName + "' and '" + name + "'");
- }
-
- final T getValue() {
- return declarationValue == null ? getDefaultValue() : declarationValue;
- }
-
- @Override
- final boolean tryParse(String name, Object value) {
- T result = parse(name, value);
- if (result != null) {
- if (hasDeclaration()) {
- error(name);
- }
- declarationName = name;
- declarationValue = result;
- return true;
- }
- return false;
- }
-
- @Override
- final AnnotationVisitor tryParseArray(String name) {
- AnnotationVisitor visitor = parseArray(name, v -> declarationValue = v);
- if (visitor != null) {
- if (hasDeclaration()) {
- error(name);
- }
- declarationName = name;
- declarationVisitor = visitor;
- return visitor;
- }
- return null;
- }
-
- @Override
- final AnnotationVisitor tryParseAnnotation(String name, String descriptor) {
- AnnotationVisitor visitor = parseAnnotation(name, descriptor, v -> declarationValue = v);
- if (visitor != null) {
- if (hasDeclaration()) {
- error(name);
- }
- declarationName = name;
- declarationVisitor = visitor;
- return visitor;
- }
- return null;
- }
- }
-
- private static class InstanceOfDeclaration extends SingleDeclaration<KeepInstanceOfPattern> {
-
- private InstanceOfDeclaration(ParsingContext parsingContext) {
- super(parsingContext.group(Item.instanceOfGroup));
- }
-
- @Override
- KeepInstanceOfPattern getDefaultValue() {
- return KeepInstanceOfPattern.any();
- }
-
- @Override
- KeepInstanceOfPattern parse(String name, Object value) {
- if (name.equals(Item.instanceOfClassConstant) && value instanceof Type) {
- return KeepInstanceOfPattern.builder()
- .classPattern(KeepQualifiedClassNamePattern.exact(((Type) value).getClassName()))
- .build();
- }
- if (name.equals(Item.instanceOfClassName) && value instanceof String) {
- return KeepInstanceOfPattern.builder()
- .classPattern(KeepQualifiedClassNamePattern.exact(((String) value)))
- .build();
- }
- if (name.equals(Item.instanceOfClassConstantExclusive) && value instanceof Type) {
- return KeepInstanceOfPattern.builder()
- .classPattern(KeepQualifiedClassNamePattern.exact(((Type) value).getClassName()))
- .setInclusive(false)
- .build();
- }
- if (name.equals(Item.instanceOfClassNameExclusive) && value instanceof String) {
- return KeepInstanceOfPattern.builder()
- .classPattern(KeepQualifiedClassNamePattern.exact(((String) value)))
- .setInclusive(false)
- .build();
- }
- if (name.equals(Item.extendsClassConstant) && value instanceof Type) {
- return KeepInstanceOfPattern.builder()
- .classPattern(KeepQualifiedClassNamePattern.exact(((Type) value).getClassName()))
- .setInclusive(false)
- .build();
- }
- if (name.equals(Item.extendsClassName) && value instanceof String) {
- return KeepInstanceOfPattern.builder()
- .classPattern(KeepQualifiedClassNamePattern.exact(((String) value)))
- .setInclusive(false)
- .build();
- }
- return null;
- }
- }
-
- private static class ClassDeclaration extends Declaration<KeepClassItemReference> {
+ private static class ClassDeclaration extends Declaration {
private final ParsingContext parsingContext;
private final Supplier<UserBindingsHelper> getBindingsHelper;
@@ -1399,8 +1264,7 @@
private KeepClassItemReference boundClassItemReference = null;
private final ClassNameParser classNameParser;
private final ClassNameParser annotatedByParser;
- private final InstanceOfDeclaration instanceOfDeclaration;
- private final List<Declaration<?>> declarations;
+ private final InstanceOfParser instanceOfParser;
private final List<PropertyParser<?, ?>> parsers;
public ClassDeclaration(
@@ -1418,19 +1282,21 @@
annotatedByParser.setProperty(
Item.classAnnotatedByClassNamePattern, ClassNameProperty.PATTERN);
- parsers = ImmutableList.of(classNameParser, annotatedByParser);
+ instanceOfParser = new InstanceOfParser(parsingContext);
+ instanceOfParser.setProperty(Item.instanceOfClassName, InstanceOfProperties.NAME);
+ instanceOfParser.setProperty(Item.instanceOfClassConstant, InstanceOfProperties.CONSTANT);
+ instanceOfParser.setProperty(
+ Item.instanceOfClassNameExclusive, InstanceOfProperties.NAME_EXCL);
+ instanceOfParser.setProperty(
+ Item.instanceOfClassConstantExclusive, InstanceOfProperties.CONSTANT_EXCL);
+ instanceOfParser.setProperty(Item.extendsClassName, InstanceOfProperties.NAME_EXCL);
+ instanceOfParser.setProperty(Item.extendsClassConstant, InstanceOfProperties.CONSTANT_EXCL);
- instanceOfDeclaration = new InstanceOfDeclaration(parsingContext);
- declarations = ImmutableList.of(instanceOfDeclaration);
+ parsers = ImmutableList.of(classNameParser, annotatedByParser, instanceOfParser);
}
@Override
- List<Declaration<?>> declarations() {
- return declarations;
- }
-
- @Override
- List<PropertyParser<?, ?>> parsers() {
+ public List<PropertyParser<?, ?>> parsers() {
return parsers;
}
@@ -1441,7 +1307,7 @@
private boolean classPatternsAreDeclared() {
return classNameParser.isDeclared()
|| annotatedByParser.isDeclared()
- || !instanceOfDeclaration.isDefault();
+ || instanceOfParser.isDeclared();
}
private void checkAllowedDefinitions() {
@@ -1467,7 +1333,7 @@
classNameParser.getValueOrDefault(KeepQualifiedClassNamePattern.any()))
.setAnnotatedByPattern(
annotatedByParser.getValueOrDefault(KeepQualifiedClassNamePattern.any()))
- .setInstanceOfPattern(instanceOfDeclaration.getValue())
+ .setInstanceOfPattern(instanceOfParser.getValueOrDefault(KeepInstanceOfPattern.any()))
.build()
.toClassItemReference();
}
@@ -1494,7 +1360,7 @@
}
}
- private static class MethodDeclaration extends Declaration<KeepMethodPattern> {
+ private static class MethodDeclaration extends Declaration {
private final ParsingContext parsingContext;
private KeepMethodAccessPattern.Builder accessBuilder = null;
@@ -1568,7 +1434,7 @@
}
}
- private static class FieldDeclaration extends Declaration<KeepFieldPattern> {
+ private static class FieldDeclaration extends Declaration {
private final ParsingContext parsingContext;
private final StringPatternParser nameParser;
@@ -1631,13 +1497,13 @@
}
}
- private static class MemberDeclaration extends Declaration<KeepMemberPattern> {
+ private static class MemberDeclaration extends Declaration {
private final ParsingContext parsingContext;
private KeepMemberAccessPattern.Builder accessBuilder = null;
private final MethodDeclaration methodDeclaration;
private final FieldDeclaration fieldDeclaration;
- private final List<Declaration<?>> declarations;
+ private final List<Declaration> declarations;
MemberDeclaration(ParsingContext parsingContext) {
this.parsingContext = parsingContext.group(Item.memberGroup);
@@ -1647,7 +1513,7 @@
}
@Override
- List<Declaration<?>> declarations() {
+ List<Declaration> declarations() {
return declarations;
}
@@ -1978,48 +1844,11 @@
}
}
- private static class OptionsDeclaration extends SingleDeclaration<KeepOptions> {
-
- public OptionsDeclaration(ParsingContext parsingContext) {
- super(parsingContext.group(Target.constraintsGroup));
- }
-
- @Override
- KeepOptions getDefaultValue() {
- return null;
- }
-
- @Override
- KeepOptions parse(String name, Object value) {
- return null;
- }
-
- @Override
- AnnotationVisitor parseArray(String name, Consumer<KeepOptions> setValue) {
- if (name.equals(AnnotationConstants.Target.constraints)) {
- return new KeepConstraintsVisitor(
- getParsingContext(),
- options -> setValue.accept(KeepOptions.disallowBuilder().addAll(options).build()));
- }
- if (name.equals(AnnotationConstants.Target.disallow)) {
- return new KeepOptionsVisitor(
- getParsingContext(),
- options -> setValue.accept(KeepOptions.disallowBuilder().addAll(options).build()));
- }
- if (name.equals(AnnotationConstants.Target.allow)) {
- return new KeepOptionsVisitor(
- getParsingContext(),
- options -> setValue.accept(KeepOptions.allowBuilder().addAll(options).build()));
- }
- return null;
- }
- }
-
private static class KeepTargetVisitor extends KeepItemVisitorBase {
private final Parent<KeepTarget> parent;
private final UserBindingsHelper bindingsHelper;
- private final OptionsDeclaration optionsDeclaration;
+ private final OptionsParser optionsParser;
private final KeepTarget.Builder builder = KeepTarget.builder();
static KeepTargetVisitor create(
@@ -2036,7 +1865,10 @@
super(parsingContext);
this.parent = parent;
this.bindingsHelper = bindingsHelper;
- optionsDeclaration = new OptionsDeclaration(parsingContext);
+ optionsParser = new OptionsParser(parsingContext);
+ optionsParser.setProperty(Target.constraints, OptionsProperty.CONSTRAINTS);
+ optionsParser.setProperty(Target.allow, OptionsProperty.ALLOW);
+ optionsParser.setProperty(Target.disallow, OptionsProperty.DISALLOW);
}
@Override
@@ -2046,7 +1878,7 @@
@Override
public AnnotationVisitor visitArray(String name) {
- AnnotationVisitor visitor = optionsDeclaration.tryParseArray(name);
+ AnnotationVisitor visitor = optionsParser.tryParseArray(name, unused -> {});
if (visitor != null) {
return visitor;
}
@@ -2056,7 +1888,7 @@
@Override
public void visitEnd() {
super.visitEnd();
- builder.setOptions(getKeepOptionsOrDefault(optionsDeclaration.getValue()));
+ builder.setOptions(getKeepOptionsOrDefault(optionsParser.getValue()));
for (KeepItemReference item : getItemsWithBinding()) {
parent.accept(builder.setItemReference(item).build());
}
@@ -2089,116 +1921,6 @@
}
}
- private static class KeepConstraintsVisitor extends AnnotationVisitorBase {
-
- private final Parent<Collection<KeepOption>> parent;
- private final Set<KeepOption> options = new HashSet<>();
-
- public KeepConstraintsVisitor(
- ParsingContext parsingContext, Parent<Collection<KeepOption>> parent) {
- super(parsingContext);
- this.parent = parent;
- }
-
- @Override
- public void visitEnum(String ignore, String descriptor, String value) {
- if (!descriptor.equals(AnnotationConstants.Constraints.DESCRIPTOR)) {
- super.visitEnum(ignore, descriptor, value);
- }
- switch (value) {
- case Constraints.LOOKUP:
- options.add(KeepOption.SHRINKING);
- break;
- case Constraints.NAME:
- options.add(KeepOption.OBFUSCATING);
- break;
- case Constraints.VISIBILITY_RELAX:
- // The compiler currently satisfies that access is never restricted.
- break;
- case Constraints.VISIBILITY_RESTRICT:
- // We don't have directional rules so this prohibits any modification.
- options.add(KeepOption.ACCESS_MODIFICATION);
- break;
- case Constraints.CLASS_INSTANTIATE:
- case Constraints.METHOD_INVOKE:
- case Constraints.FIELD_GET:
- case Constraints.FIELD_SET:
- // These options are the item-specific actual uses of the items.
- // Allocating, invoking and read/writing all imply that the item cannot be "optimized"
- // at compile time. It would be natural to refine the field specific uses but that is
- // not expressible as keep options.
- options.add(KeepOption.OPTIMIZING);
- break;
- case Constraints.METHOD_REPLACE:
- case Constraints.FIELD_REPLACE:
- case Constraints.NEVER_INLINE:
- case Constraints.CLASS_OPEN_HIERARCHY:
- options.add(KeepOption.OPTIMIZING);
- break;
- case Constraints.ANNOTATIONS:
- // The annotation constrain only implies that annotations should remain, no restrictions
- // are on the item otherwise.
- options.add(KeepOption.ANNOTATION_REMOVAL);
- break;
- default:
- super.visitEnum(ignore, descriptor, value);
- }
- }
-
- @Override
- public void visitEnd() {
- parent.accept(options);
- super.visitEnd();
- }
- }
-
- private static class KeepOptionsVisitor extends AnnotationVisitorBase {
-
- private final Parent<Collection<KeepOption>> parent;
- private final Set<KeepOption> options = new HashSet<>();
-
- public KeepOptionsVisitor(
- ParsingContext parsingContext, Parent<Collection<KeepOption>> parent) {
- super(parsingContext);
- this.parent = parent;
- }
-
- @Override
- public void visitEnum(String ignore, String descriptor, String value) {
- if (!descriptor.equals(AnnotationConstants.Option.DESCRIPTOR)) {
- super.visitEnum(ignore, descriptor, value);
- }
- KeepOption option;
- switch (value) {
- case Option.SHRINKING:
- option = KeepOption.SHRINKING;
- break;
- case Option.OPTIMIZATION:
- option = KeepOption.OPTIMIZING;
- break;
- case Option.OBFUSCATION:
- option = KeepOption.OBFUSCATING;
- break;
- case Option.ACCESS_MODIFICATION:
- option = KeepOption.ACCESS_MODIFICATION;
- break;
- case Option.ANNOTATION_REMOVAL:
- option = KeepOption.ANNOTATION_REMOVAL;
- break;
- default:
- super.visitEnum(ignore, descriptor, value);
- return;
- }
- options.add(option);
- }
-
- @Override
- public void visitEnd() {
- parent.accept(options);
- super.visitEnd();
- }
- }
-
private static class MemberAccessVisitor extends AnnotationVisitorBase {
private KeepMemberAccessPattern.BuilderBase<?, ?> builder;
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepOptionsVisitor.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepOptionsVisitor.java
new file mode 100644
index 0000000..b369d2d
--- /dev/null
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepOptionsVisitor.java
@@ -0,0 +1,60 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.keepanno.asm;
+
+import com.android.tools.r8.keepanno.asm.KeepEdgeReader.Parent;
+import com.android.tools.r8.keepanno.ast.AnnotationConstants;
+import com.android.tools.r8.keepanno.ast.AnnotationConstants.Option;
+import com.android.tools.r8.keepanno.ast.KeepOptions.KeepOption;
+import com.android.tools.r8.keepanno.ast.ParsingContext;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class KeepOptionsVisitor extends AnnotationVisitorBase {
+
+ private final Parent<Collection<KeepOption>> parent;
+ private final Set<KeepOption> options = new HashSet<>();
+
+ public KeepOptionsVisitor(ParsingContext parsingContext, Parent<Collection<KeepOption>> parent) {
+ super(parsingContext);
+ this.parent = parent;
+ }
+
+ @Override
+ public void visitEnum(String ignore, String descriptor, String value) {
+ if (!descriptor.equals(AnnotationConstants.Option.DESCRIPTOR)) {
+ super.visitEnum(ignore, descriptor, value);
+ }
+ KeepOption option;
+ switch (value) {
+ case Option.SHRINKING:
+ option = KeepOption.SHRINKING;
+ break;
+ case Option.OPTIMIZATION:
+ option = KeepOption.OPTIMIZING;
+ break;
+ case Option.OBFUSCATION:
+ option = KeepOption.OBFUSCATING;
+ break;
+ case Option.ACCESS_MODIFICATION:
+ option = KeepOption.ACCESS_MODIFICATION;
+ break;
+ case Option.ANNOTATION_REMOVAL:
+ option = KeepOption.ANNOTATION_REMOVAL;
+ break;
+ default:
+ super.visitEnum(ignore, descriptor, value);
+ return;
+ }
+ options.add(option);
+ }
+
+ @Override
+ public void visitEnd() {
+ parent.accept(options);
+ super.visitEnd();
+ }
+}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/OptionsParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/OptionsParser.java
new file mode 100644
index 0000000..dd2beda
--- /dev/null
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/OptionsParser.java
@@ -0,0 +1,46 @@
+// Copyright (c) 2024, the R8 project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+package com.android.tools.r8.keepanno.asm;
+
+import com.android.tools.r8.keepanno.asm.OptionsParser.OptionsProperty;
+import com.android.tools.r8.keepanno.ast.AnnotationConstants.Target;
+import com.android.tools.r8.keepanno.ast.KeepOptions;
+import com.android.tools.r8.keepanno.ast.ParsingContext;
+import java.util.function.Consumer;
+import org.objectweb.asm.AnnotationVisitor;
+
+public class OptionsParser extends PropertyParserBase<KeepOptions, OptionsProperty> {
+
+ public enum OptionsProperty {
+ CONSTRAINTS,
+ ALLOW,
+ DISALLOW
+ }
+
+ public OptionsParser(ParsingContext parsingContext) {
+ super(parsingContext.group(Target.constraintsGroup));
+ }
+
+ @Override
+ AnnotationVisitor tryPropertyArray(
+ OptionsProperty property, String name, Consumer<KeepOptions> setValue) {
+ switch (property) {
+ case CONSTRAINTS:
+ return new KeepConstraintsVisitor(
+ getParsingContext(),
+ options -> setValue.accept(KeepOptions.disallowBuilder().addAll(options).build()));
+ case ALLOW:
+ return new KeepOptionsVisitor(
+ getParsingContext(),
+ options -> setValue.accept(KeepOptions.allowBuilder().addAll(options).build()));
+ case DISALLOW:
+ return new KeepOptionsVisitor(
+ getParsingContext(),
+ options -> setValue.accept(KeepOptions.disallowBuilder().addAll(options).build()));
+ default:
+ return null;
+ }
+ }
+}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMemberPattern.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMemberPattern.java
index 05c54e5..05c05f8 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMemberPattern.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMemberPattern.java
@@ -46,12 +46,11 @@
}
@Override
- @SuppressWarnings("EqualsGetClass")
public boolean equals(Object o) {
if (this == o) {
return true;
}
- if (o == null || getClass() != o.getClass()) {
+ if (!(o instanceof Some)) {
return false;
}
Some some = (Some) o;
@@ -99,7 +98,7 @@
@Override
public String toString() {
- return "*";
+ return "<all>";
}
}