summaryrefslogtreecommitdiff
path: root/tools/processors
diff options
context:
space:
mode:
authorAndrei Onea <andreionea@google.com>2019-05-08 13:50:16 +0100
committerAndrei Onea <andreionea@google.com>2019-05-08 18:03:15 +0100
commit5e226140987c6042679fc8110766959e679105e8 (patch)
tree823256152e53a1589a9d8383273627cb8e1b154f /tools/processors
parent5c47b52b93bc84521b8caa9e115ab415ed9f86ac (diff)
Support all UnsupportedAppUsage annotations in processor
Add support for the libcore UnsupportedAppUsage annotation to UnsupportedAppUsageProcessor. This is in order to make the two annotations even more interchangeable. Also take the opportunity to correct the documentation: UnsupportedAppUsageProcessor no longer is involved in creating greylist.txt, that functionality has been moved to Class2Greylist.java in the art repository. Bug: 130721457 Test: m framework-annotation-proc Change-Id: I5cf1f97ca41349fc053315a2fd5bfd53a80ae128
Diffstat (limited to 'tools/processors')
-rw-r--r--tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java54
-rw-r--r--tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java72
2 files changed, 81 insertions, 45 deletions
diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java
index ef2914610f80..5a5703ed520c 100644
--- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java
+++ b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/SignatureBuilder.java
@@ -20,12 +20,13 @@ import static javax.lang.model.element.ElementKind.PACKAGE;
import static javax.tools.Diagnostic.Kind.ERROR;
import static javax.tools.Diagnostic.Kind.WARNING;
-import android.annotation.UnsupportedAppUsage;
-
import com.google.common.base.Strings;
import com.google.common.collect.ImmutableMap;
import com.sun.tools.javac.code.Type;
+import java.lang.annotation.Annotation;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@@ -69,6 +70,7 @@ public class SignatureBuilder {
public SignatureBuilderException(String message) {
super(message);
}
+
public void report(Element offendingElement) {
mMessager.printMessage(ERROR, getMessage(), offendingElement);
}
@@ -153,7 +155,7 @@ public class SignatureBuilder {
/**
* Get the signature for an executable, either a method or a constructor.
*
- * @param name "<init>" for constructor, else the method name
+ * @param name "<init>" for constructor, else the method name
* @param method The executable element in question.
*/
private String getExecutableSignature(CharSequence name, ExecutableElement method)
@@ -191,8 +193,13 @@ public class SignatureBuilder {
return sig.toString();
}
- public String buildSignature(Element element) {
- UnsupportedAppUsage uba = element.getAnnotation(UnsupportedAppUsage.class);
+ /**
+ * Creates the signature for an annotated element.
+ *
+ * @param annotationType type of annotation being processed.
+ * @param element element for which we want to create a signature.
+ */
+ public String buildSignature(Class<? extends Annotation> annotationType, Element element) {
try {
String signature;
switch (element.getKind()) {
@@ -208,18 +215,35 @@ public class SignatureBuilder {
default:
return null;
}
- // if we have an expected signature on the annotation, warn if it doesn't match.
- if (!Strings.isNullOrEmpty(uba.expectedSignature())) {
- if (!signature.equals(uba.expectedSignature())) {
- mMessager.printMessage(
- WARNING,
- String.format("Expected signature doesn't match generated signature.\n"
- + " Expected: %s\n Generated: %s",
- uba.expectedSignature(), signature),
- element);
+ // Obtain annotation objects
+ Annotation annotation = element.getAnnotation(annotationType);
+ if (annotation == null) {
+ throw new IllegalStateException(
+ "Element doesn't have any UnsupportedAppUsage annotation");
+ }
+ try {
+ Method expectedSignatureMethod = annotationType.getMethod("expectedSignature");
+ // If we have an expected signature on the annotation, warn if it doesn't match.
+ String expectedSignature = expectedSignatureMethod.invoke(annotation).toString();
+ if (!Strings.isNullOrEmpty(expectedSignature)) {
+ if (!signature.equals(expectedSignature)) {
+ mMessager.printMessage(
+ WARNING,
+ String.format(
+ "Expected signature doesn't match generated signature.\n"
+ + " Expected: %s\n Generated: %s",
+ expectedSignature, signature),
+ element);
+ }
}
+ return signature;
+ } catch (NoSuchMethodException e) {
+ throw new IllegalStateException(
+ "Annotation type does not have expectedSignature parameter", e);
+ } catch (IllegalAccessException | InvocationTargetException e) {
+ throw new IllegalStateException(
+ "Could not get expectedSignature parameter for annotation", e);
}
- return signature;
} catch (SignatureBuilderException problem) {
problem.report(element);
return null;
diff --git a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
index d368136c7081..5bb956a1fea2 100644
--- a/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
+++ b/tools/processors/unsupportedappusage/src/android/processor/unsupportedappusage/UnsupportedAppUsageProcessor.java
@@ -18,9 +18,8 @@ package android.processor.unsupportedappusage;
import static javax.tools.StandardLocation.CLASS_OUTPUT;
-import android.annotation.UnsupportedAppUsage;
-
import com.google.common.base.Joiner;
+import com.google.common.collect.ImmutableSet;
import com.sun.tools.javac.model.JavacElements;
import com.sun.tools.javac.tree.JCTree;
import com.sun.tools.javac.util.Pair;
@@ -28,6 +27,7 @@ import com.sun.tools.javac.util.Position;
import java.io.IOException;
import java.io.PrintStream;
+import java.lang.annotation.Annotation;
import java.net.URLEncoder;
import java.util.Map;
import java.util.Set;
@@ -47,14 +47,14 @@ import javax.lang.model.element.TypeElement;
/**
* Annotation processor for {@link UnsupportedAppUsage} annotations.
*
- * This processor currently outputs two things:
- * 1. A greylist.txt containing dex signatures of all annotated elements.
- * 2. A CSV file with a mapping of dex signatures to corresponding source positions.
+ * This processor currently outputs a CSV file with a mapping of dex signatures to corresponding
+ * source positions.
*
- * The first will be used at a later stage of the build to add access flags to the dex file. The
- * second is used for automating updates to the annotations themselves.
+ * This is used for automating updates to the annotations themselves.
*/
-@SupportedAnnotationTypes({"android.annotation.UnsupportedAppUsage"})
+@SupportedAnnotationTypes({"android.annotation.UnsupportedAppUsage",
+ "dalvik.annotation.compat.UnsupportedAppUsage"
+})
public class UnsupportedAppUsageProcessor extends AbstractProcessor {
// Package name for writing output. Output will be written to the "class output" location within
@@ -62,6 +62,13 @@ public class UnsupportedAppUsageProcessor extends AbstractProcessor {
private static final String PACKAGE = "unsupportedappusage";
private static final String INDEX_CSV = "unsupportedappusage_index.csv";
+ private static final ImmutableSet<Class<? extends Annotation>> SUPPORTED_ANNOTATIONS =
+ ImmutableSet.of(android.annotation.UnsupportedAppUsage.class,
+ dalvik.annotation.compat.UnsupportedAppUsage.class);
+ private static final ImmutableSet<String> SUPPORTED_ANNOTATION_NAMES =
+ SUPPORTED_ANNOTATIONS.stream().map(annotation -> annotation.getCanonicalName()).collect(
+ ImmutableSet.toImmutableSet());
+
@Override
public SourceVersion getSupportedSourceVersion() {
return SourceVersion.latest();
@@ -92,8 +99,7 @@ public class UnsupportedAppUsageProcessor extends AbstractProcessor {
private AnnotationMirror getUnsupportedAppUsageAnnotationMirror(Element e) {
for (AnnotationMirror m : e.getAnnotationMirrors()) {
TypeElement type = (TypeElement) m.getAnnotationType().asElement();
- if (type.getQualifiedName().toString().equals(
- UnsupportedAppUsage.class.getCanonicalName())) {
+ if (SUPPORTED_ANNOTATION_NAMES.contains(type.getQualifiedName().toString())) {
return m;
}
}
@@ -133,12 +139,12 @@ public class UnsupportedAppUsageProcessor extends AbstractProcessor {
/**
* Maps an annotated element to the source position of the @UnsupportedAppUsage annotation
* attached to it. It returns CSV in the format:
- * dex-signature,filename,start-line,start-col,end-line,end-col
+ * dex-signature,filename,start-line,start-col,end-line,end-col
*
* The positions refer to the annotation itself, *not* the annotated member. This can therefore
* be used to read just the annotation from the file, and to perform in-place edits on it.
*
- * @param signature the dex signature for the element.
+ * @param signature the dex signature for the element.
* @param annotatedElement The annotated element
* @return A single line of CSV text
*/
@@ -164,28 +170,34 @@ public class UnsupportedAppUsageProcessor extends AbstractProcessor {
*/
@Override
public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
- Set<? extends Element> annotated = roundEnv.getElementsAnnotatedWith(
- UnsupportedAppUsage.class);
- if (annotated.size() == 0) {
- return true;
- }
- // build signatures for each annotated member, and put them in a map of signature to member
Map<String, Element> signatureMap = new TreeMap<>();
SignatureBuilder sb = new SignatureBuilder(processingEnv.getMessager());
- for (Element e : annotated) {
- String sig = sb.buildSignature(e);
- if (sig != null) {
- signatureMap.put(sig, e);
+ for (Class<? extends Annotation> supportedAnnotation : SUPPORTED_ANNOTATIONS) {
+ Set<? extends Element> annotated = roundEnv.getElementsAnnotatedWith(
+ supportedAnnotation);
+ if (annotated.size() == 0) {
+ continue;
+ }
+ // Build signatures for each annotated member and put them in a map from signature to
+ // member.
+ for (Element e : annotated) {
+ String sig = sb.buildSignature(supportedAnnotation, e);
+ if (sig != null) {
+ signatureMap.put(sig, e);
+ }
}
}
- try {
- writeToFile(INDEX_CSV,
- getCsvHeaders(),
- signatureMap.entrySet()
- .stream()
- .map(e -> getAnnotationIndex(e.getKey() ,e.getValue())));
- } catch (IOException e) {
- throw new RuntimeException("Failed to write output", e);
+
+ if (!signatureMap.isEmpty()) {
+ try {
+ writeToFile(INDEX_CSV,
+ getCsvHeaders(),
+ signatureMap.entrySet()
+ .stream()
+ .map(e -> getAnnotationIndex(e.getKey(), e.getValue())));
+ } catch (IOException e) {
+ throw new RuntimeException("Failed to write output", e);
+ }
}
return true;
}