6411385: Trees.getPath does not work for constructors
Summary: Enhancing TestTrees test to ensure proper function of Trees.getPath/getTree, fixing cases where getTree did not work properly.
Reviewed-by: jjg
Contributed-by: jan.lahoda@oracle.com, dusan.balek@oracle.com
--- a/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Thu Feb 20 20:00:43 2014 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri Feb 21 10:35:19 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -269,20 +269,7 @@
}
public JCTree getTree(Element element) {
- Symbol symbol = (Symbol) element;
- TypeSymbol enclosing = symbol.enclClass();
- Env<AttrContext> env = enter.getEnv(enclosing);
- if (env == null)
- return null;
- JCClassDecl classNode = env.enclClass;
- if (classNode != null) {
- if (TreeInfo.symbolFor(classNode) == element)
- return classNode;
- for (JCTree node : classNode.getMembers())
- if (TreeInfo.symbolFor(node) == element)
- return node;
- }
- return null;
+ return getTree(element, null);
}
public JCTree getTree(Element e, AnnotationMirror a) {
--- a/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Thu Feb 20 20:00:43 2014 -0800
+++ b/langtools/src/share/classes/com/sun/tools/javac/model/JavacElements.java Fri Feb 21 10:35:19 2014 +0100
@@ -193,13 +193,17 @@
public void visitVarDef(JCVariableDecl tree) {
result = tree.mods.annotations;
}
+ @Override
+ public void visitTypeParameter(JCTypeParameter tree) {
+ result = tree.annotations;
+ }
}
Vis vis = new Vis();
tree.accept(vis);
if (vis.result == null)
return null;
- List<Attribute.Compound> annos = sym.getRawAttributes();
+ List<Attribute.Compound> annos = sym.getAnnotationMirrors();
return matchAnnoToTree(cast(Attribute.Compound.class, findme),
annos,
vis.result);
--- a/langtools/test/tools/javac/api/TestTrees.java Thu Feb 20 20:00:43 2014 -0800
+++ b/langtools/test/tools/javac/api/TestTrees.java Fri Feb 21 10:35:19 2014 +0100
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
@@ -23,7 +23,7 @@
/*
* @test
- * @bug 6346249 6392177
+ * @bug 6346249 6392177 6411385
* @summary new Trees API
*/
@@ -51,6 +51,9 @@
@Anno
int annoField;
+ @Anno
+ public TestTrees() {
+ }
static final String testSrcDir = System.getProperty("test.src");
static final String testClassDir = System.getProperty("test.classes");
@@ -75,7 +78,7 @@
Iterable<? extends JavaFileObject> files =
fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java")));
- Iterable<String> opts = Arrays.asList("-d", ".");
+ Iterable<String> opts = Arrays.asList("-d", ".", "-XDcompilePolicy=simple");
System.err.println("simple compilation, no processing");
JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
@@ -83,7 +86,8 @@
if (!task.call())
throw new AssertionError("compilation failed");
- opts = Arrays.asList("-d", ".", "-processorpath", testClassDir, "-processor", self);
+ opts = Arrays.asList("-d", ".", "-processorpath", testClassDir, "-processor", self,
+ "-XDcompilePolicy=simple");
System.err.println();
System.err.println("compilation with processing");
@@ -138,7 +142,7 @@
System.err.println("testAnnotation: " + e + " " + a);
Tree tree = trees.getTree(e, a);
- if (tree.getKind() != Tree.Kind.ANNOTATION)
+ if (tree.getKind() != Tree.Kind.ANNOTATION && tree.getKind() != Tree.Kind.TYPE_ANNOTATION)
error("bad result from getTree");
TreePath path = trees.getPath(e, a);
@@ -146,6 +150,36 @@
error("bad result from getPath");
}
+ void testAllDeclarations(Trees trees, CompilationUnitTree cut) {
+ new TreePathScanner<Void, Void>() {
+ @Override public Void scan(Tree tree, Void p) {
+ if (tree == null) return null;
+ switch (tree.getKind()) {
+ case METHOD: case CLASS: case VARIABLE: case TYPE_PARAMETER:
+ TreePath path = new TreePath(getCurrentPath(), tree);
+ Element el = trees.getElement(path);
+ if (el == null) {
+ error("null element");
+ } else {
+ TreePath inferred = trees.getPath(el);
+ if (inferred == null) {
+ error("null path");
+ } else {
+ if (inferred.getLeaf() != path.getLeaf())
+ error("bad result from getPath");
+ }
+ if (trees.getTree(el) != path.getLeaf())
+ error("bad result from getTree");
+ for (AnnotationMirror m: el.getAnnotationMirrors()) {
+ testAnnotation(trees, el, m);
+ }
+ }
+ }
+ return super.scan(tree, p);
+ }
+ }.scan(cut, null);
+ }
+
void error(String msg) {
if (messager != null)
// annotation processing will happen in a separate instance/classloader
@@ -202,6 +236,7 @@
switch (e.getKind()) {
case ANALYZE:
testElement(Trees.instance(task), e.getTypeElement());
+ testAllDeclarations(Trees.instance(task), e.getCompilationUnit());
break;
}
}
@@ -209,8 +244,19 @@
private final JavacTask task;
}
+ public static class TestTypeParams<@Anno T extends CharSequence> {
+ public <@Anno T extends Object> TestTypeParams(T param) { }
+ public <@Anno T extends Number> void m(T param) {
+ int local;
+ try {
+ new String();
+ } catch (Exception exc) { }
+ }
+ }
}
@Retention(RetentionPolicy.SOURCE)
+@Target({ElementType.TYPE, ElementType.METHOD, ElementType.CONSTRUCTOR, ElementType.TYPE_PARAMETER,
+ ElementType.FIELD, ElementType.LOCAL_VARIABLE})
@interface Anno {
}