1 /*
2  * @test    /nodynamiccopyright/
3  * @bug     6388543
4  * @summary improve accuracy of source positions for AnnotationValue param of Messager.printMessage
5  * @library /tools/javac/lib
6  * @modules jdk.compiler
7  * @build   JavacTestingAbstractProcessor T6388543
8  * @compile/ref=T6388543.out -XDrawDiagnostics -processor T6388543 -proc:only T6388543.java
9  */
10 
11 import java.lang.annotation.Retention;
12 import java.lang.annotation.RetentionPolicy;
13 import java.util.List;
14 import java.util.Set;
15 import javax.annotation.processing.RoundEnvironment;
16 import javax.lang.model.element.AnnotationMirror;
17 import javax.lang.model.element.AnnotationValue;
18 import javax.lang.model.element.Element;
19 import javax.lang.model.element.TypeElement;
20 
21 import static javax.tools.Diagnostic.Kind.NOTE;
22 
23 class Annotated {
24     @A(1)
25     int a1;
26 
27     @A(value = 2)
28     int a2;
29 
30     @A(value = {3})
31     int a3;
32 
33     @A(value = {4, 5})
34     int a4;
35 
36     @B(x = @C(x = E.ONE, y = E.TWO), y = @C(x = E.ONE, y = E.TWO))
37     int b;
38 }
39 
40 @Retention(RetentionPolicy.RUNTIME)
41 @interface A {
value()42     int[] value() default 0;
43 }
44 
45 @Retention(RetentionPolicy.RUNTIME)
46 @interface B {
x()47     C x() default @C;
48 
y()49     C y() default @C;
50 }
51 
52 @Retention(RetentionPolicy.RUNTIME)
53 @interface C {
x()54     E x() default E.ONE;
55 
y()56     E y() default E.ONE;
57 }
58 
59 enum E {
60     ONE,
61     TWO
62 }
63 
64 public class T6388543 extends JavacTestingAbstractProcessor {
process(Set<? extends TypeElement> annos, RoundEnvironment roundEnv)65     public boolean process(Set<? extends TypeElement> annos, RoundEnvironment roundEnv) {
66         if (roundEnv.processingOver()) {
67             return false;
68         }
69         for (Element e : elements.getTypeElement("Annotated").getEnclosedElements()) {
70             for (AnnotationMirror a : e.getAnnotationMirrors()) {
71                 for (AnnotationValue v : a.getElementValues().values()) {
72                     printValue(e, a, v);
73                 }
74             }
75         }
76         return false;
77     }
78 
printValue(Element e, AnnotationMirror a, AnnotationValue v)79     private void printValue(Element e, AnnotationMirror a, AnnotationValue v) {
80         messager.printMessage(NOTE, String.format("note:value %s + %s", a, v), e, a, v);
81         v.accept(
82                 new SimpleAnnotationValueVisitor<Void, Void>() {
83                     @Override
84                     public Void visitArray(List<? extends AnnotationValue> values, Void unused) {
85                         for (AnnotationValue value : values) {
86                             printValue(e, a, value);
87                         }
88                         return null;
89                     }
90 
91                     @Override
92                     public Void visitAnnotation(AnnotationMirror nestedAnnotation, Void unused) {
93                         for (AnnotationValue value : nestedAnnotation.getElementValues().values()) {
94                             printValue(e, a, value);
95                         }
96                         return null;
97                     }
98                 },
99                 null);
100     }
101 }
102