Fri, 10 May 2013 15:15:50 +0200
8012929: Trees.getElement should work not only for declaration trees, but also for use-trees
Reviewed-by: jjg
Contributed-by: Dusan Balek <dbalek@netbeans.org>, Jan Lahoda <jlahoda@netbeans.org>
1.1 --- a/src/share/classes/com/sun/tools/doclint/Env.java Sun May 12 18:18:54 2013 -0700 1.2 +++ b/src/share/classes/com/sun/tools/doclint/Env.java Fri May 10 15:15:50 2013 +0200 1.3 @@ -29,6 +29,7 @@ 1.4 import java.util.Set; 1.5 1.6 import javax.lang.model.element.Element; 1.7 +import javax.lang.model.element.ElementKind; 1.8 import javax.lang.model.element.ExecutableElement; 1.9 import javax.lang.model.element.Modifier; 1.10 import javax.lang.model.type.TypeMirror; 1.11 @@ -144,7 +145,7 @@ 1.12 AccessKind ak = null; 1.13 for (TreePath p = path; p != null; p = p.getParentPath()) { 1.14 Element e = trees.getElement(p); 1.15 - if (e != null) { 1.16 + if (e != null && e.getKind() != ElementKind.PACKAGE) { 1.17 ak = min(ak, AccessKind.of(e.getModifiers())); 1.18 } 1.19 }
2.1 --- a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Sun May 12 18:18:54 2013 -0700 2.2 +++ b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java Fri May 10 15:15:50 2013 +0200 2.3 @@ -333,11 +333,6 @@ 2.4 } 2.5 } 2.6 } 2.7 - } else if (tree.hasTag(Tag.TOPLEVEL)) { 2.8 - JCCompilationUnit cu = (JCCompilationUnit) tree; 2.9 - if (cu.sourcefile.isNameCompatible("package-info", JavaFileObject.Kind.SOURCE)) { 2.10 - sym = cu.packge; 2.11 - } 2.12 } 2.13 } 2.14 return sym;
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Sun May 12 18:18:54 2013 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri May 10 15:15:50 2013 +0200 3.3 @@ -1338,7 +1338,7 @@ 3.4 //check that resource type cannot throw InterruptedException 3.5 checkAutoCloseable(resource.pos(), localEnv, resource.type); 3.6 3.7 - VarSymbol var = (VarSymbol)TreeInfo.symbolFor(resource); 3.8 + VarSymbol var = ((JCVariableDecl) resource).sym; 3.9 var.setData(ElementKind.RESOURCE_VARIABLE); 3.10 } else { 3.11 attribTree(resource, tryEnv, twrResult);
4.1 --- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Sun May 12 18:18:54 2013 -0700 4.2 +++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java Fri May 10 15:15:50 2013 +0200 4.3 @@ -763,14 +763,40 @@ 4.4 } 4.5 4.6 public static Symbol symbolFor(JCTree node) { 4.7 + Symbol sym = symbolForImpl(node); 4.8 + 4.9 + return sym != null ? sym.baseSymbol() : null; 4.10 + } 4.11 + 4.12 + private static Symbol symbolForImpl(JCTree node) { 4.13 node = skipParens(node); 4.14 switch (node.getTag()) { 4.15 + case TOPLEVEL: 4.16 + return ((JCCompilationUnit) node).packge; 4.17 case CLASSDEF: 4.18 return ((JCClassDecl) node).sym; 4.19 case METHODDEF: 4.20 return ((JCMethodDecl) node).sym; 4.21 case VARDEF: 4.22 return ((JCVariableDecl) node).sym; 4.23 + case IDENT: 4.24 + return ((JCIdent) node).sym; 4.25 + case SELECT: 4.26 + return ((JCFieldAccess) node).sym; 4.27 + case REFERENCE: 4.28 + return ((JCMemberReference) node).sym; 4.29 + case NEWCLASS: 4.30 + return ((JCNewClass) node).constructor; 4.31 + case APPLY: 4.32 + return symbolFor(((JCMethodInvocation) node).meth); 4.33 + case TYPEAPPLY: 4.34 + return symbolFor(((JCTypeApply) node).clazz); 4.35 + case ANNOTATION: 4.36 + case TYPE_ANNOTATION: 4.37 + case TYPEPARAMETER: 4.38 + if (node.type != null) 4.39 + return node.type.tsym; 4.40 + return null; 4.41 default: 4.42 return null; 4.43 }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/api/TestGetElementReference.java Fri May 10 15:15:50 2013 +0200 5.3 @@ -0,0 +1,120 @@ 5.4 +/* 5.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 + * or visit www.oracle.com if you need additional information or have any 5.24 + * questions. 5.25 + */ 5.26 + 5.27 +/* 5.28 + * @test 5.29 + * @bug 8012929 5.30 + * @summary Trees.getElement should work not only for declaration trees, but also for use-trees 5.31 + * @build TestGetElementReference 5.32 + * @run main TestGetElementReference 5.33 + */ 5.34 + 5.35 +import com.sun.source.tree.CompilationUnitTree; 5.36 +import com.sun.source.tree.Tree; 5.37 +import com.sun.source.util.*; 5.38 +import java.io.File; 5.39 +import java.io.IOException; 5.40 +import java.net.URI; 5.41 +import java.util.Arrays; 5.42 +import java.util.regex.Matcher; 5.43 +import java.util.regex.Pattern; 5.44 +import javax.lang.model.element.Element; 5.45 +import javax.tools.Diagnostic; 5.46 +import javax.tools.DiagnosticCollector; 5.47 +import javax.tools.JavaFileObject; 5.48 +import javax.tools.SimpleJavaFileObject; 5.49 +import javax.tools.StandardJavaFileManager; 5.50 +import javax.tools.ToolProvider; 5.51 + 5.52 +public class TestGetElementReference { 5.53 + 5.54 + public static void main(String... args) throws IOException { 5.55 + File source = new File(System.getProperty("test.src", "."), "TestGetElementReferenceData.java").getAbsoluteFile(); 5.56 + StandardJavaFileManager fm = ToolProvider.getSystemJavaCompiler().getStandardFileManager(null, null, null); 5.57 + DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<>(); 5.58 + JavacTask ct = (JavacTask) ToolProvider.getSystemJavaCompiler().getTask(null, null, diagnostics, Arrays.asList("-Xjcov", "-source", "1.8"), null, fm.getJavaFileObjects(source)); 5.59 + Trees trees = Trees.instance(ct); 5.60 + CompilationUnitTree cut = ct.parse().iterator().next(); 5.61 + 5.62 + ct.analyze(); 5.63 + 5.64 + for (Diagnostic<? extends JavaFileObject> d : diagnostics.getDiagnostics()) { 5.65 + if (d.getKind() == Diagnostic.Kind.ERROR) { 5.66 + throw new IllegalStateException("Should have been attributed without errors: " + diagnostics.getDiagnostics()); 5.67 + } 5.68 + } 5.69 + 5.70 + Pattern p = Pattern.compile("/\\*getElement:(.*?)\\*/"); 5.71 + Matcher m = p.matcher(cut.getSourceFile().getCharContent(false)); 5.72 + 5.73 + while (m.find()) { 5.74 + TreePath tp = pathFor(trees, cut, m.start() - 1); 5.75 + Element found = trees.getElement(tp); 5.76 + String expected = m.group(1); 5.77 + String actual = found != null ? found.getKind() + ":" + symbolToString(found) : "<null>"; 5.78 + 5.79 + if (!expected.equals(actual)) { 5.80 + throw new IllegalStateException("expected=" + expected + "; actual=" + actual); 5.81 + } 5.82 + } 5.83 + } 5.84 + 5.85 + private static TreePath pathFor(final Trees trees, final CompilationUnitTree cut, final int pos) { 5.86 + final TreePath[] result = new TreePath[1]; 5.87 + 5.88 + new TreePathScanner<Void, Void>() { 5.89 + @Override public Void scan(Tree node, Void p) { 5.90 + if ( node != null 5.91 + && trees.getSourcePositions().getStartPosition(cut, node) <= pos 5.92 + && pos <= trees.getSourcePositions().getEndPosition(cut, node)) { 5.93 + result[0] = new TreePath(getCurrentPath(), node); 5.94 + return super.scan(node, p); 5.95 + } 5.96 + return null; 5.97 + } 5.98 + }.scan(cut, null); 5.99 + 5.100 + return result[0]; 5.101 + } 5.102 + 5.103 + private static String symbolToString(Element el) { 5.104 + switch (el.getKind()) { 5.105 + case METHOD: return symbolToString(el.getEnclosingElement()) + "." + el.toString(); 5.106 + case CONSTRUCTOR: return symbolToString(el.getEnclosingElement().getEnclosingElement()) + "." + el.toString(); 5.107 + default: 5.108 + return el.toString(); 5.109 + } 5.110 + } 5.111 + 5.112 + static class TestFileObject extends SimpleJavaFileObject { 5.113 + private final String text; 5.114 + public TestFileObject(String text) { 5.115 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 5.116 + this.text = text; 5.117 + } 5.118 + @Override public CharSequence getCharContent(boolean ignoreEncodingErrors) { 5.119 + return text; 5.120 + } 5.121 + } 5.122 + 5.123 +}
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/test/tools/javac/api/TestGetElementReferenceData.java Fri May 10 15:15:50 2013 +0200 6.3 @@ -0,0 +1,50 @@ 6.4 +/* 6.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. 6.11 + * 6.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.15 + * version 2 for more details (a copy is included in the LICENSE file that 6.16 + * accompanied this code). 6.17 + * 6.18 + * You should have received a copy of the GNU General Public License version 6.19 + * 2 along with this work; if not, write to the Free Software Foundation, 6.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.21 + * 6.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.23 + * or visit www.oracle.com if you need additional information or have any 6.24 + * questions. 6.25 + */ 6.26 +package test; 6.27 +/*getElement:PACKAGE:test*/ 6.28 +import java.lang.annotation.*; 6.29 +import static test.TestGetElementReferenceData.Sub.*; 6.30 + 6.31 +public class TestGetElementReferenceData { 6.32 + 6.33 + private static void test() { 6.34 + StringBuilder/*getElement:CLASS:java.lang.StringBuilder*/ sb = new/*getElement:CONSTRUCTOR:java.lang.StringBuilder()*/ StringBuilder(); 6.35 + sb/*getElement:LOCAL_VARIABLE:sb*/.append/*getElement:METHOD:java.lang.StringBuilder.append(int)*/(0); 6.36 + sb.reverse( /*getElement:METHOD:java.lang.StringBuilder.reverse()*/); 6.37 + java.util.List< /*getElement:INTERFACE:java.util.List*/ String> l; 6.38 + utility/*getElement:METHOD:test.TestGetElementReferenceData.Base.utility()*/(); 6.39 + target(TestGetElementReferenceData :: test/*getElement:METHOD:test.TestGetElementReferenceData.test()*/); 6.40 + } 6.41 + private static void target(Runnable r) { r.run(); } 6.42 + public static class Base { 6.43 + public static void utility() {} 6.44 + } 6.45 + public static class Sub extends @TypeAnnotation( /*getElement:ANNOTATION_TYPE:test.TestGetElementReferenceData.TypeAnnotation*/) Base { 6.46 + } 6.47 + @Deprecated( /*getElement:ANNOTATION_TYPE:java.lang.Deprecated*/) 6.48 + public static class TypeParam<TT/*getElement:TYPE_PARAMETER:TT*/> { 6.49 + } 6.50 + @Target(ElementType.TYPE_USE) 6.51 + @interface TypeAnnotation { 6.52 + } 6.53 +}