[KeepAnno] Migrate more declarations to the new parsers
This contains a few fixes for default values and null in the parsers.
The parser exception is taken out to the KeepEdgeException type as it
seems like the two should be kept apart.
Bug: b/248408342
Change-Id: Iddbde5fa6d04d15042c0e699a5836810eccd375c
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/ClassNameParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/ClassNameParser.java
index 6712bfe..3034d7a 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/ClassNameParser.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/ClassNameParser.java
@@ -7,6 +7,7 @@
import com.android.tools.r8.keepanno.asm.ClassNameParser.ClassNameProperty;
import com.android.tools.r8.keepanno.asm.ClassSimpleNameParser.ClassSimpleNameProperty;
import com.android.tools.r8.keepanno.asm.PackageNameParser.PackageNameProperty;
+import com.android.tools.r8.keepanno.asm.TypeParser.TypeProperty;
import com.android.tools.r8.keepanno.ast.AnnotationConstants.ClassNamePattern;
import com.android.tools.r8.keepanno.ast.KeepPackagePattern;
import com.android.tools.r8.keepanno.ast.KeepQualifiedClassNamePattern;
@@ -25,7 +26,39 @@
}
public enum ClassNameProperty {
- PATTERN
+ PATTERN,
+ NAME,
+ CONSTANT,
+ }
+
+ @Override
+ boolean tryProperty(
+ ClassNameProperty property,
+ String name,
+ Object value,
+ Consumer<KeepQualifiedClassNamePattern> setValue) {
+ switch (property) {
+ case NAME:
+ return new TypeParser(getParsingContext())
+ .tryProperty(
+ TypeProperty.TYPE_NAME,
+ name,
+ value,
+ type ->
+ setValue.accept(
+ KeepQualifiedClassNamePattern.exactFromDescriptor(type.getDescriptor())));
+ case CONSTANT:
+ return new TypeParser(getParsingContext())
+ .tryProperty(
+ TypeProperty.TYPE_CONSTANT,
+ name,
+ value,
+ type ->
+ setValue.accept(
+ KeepQualifiedClassNamePattern.exactFromDescriptor(type.getDescriptor())));
+ default:
+ return false;
+ }
}
@Override
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConvertingPropertyParser.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConvertingPropertyParser.java
index 3be9c92..ddbfb58 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConvertingPropertyParser.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/ConvertingPropertyParser.java
@@ -51,7 +51,8 @@
@Override
public T2 tryParse(String name, Object value) {
- return converter.apply(parser.tryParse(name, value));
+ T1 t1 = parser.tryParse(name, value);
+ return t1 == null ? null : converter.apply(t1);
}
@Override
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 b49d399..1706b3a 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
@@ -3,11 +3,11 @@
// 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.ClassNameParser.ClassNameProperty;
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.ClassNamePattern;
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;
@@ -51,12 +51,10 @@
import com.android.tools.r8.keepanno.ast.KeepMethodReturnTypePattern;
import com.android.tools.r8.keepanno.ast.KeepOptions;
import com.android.tools.r8.keepanno.ast.KeepOptions.KeepOption;
-import com.android.tools.r8.keepanno.ast.KeepPackagePattern;
import com.android.tools.r8.keepanno.ast.KeepPreconditions;
import com.android.tools.r8.keepanno.ast.KeepQualifiedClassNamePattern;
import com.android.tools.r8.keepanno.ast.KeepTarget;
import com.android.tools.r8.keepanno.ast.KeepTypePattern;
-import com.android.tools.r8.keepanno.ast.KeepUnqualfiedClassNamePattern;
import com.android.tools.r8.keepanno.ast.ParsingContext;
import com.android.tools.r8.keepanno.ast.ParsingContext.AnnotationParsingContext;
import com.android.tools.r8.keepanno.ast.ParsingContext.ClassParsingContext;
@@ -1224,12 +1222,23 @@
return Collections.emptyList();
}
+ List<PropertyParser<?, ?>> parsers() {
+ return Collections.emptyList();
+ }
+
+ private void ignore(Object arg) {}
+
boolean tryParse(String name, Object value) {
for (Declaration<?> declaration : declarations()) {
if (declaration.tryParse(name, value)) {
return true;
}
}
+ for (PropertyParser<?, ?> parser : parsers()) {
+ if (parser.tryParse(name, value, this::ignore)) {
+ return true;
+ }
+ }
return false;
}
@@ -1240,6 +1249,12 @@
return visitor;
}
}
+ for (PropertyParser<?, ?> parser : parsers()) {
+ AnnotationVisitor visitor = parser.tryParseArray(name, this::ignore);
+ if (visitor != null) {
+ return visitor;
+ }
+ }
return null;
}
@@ -1250,6 +1265,12 @@
return visitor;
}
}
+ for (PropertyParser<?, ?> parser : parsers()) {
+ AnnotationVisitor visitor = parser.tryParseAnnotation(name, descriptor, this::ignore);
+ if (visitor != null) {
+ return visitor;
+ }
+ }
return null;
}
}
@@ -1349,45 +1370,6 @@
}
}
- private static class ClassNameDeclaration
- extends SingleDeclaration<KeepQualifiedClassNamePattern> {
-
- private ClassNameDeclaration(ParsingContext parsingContext) {
- super(parsingContext);
- }
-
- @Override
- String kind() {
- return "class-name";
- }
-
- @Override
- KeepQualifiedClassNamePattern getDefaultValue() {
- return KeepQualifiedClassNamePattern.any();
- }
-
- @Override
- KeepQualifiedClassNamePattern parse(String name, Object value) {
- if (name.equals(Item.classConstant) && value instanceof Type) {
- return KeepQualifiedClassNamePattern.exact(((Type) value).getClassName());
- }
- if (name.equals(Item.className) && value instanceof String) {
- return KeepQualifiedClassNamePattern.exact(((String) value));
- }
- return null;
- }
-
- @Override
- AnnotationVisitor parseAnnotation(
- String name, String descriptor, Consumer<KeepQualifiedClassNamePattern> setValue) {
- if (name.equals(Item.classNamePattern) && descriptor.equals(ClassNamePattern.DESCRIPTOR)) {
- return new ClassNamePatternVisitor(
- new AnnotationParsingContext(getParsingContext(), descriptor), setValue);
- }
- return super.parseAnnotation(name, descriptor, setValue);
- }
- }
-
private static class InstanceOfDeclaration extends SingleDeclaration<KeepInstanceOfPattern> {
private InstanceOfDeclaration(ParsingContext parsingContext) {
@@ -1450,17 +1432,23 @@
private final Supplier<UserBindingsHelper> getBindingsHelper;
private KeepClassItemReference boundClassItemReference = null;
- private final ClassNameDeclaration classNameDeclaration;
+ private final ClassNameParser classNameParser;
private final InstanceOfDeclaration instanceOfDeclaration;
private final List<Declaration<?>> declarations;
+ private final List<PropertyParser<?, ?>> parsers;
public ClassDeclaration(
ParsingContext parsingContext, Supplier<UserBindingsHelper> getBindingsHelper) {
this.parsingContext = parsingContext;
this.getBindingsHelper = getBindingsHelper;
- classNameDeclaration = new ClassNameDeclaration(parsingContext);
+ classNameParser = new ClassNameParser(parsingContext);
+ classNameParser.setProperty(Item.className, ClassNameProperty.NAME);
+ classNameParser.setProperty(Item.classConstant, ClassNameProperty.CONSTANT);
+ classNameParser.setProperty(Item.classNamePattern, ClassNameProperty.PATTERN);
+ parsers = ImmutableList.of(classNameParser);
+
instanceOfDeclaration = new InstanceOfDeclaration(parsingContext);
- declarations = ImmutableList.of(classNameDeclaration, instanceOfDeclaration);
+ declarations = ImmutableList.of(instanceOfDeclaration);
}
@Override
@@ -1468,12 +1456,17 @@
return declarations;
}
+ @Override
+ List<PropertyParser<?, ?>> parsers() {
+ return parsers;
+ }
+
private boolean isBindingReferenceDefined() {
return boundClassItemReference != null;
}
private boolean classPatternsAreDefined() {
- return !classNameDeclaration.isDefault() || !instanceOfDeclaration.isDefault();
+ return !classNameParser.isDefault() || !instanceOfDeclaration.isDefault();
}
private void checkAllowedDefinitions() {
@@ -1501,7 +1494,8 @@
}
if (classPatternsAreDefined()) {
return KeepClassItemPattern.builder()
- .setClassNamePattern(classNameDeclaration.getValue())
+ .setClassNamePattern(
+ classNameParser.getValueOrDefault(KeepQualifiedClassNamePattern.any()))
.setInstanceOfPattern(instanceOfDeclaration.getValue())
.build()
.toClassItemReference();
@@ -1529,94 +1523,34 @@
}
}
- private static class MethodReturnTypeDeclaration
- extends SingleDeclaration<KeepMethodReturnTypePattern> {
-
- private final MethodReturnTypeParser typeParser;
-
- private MethodReturnTypeDeclaration(ParsingContext parsingContext) {
- super(parsingContext);
- typeParser = new MethodReturnTypeParser(parsingContext);
- typeParser.setProperty(Item.methodReturnType, TypeProperty.TYPE_NAME);
- typeParser.setProperty(Item.methodReturnTypeConstant, TypeProperty.TYPE_CONSTANT);
- typeParser.setProperty(Item.methodReturnTypePattern, TypeProperty.TYPE_PATTERN);
- }
-
- @Override
- String kind() {
- return typeParser.kind();
- }
-
- @Override
- KeepMethodReturnTypePattern getDefaultValue() {
- return KeepMethodReturnTypePattern.any();
- }
-
- @Override
- public KeepMethodReturnTypePattern parse(String name, Object value) {
- return typeParser.tryParse(name, value);
- }
-
- @Override
- public AnnotationVisitor parseAnnotation(
- String name, String descriptor, Consumer<KeepMethodReturnTypePattern> setValue) {
- return typeParser.tryParseAnnotation(name, descriptor, setValue);
- }
- }
-
- private static class MethodParametersDeclaration
- extends SingleDeclaration<KeepMethodParametersPattern> {
-
- private final MethodParametersParser parser;
-
- public MethodParametersDeclaration(ParsingContext parsingContext) {
- super(parsingContext);
- parser = new MethodParametersParser(parsingContext);
- parser.setProperty(Item.methodParameters, TypeProperty.TYPE_NAME);
- parser.setProperty(Item.methodParameterTypePatterns, TypeProperty.TYPE_PATTERN);
- }
-
- @Override
- String kind() {
- return parser.kind();
- }
-
- @Override
- KeepMethodParametersPattern getDefaultValue() {
- return KeepMethodParametersPattern.any();
- }
-
- @Override
- KeepMethodParametersPattern parse(String name, Object value) {
- return null;
- }
-
- @Override
- AnnotationVisitor parseArray(String name, Consumer<KeepMethodParametersPattern> setValue) {
- return parser.tryParseArray(name, setValue);
- }
- }
-
private static class MethodDeclaration extends Declaration<KeepMethodPattern> {
private final ParsingContext parsingContext;
private KeepMethodAccessPattern.Builder accessBuilder = null;
private KeepMethodPattern.Builder builder = null;
- private final MethodReturnTypeDeclaration returnTypeDeclaration;
- private final MethodParametersDeclaration parametersDeclaration;
+ private final MethodReturnTypeParser returnTypeParser;
+ private final MethodParametersParser parametersParser;
- private final List<Declaration<?>> declarations;
+ private final List<PropertyParser<?, ?>> parsers;
private MethodDeclaration(ParsingContext parsingContext) {
this.parsingContext = parsingContext;
- returnTypeDeclaration = new MethodReturnTypeDeclaration(parsingContext);
- parametersDeclaration = new MethodParametersDeclaration(parsingContext);
- declarations = ImmutableList.of(returnTypeDeclaration, parametersDeclaration);
+
+ returnTypeParser = new MethodReturnTypeParser(parsingContext);
+ returnTypeParser.setProperty(Item.methodReturnType, TypeProperty.TYPE_NAME);
+ returnTypeParser.setProperty(Item.methodReturnTypeConstant, TypeProperty.TYPE_CONSTANT);
+ returnTypeParser.setProperty(Item.methodReturnTypePattern, TypeProperty.TYPE_PATTERN);
+
+ parametersParser = new MethodParametersParser(parsingContext);
+ parametersParser.setProperty(Item.methodParameters, TypeProperty.TYPE_NAME);
+ parametersParser.setProperty(Item.methodParameterTypePatterns, TypeProperty.TYPE_PATTERN);
+
+ parsers = ImmutableList.of(returnTypeParser, parametersParser);
}
@Override
- List<Declaration<?>> declarations() {
- return declarations;
+ List<PropertyParser<?, ?>> parsers() {
+ return parsers;
}
private KeepMethodPattern.Builder getBuilder() {
@@ -1641,11 +1575,11 @@
if (accessBuilder != null) {
getBuilder().setAccessPattern(accessBuilder.build());
}
- if (!returnTypeDeclaration.isDefault()) {
- getBuilder().setReturnTypePattern(returnTypeDeclaration.getValue());
+ if (!returnTypeParser.isDefault()) {
+ getBuilder().setReturnTypePattern(returnTypeParser.getValue());
}
- if (!parametersDeclaration.isDefault()) {
- getBuilder().setParametersPattern(parametersDeclaration.getValue());
+ if (!parametersParser.isDefault()) {
+ getBuilder().setParametersPattern(parametersParser.getValue());
}
return builder != null ? builder.build() : null;
}
@@ -1669,57 +1603,27 @@
}
}
- private static class FieldTypeDeclaration extends SingleDeclaration<KeepFieldTypePattern> {
+ private static class FieldDeclaration extends Declaration<KeepFieldPattern> {
+ private final ParsingContext parsingContext;
private final FieldTypeParser typeParser;
+ private KeepFieldAccessPattern.Builder accessBuilder = null;
+ private KeepFieldPattern.Builder builder = null;
+ private final List<PropertyParser<?, ?>> parsers;
- private FieldTypeDeclaration(ParsingContext parsingContext) {
- super(parsingContext);
+ public FieldDeclaration(ParsingContext parsingContext) {
+ this.parsingContext = parsingContext;
typeParser = new FieldTypeParser(parsingContext);
typeParser.setProperty(Item.fieldTypePattern, TypeProperty.TYPE_PATTERN);
typeParser.setProperty(Item.fieldType, TypeProperty.TYPE_NAME);
typeParser.setProperty(Item.fieldTypeConstant, TypeProperty.TYPE_CONSTANT);
+
+ parsers = Collections.singletonList(typeParser);
}
@Override
- String kind() {
- return "field type";
- }
-
- @Override
- KeepFieldTypePattern getDefaultValue() {
- return KeepFieldTypePattern.any();
- }
-
- @Override
- public KeepFieldTypePattern parse(String name, Object value) {
- return typeParser.tryParse(name, value);
- }
-
- @Override
- public AnnotationVisitor parseAnnotation(
- String name, String descriptor, Consumer<KeepFieldTypePattern> setValue) {
- return typeParser.tryParseAnnotation(name, descriptor, setValue);
- }
- }
-
- private static class FieldDeclaration extends Declaration<KeepFieldPattern> {
-
- private final ParsingContext parsingContext;
- private final FieldTypeDeclaration typeDeclaration;
- private KeepFieldAccessPattern.Builder accessBuilder = null;
- private KeepFieldPattern.Builder builder = null;
- private final List<Declaration<?>> declarations;
-
- public FieldDeclaration(ParsingContext parsingContext) {
- this.parsingContext = parsingContext;
- typeDeclaration = new FieldTypeDeclaration(parsingContext);
- declarations = Collections.singletonList(typeDeclaration);
- }
-
- @Override
- List<Declaration<?>> declarations() {
- return declarations;
+ List<PropertyParser<?, ?>> parsers() {
+ return parsers;
}
private KeepFieldPattern.Builder getBuilder() {
@@ -1744,8 +1648,8 @@
if (accessBuilder != null) {
getBuilder().setAccessPattern(accessBuilder.build());
}
- if (!typeDeclaration.isDefault()) {
- getBuilder().setTypePattern(typeDeclaration.getValue());
+ if (!typeParser.isDefault()) {
+ getBuilder().setTypePattern(typeParser.getValue());
}
return builder != null ? builder.build() : null;
}
@@ -2147,120 +2051,6 @@
}
}
- private static class ClassSimpleNameDeclaration
- extends SingleDeclaration<KeepUnqualfiedClassNamePattern> {
-
- private ClassSimpleNameDeclaration(ParsingContext parsingContext) {
- super(parsingContext);
- }
-
- @Override
- String kind() {
- return "class-simple-name";
- }
-
- @Override
- KeepUnqualfiedClassNamePattern getDefaultValue() {
- return KeepUnqualfiedClassNamePattern.any();
- }
-
- @Override
- KeepUnqualfiedClassNamePattern parse(String name, Object value) {
- if (name.equals(ClassNamePattern.simpleName) && value instanceof String) {
- return KeepUnqualfiedClassNamePattern.builder().exact((String) value).build();
- }
- return null;
- }
- }
-
- private static class PackageDeclaration extends SingleDeclaration<KeepPackagePattern> {
-
- private PackageDeclaration(ParsingContext parsingContext) {
- super(parsingContext);
- }
-
- @Override
- String kind() {
- return "package";
- }
-
- @Override
- KeepPackagePattern getDefaultValue() {
- return KeepPackagePattern.any();
- }
-
- @Override
- KeepPackagePattern parse(String name, Object value) {
- if (name.equals(ClassNamePattern.packageName) && value instanceof String) {
- return KeepPackagePattern.builder().exact((String) value).build();
- }
- return null;
- }
- }
-
- private static class ClassNamePatternDeclaration
- extends Declaration<KeepQualifiedClassNamePattern> {
-
- private final ClassSimpleNameDeclaration nameDeclaration;
- private final PackageDeclaration packageDeclaration;
- private final List<Declaration<?>> declarations;
-
- public ClassNamePatternDeclaration(ParsingContext parsingContext) {
- nameDeclaration = new ClassSimpleNameDeclaration(parsingContext);
- packageDeclaration = new PackageDeclaration(parsingContext);
- declarations = ImmutableList.of(nameDeclaration, packageDeclaration);
- }
-
- @Override
- String kind() {
- return "class-name";
- }
-
- @Override
- KeepQualifiedClassNamePattern getValue() {
- if (!packageDeclaration.isDefault() || !nameDeclaration.isDefault()) {
- return KeepQualifiedClassNamePattern.builder()
- .setPackagePattern(packageDeclaration.getValue())
- .setNamePattern(nameDeclaration.getValue())
- .build();
- }
- return null;
- }
-
- @Override
- List<Declaration<?>> declarations() {
- return declarations;
- }
- }
-
- private static class ClassNamePatternVisitor extends AnnotationVisitorBase {
-
- private final ClassNamePatternDeclaration declaration;
- private final Consumer<KeepQualifiedClassNamePattern> setValue;
-
- public ClassNamePatternVisitor(
- AnnotationParsingContext parsingContext, Consumer<KeepQualifiedClassNamePattern> setValue) {
- super(parsingContext);
- this.setValue = setValue;
- declaration = new ClassNamePatternDeclaration(parsingContext);
- }
-
- @Override
- public void visit(String name, Object value) {
- if (!declaration.tryParse(name, value)) {
- super.visit(name, value);
- }
- }
-
- @Override
- public void visitEnd() {
- if (!declaration.isDefault()) {
- setValue.accept(declaration.getValue());
- }
- super.visitEnd();
- }
- }
-
private static class OptionsDeclaration extends SingleDeclaration<KeepOptions> {
public OptionsDeclaration(ParsingContext parsingContext) {
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReaderUtils.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReaderUtils.java
index 18e5c02..6f963c4 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReaderUtils.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/KeepEdgeReaderUtils.java
@@ -86,9 +86,12 @@
{
StringBuilder builder = new StringBuilder(type.length());
int i = type.length() - 1;
+ if (i < 0) {
+ throw new KeepEdgeException("Invalid empty type");
+ }
while (type.charAt(i) == ']') {
if (type.charAt(--i) != '[') {
- throw new KeepEdgeException("Invalid type: " + type);
+ throw new KeepEdgeException("Invalid type: '" + type + "'");
}
builder.append('[');
--i;
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParserBase.java b/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParserBase.java
index 0982c9f..6578a7f 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParserBase.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/asm/PropertyParserBase.java
@@ -4,7 +4,6 @@
package com.android.tools.r8.keepanno.asm;
-import com.android.tools.r8.keepanno.ast.KeepEdgeException;
import com.android.tools.r8.keepanno.ast.ParsingContext;
import java.util.HashMap;
import java.util.Map;
@@ -66,7 +65,7 @@
}
private void error(String name) {
- throw new KeepEdgeException(
+ throw parsingContext.error(
"Multiple properties defining "
+ kind()
+ ": '"
@@ -111,7 +110,11 @@
public final T tryParse(String name, Object value) {
P prop = mapping.get(name);
if (prop != null) {
- tryProperty(prop, name, value, wrap(name, unused -> {}));
+ try {
+ tryProperty(prop, name, value, wrap(name, unused -> {}));
+ } catch (RuntimeException e) {
+ throw parsingContext.rethrow(e);
+ }
return resultValue;
}
return null;
@@ -122,7 +125,11 @@
String name, String descriptor, String value, Consumer<T> setValue) {
P prop = mapping.get(name);
if (prop != null) {
- return tryPropertyEnum(prop, name, descriptor, value, wrap(name, setValue));
+ try {
+ return tryPropertyEnum(prop, name, descriptor, value, wrap(name, setValue));
+ } catch (RuntimeException e) {
+ throw parsingContext.rethrow(e);
+ }
}
return false;
}
@@ -131,7 +138,11 @@
public final AnnotationVisitor tryParseArray(String name, Consumer<T> setValue) {
P prop = mapping.get(name);
if (prop != null) {
- return tryPropertyArray(prop, name, wrap(name, setValue));
+ try {
+ return tryPropertyArray(prop, name, wrap(name, setValue));
+ } catch (RuntimeException e) {
+ throw parsingContext.rethrow(e);
+ }
}
return null;
}
@@ -141,7 +152,11 @@
String name, String descriptor, Consumer<T> setValue) {
P prop = mapping.get(name);
if (prop != null) {
- return tryPropertyAnnotation(prop, name, descriptor, wrap(name, setValue));
+ try {
+ return tryPropertyAnnotation(prop, name, descriptor, wrap(name, setValue));
+ } catch (RuntimeException e) {
+ throw parsingContext.rethrow(e);
+ }
}
return null;
}
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepAnnotationParserException.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepAnnotationParserException.java
index d98d410..910b95a 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepAnnotationParserException.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepAnnotationParserException.java
@@ -4,7 +4,7 @@
package com.android.tools.r8.keepanno.ast;
-public class KeepAnnotationParserException extends KeepEdgeException {
+public class KeepAnnotationParserException extends RuntimeException {
private final ParsingContext context;
@@ -13,6 +13,11 @@
this.context = context;
}
+ public KeepAnnotationParserException(ParsingContext context, RuntimeException cause) {
+ super(cause);
+ this.context = context;
+ }
+
@Override
public String getMessage() {
return super.getMessage() + getContextAsString();
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepQualifiedClassNamePattern.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepQualifiedClassNamePattern.java
index ee7f3d9..574336d 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepQualifiedClassNamePattern.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/KeepQualifiedClassNamePattern.java
@@ -18,6 +18,13 @@
.build();
}
+ public static KeepQualifiedClassNamePattern exactFromDescriptor(String classDescriptor) {
+ if (!classDescriptor.startsWith("L") && classDescriptor.endsWith(";")) {
+ throw new KeepEdgeException("Invalid class descriptor: " + classDescriptor);
+ }
+ return exact(classDescriptor.substring(1, classDescriptor.length() - 1).replace('/', '.'));
+ }
+
public static KeepQualifiedClassNamePattern exact(String qualifiedClassName) {
int pkgSeparator = qualifiedClassName.lastIndexOf('.');
if (pkgSeparator == 0) {
diff --git a/src/keepanno/java/com/android/tools/r8/keepanno/ast/ParsingContext.java b/src/keepanno/java/com/android/tools/r8/keepanno/ast/ParsingContext.java
index d7ce9a4..9998b6a 100644
--- a/src/keepanno/java/com/android/tools/r8/keepanno/ast/ParsingContext.java
+++ b/src/keepanno/java/com/android/tools/r8/keepanno/ast/ParsingContext.java
@@ -14,6 +14,13 @@
throw new KeepAnnotationParserException(this, message);
}
+ public KeepAnnotationParserException rethrow(RuntimeException e) {
+ if (e instanceof KeepAnnotationParserException) {
+ throw e;
+ }
+ throw new KeepAnnotationParserException(this, e);
+ }
+
public abstract String getHolderName();
public ParsingContext getParentContext() {
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepInvalidForApiTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepInvalidForApiTest.java
index 88d7afa..3d70d4c 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepInvalidForApiTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepInvalidForApiTest.java
@@ -15,8 +15,8 @@
import com.android.tools.r8.keepanno.annotations.KeepForApi;
import com.android.tools.r8.keepanno.annotations.MemberAccessFlags;
import com.android.tools.r8.keepanno.asm.KeepEdgeReader;
+import com.android.tools.r8.keepanno.ast.KeepAnnotationParserException;
import com.android.tools.r8.keepanno.ast.KeepDeclaration;
-import com.android.tools.r8.keepanno.ast.KeepEdgeException;
import com.android.tools.r8.keepanno.keeprules.KeepRuleExtractor;
import java.io.IOException;
import java.util.ArrayList;
@@ -51,7 +51,7 @@
private void assertThrowsWith(ThrowingRunnable fn, Matcher<String> matcher) {
try {
fn.run();
- } catch (KeepEdgeException e) {
+ } catch (KeepAnnotationParserException e) {
assertThat(e.getMessage(), matcher);
return;
} catch (Throwable e) {
diff --git a/src/test/java/com/android/tools/r8/keepanno/KeepInvalidTargetTest.java b/src/test/java/com/android/tools/r8/keepanno/KeepInvalidTargetTest.java
index eb5791a..9165d59 100644
--- a/src/test/java/com/android/tools/r8/keepanno/KeepInvalidTargetTest.java
+++ b/src/test/java/com/android/tools/r8/keepanno/KeepInvalidTargetTest.java
@@ -16,8 +16,8 @@
import com.android.tools.r8.keepanno.annotations.KeepTarget;
import com.android.tools.r8.keepanno.annotations.UsesReflection;
import com.android.tools.r8.keepanno.asm.KeepEdgeReader;
+import com.android.tools.r8.keepanno.ast.KeepAnnotationParserException;
import com.android.tools.r8.keepanno.ast.KeepDeclaration;
-import com.android.tools.r8.keepanno.ast.KeepEdgeException;
import com.android.tools.r8.keepanno.keeprules.KeepRuleExtractor;
import java.io.IOException;
import java.util.ArrayList;
@@ -52,7 +52,7 @@
private void assertThrowsWith(ThrowingRunnable fn, Matcher<String> matcher) {
try {
fn.run();
- } catch (KeepEdgeException e) {
+ } catch (KeepAnnotationParserException e) {
assertThat(e.getMessage(), matcher);
return;
} catch (Throwable e) {
@@ -66,7 +66,7 @@
assertThrowsWith(
() -> extractRuleForClass(MultipleClassDeclarations.class),
allOf(
- containsString("Multiple declarations"),
+ containsString("Multiple properties"),
containsString("className"),
containsString("classConstant")));
}
@@ -88,8 +88,7 @@
static class BindingAndClassDeclarations {
- // Both properties are using the "default" value of an empty string, but should still fail.
- @UsesReflection({@KeepTarget(classFromBinding = "", className = "")})
+ @UsesReflection({@KeepTarget(classFromBinding = "BINDING", className = "CLASS")})
public static void main(String[] args) {
System.out.println("Hello, world");
}