langtools/test/tools/javac/api/8007344/Test.java
changeset 15562 e05336e44a9e
child 15704 02afd052face
equal deleted inserted replaced
15561:ef818953c598 15562:e05336e44a9e
       
     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  */
       
    23 
       
    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  */
       
    33 
       
    34 import java.io.File;
       
    35 import java.io.PrintWriter;
       
    36 import java.util.Arrays;
       
    37 import java.util.Set;
       
    38 
       
    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 
       
    45 import com.sun.source.doctree.DocCommentTree;
       
    46 import com.sun.source.tree.*;
       
    47 import com.sun.source.util.DocTrees;
       
    48 import com.sun.source.util.JavacTask;
       
    49 import com.sun.source.util.SourcePositions;
       
    50 import com.sun.source.util.TaskEvent;
       
    51 import com.sun.source.util.TaskListener;
       
    52 import com.sun.source.util.TreePath;
       
    53 import com.sun.source.util.TreePathScanner;
       
    54 import com.sun.tools.javac.api.JavacTool;
       
    55 import com.sun.tools.javac.tree.JCTree;
       
    56 import com.sun.tools.javac.tree.Pretty;
       
    57 import com.sun.tools.javac.util.Position;
       
    58 
       
    59 /** Doc comment: Test */
       
    60 public class Test {
       
    61     public static final int EXPECT_DOC_COMMENTS = 3;
       
    62 
       
    63     /** Doc comment: main */
       
    64     public static void main(String... args) throws Exception {
       
    65         PrintWriter out = new PrintWriter(System.err);
       
    66         try {
       
    67             new Test(out).run();
       
    68         } finally {
       
    69             out.flush();
       
    70         }
       
    71     }
       
    72 
       
    73     PrintWriter out;
       
    74     int errors;
       
    75 
       
    76     Test(PrintWriter out) {
       
    77         this.out = out;
       
    78     }
       
    79 
       
    80     /** Doc comment: run */
       
    81     void run() throws Exception {
       
    82         File testSrc = new File(System.getProperty("test.src"));
       
    83         File thisFile = new File(testSrc, getClass().getName() + ".java");
       
    84         JavacTool javac = JavacTool.create();
       
    85         StandardJavaFileManager fm = javac.getStandardFileManager(null, null, null);
       
    86         Iterable<? extends JavaFileObject> fos = fm.getJavaFileObjects(thisFile);
       
    87         testAnnoProcessor(javac, fm, fos, out, EXPECT_DOC_COMMENTS);
       
    88         testTaskListener(javac, fm, fos, out, EXPECT_DOC_COMMENTS);
       
    89 
       
    90         if (errors > 0)
       
    91             throw new Exception(errors + " errors occurred");
       
    92     }
       
    93 
       
    94     void testAnnoProcessor(JavacTool javac, StandardJavaFileManager fm,
       
    95             Iterable<? extends JavaFileObject> files, PrintWriter out,
       
    96             int expectedDocComments) {
       
    97         out.println("Test annotation processor");
       
    98         JavacTask task = javac.getTask(out, fm, null, null, null, files);
       
    99         AnnoProc ap = new AnnoProc(DocTrees.instance(task));
       
   100         task.setProcessors(Arrays.asList(ap));
       
   101         task.call();
       
   102         ap.checker.checkDocComments(expectedDocComments);
       
   103     }
       
   104 
       
   105     void testTaskListener(JavacTool javac, StandardJavaFileManager fm,
       
   106             Iterable<? extends JavaFileObject> files, PrintWriter out,
       
   107             int expectedDocComments) {
       
   108         out.println("Test task listener");
       
   109         JavacTask task = javac.getTask(out, fm, null, null, null, files);
       
   110         TaskListnr tl = new TaskListnr(DocTrees.instance(task));
       
   111         task.addTaskListener(tl);
       
   112         task.call();
       
   113         tl.checker.checkDocComments(expectedDocComments);
       
   114     }
       
   115 
       
   116     void error(String msg) {
       
   117         out.println("Error: " + msg);
       
   118         errors++;
       
   119     }
       
   120 
       
   121     class AnnoProc extends JavacTestingAbstractProcessor {
       
   122         Checker checker;
       
   123 
       
   124         AnnoProc(DocTrees trees) {
       
   125             checker = new Checker(trees);
       
   126         }
       
   127 
       
   128         @Override
       
   129         public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
       
   130             for (Element e : roundEnv.getRootElements()) {
       
   131                 checker.scan(checker.trees.getPath(e), null);
       
   132             }
       
   133             return true;
       
   134         }
       
   135     }
       
   136 
       
   137     class TaskListnr implements TaskListener {
       
   138         Checker checker;
       
   139 
       
   140         TaskListnr(DocTrees trees) {
       
   141             checker = new Checker(trees);
       
   142         }
       
   143 
       
   144         public void started(TaskEvent e) {
       
   145             if (e.getKind() == TaskEvent.Kind.ANALYZE)
       
   146                 checker.scan(new TreePath(e.getCompilationUnit()), null);
       
   147         }
       
   148 
       
   149         public void finished(TaskEvent e) {
       
   150         }
       
   151     }
       
   152 
       
   153     class Checker extends TreePathScanner<Void,Void> {
       
   154         DocTrees trees;
       
   155         SourcePositions srcPosns;
       
   156 
       
   157         int docComments = 0;
       
   158 
       
   159         Checker(DocTrees trees) {
       
   160             this.trees = trees;
       
   161             srcPosns = trees.getSourcePositions();
       
   162         }
       
   163 
       
   164         @Override
       
   165         public Void scan(Tree tree, Void ignore) {
       
   166             if (tree != null) {
       
   167                 switch (tree.getKind()) {
       
   168                     // HACK: Workaround 8007350
       
   169                     // Some tree nodes do not have endpos set
       
   170                     case ASSIGNMENT:
       
   171                     case BLOCK:
       
   172                     case IDENTIFIER:
       
   173                     case METHOD_INVOCATION:
       
   174                         break;
       
   175 
       
   176                     default:
       
   177                         checkEndPos(getCurrentPath().getCompilationUnit(), tree);
       
   178                 }
       
   179             }
       
   180             return super.scan(tree, ignore);
       
   181         }
       
   182 
       
   183         @Override
       
   184         public Void visitClass(ClassTree tree, Void ignore) {
       
   185             checkComment();
       
   186             return super.visitClass(tree, ignore);
       
   187         }
       
   188 
       
   189         @Override
       
   190         public Void visitMethod(MethodTree tree, Void ignore) {
       
   191             checkComment();
       
   192             return super.visitMethod(tree, ignore);
       
   193         }
       
   194 
       
   195         @Override
       
   196         public Void visitVariable(VariableTree tree, Void ignore) {
       
   197             checkComment();
       
   198             return super.visitVariable(tree, ignore);
       
   199         }
       
   200 
       
   201         void checkComment() {
       
   202             DocCommentTree dc = trees.getDocCommentTree(getCurrentPath());
       
   203             if (dc != null) {
       
   204                 out.println("comment: " + dc.toString().replaceAll("\\s+", " "));
       
   205                 docComments++;
       
   206             }
       
   207         }
       
   208 
       
   209         void checkEndPos(CompilationUnitTree unit, Tree tree) {
       
   210             long sp = srcPosns.getStartPosition(unit, tree);
       
   211             long ep = srcPosns.getEndPosition(unit, tree);
       
   212             if (sp >= 0 && ep == Position.NOPOS) {
       
   213                 error("endpos not set for " + tree.getKind()
       
   214                         + " " + Pretty.toSimpleString(((JCTree) tree))
       
   215                         +", start:" + sp);
       
   216             }
       
   217         }
       
   218 
       
   219         void checkDocComments(int expected) {
       
   220             if (docComments != expected) {
       
   221                 error("Unexpected number of doc comments received: "
       
   222                         + docComments + ", expected: " + expected);
       
   223             }
       
   224         }
       
   225 
       
   226     }
       
   227 }