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