6388543: improve accuracy of source positions for AnnotationValue param of Messager.printMessage

Reviewed-by: jjg
This commit is contained in:
Liam Miller-Cushon 2017-02-06 17:19:06 -08:00
parent 23017d450e
commit 9229886d99
4 changed files with 144 additions and 18 deletions

View File

@ -288,7 +288,9 @@ public class JavacElements implements Elements {
List<JCAnnotation> trees) {
for (Attribute.Compound anno : annos) {
for (JCAnnotation tree : trees) {
JCTree match = matchAnnoToTree(findme, anno, tree);
if (tree.type.tsym != anno.type.tsym)
continue;
JCTree match = matchAttributeToTree(findme, anno, tree);
if (match != null)
return match;
}
@ -297,15 +299,15 @@ public class JavacElements implements Elements {
}
/**
* Returns the tree for an annotation given an Attribute to
* search (recursively) and its corresponding tree.
* Returns the tree for an attribute given an enclosing attribute to
* search (recursively) and the enclosing attribute's corresponding tree.
* Returns null if the tree cannot be found.
*/
private JCTree matchAnnoToTree(final Attribute.Compound findme,
final Attribute attr,
final JCTree tree) {
private JCTree matchAttributeToTree(final Attribute findme,
final Attribute attr,
final JCTree tree) {
if (attr == findme)
return (tree.type.tsym == findme.type.tsym) ? tree : null;
return tree;
class Vis implements Attribute.Visitor {
JCTree result = null;
@ -317,7 +319,7 @@ public class JavacElements implements Elements {
for (Pair<MethodSymbol, Attribute> pair : anno.values) {
JCExpression expr = scanForAssign(pair.fst, tree);
if (expr != null) {
JCTree match = matchAnnoToTree(findme, pair.snd, expr);
JCTree match = matchAttributeToTree(findme, pair.snd, expr);
if (match != null) {
result = match;
return;
@ -326,16 +328,19 @@ public class JavacElements implements Elements {
}
}
public void visitArray(Attribute.Array array) {
if (tree.hasTag(NEWARRAY) &&
types.elemtype(array.type).tsym == findme.type.tsym) {
List<JCExpression> elems = ((JCNewArray) tree).elems;
if (tree.hasTag(NEWARRAY)) {
List<JCExpression> elems = ((JCNewArray)tree).elems;
for (Attribute value : array.values) {
if (value == findme) {
result = elems.head;
JCTree match = matchAttributeToTree(findme, value, elems.head);
if (match != null) {
result = match;
return;
}
elems = elems.tail;
}
} else if (array.values.length == 1) {
// the tree may not be a NEWARRAY for single-element array initializers
result = matchAttributeToTree(findme, array.values[0], tree);
}
}
public void visitEnum(Attribute.Enum e) {
@ -710,10 +715,15 @@ public class JavacElements implements Elements {
if (annoTree == null)
return elemTreeTop;
// 6388543: if v != null, we should search within annoTree to find
// the tree matching v. For now, we ignore v and return the tree of
// the annotation.
return new Pair<>(annoTree, elemTreeTop.snd);
if (v == null)
return new Pair<>(annoTree, elemTreeTop.snd);
JCTree valueTree = matchAttributeToTree(
cast(Attribute.class, v), cast(Attribute.class, a), annoTree);
if (valueTree == null)
return new Pair<>(annoTree, elemTreeTop.snd);
return new Pair<>(valueTree, elemTreeTop.snd);
}
/**

View File

@ -1,5 +1,5 @@
T6362067.java:19:8: compiler.note.proc.messager: note:elem
T6362067.java:17:1: compiler.note.proc.messager: note:anno
T6362067.java:18:1: compiler.note.proc.messager: note:anno
T6362067.java:18:1: compiler.note.proc.messager: note:value
T6362067.java:18:19: compiler.note.proc.messager: note:value
- compiler.note.proc.messager: note:nopos

View File

@ -0,0 +1,101 @@
/*
* @test /nodynamiccopyright/
* @bug 6388543
* @summary improve accuracy of source positions for AnnotationValue param of Messager.printMessage
* @library /tools/javac/lib
* @modules jdk.compiler
* @build JavacTestingAbstractProcessor T6388543
* @compile/ref=T6388543.out -XDrawDiagnostics -processor T6388543 -proc:only T6388543.java
*/
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.util.List;
import java.util.Set;
import javax.annotation.processing.RoundEnvironment;
import javax.lang.model.element.AnnotationMirror;
import javax.lang.model.element.AnnotationValue;
import javax.lang.model.element.Element;
import javax.lang.model.element.TypeElement;
import static javax.tools.Diagnostic.Kind.NOTE;
class Annotated {
@A(1)
int a1;
@A(value = 2)
int a2;
@A(value = {3})
int a3;
@A(value = {4, 5})
int a4;
@B(x = @C(x = E.ONE, y = E.TWO), y = @C(x = E.ONE, y = E.TWO))
int b;
}
@Retention(RetentionPolicy.RUNTIME)
@interface A {
int[] value() default 0;
}
@Retention(RetentionPolicy.RUNTIME)
@interface B {
C x() default @C;
C y() default @C;
}
@Retention(RetentionPolicy.RUNTIME)
@interface C {
E x() default E.ONE;
E y() default E.ONE;
}
enum E {
ONE,
TWO
}
public class T6388543 extends JavacTestingAbstractProcessor {
public boolean process(Set<? extends TypeElement> annos, RoundEnvironment roundEnv) {
if (roundEnv.processingOver()) {
return false;
}
for (Element e : elements.getTypeElement("Annotated").getEnclosedElements()) {
for (AnnotationMirror a : e.getAnnotationMirrors()) {
for (AnnotationValue v : a.getElementValues().values()) {
printValue(e, a, v);
}
}
}
return false;
}
private void printValue(Element e, AnnotationMirror a, AnnotationValue v) {
messager.printMessage(NOTE, String.format("note:value %s + %s", a, v), e, a, v);
v.accept(
new SimpleAnnotationValueVisitor<Void, Void>() {
@Override
public Void visitArray(List<? extends AnnotationValue> values, Void unused) {
for (AnnotationValue value : values) {
printValue(e, a, value);
}
return null;
}
@Override
public Void visitAnnotation(AnnotationMirror nestedAnnotation, Void unused) {
for (AnnotationValue value : nestedAnnotation.getElementValues().values()) {
printValue(e, a, value);
}
return null;
}
},
null);
}
}

View File

@ -0,0 +1,15 @@
T6388543.java:24:8: compiler.note.proc.messager: note:value @A({1}) + {1}
T6388543.java:24:8: compiler.note.proc.messager: note:value @A({1}) + 1
T6388543.java:27:16: compiler.note.proc.messager: note:value @A({2}) + {2}
T6388543.java:27:16: compiler.note.proc.messager: note:value @A({2}) + 2
T6388543.java:30:16: compiler.note.proc.messager: note:value @A({3}) + {3}
T6388543.java:30:17: compiler.note.proc.messager: note:value @A({3}) + 3
T6388543.java:33:16: compiler.note.proc.messager: note:value @A({4, 5}) + {4, 5}
T6388543.java:33:17: compiler.note.proc.messager: note:value @A({4, 5}) + 4
T6388543.java:33:20: compiler.note.proc.messager: note:value @A({4, 5}) + 5
T6388543.java:36:12: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + @C(x=E.ONE, y=E.TWO)
T6388543.java:36:20: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + E.ONE
T6388543.java:36:31: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + E.TWO
T6388543.java:36:42: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + @C(x=E.ONE, y=E.TWO)
T6388543.java:36:50: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + E.ONE
T6388543.java:36:61: compiler.note.proc.messager: note:value @B(x=@C(x=E.ONE, y=E.TWO), y=@C(x=E.ONE, y=E.TWO)) + E.TWO