duke@1: /* ohair@554: * Copyright (c) 2006, Oracle and/or its affiliates. All rights reserved. duke@1: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. duke@1: * duke@1: * This code is free software; you can redistribute it and/or modify it duke@1: * under the terms of the GNU General Public License version 2 only, as duke@1: * published by the Free Software Foundation. duke@1: * duke@1: * This code is distributed in the hope that it will be useful, but WITHOUT duke@1: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or duke@1: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License duke@1: * version 2 for more details (a copy is included in the LICENSE file that duke@1: * accompanied this code). duke@1: * duke@1: * You should have received a copy of the GNU General Public License version duke@1: * 2 along with this work; if not, write to the Free Software Foundation, duke@1: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. duke@1: * ohair@554: * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA ohair@554: * or visit www.oracle.com if you need additional information or have any ohair@554: * questions. duke@1: */ duke@1: duke@1: /* duke@1: * @test duke@1: * @bug 6346249 6392177 duke@1: * @summary new Trees API duke@1: */ duke@1: duke@1: import com.sun.source.tree.*; duke@1: import com.sun.source.util.*; duke@1: import java.io.*; duke@1: import java.lang.annotation.*; duke@1: import java.util.*; duke@1: import javax.annotation.processing.*; duke@1: import javax.lang.model.SourceVersion; duke@1: import javax.lang.model.element.*; duke@1: import javax.lang.model.type.*; duke@1: import javax.tools.*; duke@1: import com.sun.tools.javac.api.JavacTool; duke@1: import com.sun.tools.javac.tree.JCTree; duke@1: import com.sun.tools.javac.tree.TreeInfo; duke@1: duke@1: @Anno duke@1: @SupportedAnnotationTypes("*") duke@1: public class TestTrees extends AbstractProcessor { duke@1: duke@1: @Anno duke@1: void annoMethod() { } duke@1: duke@1: @Anno duke@1: int annoField; duke@1: duke@1: duke@1: static final String testSrcDir = System.getProperty("test.src"); duke@1: static final String testClassDir = System.getProperty("test.classes"); duke@1: static final String self = TestTrees.class.getName(); duke@1: static PrintWriter out = new PrintWriter(System.err, true); duke@1: duke@1: public static void main(String[] args) throws IOException { duke@1: new TestTrees().run(); duke@1: } duke@1: duke@1: void run() throws IOException { duke@1: duke@1: JavacTool tool = JavacTool.create(); duke@1: duke@1: DiagnosticListener dl = new DiagnosticListener() { duke@1: public void report(Diagnostic d) { duke@1: error(d.toString()); duke@1: } duke@1: }; duke@1: duke@1: StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null); duke@1: Iterable files = duke@1: fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrcDir, self + ".java"))); duke@1: duke@1: Iterable opts = Arrays.asList("-d", "."); duke@1: duke@1: System.err.println("simple compilation, no processing"); duke@1: JavacTask task = tool.getTask(out, fm, dl, opts, null, files); duke@1: task.setTaskListener(new MyTaskListener(task)); duke@1: if (!task.call()) duke@1: throw new AssertionError("compilation failed"); duke@1: duke@1: opts = Arrays.asList("-d", ".", "-processorpath", testClassDir, "-processor", self); duke@1: duke@1: System.err.println(); duke@1: System.err.println("compilation with processing"); duke@1: task = tool.getTask(out, fm, dl,opts, null, files); duke@1: if (!task.call()) duke@1: throw new AssertionError("compilation failed"); duke@1: duke@1: if (errors > 0) duke@1: throw new AssertionError(errors + " errors occurred"); duke@1: } duke@1: duke@1: void testElement(Trees trees, Element e) { duke@1: trees.getClass(); duke@1: e.getClass(); duke@1: duke@1: System.err.println("testElement: " + e); duke@1: Tree tree = trees.getTree(e); duke@1: //System.err.println(tree); duke@1: duke@1: if (TreeInfo.symbolFor((JCTree)tree) != e) duke@1: error("bad result from getTree"); duke@1: duke@1: TreePath path = trees.getPath(e); duke@1: if (path == null) { duke@1: error("getPath returned null"); duke@1: return; duke@1: } duke@1: if (path.getLeaf() != tree) duke@1: error("bad result from getPath"); duke@1: duke@1: Element e2 = trees.getElement(path); duke@1: if (e2 == null) { duke@1: error("getElement returned null"); duke@1: return; duke@1: } duke@1: if (e2 != e) duke@1: error("bad result from getElement"); duke@1: duke@1: // The TypeMirror is not available yet when annotation processing; duke@1: // it is set up later during ANALYSE. duke@1: TypeMirror t = trees.getTypeMirror(path); duke@1: if (t != null && t.getKind() == TypeKind.DECLARED && duke@1: ((DeclaredType)t).asElement() != e2) duke@1: error("bad result from getTypeMirror"); duke@1: duke@1: for (AnnotationMirror m: e.getAnnotationMirrors()) { duke@1: testAnnotation(trees, e, m); duke@1: } duke@1: } duke@1: duke@1: void testAnnotation(Trees trees, Element e, AnnotationMirror a) { duke@1: System.err.println("testAnnotation: " + e + " " + a); duke@1: Tree tree = trees.getTree(e, a); duke@1: duke@1: if (tree.getKind() != Tree.Kind.ANNOTATION) duke@1: error("bad result from getTree"); duke@1: duke@1: TreePath path = trees.getPath(e, a); duke@1: if (path.getLeaf() != tree) duke@1: error("bad result from getPath"); duke@1: } duke@1: duke@1: void error(String msg) { duke@1: if (messager != null) duke@1: // annotation processing will happen in a separate instance/classloader duke@1: // so pass the message back to the calling instance. duke@1: messager.printMessage(Diagnostic.Kind.ERROR, msg); duke@1: else { duke@1: System.err.println(msg); duke@1: errors++; duke@1: } duke@1: duke@1: } duke@1: duke@1: Messager messager; duke@1: int errors; duke@1: duke@1: duke@1: public boolean process(Set annos, RoundEnvironment rEnv) { duke@1: Trees trees = Trees.instance(processingEnv); duke@1: messager = processingEnv.getMessager(); duke@1: duke@1: for (Element e: rEnv.getRootElements()) { duke@1: testElement(trees, e); duke@1: } duke@1: duke@1: for (TypeElement anno: annos) { duke@1: Set elts = rEnv.getElementsAnnotatedWith(anno); duke@1: System.err.println("anno: " + anno); duke@1: System.err.println("elts: " + elts); duke@1: if (elts != null) { // 6397298, should return empty set duke@1: for (Element e: rEnv.getElementsAnnotatedWith(anno)) duke@1: testElement(trees, e); duke@1: } duke@1: } duke@1: duke@1: return true; duke@1: } duke@1: duke@1: @Override duke@1: public SourceVersion getSupportedSourceVersion() { duke@1: return SourceVersion.latest(); duke@1: } duke@1: duke@1: class MyTaskListener implements TaskListener { duke@1: MyTaskListener(JavacTask task) { duke@1: this.task = task; duke@1: } duke@1: duke@1: public void started(TaskEvent e) { duke@1: System.err.println("started " + e); duke@1: } duke@1: duke@1: public void finished(TaskEvent e) { duke@1: //System.err.println("finished " + e); duke@1: switch (e.getKind()) { duke@1: case ANALYZE: duke@1: testElement(Trees.instance(task), e.getTypeElement()); duke@1: break; duke@1: } duke@1: } duke@1: duke@1: private final JavacTask task; duke@1: } duke@1: duke@1: } duke@1: duke@1: @Retention(RetentionPolicy.SOURCE) duke@1: @interface Anno { duke@1: }