test/tools/javadoc/lib/Tester.java

Tue, 25 May 2010 15:54:51 -0700

author
ohair
date
Tue, 25 May 2010 15:54:51 -0700
changeset 554
9d9f26857129
parent 289
84061bd68019
child 2525
2eb010b6cb22
permissions
-rw-r--r--

6943119: Rebrand source copyright notices
Reviewed-by: darcy

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

mercurial