[KeepAnno] Allow only singular member patterns in items.
Bug: b/248408342
Change-Id: Id8e297a4a2b86d19cba6d98d8c3aa31567c8addd
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 3ba3b8b..37c4087 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
@@ -10,7 +10,6 @@
import com.android.tools.r8.keepanno.ast.KeepEdgeException;
import com.android.tools.r8.keepanno.ast.KeepItemPattern;
import com.android.tools.r8.keepanno.ast.KeepItemPattern.Builder;
-import com.android.tools.r8.keepanno.ast.KeepMembersPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodNamePattern;
import com.android.tools.r8.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.keepanno.ast.KeepPreconditions;
@@ -170,9 +169,7 @@
}
if (methodName != null) {
itemBuilder.setMembersPattern(
- KeepMembersPattern.builder()
- .addMethodPattern(KeepMethodPattern.builder().setNamePattern(methodName).build())
- .build());
+ KeepMethodPattern.builder().setNamePattern(methodName).build());
}
KeepTarget target = KeepTarget.builder().setItem(itemBuilder.build()).build();
parent.accept(target);
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeWriter.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeWriter.java
index ee6d1f5..373853f 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeWriter.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeWriter.java
@@ -8,7 +8,9 @@
import com.android.tools.r8.keepanno.ast.KeepConsequences;
import com.android.tools.r8.keepanno.ast.KeepEdge;
import com.android.tools.r8.keepanno.ast.KeepItemPattern;
+import com.android.tools.r8.keepanno.ast.KeepMembersPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodNamePattern;
+import com.android.tools.r8.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.keepanno.ast.KeepPreconditions;
import com.android.tools.r8.keepanno.ast.KeepQualifiedClassNamePattern;
import com.android.tools.r8.keepanno.utils.Unimplemented;
@@ -68,39 +70,38 @@
if (!item.getExtendsPattern().isAny()) {
throw new Unimplemented();
}
- if (item.getMembersPattern().isNone()) {
- // Default is "no methods".
- } else if (item.getMembersPattern().isAll()) {
- throw new Unimplemented();
- } else {
- item.getMembersPattern()
- .forEach(
- field -> {
- throw new Unimplemented();
- },
- method -> {
- KeepMethodNamePattern methodNamePattern = method.getNamePattern();
- methodNamePattern.match(
- () -> {
- throw new Unimplemented();
- },
- exactMethodName -> {
- targetVisitor.visit(Target.methodName, exactMethodName);
- return null;
- });
- if (!method.getAccessPattern().isAny()) {
- throw new Unimplemented();
- }
- if (!method.getReturnTypePattern().isAny()) {
- throw new Unimplemented();
- }
- if (!method.getParametersPattern().isAny()) {
- throw new Unimplemented();
- }
- });
- }
+ writeMembers(item.getMembersPattern(), targetVisitor);
targetVisitor.visitEnd();
});
arrayVisitor.visitEnd();
}
+
+ private void writeMembers(KeepMembersPattern membersPattern, AnnotationVisitor targetVisitor) {
+ if (membersPattern.isNone()) {
+ // Default is "no methods".
+ return;
+ }
+ if (membersPattern.isAll()) {
+ throw new Unimplemented();
+ }
+ KeepMethodPattern method = membersPattern.asMethod();
+ KeepMethodNamePattern methodNamePattern = method.getNamePattern();
+ methodNamePattern.match(
+ () -> {
+ throw new Unimplemented();
+ },
+ exactMethodName -> {
+ targetVisitor.visit(Target.methodName, exactMethodName);
+ return null;
+ });
+ if (!method.getAccessPattern().isAny()) {
+ throw new Unimplemented();
+ }
+ if (!method.getReturnTypePattern().isAny()) {
+ throw new Unimplemented();
+ }
+ if (!method.getParametersPattern().isAny()) {
+ throw new Unimplemented();
+ }
+ }
}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java
index 2865b8f..5271837 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepEdge.java
@@ -25,7 +25,7 @@
* CONDITION ::= ITEM_PATTERN
*
* CONSEQUENCES ::= TARGET+
- * TARGET ::= any | OPTIONS ITEM_PATTERN
+ * TARGET ::= any | OPTIONS ITEM_PATTERN // TODO(b/248408342): What options are on target 'any'?
* OPTIONS ::= keep-all | OPTION+
* OPTION ::= shrinking | optimizing | obfuscating | access-modifying
*
@@ -38,7 +38,7 @@
* UNQUALIFIED_CLASS_NAME_PATTERN ::= any | exact simple-class-name
* EXTENDS_PATTERN ::= any | QUALIFIED_CLASS_NAME_PATTERN
*
- * MEMBERS_PATTERN ::= none | all | METHOD_PATTERN*
+ * MEMBERS_PATTERN ::= none | all | METHOD_PATTERN
*
* METHOD_PATTERN
* ::= METHOD_ACCESS_PATTERN
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepFieldPattern.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepFieldPattern.java
deleted file mode 100644
index 8de46e1..0000000
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepFieldPattern.java
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright (c) 2022, 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.ast;
-
-public class KeepFieldPattern extends KeepMemberPattern {
-
- private KeepFieldPattern() {}
-
- public boolean isAnyField() {
- return false;
- }
-}
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
deleted file mode 100644
index 51884e1..0000000
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMemberPattern.java
+++ /dev/null
@@ -1,35 +0,0 @@
-// Copyright (c) 2022, 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.ast;
-
-public abstract class KeepMemberPattern {
-
- public static KeepMemberPattern anyMember() {
- return Any.getInstance();
- }
-
- private static class Any extends KeepMemberPattern {
- private static final Any INSTANCE = new Any();
-
- public static Any getInstance() {
- return INSTANCE;
- }
-
- @Override
- public boolean isAnyMember() {
- return true;
- }
- }
-
- public boolean isAnyMember() {
- return false;
- }
-
- abstract static class Builder<T extends Builder<T>> {
-
- public abstract T self();
-
- Builder() {}
- }
-}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMembersPattern.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMembersPattern.java
index 9571329..64e1b25 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMembersPattern.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMembersPattern.java
@@ -3,19 +3,9 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.keepanno.ast;
-import com.android.tools.r8.keepanno.utils.Unimplemented;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Consumer;
-import java.util.stream.Collectors;
public abstract class KeepMembersPattern {
- public static Builder builder() {
- return new Builder();
- }
-
public static KeepMembersPattern none() {
return None.getInstance();
}
@@ -24,48 +14,6 @@
return All.getInstance();
}
- public static class Builder {
-
- private boolean anyMethod = false;
- private boolean anyField = false;
- private List<KeepMethodPattern> methods = new ArrayList<>();
- private List<KeepFieldPattern> fields = new ArrayList<>();
-
- public Builder addMethodPattern(KeepMethodPattern methodPattern) {
- if (anyMethod) {
- return this;
- }
- if (methodPattern.isAnyMethod()) {
- methods.clear();
- anyMethod = true;
- }
- methods.add(methodPattern);
- return this;
- }
-
- public Builder addFieldPattern(KeepFieldPattern fieldPattern) {
- if (anyField) {
- return this;
- }
- if (fieldPattern.isAnyField()) {
- fields.clear();
- anyField = true;
- }
- fields.add(fieldPattern);
- return this;
- }
-
- public KeepMembersPattern build() {
- if (methods.isEmpty() && fields.isEmpty()) {
- return KeepMembersPattern.none();
- }
- if (anyMethod && anyField) {
- return KeepMembersPattern.all();
- }
- return new Some(methods, fields);
- }
- }
-
private static class All extends KeepMembersPattern {
private static final All INSTANCE = new All();
@@ -80,16 +28,6 @@
}
@Override
- public boolean isNone() {
- return true;
- }
-
- @Override
- public void forEach(Consumer<KeepFieldPattern> onField, Consumer<KeepMethodPattern> onMethod) {
- throw new Unimplemented("Should this include all and none?");
- }
-
- @Override
public boolean equals(Object obj) {
return this == obj;
}
@@ -114,21 +52,11 @@
}
@Override
- public boolean isAll() {
- return false;
- }
-
- @Override
public boolean isNone() {
return true;
}
@Override
- public void forEach(Consumer<KeepFieldPattern> onField, Consumer<KeepMethodPattern> onMethod) {
- throw new Unimplemented("Should this include all and none?");
- }
-
- @Override
public boolean equals(Object obj) {
return this == obj;
}
@@ -144,69 +72,21 @@
}
}
- private static class Some extends KeepMembersPattern {
+ KeepMembersPattern() {}
- private final List<KeepMethodPattern> methods;
- private final List<KeepFieldPattern> fields;
-
- private Some(List<KeepMethodPattern> methods, List<KeepFieldPattern> fields) {
- assert !methods.isEmpty() || !fields.isEmpty();
- this.methods = methods;
- this.fields = fields;
- }
-
- @Override
- public boolean isAll() {
- // Since there is at least one none-all field or method this is not a match all.
- return false;
- }
-
- @Override
- public boolean isNone() {
- // Since there is at least one field or method this is not a match none.
- return false;
- }
-
- @Override
- public void forEach(Consumer<KeepFieldPattern> onField, Consumer<KeepMethodPattern> onMethod) {
- fields.forEach(onField);
- methods.forEach(onMethod);
- }
-
- @Override
- public boolean equals(Object obj) {
- if (this == obj) {
- return true;
- }
- if (obj == null || getClass() != obj.getClass()) {
- return false;
- }
- Some that = (Some) obj;
- return methods.equals(that.methods) && fields.equals(that.fields);
- }
-
- @Override
- public int hashCode() {
- return Objects.hash(methods, fields);
- }
-
- @Override
- public String toString() {
- return "KeepMembersSomePattern{"
- + "methods={"
- + methods.stream().map(Object::toString).collect(Collectors.joining(", "))
- + "}, fields={"
- + fields.stream().map(Object::toString).collect(Collectors.joining(", "))
- + "}}";
- }
+ public boolean isAll() {
+ return false;
}
- private KeepMembersPattern() {}
+ public boolean isNone() {
+ return false;
+ }
- public abstract boolean isAll();
+ public final boolean isMethod() {
+ return asMethod() != null;
+ }
- public abstract boolean isNone();
-
- public abstract void forEach(
- Consumer<KeepFieldPattern> onField, Consumer<KeepMethodPattern> onMethod);
+ public KeepMethodPattern asMethod() {
+ return null;
+ }
}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMethodPattern.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMethodPattern.java
index b3ec418..bec8102 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMethodPattern.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepMethodPattern.java
@@ -5,13 +5,13 @@
import java.util.Objects;
-public final class KeepMethodPattern extends KeepMemberPattern {
+public final class KeepMethodPattern extends KeepMembersPattern {
public static Builder builder() {
return new Builder();
}
- public static class Builder extends KeepMemberPattern.Builder<Builder> {
+ public static class Builder {
private KeepMethodAccessPattern accessPattern = KeepMethodAccessPattern.any();
private KeepMethodNamePattern namePattern = null;
@@ -20,7 +20,6 @@
private Builder() {}
- @Override
public Builder self() {
return this;
}
@@ -74,8 +73,16 @@
this.parametersPattern = parametersPattern;
}
+ @Override
+ public KeepMethodPattern asMethod() {
+ return this;
+ }
+
public boolean isAnyMethod() {
- return false;
+ return accessPattern.isAny()
+ && namePattern.isAny()
+ && returnTypePattern.isAny()
+ && parametersPattern.isAny();
}
public KeepMethodAccessPattern getAccessPattern() {
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractor.java b/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractor.java
index 735c6de..2d0df1b 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractor.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/keeprules/KeepRuleExtractor.java
@@ -5,7 +5,6 @@
import com.android.tools.r8.keepanno.ast.KeepConsequences;
import com.android.tools.r8.keepanno.ast.KeepEdge;
-import com.android.tools.r8.keepanno.ast.KeepFieldPattern;
import com.android.tools.r8.keepanno.ast.KeepItemPattern;
import com.android.tools.r8.keepanno.ast.KeepMembersPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodAccessPattern;
@@ -110,19 +109,12 @@
if (members.isAll()) {
return builder.append(" { *; }");
}
- builder.append(" {");
- members.forEach(
- field -> printField(builder.append(' '), field),
- method -> printMethod(builder.append(' '), method));
- return builder.append(" }");
- }
-
- private static StringBuilder printField(StringBuilder builder, KeepFieldPattern field) {
- if (field.isAnyField()) {
- return builder.append("<fields>;");
- } else {
- throw new Unimplemented();
+ if (members.isMethod()) {
+ builder.append(" {");
+ printMethod(builder.append(' '), members.asMethod());
+ return builder.append(" }");
}
+ throw new Unimplemented();
}
private static StringBuilder printMethod(StringBuilder builder, KeepMethodPattern methodPattern) {
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/processor/KeepEdgeProcessor.java b/src/keepanno/java/com/android/tools/r8/keepanno/processor/KeepEdgeProcessor.java
index 36bbaeb..58601a6 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/processor/KeepEdgeProcessor.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/processor/KeepEdgeProcessor.java
@@ -16,7 +16,6 @@
import com.android.tools.r8.keepanno.ast.KeepEdge;
import com.android.tools.r8.keepanno.ast.KeepEdge.Builder;
import com.android.tools.r8.keepanno.ast.KeepItemPattern;
-import com.android.tools.r8.keepanno.ast.KeepMembersPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodNamePattern;
import com.android.tools.r8.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.keepanno.ast.KeepQualifiedClassNamePattern;
@@ -137,11 +136,8 @@
if (methodNameValue != null) {
String methodName = AnnotationStringValueVisitor.getString(methodNameValue);
itemBuilder.setMembersPattern(
- KeepMembersPattern.builder()
- .addMethodPattern(
- KeepMethodPattern.builder()
- .setNamePattern(KeepMethodNamePattern.exact(methodName))
- .build())
+ KeepMethodPattern.builder()
+ .setNamePattern(KeepMethodNamePattern.exact(methodName))
.build());
}
diff --git a/src/test/java/com/android/tools/r8/keepanno/ast/KeepEdgeAstTest.java b/src/test/java/com/android/tools/r8/keepanno/ast/KeepEdgeAstTest.java
index bcdb8ed..0f07d76 100644
--- a/src/test/java/com/android/tools/r8/keepanno/ast/KeepEdgeAstTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/ast/KeepEdgeAstTest.java
@@ -170,13 +170,10 @@
}
private KeepMembersPattern defaultInitializerPattern() {
- return KeepMembersPattern.builder()
- .addMethodPattern(
- KeepMethodPattern.builder()
- .setNamePattern(KeepMethodNamePattern.initializer())
- .setParametersPattern(KeepMethodParametersPattern.none())
- .setReturnTypeVoid()
- .build())
+ return KeepMethodPattern.builder()
+ .setNamePattern(KeepMethodNamePattern.initializer())
+ .setParametersPattern(KeepMethodParametersPattern.none())
+ .setReturnTypeVoid()
.build();
}
}
diff --git a/src/test/java/com/android/tools/r8/keepanno/testsource/KeepSourceEdges.java b/src/test/java/com/android/tools/r8/keepanno/testsource/KeepSourceEdges.java
index 187a019..b6369de 100644
--- a/src/test/java/com/android/tools/r8/keepanno/testsource/KeepSourceEdges.java
+++ b/src/test/java/com/android/tools/r8/keepanno/testsource/KeepSourceEdges.java
@@ -6,7 +6,6 @@
import com.android.tools.r8.keepanno.ast.KeepConsequences;
import com.android.tools.r8.keepanno.ast.KeepEdge;
import com.android.tools.r8.keepanno.ast.KeepItemPattern;
-import com.android.tools.r8.keepanno.ast.KeepMembersPattern;
import com.android.tools.r8.keepanno.ast.KeepMethodNamePattern;
import com.android.tools.r8.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.keepanno.ast.KeepQualifiedClassNamePattern;
@@ -37,12 +36,10 @@
// Build the constructor target.
KeepMethodPattern constructorMethod =
KeepMethodPattern.builder().setNamePattern(KeepMethodNamePattern.exact("<init>")).build();
- KeepMembersPattern constructorMembers =
- KeepMembersPattern.builder().addMethodPattern(constructorMethod).build();
KeepItemPattern constructorItem =
KeepItemPattern.builder()
.setClassPattern(name)
- .setMembersPattern(constructorMembers)
+ .setMembersPattern(constructorMethod)
.build();
KeepTarget constructorTarget = KeepTarget.builder().setItem(constructorItem).build();
// The consequet set is the class an its constructor.