test/tools/javadoc/lib/Tester.java

Wed, 09 Apr 2008 11:19:15 -0700

author
xdono
date
Wed, 09 Apr 2008 11:19:15 -0700
changeset 15
18f0b1b5ffd6
parent 1
9a66ca7c79fa
child 140
22c4c1143a3a
permissions
-rw-r--r--

Added tag jdk7-b25 for changeset 58039502942e

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

mercurial