test/tools/javac/processing/model/util/elements/doccomments/TestDocComments.java

Fri, 21 Dec 2012 08:45:43 -0800

author
darcy
date
Fri, 21 Dec 2012 08:45:43 -0800
changeset 1466
b52a38d4536c
parent 696
d4df3b6ee729
child 2525
2eb010b6cb22
permissions
-rw-r--r--

8005282: Use @library tag with non-relative path for javac tests
Reviewed-by: jjg

     1 /*
     2  * Copyright (c) 2010, 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 6877202 6986246
    27  * @summary Elements.getDocComment() is not getting JavaDocComments
    28  */
    30 import com.sun.source.tree.*;
    31 import com.sun.source.util.*;
    32 import java.io.*;
    33 import java.util.*;
    34 import javax.annotation.processing.*;
    35 import javax.lang.model.*;
    36 import javax.lang.model.element.*;
    37 import javax.lang.model.util.*;
    38 import javax.tools.*;
    40 /*
    41  * For a mixture of pre-existing and generated source files, ensure that we can
    42  * get the doc comments.
    43  * The test uses both a standard ElementScanner to find all the elements being
    44  * processed, and a TreeScanner to find all the local and anonymous inner classes
    45  * as well.
    46  * And, because the relevant code paths in the compiler are different for
    47  * command line and JSR 199 invocation, the test covers both ways of invoking the
    48  * compiler.
    49  */
    51 @SupportedOptions("scan")
    52 @SupportedAnnotationTypes("*")
    53 public class TestDocComments extends AbstractProcessor {
    54     enum CompileKind { API, CMD };
    55     enum ScanKind { TREE, ELEMENT };
    57     // ----- Main test driver: invoke compiler for the various test cases ------
    59     public static void main(String... args) throws Exception {
    60         for (CompileKind ck: CompileKind.values()) {
    61             for (ScanKind sk: ScanKind.values()) {
    62                 try {
    63                     test(ck, sk);
    64                 } catch (IOException e) {
    65                     error(e.toString());
    66                 }
    67             }
    68         }
    70         if (errors > 0)
    71             throw new Exception(errors + " errors occurred");
    72     }
    74     static void test(CompileKind ck, ScanKind sk) throws IOException {
    75         String testClasses = System.getProperty("test.classes");
    76         String testSrc = System.getProperty("test.src");
    77         File testDir = new File("test." + ck + "." + sk);
    78         testDir.mkdirs();
    79         String[] opts = {
    80             "-d", testDir.getPath(),
    81             "-implicit:none",
    82             "-processor", TestDocComments.class.getName(),
    83             "-processorpath", testClasses,
    84             //"-XprintRounds",
    85             "-Ascan=" + sk
    86         };
    87         File[] files = {
    88             new File(testSrc, "a/First.java")
    89         };
    91         if (ck == CompileKind.API)
    92             test_javac_api(opts, files);
    93         else
    94             test_javac_cmd(opts, files);
    95     }
    97     static void test_javac_api(String[] opts, File[] files) throws IOException {
    98         System.err.println("test javac api: " + Arrays.asList(opts) + " " + Arrays.asList(files));
    99         DiagnosticListener<JavaFileObject> dl = new DiagnosticListener<JavaFileObject>() {
   100             public void report(Diagnostic diagnostic) {
   101                 error(diagnostic.toString());
   102             }
   103         };
   104         JavaCompiler c = ToolProvider.getSystemJavaCompiler();
   105         StandardJavaFileManager fm = c.getStandardFileManager(null, null, null);
   106         Iterable<? extends JavaFileObject> units = fm.getJavaFileObjects(files);
   107         JavacTask t = (JavacTask) c.getTask(null, fm, dl, Arrays.asList(opts), null, units);
   108         t.parse();
   109         t.analyze();
   110     }
   112     static void test_javac_cmd(String[] opts, File[] files) {
   113         System.err.println("test javac cmd: " + Arrays.asList(opts) + " " + Arrays.asList(files));
   114         StringWriter sw = new StringWriter();
   115         PrintWriter pw = new PrintWriter(sw);
   116         List<String> args = new ArrayList<String>(Arrays.asList(opts));
   117         for (File f: files)
   118             args.add(f.getPath());
   119         int rc = com.sun.tools.javac.Main.compile(args.toArray(new String[args.size()]), pw);
   120         pw.close();
   121         String out = sw.toString();
   122         if (out.length() > 0)
   123             System.err.println(out);
   124         if (rc > 0)
   125             error("Compilation failed: rc=" + rc);
   126     }
   128     static void error(String msg) {
   129         System.err.println(msg);
   130         errors++;
   131         //throw new Error(msg);
   132     }
   134     static int errors;
   136     // ----- Annotation processor: scan for elements and check doc comments ----
   138     Map<String,String> options;
   139     Filer filer;
   140     Messager messager;
   141     Elements elements;
   142     Trees trees;
   143     ScanKind skind;
   145     int round = 0;
   147     @Override
   148     public SourceVersion getSupportedSourceVersion() {
   149         return SourceVersion.latest();
   150     }
   152     @Override
   153     public void init(ProcessingEnvironment pEnv) {
   154         super.init(pEnv);
   155         options = pEnv.getOptions();
   156         filer = pEnv.getFiler();
   157         messager = pEnv.getMessager();
   158         elements = pEnv.getElementUtils();
   159         trees = Trees.instance(processingEnv);
   160         skind = ScanKind.valueOf(options.get("scan"));
   161     }
   163     @Override
   164     public boolean process(Set<? extends TypeElement> annotations, RoundEnvironment roundEnv) {
   165         round++;
   167         // Scan elements using an appropriate scanner, and for each element found,
   168         // call check(Element e) to verify the doc comment on that element
   169         for (Element e: roundEnv.getRootElements()) {
   170             System.err.println("scan " + skind + " " + e.getKind() + " " + e.getSimpleName());
   171             if (skind == ScanKind.TREE) {
   172                 new TestTreeScanner().scan(trees.getPath(e), trees);
   173             }  else
   174                 new TestElementScanner().scan(e);
   175         }
   177         // For a few rounds, generate new source files, so that we can check whether
   178         // doc comments are correctly handled in subsequent processing rounds
   179         final int MAX_ROUNDS = 3;
   180         if (round <= MAX_ROUNDS) {
   181             String pkg = "p";
   182             String currClass = "Gen" + round;
   183             String curr = pkg + "." + currClass;
   184             String next = (round < MAX_ROUNDS) ? (pkg + ".Gen" + (round + 1)) : "z.Last";
   185             StringBuilder text = new StringBuilder();
   186             text.append("package ").append(pkg).append(";\n");
   187             text.append("/** CLASS ").append(currClass).append(" */\n");
   188             text.append("public class ").append(currClass).append(" {\n");
   189             text.append("    /** CONSTRUCTOR <init> **/\n");
   190             text.append("    ").append(currClass).append("() { }\n");
   191             text.append("    /** FIELD x */\n");
   192             text.append("    ").append(next).append(" x;\n");
   193             text.append("    /** METHOD m */\n");
   194             text.append("    void m() { }\n");
   195             text.append("}\n");
   197             try {
   198                 JavaFileObject fo = filer.createSourceFile(curr);
   199                 Writer out = fo.openWriter();
   200                 try {
   201                     out.write(text.toString());
   202                 } finally {
   203                     out.close();
   204                 }
   205             } catch (IOException e) {
   206                 throw new Error(e);
   207             }
   208         }
   210         return true;
   211     }
   213     /*
   214      * Check that the doc comment on an element is as expected.
   215      * This method is invoked for each element found by the scanners run by process.
   216      */
   217     void check(Element e) {
   218         System.err.println("Checking " + e);
   220         String dc = elements.getDocComment(e);
   221         System.err.println("   found " + dc);
   223         String expect = (e.getKind() + " " + e.getSimpleName()); // default
   225         Name name = e.getSimpleName();
   226         Element encl = e.getEnclosingElement();
   227         Name enclName = encl.getSimpleName();
   228         ElementKind enclKind = encl.getKind();
   229         switch (e.getKind()) {
   230             case PARAMETER:
   231             case LOCAL_VARIABLE:
   232                 // doc comments not retained for these elements
   233                 expect = null;
   234                 break;
   236             case CONSTRUCTOR:
   237                 if (enclName.length() == 0 || enclKind == ElementKind.ENUM) {
   238                     // Enum constructor is synthetic
   239                     expect = null;
   240                 }
   241                 break;
   243             case METHOD:
   244                 if (enclKind == ElementKind.ENUM
   245                         && (name.contentEquals("values") || name.contentEquals("valueOf"))) {
   246                     // synthetic enum methods
   247                     expect = null;
   248                 }
   249                 break;
   251             case CLASS:
   252                 if (e.getSimpleName().length() == 0) {
   253                     // anon inner class
   254                     expect = null;
   255                 }
   256                 break;
   257         }
   259         System.err.println("  expect " + expect);
   261         if (dc == null ? expect == null : dc.trim().equals(expect))
   262             return;
   264         if (dc == null)
   265             messager.printMessage(Diagnostic.Kind.ERROR, "doc comment is null", e);
   266         else {
   267             messager.printMessage(Diagnostic.Kind.ERROR,
   268                     "unexpected comment: \"" + dc + "\", expected \"" + expect + "\"", e);
   269         }
   270     }
   272     // ----- Scanners to find elements -----------------------------------------
   274     class TestElementScanner extends ElementScanner7<Void, Void> {
   275         @Override
   276         public Void visitExecutable(ExecutableElement e, Void _) {
   277             check(e);
   278             return super.visitExecutable(e, _);
   279         }
   280         @Override
   281         public Void visitType(TypeElement e, Void _) {
   282             check(e);
   283             return super.visitType(e, _);
   284         }
   285         @Override
   286         public Void visitVariable(VariableElement e, Void _) {
   287             check(e);
   288             return super.visitVariable(e, _);
   289         }
   290     }
   292     class TestTreeScanner extends TreePathScanner<Void,Trees> {
   293         @Override
   294         public Void visitClass(ClassTree tree, Trees trees) {
   295             check(trees.getElement(getCurrentPath()));
   296             return super.visitClass(tree, trees);
   297         }
   298         @Override
   299         public Void visitMethod(MethodTree tree, Trees trees) {
   300             check(trees.getElement(getCurrentPath()));
   301             return super.visitMethod(tree, trees);
   302         }
   303         @Override
   304         public Void visitVariable(VariableTree tree, Trees trees) {
   305             check(trees.getElement(getCurrentPath()));
   306             return super.visitVariable(tree, trees);
   307         }
   308     }
   310 }

mercurial