test/tools/javadoc/lib/Tester.java

Thu, 14 May 2009 10:58:12 -0700

author
vasya
date
Thu, 14 May 2009 10:58:12 -0700
changeset 270
0f653be1a42f
parent 174
fdfed22db054
child 289
84061bd68019
permissions
-rw-r--r--

Added tag jdk7-b59 for changeset 88bcb6772159

duke@1 1 /*
xdono@174 2 * Copyright 2003-2008 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",
jjg@140 92 docletName,
jjg@140 93 getClass().getClassLoader(),
jjg@140 94 args) != 0) {
duke@1 95 throw new Error("Javadoc errors encountered.");
duke@1 96 }
duke@1 97 System.out.println("--> Output written to " + outputFile);
duke@1 98 } finally {
duke@1 99 out.close();
duke@1 100 }
duke@1 101 }
duke@1 102
duke@1 103 /*
duke@1 104 * Compare output of test run to expected output.
duke@1 105 * Throw an Error if they don't match.
duke@1 106 */
duke@1 107 public void verify() throws IOException {
duke@1 108 BufferedReader thisRun =
duke@1 109 new BufferedReader(new FileReader(outputFile));
duke@1 110 BufferedReader expected =
duke@1 111 new BufferedReader(new FileReader(expectedOutputFile));
duke@1 112
duke@1 113 for (int lineNum = 1; true; lineNum++) {
duke@1 114 String line1 = thisRun.readLine();
duke@1 115 String line2 = expected.readLine();
duke@1 116 if (line1 == null && line2 == null) {
duke@1 117 return; // EOF with all lines matching
duke@1 118 }
duke@1 119 if (line1 == null || !line1.equals(line2)) {
duke@1 120 throw new Error(outputFile + ":" + lineNum +
duke@1 121 ": output doesn't match");
duke@1 122 }
duke@1 123 }
duke@1 124 }
duke@1 125
duke@1 126
duke@1 127 public void println(Object o) throws IOException {
duke@1 128 prln(0, o);
duke@1 129 }
duke@1 130
duke@1 131 public void println() throws IOException {
duke@1 132 prln();
duke@1 133 }
duke@1 134
duke@1 135 public void printPackage(PackageDoc p) throws IOException {
duke@1 136 prPackage(0, p);
duke@1 137 }
duke@1 138
duke@1 139 public void printClass(ClassDoc cd) throws IOException {
duke@1 140 if (cd.isAnnotationType())
duke@1 141 printAnnotationType((AnnotationTypeDoc)cd);
duke@1 142 else
duke@1 143 prClass(0, cd);
duke@1 144 }
duke@1 145
duke@1 146 public void printAnnotationType(AnnotationTypeDoc at) throws IOException {
duke@1 147 prAnnotationType(0, at);
duke@1 148 }
duke@1 149
duke@1 150 public void printField(FieldDoc f) throws IOException {
duke@1 151 prField(0, f);
duke@1 152 }
duke@1 153
duke@1 154 public void printParameter(Parameter p) throws IOException {
duke@1 155 prParameter(0, p);
duke@1 156 }
duke@1 157
duke@1 158 public void printMethod(MethodDoc m) throws IOException {
duke@1 159 prln(0, "method " + m);
duke@1 160 prMethod(0, m);
duke@1 161 }
duke@1 162
duke@1 163 public void printAnnotationTypeElement(AnnotationTypeElementDoc e)
duke@1 164 throws IOException {
duke@1 165 prln(0, "element " + e);
duke@1 166 prMethod(0, e);
duke@1 167 }
duke@1 168
duke@1 169 public void printConstructor(ConstructorDoc c) throws IOException {
duke@1 170 prln(0, "constructor " + c);
duke@1 171 prExecutable(0, c);
duke@1 172 }
duke@1 173
duke@1 174
duke@1 175 private void prPackage(int off, PackageDoc p) throws IOException {
duke@1 176 prln(off, "package " + p);
duke@1 177 prAnnotations(off + 2, p.annotations());
duke@1 178 }
duke@1 179
duke@1 180 private void prClass(int off, ClassDoc cd) throws IOException {
duke@1 181 prln(off,
duke@1 182 (cd.isInterface() ? "interface" : cd.isEnum() ? "enum" : "class")
duke@1 183 + " " + cd);
duke@1 184 prln(off + 2, "name: " + cd.simpleTypeName() + " / " +
duke@1 185 cd.typeName() + " / " + cd.qualifiedTypeName());
duke@1 186 prAnnotations(off + 2, cd.annotations());
duke@1 187 prLabel(off + 2, "type parameters");
duke@1 188 for (Type t : cd.typeParameters())
duke@1 189 prln(off + 4, t);
duke@1 190 prParamTags(off + 2, cd.typeParamTags());
duke@1 191 prLabel(off + 2, "nested in");
duke@1 192 prln(off + 4, cd.containingClass());
duke@1 193 prLabel(off + 2, "superclass");
duke@1 194 prln(off + 4, cd.superclassType());
duke@1 195 prLabel(off + 2, "interfaces");
duke@1 196 Type[] ts = cd.interfaceTypes();
duke@1 197 Arrays.sort(ts);
duke@1 198 for (Type t : ts)
duke@1 199 prln(off + 4, t);
duke@1 200 prLabel(off + 2, "enum constants");
duke@1 201 for (FieldDoc f : cd.enumConstants())
duke@1 202 prln(off + 4, f.name());
duke@1 203 prLabel(off + 2, "fields");
duke@1 204 for (FieldDoc f : cd.fields())
duke@1 205 prln(off + 4, f.type() + " " + f.name());
duke@1 206 prLabel(off + 2, "constructors");
duke@1 207 for (ConstructorDoc c : cd.constructors())
duke@1 208 prln(off + 4, c.name() + c.flatSignature());
duke@1 209 prLabel(off + 2, "methods");
duke@1 210 for (MethodDoc m : cd.methods())
duke@1 211 prln(off + 4, typeUseString(m.returnType()) + " " +
duke@1 212 m.name() + m.flatSignature());
duke@1 213 }
duke@1 214
duke@1 215 private void prAnnotationType(int off, AnnotationTypeDoc at)
duke@1 216 throws IOException {
duke@1 217 prln(off, "@interface " + at);
duke@1 218 prAnnotations(off + 2, at.annotations());
duke@1 219 prLabel(off + 2, "elements");
duke@1 220 for (AnnotationTypeElementDoc e : at.elements()) {
duke@1 221 String def = (e.defaultValue() == null)
duke@1 222 ? ""
duke@1 223 : " default " + e.defaultValue();
duke@1 224 prln(off + 4, typeUseString(e.returnType()) + " " + e.name() +
duke@1 225 e.flatSignature() + def);
duke@1 226 }
duke@1 227 }
duke@1 228
duke@1 229 private void prField(int off, FieldDoc f) throws IOException {
duke@1 230 prln(off, "field " + typeUseString(f.type()) + " " + f.name());
duke@1 231 prAnnotations(off + 2, f.annotations());
duke@1 232 }
duke@1 233
duke@1 234 private void prParameter(int off, Parameter p) throws IOException {
duke@1 235 prln(off, "parameter " + p);
duke@1 236 prAnnotations(off + 2, p.annotations());
duke@1 237 }
duke@1 238
duke@1 239 private void prMethod(int off, MethodDoc m) throws IOException {
duke@1 240 prExecutable(off, m);
duke@1 241 prLabel(off + 2, "returns");
duke@1 242 prln(off + 4, typeUseString(m.returnType()));
duke@1 243 prLabel(off + 2, "overridden type");
duke@1 244 prln(off + 4, m.overriddenType());
duke@1 245 }
duke@1 246
duke@1 247 private void prExecutable(int off, ExecutableMemberDoc m)
duke@1 248 throws IOException {
duke@1 249 if (!m.isAnnotationTypeElement()) {
duke@1 250 prln(off + 2, "signature: " + m.flatSignature());
duke@1 251 prln(off + 2, " " + m.signature());
duke@1 252 }
duke@1 253 prAnnotations(off + 2, m.annotations());
duke@1 254 prParamTags(off + 2, m.typeParamTags());
duke@1 255 prParamTags(off + 2, m.paramTags());
duke@1 256 prLabel(off + 2, "type parameters");
duke@1 257 for (Type t : m.typeParameters())
duke@1 258 prln(off + 4, t);
duke@1 259 prLabel(off + 2, "throws");
duke@1 260 Type[] ts = m.thrownExceptionTypes();
duke@1 261 Arrays.sort(ts);
duke@1 262 for (Type t : ts)
duke@1 263 prln(off + 4, t);
duke@1 264 }
duke@1 265
duke@1 266 private void prAnnotations(int off, AnnotationDesc[] as)
duke@1 267 throws IOException {
duke@1 268 prLabel(off, "annotations");
duke@1 269 for (AnnotationDesc a : as)
duke@1 270 prln(off + 2, a.toString());
duke@1 271 }
duke@1 272
duke@1 273 private void prParamTags(int off, ParamTag tags[]) throws IOException {
duke@1 274 for (ParamTag tag : tags)
duke@1 275 prParamTag(off, tag);
duke@1 276 }
duke@1 277
duke@1 278 private void prParamTag(int off, ParamTag tag) throws IOException {
duke@1 279 String name = tag.parameterName();
duke@1 280 if (tag.isTypeParameter()) name = "<" + name + ">";
duke@1 281 prln(off, "@param " + name + " " + tag.parameterComment());
duke@1 282 }
duke@1 283
duke@1 284
duke@1 285 private String typeUseString(Type t) {
duke@1 286 return (t instanceof ClassDoc || t instanceof TypeVariable)
duke@1 287 ? t.typeName()
duke@1 288 : t.toString();
duke@1 289 }
duke@1 290
duke@1 291
duke@1 292 // Labels queued for possible printing. Innermost is first in list.
duke@1 293 List<Line> labels = new ArrayList<Line>();
duke@1 294
duke@1 295 // Print label if its section is nonempty.
duke@1 296 void prLabel(int off, String s) {
duke@1 297 while (!labels.isEmpty() && labels.get(0).off >= off)
duke@1 298 labels.remove(0);
duke@1 299 labels.add(0, new Line(off, s));
duke@1 300 }
duke@1 301
duke@1 302 // Print queued labels with offsets less than "off".
duke@1 303 void popLabels(int off) throws IOException {
duke@1 304 while (!labels.isEmpty()) {
duke@1 305 Line label = labels.remove(0);
duke@1 306 if (label.off < off)
duke@1 307 prln(label.off, label.o + ":");
duke@1 308 }
duke@1 309 }
duke@1 310
duke@1 311 // Print "o" at given offset.
duke@1 312 void pr(int off, Object o) throws IOException {
duke@1 313 popLabels(off);
duke@1 314 for (int i = 0; i < off; i++)
duke@1 315 out.write(' ');
duke@1 316 if (o != null)
duke@1 317 out.write(o.toString());
duke@1 318 }
duke@1 319
duke@1 320 // Print "o" (if non-null) at given offset, then newline.
duke@1 321 void prln(int off, Object o) throws IOException {
duke@1 322 if (o != null) {
duke@1 323 pr(off, o);
duke@1 324 prln();
duke@1 325 }
duke@1 326 }
duke@1 327
duke@1 328 // Print newline.
duke@1 329 void prln() throws IOException {
duke@1 330 out.write('\n'); // don't want platform-dependent separator
duke@1 331 }
duke@1 332
duke@1 333
duke@1 334 static class Line {
duke@1 335 int off;
duke@1 336 Object o;
duke@1 337 Line(int off, Object o) { this.off = off; this.o = o; }
duke@1 338 }
duke@1 339 }

mercurial