Wed, 08 Oct 2014 14:16:40 -0700
Merge
1 /*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
24 /*
25 * @test
26 * @bug 8007344
27 * @summary javac may not make tree end positions and/or doc comments
28 * available to processors and listeners
29 * @library /tools/javac/lib
30 * @build JavacTestingAbstractProcessor
31 * @run main Test
32 */
34 import java.io.File;
35 import java.io.PrintWriter;
36 import java.util.Arrays;
37 import java.util.Set;
39 import javax.annotation.processing.RoundEnvironment;
40 import javax.lang.model.element.Element;
41 import javax.lang.model.element.TypeElement;
42 import javax.tools.JavaFileObject;
43 import javax.tools.StandardJavaFileManager;
44 import javax.tools.StandardLocation;
46 import com.sun.source.doctree.DocCommentTree;
47 import com.sun.source.tree.*;
48 import com.sun.source.util.DocTrees;
49 import com.sun.source.util.JavacTask;
50 import com.sun.source.util.SourcePositions;
51 import com.sun.source.util.TaskEvent;
52 import com.sun.source.util.TaskListener;
53 import com.sun.source.util.TreePath;
54 import com.sun.source.util.TreePathScanner;
55 import com.sun.tools.javac.api.JavacTool;
56 import com.sun.tools.javac.tree.JCTree;
57 import com.sun.tools.javac.tree.Pretty;
58 import com.sun.tools.javac.util.Position;
60 /** Doc comment: Test */
61 public class Test {
62 public static final int EXPECT_DOC_COMMENTS = 3;
64 /** Doc comment: main */
65 public static void main(String... args) throws Exception {
66 PrintWriter out = new PrintWriter(System.err);
67 try {
68 new Test(out).run();
69 } finally {
70 out.flush();
71 }
72 }
74 PrintWriter out;
75 int errors;
77 Test(PrintWriter out) {
78 this.out = out;
79 }
81 /** Doc comment: run */
82 void run() throws Exception {
83 File testSrc = new File(System.getProperty("test.src"));
84 File thisFile = new File(testSrc, getClass().getName() + ".java");
85 JavacTool javac = JavacTool.create();
86 StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
87 fm.setLocation(StandardLocation.CLASS_OUTPUT, Arrays.asList(new File(".")));
88 Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjects(thisFile);
89 testAnnoProcessor(javac, fm, fos, out, EXPECT_DOC_COMMENTS);
90 testTaskListener(javac, fm, fos, out, EXPECT_DOC_COMMENTS);
92 if (errors > 0)
93 throw new Exception(errors + " errors occurred");
94 }
96 void testAnnoProcessor(JavacTool javac, StandardJavaFileManager fm,
97 Iterable<? extends JavaFileObject> files, PrintWriter out,
98 int expectedDocComments) {
99 out.println("Test annotation processor");
100 JavacTask task = javac.getTask(out, fm, null, null, null, files);
101 AnnoProc ap = new AnnoProc(DocTrees.instance(task));
102 task.setProcessors(Arrays.asList(ap));
103 task.call();
104 ap.checker.checkDocComments(expectedDocComments);
105 }
107 void testTaskListener(JavacTool javac, StandardJavaFileManager fm,
108 Iterable<? extends JavaFileObject> files, PrintWriter out,
109 int expectedDocComments) {
110 out.println("Test task listener");
111 JavacTask task = javac.getTask(out, fm, null, null, null, files);
112 TaskListnr tl = new TaskListnr(DocTrees.instance(task));
113 task.addTaskListener(tl);
114 task.call();
115 tl.checker.checkDocComments(expectedDocComments);
116 }
118 void error(String msg) {
119 out.println("Error: " + msg);
120 errors++;
121 }
123 class AnnoProc extends JavacTestingAbstractProcessor {
124 Checker checker;
126 AnnoProc(DocTrees trees) {
127 checker = new Checker(trees);
128 }
130 @Override
131 public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
132 for (Element e : roundEnv.getRootElements()) {
133 checker.scan(checker.trees.getPath(e), null);
134 }
135 return true;
136 }
137 }
139 class TaskListnr implements TaskListener {
140 Checker checker;
142 TaskListnr(DocTrees trees) {
143 checker = new Checker(trees);
144 }
146 public void started(TaskEvent e) {
147 if (e.getKind() == TaskEvent.Kind.ANALYZE)
148 checker.scan(new TreePath(e.getCompilationUnit()), null);
149 }
151 public void finished(TaskEvent e) {
152 }
153 }
155 class Checker extends TreePathScanner<Void,Void> {
156 DocTrees trees;
157 SourcePositions srcPosns;
159 int docComments = 0;
161 Checker(DocTrees trees) {
162 this.trees = trees;
163 srcPosns = trees.getSourcePositions();
164 }
166 @Override
167 public Void scan(Tree tree, Void ignore) {
168 if (tree != null) {
169 switch (tree.getKind()) {
170 // HACK: Workaround 8007350
171 // Some tree nodes do not have endpos set
172 case ASSIGNMENT:
173 case BLOCK:
174 case IDENTIFIER:
175 case METHOD_INVOCATION:
176 break;
178 default:
179 checkEndPos(getCurrentPath().getCompilationUnit(), tree);
180 }
181 }
182 return super.scan(tree, ignore);
183 }
185 @Override
186 public Void visitClass(ClassTree tree, Void ignore) {
187 checkComment();
188 return super.visitClass(tree, ignore);
189 }
191 @Override
192 public Void visitMethod(MethodTree tree, Void ignore) {
193 checkComment();
194 return super.visitMethod(tree, ignore);
195 }
197 @Override
198 public Void visitVariable(VariableTree tree, Void ignore) {
199 checkComment();
200 return super.visitVariable(tree, ignore);
201 }
203 void checkComment() {
204 DocCommentTree dc = trees.getDocCommentTree(getCurrentPath());
205 if (dc != null) {
206 out.println("comment: " + dc.toString().replaceAll("\\s+", " "));
207 docComments++;
208 }
209 }
211 void checkEndPos(CompilationUnitTree unit, Tree tree) {
212 long sp = srcPosns.getStartPosition(unit, tree);
213 long ep = srcPosns.getEndPosition(unit, tree);
214 if (sp >= 0 && ep == Position.NOPOS) {
215 error("endpos not set for " + tree.getKind()
216 + " " + Pretty.toSimpleString(((JCTree) tree))
217 +", start:" + sp);
218 }
219 }
221 void checkDocComments(int expected) {
222 if (docComments != expected) {
223 error("Unexpected number of doc comments received: "
224 + docComments + ", expected: " + expected);
225 }
226 }
228 }
229 }