Support method name in keep edge AST, readers and writers.
Bug: b/248408342
Change-Id: I1f5218631a57e8271bf1f896614223ce9963100f
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/annotations/KeepConstants.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/annotations/KeepConstants.java
index c12ba98..9479a5d 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/annotations/KeepConstants.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/annotations/KeepConstants.java
@@ -30,5 +30,6 @@
public static final Class<KeepTarget> CLASS = KeepTarget.class;
public static final String DESCRIPTOR = getDescriptor(CLASS);
public static final String classConstant = "classConstant";
+ public static final String methodName = "methodName";
}
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/asm/KeepEdgeReader.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/asm/KeepEdgeReader.java
index 3c705c7..840713d 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/asm/KeepEdgeReader.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/asm/KeepEdgeReader.java
@@ -9,6 +9,10 @@
import com.android.tools.r8.experimental.keepanno.ast.KeepEdge;
import com.android.tools.r8.experimental.keepanno.ast.KeepEdgeException;
import com.android.tools.r8.experimental.keepanno.ast.KeepItemPattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepItemPattern.Builder;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMembersPattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMethodNamePattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.experimental.keepanno.ast.KeepPreconditions;
import com.android.tools.r8.experimental.keepanno.ast.KeepQualifiedClassNamePattern;
import com.android.tools.r8.experimental.keepanno.ast.KeepTarget;
@@ -138,7 +142,8 @@
private static class KeepTargetVisitor extends AnnotationVisitorBase {
private final Parent<KeepTarget> parent;
- private String classConstant = null;
+ private KeepQualifiedClassNamePattern classNamePattern = null;
+ private KeepMethodNamePattern methodName = null;
public KeepTargetVisitor(Parent<KeepTarget> parent) {
this.parent = parent;
@@ -147,7 +152,11 @@
@Override
public void visit(String name, Object value) {
if (name.equals(Target.classConstant) && value instanceof Type) {
- classConstant = ((Type) value).getClassName();
+ classNamePattern = KeepQualifiedClassNamePattern.exact(((Type) value).getClassName());
+ return;
+ }
+ if (name.equals(Target.methodName) && value instanceof String) {
+ methodName = KeepMethodNamePattern.exact((String) value);
return;
}
super.visit(name, value);
@@ -155,18 +164,18 @@
@Override
public void visitEnd() {
- if (classConstant != null) {
- KeepTarget target =
- KeepTarget.builder()
- .setItem(
- KeepItemPattern.builder()
- .setClassPattern(KeepQualifiedClassNamePattern.exact(classConstant))
- .build())
- .build();
- parent.accept(target);
- return;
+ Builder itemBuilder = KeepItemPattern.builder();
+ if (classNamePattern != null) {
+ itemBuilder.setClassPattern(classNamePattern);
}
- throw new KeepEdgeException("Unexpected failure to build @KeepTarget");
+ if (methodName != null) {
+ itemBuilder.setMembersPattern(
+ KeepMembersPattern.builder()
+ .addMethodPattern(KeepMethodPattern.builder().setNamePattern(methodName).build())
+ .build());
+ }
+ KeepTarget target = KeepTarget.builder().setItem(itemBuilder.build()).build();
+ parent.accept(target);
}
}
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/asm/KeepEdgeWriter.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/asm/KeepEdgeWriter.java
index bda02d8..05d11ff 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/asm/KeepEdgeWriter.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/asm/KeepEdgeWriter.java
@@ -5,8 +5,10 @@
import com.android.tools.r8.experimental.keepanno.annotations.KeepConstants;
import com.android.tools.r8.experimental.keepanno.annotations.KeepConstants.Edge;
+import com.android.tools.r8.experimental.keepanno.annotations.KeepConstants.Target;
import com.android.tools.r8.experimental.keepanno.ast.KeepConsequences;
import com.android.tools.r8.experimental.keepanno.ast.KeepEdge;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMethodNamePattern;
import com.android.tools.r8.experimental.keepanno.ast.KeepPreconditions;
import com.android.tools.r8.experimental.keepanno.ast.KeepQualifiedClassNamePattern;
import com.android.tools.r8.experimental.keepanno.utils.Unimplemented;
@@ -66,6 +68,41 @@
} else {
throw new Unimplemented();
}
+ if (!clazz.getExtendsPattern().isAny()) {
+ throw new Unimplemented();
+ }
+ if (clazz.getMembersPattern().isNone()) {
+ // Default is "no methods".
+ } else if (clazz.getMembersPattern().isAll()) {
+ throw new Unimplemented();
+ } else {
+ clazz
+ .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();
+ }
+ });
+ }
return null;
});
targetVisitor.visitEnd();
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepConsequences.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepConsequences.java
index 524192e..b2c0fdd 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepConsequences.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepConsequences.java
@@ -6,6 +6,7 @@
import java.util.ArrayList;
import java.util.List;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
/**
* Set of consequences of a keep edge.
@@ -68,4 +69,9 @@
public int hashCode() {
return targets.hashCode();
}
+
+ @Override
+ public String toString() {
+ return targets.stream().map(Object::toString).collect(Collectors.joining(", "));
+ }
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepEdge.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepEdge.java
index 7cd6d9f..c6127e4 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepEdge.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepEdge.java
@@ -76,4 +76,9 @@
public int hashCode() {
return Objects.hash(preconditions, consequences);
}
+
+ @Override
+ public String toString() {
+ return "KeepEdge{" + "preconditions=" + preconditions + ", consequences=" + consequences + '}';
+ }
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepExtendsPattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepExtendsPattern.java
index 1f6ef9d..b447925 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepExtendsPattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepExtendsPattern.java
@@ -52,6 +52,11 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public String toString() {
+ return "*";
+ }
}
private static class KeepExtendsClassPattern extends KeepExtendsPattern {
@@ -84,6 +89,11 @@
public int hashCode() {
return pattern.hashCode();
}
+
+ @Override
+ public String toString() {
+ return pattern.toString();
+ }
}
public static Builder builder() {
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepItemPattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepItemPattern.java
index 443d63b..60bb6e8 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepItemPattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepItemPattern.java
@@ -98,6 +98,11 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public String toString() {
+ return "*";
+ }
}
public static class KeepClassPattern extends KeepItemPattern {
@@ -163,6 +168,18 @@
public int hashCode() {
return Objects.hash(qualifiedClassPattern, extendsPattern, membersPattern);
}
+
+ @Override
+ public String toString() {
+ return "KeepClassPattern{"
+ + "qualifiedClassPattern="
+ + qualifiedClassPattern
+ + ", extendsPattern="
+ + extendsPattern
+ + ", membersPattern="
+ + membersPattern
+ + '}';
+ }
}
public abstract boolean isAny();
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMembersPattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMembersPattern.java
index f8b3515..ee4c75a 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMembersPattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMembersPattern.java
@@ -8,6 +8,7 @@
import java.util.List;
import java.util.Objects;
import java.util.function.Consumer;
+import java.util.stream.Collectors;
public abstract class KeepMembersPattern {
@@ -100,6 +101,11 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public String toString() {
+ return "*";
+ }
}
private static class KeepMembersNonePattern extends KeepMembersPattern {
@@ -137,6 +143,11 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public String toString() {
+ return "<none>";
+ }
}
private static class KeepMembersSomePattern extends KeepMembersPattern {
@@ -184,6 +195,16 @@
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(", "))
+ + "}}";
+ }
}
private KeepMembersPattern() {}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodAccessPattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodAccessPattern.java
index 7f83937..e0cdff9 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodAccessPattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodAccessPattern.java
@@ -4,13 +4,43 @@
package com.android.tools.r8.experimental.keepanno.ast;
// TODO: finish this.
-public class KeepMethodAccessPattern {
+public abstract class KeepMethodAccessPattern {
public static KeepMethodAccessPattern any() {
- return new KeepMethodAccessPattern();
+ return Any.getInstance();
}
- public boolean isAny() {
- return true;
+ public abstract boolean isAny();
+
+ private static class Any extends KeepMethodAccessPattern {
+
+ private static Any INSTANCE = null;
+
+ private static Any getInstance() {
+ if (INSTANCE == null) {
+ INSTANCE = new Any();
+ }
+ return INSTANCE;
+ }
+
+ @Override
+ public boolean isAny() {
+ return true;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return "*";
+ }
}
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodNamePattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodNamePattern.java
index ada6701..032d4a8 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodNamePattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodNamePattern.java
@@ -47,12 +47,28 @@
public <T> T match(Supplier<T> onAny, Function<String, T> onExact) {
return onAny.get();
}
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return "*";
+ }
}
private static class KeepMethodNameExactPattern extends KeepMethodNamePattern {
private final String name;
public KeepMethodNameExactPattern(String name) {
+ assert name != null;
this.name = name;
}
@@ -60,5 +76,27 @@
public <T> T match(Supplier<T> onAny, Function<String, T> onExact) {
return onExact.apply(name);
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ KeepMethodNameExactPattern that = (KeepMethodNameExactPattern) o;
+ return name.equals(that.name);
+ }
+
+ @Override
+ public int hashCode() {
+ return name.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return name;
+ }
}
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodParametersPattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodParametersPattern.java
index 4f42202..bd7539d 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodParametersPattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodParametersPattern.java
@@ -22,6 +22,10 @@
public abstract <T> T match(Supplier<T> onAny, Function<List<KeepTypePattern>, T> onList);
+ public boolean isAny() {
+ return match(() -> true, params -> false);
+ }
+
private static class None extends KeepMethodParametersPattern {
private static None INSTANCE = null;
@@ -36,6 +40,21 @@
public <T> T match(Supplier<T> onAny, Function<List<KeepTypePattern>, T> onList) {
return onList.apply(Collections.emptyList());
}
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return "()";
+ }
}
private static class Any extends KeepMethodParametersPattern {
@@ -52,5 +71,20 @@
public <T> T match(Supplier<T> onAny, Function<List<KeepTypePattern>, T> onList) {
return onAny.get();
}
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return "(...)";
+ }
}
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodPattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodPattern.java
index 5db7d26..b393621 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodPattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodPattern.java
@@ -3,6 +3,8 @@
// BSD-style license that can be found in the LICENSE file.
package com.android.tools.r8.experimental.keepanno.ast;
+import java.util.Objects;
+
public final class KeepMethodPattern extends KeepMemberPattern {
public static Builder builder() {
@@ -62,6 +64,10 @@
KeepMethodNamePattern namePattern,
KeepMethodReturnTypePattern returnTypePattern,
KeepMethodParametersPattern parametersPattern) {
+ assert accessPattern != null;
+ assert namePattern != null;
+ assert returnTypePattern != null;
+ assert parametersPattern != null;
this.accessPattern = accessPattern;
this.namePattern = namePattern;
this.returnTypePattern = returnTypePattern;
@@ -87,4 +93,38 @@
public KeepMethodParametersPattern getParametersPattern() {
return parametersPattern;
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ KeepMethodPattern that = (KeepMethodPattern) o;
+ return accessPattern.equals(that.accessPattern)
+ && namePattern.equals(that.namePattern)
+ && returnTypePattern.equals(that.returnTypePattern)
+ && parametersPattern.equals(that.parametersPattern);
+ }
+
+ @Override
+ public int hashCode() {
+ return Objects.hash(accessPattern, namePattern, returnTypePattern, parametersPattern);
+ }
+
+ @Override
+ public String toString() {
+ return "KeepMethodPattern{"
+ + "access="
+ + accessPattern
+ + ", name="
+ + namePattern
+ + ", returnType="
+ + returnTypePattern
+ + ", parameters="
+ + parametersPattern
+ + '}';
+ }
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodReturnTypePattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodReturnTypePattern.java
index 4e7b5b9..1926c92 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodReturnTypePattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepMethodReturnTypePattern.java
@@ -23,6 +23,10 @@
public abstract <T> T match(Supplier<T> onVoid, Function<KeepTypePattern, T> onType);
+ public boolean isAny() {
+ return match(() -> false, KeepTypePattern::isAny);
+ }
+
private static class VoidType extends KeepMethodReturnTypePattern {
private static VoidType INSTANCE = null;
@@ -37,6 +41,21 @@
public <T> T match(Supplier<T> onVoid, Function<KeepTypePattern, T> onType) {
return onVoid.get();
}
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return "void";
+ }
}
private static class SomeType extends KeepMethodReturnTypePattern {
@@ -44,6 +63,7 @@
private final KeepTypePattern typePattern;
private SomeType(KeepTypePattern typePattern) {
+ assert typePattern != null;
this.typePattern = typePattern;
}
@@ -51,5 +71,27 @@
public <T> T match(Supplier<T> onVoid, Function<KeepTypePattern, T> onType) {
return onType.apply(typePattern);
}
+
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass()) {
+ return false;
+ }
+ SomeType someType = (SomeType) o;
+ return typePattern.equals(someType.typePattern);
+ }
+
+ @Override
+ public int hashCode() {
+ return typePattern.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return typePattern.toString();
+ }
}
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepOptions.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepOptions.java
index 539ae71..2def578 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepOptions.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepOptions.java
@@ -7,7 +7,9 @@
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
+import java.util.Objects;
import java.util.Set;
+import java.util.stream.Collectors;
public final class KeepOptions {
@@ -123,4 +125,11 @@
public int hashCode() {
return allowedOptions.hashCode();
}
+
+ @Override
+ public String toString() {
+ return "KeepOptions{"
+ + allowedOptions.stream().map(Objects::toString).collect(Collectors.joining(", "))
+ + '}';
+ }
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepPackagePattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepPackagePattern.java
index 10db385..ae6528f 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepPackagePattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepPackagePattern.java
@@ -88,6 +88,11 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public String toString() {
+ return "*";
+ }
}
private static final class KeepPackageTopPattern extends KeepPackageExactPattern {
@@ -114,6 +119,11 @@
public boolean isTop() {
return true;
}
+
+ @Override
+ public String toString() {
+ return "";
+ }
}
public static class KeepPackageExactPattern extends KeepPackagePattern {
@@ -166,6 +176,11 @@
public int hashCode() {
return fullPackage.hashCode();
}
+
+ @Override
+ public String toString() {
+ return fullPackage;
+ }
}
public abstract boolean isAny();
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepPreconditions.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepPreconditions.java
index 2a2c3b2..f9de6ab 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepPreconditions.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepPreconditions.java
@@ -69,6 +69,11 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public String toString() {
+ return "true";
+ }
}
private static class KeepPreconditionsSome extends KeepPreconditions {
@@ -107,5 +112,10 @@
public int hashCode() {
return preconditions.hashCode();
}
+
+ @Override
+ public String toString() {
+ return preconditions.toString();
+ }
}
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepQualifiedClassNamePattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepQualifiedClassNamePattern.java
index 8aae535..4423968 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepQualifiedClassNamePattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepQualifiedClassNamePattern.java
@@ -113,4 +113,9 @@
public int hashCode() {
return Objects.hash(packagePattern.hashCode(), namePattern.hashCode());
}
+
+ @Override
+ public String toString() {
+ return packagePattern + (packagePattern.isTop() ? "" : ".") + namePattern;
+ }
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepTarget.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepTarget.java
index 059668a..3a318c3 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepTarget.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepTarget.java
@@ -74,4 +74,9 @@
public int hashCode() {
return Objects.hash(item, options);
}
+
+ @Override
+ public String toString() {
+ return "KeepTarget{" + "item=" + item + ", options=" + options + '}';
+ }
}
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepTypePattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepTypePattern.java
index eff9e9c..b105558 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepTypePattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepTypePattern.java
@@ -23,6 +23,21 @@
public boolean isAny() {
return true;
}
+
+ @Override
+ public boolean equals(Object obj) {
+ return this == obj;
+ }
+
+ @Override
+ public int hashCode() {
+ return System.identityHashCode(this);
+ }
+
+ @Override
+ public String toString() {
+ return "*";
+ }
}
public abstract boolean isAny();
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepUnqualfiedClassNamePattern.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepUnqualfiedClassNamePattern.java
index ab38ed2..116ccf9 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepUnqualfiedClassNamePattern.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/ast/KeepUnqualfiedClassNamePattern.java
@@ -71,6 +71,11 @@
public int hashCode() {
return System.identityHashCode(this);
}
+
+ @Override
+ public String toString() {
+ return "*";
+ }
}
public static class KeepClassNameExactPattern extends KeepUnqualfiedClassNamePattern {
@@ -117,6 +122,11 @@
public int hashCode() {
return className.hashCode();
}
+
+ @Override
+ public String toString() {
+ return className;
+ }
}
public abstract boolean isAny();
diff --git a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/processor/KeepEdgeProcessor.java b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/processor/KeepEdgeProcessor.java
index 6eb851d..2140cf6 100644
--- a/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/processor/KeepEdgeProcessor.java
+++ b/src/keepanno/main/java/com/android/tools/r8/experimental/keepanno/processor/KeepEdgeProcessor.java
@@ -8,12 +8,17 @@
import static org.objectweb.asm.Opcodes.ACC_SUPER;
import com.android.tools.r8.experimental.keepanno.annotations.KeepConstants;
+import com.android.tools.r8.experimental.keepanno.annotations.KeepConstants.Edge;
+import com.android.tools.r8.experimental.keepanno.annotations.KeepConstants.Target;
import com.android.tools.r8.experimental.keepanno.asm.KeepEdgeReader;
import com.android.tools.r8.experimental.keepanno.asm.KeepEdgeWriter;
import com.android.tools.r8.experimental.keepanno.ast.KeepConsequences;
import com.android.tools.r8.experimental.keepanno.ast.KeepEdge;
import com.android.tools.r8.experimental.keepanno.ast.KeepEdge.Builder;
import com.android.tools.r8.experimental.keepanno.ast.KeepItemPattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMembersPattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMethodNamePattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.experimental.keepanno.ast.KeepQualifiedClassNamePattern;
import com.android.tools.r8.experimental.keepanno.ast.KeepTarget;
import com.android.tools.r8.experimental.keepanno.utils.Unimplemented;
@@ -98,7 +103,7 @@
}
private void processPreconditions(Builder edgeBuilder, AnnotationMirror mirror) {
- AnnotationValue preconditions = getAnnotationValue(mirror, "preconditions");
+ AnnotationValue preconditions = getAnnotationValue(mirror, Edge.preconditions);
if (preconditions == null) {
return;
}
@@ -106,7 +111,7 @@
}
private void processConsequences(Builder edgeBuilder, AnnotationMirror mirror) {
- AnnotationValue consequences = getAnnotationValue(mirror, "consequences");
+ AnnotationValue consequences = getAnnotationValue(mirror, Edge.consequences);
if (consequences == null) {
return;
}
@@ -123,11 +128,23 @@
private void processTarget(KeepTarget.Builder builder, AnnotationMirror mirror) {
KeepItemPattern.Builder itemBuilder = KeepItemPattern.builder();
- AnnotationValue classConstantValue = getAnnotationValue(mirror, "classConstant");
+ AnnotationValue classConstantValue = getAnnotationValue(mirror, Target.classConstant);
if (classConstantValue != null) {
DeclaredType type = AnnotationClassValueVisitor.getType(classConstantValue);
itemBuilder.setClassPattern(KeepQualifiedClassNamePattern.exact(type.toString()));
}
+ AnnotationValue methodNameValue = getAnnotationValue(mirror, Target.methodName);
+ if (methodNameValue != null) {
+ String methodName = AnnotationStringValueVisitor.getString(methodNameValue);
+ itemBuilder.setMembersPattern(
+ KeepMembersPattern.builder()
+ .addMethodPattern(
+ KeepMethodPattern.builder()
+ .setNamePattern(KeepMethodNamePattern.exact(methodName))
+ .build())
+ .build());
+ }
+
builder.setItem(itemBuilder.build());
}
@@ -211,6 +228,21 @@
}
}
+ private static class AnnotationStringValueVisitor
+ extends AnnotationValueVisitorBase<AnnotationStringValueVisitor> {
+ private String string;
+
+ public static String getString(AnnotationValue value) {
+ return new AnnotationStringValueVisitor().onValue(value).string;
+ }
+
+ @Override
+ public AnnotationStringValueVisitor visitString(String string, Object ignore) {
+ this.string = string;
+ return this;
+ }
+ }
+
private static class AnnotationClassValueVisitor
extends AnnotationValueVisitorBase<AnnotationClassValueVisitor> {
private DeclaredType type = null;
diff --git a/src/test/java/com/android/tools/r8/experimental/keepanno/testsource/KeepClassAndDefaultConstructorSource.java b/src/test/java/com/android/tools/r8/experimental/keepanno/testsource/KeepClassAndDefaultConstructorSource.java
index 0550498..965651d 100644
--- a/src/test/java/com/android/tools/r8/experimental/keepanno/testsource/KeepClassAndDefaultConstructorSource.java
+++ b/src/test/java/com/android/tools/r8/experimental/keepanno/testsource/KeepClassAndDefaultConstructorSource.java
@@ -9,13 +9,9 @@
@KeepEdge(
consequences = {
// Keep the class to allow lookup of it.
- @KeepTarget(classConstant = KeepClassAndDefaultConstructorSource.class)
- // TODO(b/248408342): Add default constructor target.
- // // Keep the default constructor.
- // @KeepTarget(
- // classConstant = KeepClassAndDefaultConstructorSource.class,
- // methodName = "<init>"
- // )
+ @KeepTarget(classConstant = KeepClassAndDefaultConstructorSource.class),
+ // Keep the default constructor.
+ @KeepTarget(classConstant = KeepClassAndDefaultConstructorSource.class, methodName = "<init>")
})
public class KeepClassAndDefaultConstructorSource {
diff --git a/src/test/java/com/android/tools/r8/experimental/keepanno/testsource/KeepSourceEdges.java b/src/test/java/com/android/tools/r8/experimental/keepanno/testsource/KeepSourceEdges.java
index 6c4f8fa..a334992 100644
--- a/src/test/java/com/android/tools/r8/experimental/keepanno/testsource/KeepSourceEdges.java
+++ b/src/test/java/com/android/tools/r8/experimental/keepanno/testsource/KeepSourceEdges.java
@@ -6,6 +6,9 @@
import com.android.tools.r8.experimental.keepanno.ast.KeepConsequences;
import com.android.tools.r8.experimental.keepanno.ast.KeepEdge;
import com.android.tools.r8.experimental.keepanno.ast.KeepItemPattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMembersPattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMethodNamePattern;
+import com.android.tools.r8.experimental.keepanno.ast.KeepMethodPattern;
import com.android.tools.r8.experimental.keepanno.ast.KeepQualifiedClassNamePattern;
import com.android.tools.r8.experimental.keepanno.ast.KeepTarget;
import java.util.Collections;
@@ -27,10 +30,24 @@
public static Set<KeepEdge> getKeepClassAndDefaultConstructorSourceEdges() {
Class<?> clazz = KeepClassAndDefaultConstructorSource.class;
+ // Build the class target.
KeepQualifiedClassNamePattern name = KeepQualifiedClassNamePattern.exact(clazz.getTypeName());
- KeepItemPattern item = KeepItemPattern.builder().setClassPattern(name).build();
- KeepTarget target = KeepTarget.builder().setItem(item).build();
- KeepConsequences consequences = KeepConsequences.builder().addTarget(target).build();
+ KeepItemPattern classItem = KeepItemPattern.builder().setClassPattern(name).build();
+ KeepTarget classTarget = KeepTarget.builder().setItem(classItem).build();
+ // 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)
+ .build();
+ KeepTarget constructorTarget = KeepTarget.builder().setItem(constructorItem).build();
+ // The consequet set is the class an its constructor.
+ KeepConsequences consequences =
+ KeepConsequences.builder().addTarget(classTarget).addTarget(constructorTarget).build();
KeepEdge edge = KeepEdge.builder().setConsequences(consequences).build();
return Collections.singleton(edge);
}