langtools/test/tools/javadoc/lib/OldToolTester.java
changeset 40316 20b50a99fe8d
parent 5520 86e4b9a9da40
equal deleted inserted replaced
40315:9e994c77db6a 40316:20b50a99fe8d
       
     1 /*
       
     2  * Copyright (c) 2003, 2016, 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  * A utility used to invoke and test the javadoc tool.
       
    26  *
       
    27  * @author Scott Seligman
       
    28  */
       
    29 
       
    30 
       
    31 import java.io.*;
       
    32 import java.util.*;
       
    33 import com.sun.javadoc.*;
       
    34 
       
    35 
       
    36 public class OldToolTester {
       
    37 
       
    38     protected final String TEST_SRC = System.getProperty("test.src", ".");
       
    39     protected final String TEST_CLASSES = System.getProperty("test.classes",
       
    40                                                              ".");
       
    41     private final String DEFAULT_ARGS[] = {
       
    42         "-sourcepath", TEST_SRC,
       
    43     };
       
    44 
       
    45     private final File outputFile = new File(TEST_CLASSES, "testrun.out");
       
    46     private final File expectedOutputFile = new File(TEST_SRC, "expected.out");
       
    47 //  private final File bootstrapMarkerFile = new File("bootstrap");
       
    48 
       
    49     // True if we should "set expectations" by writing the expected output file
       
    50     // rather than reading it and comparing.
       
    51 //  private final boolean bootstrap = bootstrapMarkerFile.isFile();
       
    52 
       
    53     private String docletName;
       
    54     private String[] args;
       
    55     private Writer out = null;
       
    56 
       
    57 
       
    58     /*
       
    59      * Individual tests can extend this to create generics-aware doclets.
       
    60      */
       
    61     public static abstract class Doclet extends com.sun.javadoc.Doclet {
       
    62         public static LanguageVersion languageVersion() {
       
    63             return LanguageVersion.JAVA_1_5;
       
    64         }
       
    65     }
       
    66 
       
    67 
       
    68     public OldToolTester(String docletName) {
       
    69         this(docletName, new String[0]);
       
    70     }
       
    71 
       
    72     public OldToolTester(String docletName, String... additionalArgs) {
       
    73         this.docletName = docletName;
       
    74 
       
    75         int len = DEFAULT_ARGS.length + additionalArgs.length;
       
    76         args = new String[len];
       
    77         System.arraycopy(DEFAULT_ARGS, 0, args, 0, DEFAULT_ARGS.length);
       
    78         System.arraycopy(additionalArgs, 0, args, DEFAULT_ARGS.length,
       
    79                          additionalArgs.length);
       
    80 
       
    81         try {
       
    82             out = new BufferedWriter(new FileWriter(outputFile));
       
    83         } catch (IOException e) {
       
    84             throw new Error("Could not open output file " + outputFile);
       
    85         }
       
    86     }
       
    87 
       
    88     public void run() throws IOException {
       
    89         try {
       
    90             if (com.sun.tools.javadoc.Main.execute("javadoc",
       
    91                                                    docletName,
       
    92                                                    getClass().getClassLoader(),
       
    93                                                    args) != 0) {
       
    94                 throw new Error("Javadoc errors encountered.");
       
    95             }
       
    96             System.out.println("--> Output written to " + outputFile);
       
    97         } finally {
       
    98             out.close();
       
    99         }
       
   100     }
       
   101 
       
   102     /*
       
   103      * Compare output of test run to expected output.
       
   104      * Throw an Error if they don't match.
       
   105      */
       
   106     public void verify() throws IOException {
       
   107         BufferedReader thisRun =
       
   108             new BufferedReader(new FileReader(outputFile));
       
   109         BufferedReader expected =
       
   110             new BufferedReader(new FileReader(expectedOutputFile));
       
   111 
       
   112         for (int lineNum = 1; true; lineNum++) {
       
   113             String line1 = thisRun.readLine();
       
   114             String line2 = expected.readLine();
       
   115             if (line1 == null && line2 == null) {
       
   116                 return;         // EOF with all lines matching
       
   117             }
       
   118             if (line1 == null || !line1.equals(line2)) {
       
   119                 throw new Error(outputFile + ":" + lineNum +
       
   120                                 ": output doesn't match");
       
   121             }
       
   122         }
       
   123     }
       
   124 
       
   125 
       
   126     public void println(Object o) throws IOException {
       
   127         prln(0, o);
       
   128     }
       
   129 
       
   130     public void println() throws IOException {
       
   131         prln();
       
   132     }
       
   133 
       
   134     public void printPackage(PackageDoc p) throws IOException {
       
   135         prPackage(0, p);
       
   136     }
       
   137 
       
   138     public void printClass(ClassDoc cd) throws IOException {
       
   139         if (cd.isAnnotationType())
       
   140             printAnnotationType((AnnotationTypeDoc)cd);
       
   141         else
       
   142             prClass(0, cd);
       
   143     }
       
   144 
       
   145     public void printAnnotationType(AnnotationTypeDoc at) throws IOException {
       
   146         prAnnotationType(0, at);
       
   147     }
       
   148 
       
   149     public void printField(FieldDoc f) throws IOException {
       
   150         prField(0, f);
       
   151     }
       
   152 
       
   153     public void printParameter(Parameter p) throws IOException {
       
   154         prParameter(0, p);
       
   155     }
       
   156 
       
   157     public void printMethod(MethodDoc m) throws IOException {
       
   158         prln(0, "method " + m);
       
   159         prMethod(0, m);
       
   160     }
       
   161 
       
   162     public void printAnnotationTypeElement(AnnotationTypeElementDoc e)
       
   163                                                         throws IOException {
       
   164         prln(0, "element " + e);
       
   165         prMethod(0, e);
       
   166     }
       
   167 
       
   168     public void printConstructor(ConstructorDoc c) throws IOException {
       
   169         prln(0, "constructor " + c);
       
   170         prExecutable(0, c);
       
   171     }
       
   172 
       
   173 
       
   174     private void prPackage(int off, PackageDoc p) throws IOException {
       
   175         prln(off, "package " + p);
       
   176         prAnnotations(off + 2, p.annotations());
       
   177     }
       
   178 
       
   179     private void prClass(int off, ClassDoc cd) throws IOException {
       
   180         prln(off,
       
   181              (cd.isInterface() ? "interface" : cd.isEnum() ? "enum" : "class")
       
   182              + " " + cd);
       
   183         prln(off + 2, "name: " + cd.simpleTypeName() + " / " +
       
   184              cd.typeName() + " / " + cd.qualifiedTypeName());
       
   185         prAnnotations(off + 2, cd.annotations());
       
   186         prLabel(off + 2, "type parameters");
       
   187         for (Type t : cd.typeParameters())
       
   188             prln(off + 4, t);
       
   189         prParamTags(off + 2, cd.typeParamTags());
       
   190         prLabel(off + 2, "nested in");
       
   191         prln(off + 4, cd.containingClass());
       
   192         prLabel(off + 2, "superclass");
       
   193         prln(off + 4, cd.superclassType());
       
   194         prLabel(off + 2, "interfaces");
       
   195         Type[] ts = cd.interfaceTypes();
       
   196         Arrays.sort(ts);
       
   197         for (Type t : ts)
       
   198             prln(off + 4, t);
       
   199         prLabel(off + 2, "enum constants");
       
   200         for (FieldDoc f : cd.enumConstants())
       
   201             prln(off + 4, f.name());
       
   202         prLabel(off + 2, "fields");
       
   203         for (FieldDoc f : cd.fields())
       
   204             prln(off + 4, f.type() + " " + f.name());
       
   205         prLabel(off + 2, "constructors");
       
   206         for (ConstructorDoc c : cd.constructors())
       
   207             prln(off + 4, c.name() + c.flatSignature());
       
   208         prLabel(off + 2, "methods");
       
   209         for (MethodDoc m : cd.methods())
       
   210             prln(off + 4, typeUseString(m.returnType()) + " " +
       
   211                           m.name() + m.flatSignature());
       
   212     }
       
   213 
       
   214     private void prAnnotationType(int off, AnnotationTypeDoc at)
       
   215                                                         throws IOException {
       
   216         prln(off, "@interface " + at);
       
   217         prAnnotations(off + 2, at.annotations());
       
   218         prLabel(off + 2, "elements");
       
   219         for (AnnotationTypeElementDoc e : at.elements()) {
       
   220             String def = (e.defaultValue() == null)
       
   221                                 ? ""
       
   222                                 : " default " + e.defaultValue();
       
   223             prln(off + 4, typeUseString(e.returnType()) + " " + e.name() +
       
   224                           e.flatSignature() + def);
       
   225         }
       
   226     }
       
   227 
       
   228     private void prField(int off, FieldDoc f) throws IOException {
       
   229         prln(off, "field " + typeUseString(f.type()) + " " + f.name());
       
   230         prAnnotations(off + 2, f.annotations());
       
   231     }
       
   232 
       
   233     private void prParameter(int off, Parameter p) throws IOException {
       
   234         prln(off, "parameter " + p);
       
   235         prAnnotations(off + 2, p.annotations());
       
   236     }
       
   237 
       
   238     private void prMethod(int off, MethodDoc m) throws IOException {
       
   239         prExecutable(off, m);
       
   240         prLabel(off + 2, "returns");
       
   241         prln(off + 4, typeUseString(m.returnType()));
       
   242         prLabel(off + 2, "overridden type");
       
   243         prln(off + 4, m.overriddenType());
       
   244     }
       
   245 
       
   246     private void prExecutable(int off, ExecutableMemberDoc m)
       
   247                                                         throws IOException {
       
   248         if (!m.isAnnotationTypeElement()) {
       
   249             prln(off + 2, "signature: " + m.flatSignature());
       
   250             prln(off + 2, "           " + m.signature());
       
   251         }
       
   252         prAnnotations(off + 2, m.annotations());
       
   253         prParamTags(off + 2, m.typeParamTags());
       
   254         prParamTags(off + 2, m.paramTags());
       
   255         prLabel(off + 2, "type parameters");
       
   256         for (Type t : m.typeParameters())
       
   257             prln(off + 4, t);
       
   258         prLabel(off + 2, "throws");
       
   259         Type[] ts = m.thrownExceptionTypes();
       
   260         Arrays.sort(ts);
       
   261         for (Type t : ts)
       
   262             prln(off + 4, t);
       
   263     }
       
   264 
       
   265     private void prAnnotations(int off, AnnotationDesc[] as)
       
   266                                                         throws IOException {
       
   267         prLabel(off, "annotations");
       
   268         for (AnnotationDesc a : as)
       
   269             prln(off + 2, a.toString());
       
   270     }
       
   271 
       
   272     private void prParamTags(int off, ParamTag tags[]) throws IOException {
       
   273         for (ParamTag tag : tags)
       
   274             prParamTag(off, tag);
       
   275     }
       
   276 
       
   277     private void prParamTag(int off, ParamTag tag) throws IOException {
       
   278         String name = tag.parameterName();
       
   279         if (tag.isTypeParameter()) name = "<" + name + ">";
       
   280         prln(off, "@param " + name + " " + tag.parameterComment());
       
   281     }
       
   282 
       
   283 
       
   284     private String typeUseString(Type t) {
       
   285         return (t instanceof ClassDoc || t instanceof TypeVariable)
       
   286                 ? t.typeName()
       
   287                 : t.toString();
       
   288     }
       
   289 
       
   290 
       
   291     // Labels queued for possible printing.  Innermost is first in list.
       
   292     List<Line> labels = new ArrayList<Line>();
       
   293 
       
   294     // Print label if its section is nonempty.
       
   295     void prLabel(int off, String s) {
       
   296         while (!labels.isEmpty() && labels.get(0).off >= off)
       
   297             labels.remove(0);
       
   298         labels.add(0, new Line(off, s));
       
   299     }
       
   300 
       
   301     // Print queued labels with offsets less than "off".
       
   302     void popLabels(int off) throws IOException {
       
   303         while (!labels.isEmpty()) {
       
   304             Line label = labels.remove(0);
       
   305             if (label.off < off)
       
   306                 prln(label.off, label.o + ":");
       
   307         }
       
   308     }
       
   309 
       
   310     // Print "o" at given offset.
       
   311     void pr(int off, Object o) throws IOException {
       
   312         popLabels(off);
       
   313         for (int i = 0; i < off; i++)
       
   314             out.write(' ');
       
   315         if (o != null)
       
   316             out.write(o.toString());
       
   317     }
       
   318 
       
   319     // Print "o" (if non-null) at given offset, then newline.
       
   320     void prln(int off, Object o) throws IOException {
       
   321         if (o != null) {
       
   322             pr(off, o);
       
   323             prln();
       
   324         }
       
   325     }
       
   326 
       
   327     // Print newline.
       
   328     void prln() throws IOException {
       
   329         out.write('\n');        // don't want platform-dependent separator
       
   330     }
       
   331 
       
   332 
       
   333     static class Line {
       
   334         int off;
       
   335         Object o;
       
   336         Line(int off, Object o) { this.off = off; this.o = o; }
       
   337     }
       
   338 }