1 /*
2  * Copyright (c) 2012, 2017, 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  */
23 
24 /*
25  * @test
26  * @bug 7021614
27  * @summary extend com.sun.source API to support parsing javadoc comments
28  * @modules jdk.compiler/com.sun.tools.javac.api
29  *          jdk.compiler/com.sun.tools.javac.file
30  */
31 
32 import com.sun.source.doctree.DocCommentTree;
33 import com.sun.source.doctree.DocTree;
34 import com.sun.source.doctree.DocTree.Kind;
35 import com.sun.source.doctree.DocTreeVisitor;
36 import com.sun.source.tree.ClassTree;
37 import com.sun.source.tree.CompilationUnitTree;
38 import com.sun.source.tree.MethodTree;
39 import com.sun.source.tree.Tree;
40 import com.sun.source.tree.VariableTree;
41 import com.sun.source.util.DocTreeScanner;
42 import com.sun.source.util.DocTrees;
43 import com.sun.source.util.JavacTask;
44 import com.sun.source.util.SimpleDocTreeVisitor;
45 import com.sun.source.util.TreePath;
46 import com.sun.source.util.TreePathScanner;
47 import com.sun.tools.javac.api.JavacTool;
48 import java.io.File;
49 import java.util.ArrayList;
50 import java.util.EnumSet;
51 import java.util.List;
52 import java.util.Set;
53 import javax.lang.model.element.Name;
54 import javax.tools.JavaFileObject;
55 import javax.tools.StandardJavaFileManager;
56 
57 public class SimpleDocTreeVisitorTest {
main(String... args)58     public static void main(String... args) throws Exception {
59         SimpleDocTreeVisitorTest t = new SimpleDocTreeVisitorTest();
60         t.run();
61     }
62 
run()63     void run() throws Exception {
64         List<File> files = new ArrayList<File>();
65         File testSrc = new File(System.getProperty("test.src"));
66         for (File f: testSrc.listFiles()) {
67             if (f.isFile() && f.getName().endsWith(".java"))
68                 files.add(f);
69         }
70 
71         JavacTool javac = JavacTool.create();
72         try (StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null)) {
73 
74             Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjectsFromFiles(files);
75 
76             JavacTask t = javac.getTask(null, fm, null, null, null, fos);
77             DocTrees trees = DocTrees.instance(t);
78 
79             Iterable<? extends CompilationUnitTree> units = t.parse();
80 
81             Set<DocTree.Kind> found = EnumSet.noneOf(DocTree.Kind.class);
82             DeclScanner ds = new DeclScanner(trees, found);
83             for (CompilationUnitTree unit: units) {
84                 ds.scan(unit, null);
85             }
86 
87             for (DocTree.Kind k: DocTree.Kind.values()) {
88                 if (!found.contains(k) && k != DocTree.Kind.OTHER && k != DocTree.Kind.DOC_TYPE)
89                     error("not found: " + k);
90             }
91 
92             if (errors > 0)
93                 throw new Exception(errors + " errors occurred");
94         }
95     }
96 
error(String msg)97     void error(String msg) {
98         System.err.println("Error: " + msg);
99         errors++;
100     }
101 
102     int errors;
103 
104     static class DeclScanner extends TreePathScanner<Void, Void> {
105         DocTrees trees;
106         DocTreeScanner<Void,Void> cs;
107 
DeclScanner(DocTrees trees, final Set<DocTree.Kind> found)108         DeclScanner(DocTrees trees, final Set<DocTree.Kind> found) {
109             this.trees = trees;
110             cs = new CommentScanner(found);
111         }
112 
113         @Override
visitClass(ClassTree tree, Void ignore)114         public Void visitClass(ClassTree tree, Void ignore) {
115             super.visitClass(tree, ignore);
116             visitDecl(tree, tree.getSimpleName());
117             return null;
118         }
119 
120         @Override
visitMethod(MethodTree tree, Void ignore)121         public Void visitMethod(MethodTree tree, Void ignore) {
122             super.visitMethod(tree, ignore);
123             visitDecl(tree, tree.getName());
124             return null;
125         }
126 
127         @Override
visitVariable(VariableTree tree, Void ignore)128         public Void visitVariable(VariableTree tree, Void ignore) {
129             super.visitVariable(tree, ignore);
130             visitDecl(tree, tree.getName());
131             return null;
132         }
133 
visitDecl(Tree tree, Name name)134         void visitDecl(Tree tree, Name name) {
135             TreePath path = getCurrentPath();
136             DocCommentTree dc = trees.getDocCommentTree(path);
137             if (dc != null)
138                 cs.scan(dc, null);
139         }
140     }
141 
142     static class CommentScanner extends DocTreeScanner<Void, Void> {
143         DocTreeVisitor<Void, Void> visitor;
144 
CommentScanner(Set<DocTree.Kind> found)145         CommentScanner(Set<DocTree.Kind> found) {
146             visitor = new Visitor(found);
147         }
148 
149         @Override
scan(DocTree tree, Void ignore)150         public Void scan(DocTree tree, Void ignore) {
151             if (tree != null)
152                 tree.accept(visitor, ignore);
153             return super.scan(tree, ignore);
154         }
155     }
156 
157     static class Visitor extends SimpleDocTreeVisitor<Void, Void> {
158         Set<DocTree.Kind> found;
159 
Visitor(Set<DocTree.Kind> found)160         Visitor(Set<DocTree.Kind> found) {
161             this.found = found;
162         }
163 
164         @Override
defaultAction(DocTree tree, Void ignore)165         public Void defaultAction(DocTree tree, Void ignore) {
166             found.add(tree.getKind());
167             return null;
168         }
169     }
170 }
171