Thu, 13 Jan 2011 21:28:38 -0800
7010528: javadoc performance regression
Reviewed-by: jjg
1 /*
2 * Copyright (c) 1997, 2010, 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. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package com.sun.tools.doclets.formats.html;
28 import com.sun.javadoc.*;
29 import com.sun.tools.doclets.formats.html.markup.*;
30 import com.sun.tools.doclets.internal.toolkit.*;
31 import com.sun.tools.doclets.internal.toolkit.util.*;
33 /**
34 * Print method and constructor info.
35 *
36 * @author Robert Field
37 * @author Atul M Dambalkar
38 * @author Bhavesh Patel (Modified)
39 */
40 public abstract class AbstractExecutableMemberWriter extends AbstractMemberWriter {
42 public AbstractExecutableMemberWriter(SubWriterHolderWriter writer,
43 ClassDoc classdoc) {
44 super(writer, classdoc);
45 }
47 public AbstractExecutableMemberWriter(SubWriterHolderWriter writer) {
48 super(writer);
49 }
51 /**
52 * Add the type parameters for the executable member.
53 *
54 * @param member the member to write type parameters for.
55 * @param htmltree the content tree to which the parameters will be added.
56 * @return the display length required to write this information.
57 */
58 protected int addTypeParameters(ExecutableMemberDoc member, Content htmltree) {
59 LinkInfoImpl linkInfo = new LinkInfoImpl(
60 LinkInfoImpl.CONTEXT_MEMBER_TYPE_PARAMS, member, false);
61 String typeParameters = writer.getTypeParameterLinks(linkInfo);
62 if (linkInfo.displayLength > 0) {
63 Content linkContent = new RawHtml(typeParameters);
64 htmltree.addContent(linkContent);
65 htmltree.addContent(writer.getSpace());
66 writer.displayLength += linkInfo.displayLength + 1;
67 }
68 return linkInfo.displayLength;
69 }
71 /**
72 * {@inheritDoc}
73 */
74 protected Content getDeprecatedLink(ProgramElementDoc member) {
75 ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
76 return writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, (MemberDoc) emd,
77 emd.qualifiedName() + emd.flatSignature());
78 }
80 /**
81 * Add the summary link for the member.
82 *
83 * @param context the id of the context where the link will be printed
84 * @param classDoc the classDoc that we should link to
85 * @param member the member being linked to
86 * @param tdSummary the content tree to which the link will be added
87 */
88 protected void addSummaryLink(int context, ClassDoc cd, ProgramElementDoc member,
89 Content tdSummary) {
90 ExecutableMemberDoc emd = (ExecutableMemberDoc)member;
91 String name = emd.name();
92 Content strong = HtmlTree.STRONG(new RawHtml(
93 writer.getDocLink(context, cd, (MemberDoc) emd,
94 name, false)));
95 Content code = HtmlTree.CODE(strong);
96 writer.displayLength = name.length();
97 addParameters(emd, false, code);
98 tdSummary.addContent(code);
99 }
101 /**
102 * Add the inherited summary link for the member.
103 *
104 * @param classDoc the classDoc that we should link to
105 * @param member the member being linked to
106 * @param linksTree the content tree to which the link will be added
107 */
108 protected void addInheritedSummaryLink(ClassDoc cd,
109 ProgramElementDoc member, Content linksTree) {
110 linksTree.addContent(new RawHtml(
111 writer.getDocLink(LinkInfoImpl.CONTEXT_MEMBER, cd, (MemberDoc) member,
112 member.name(), false)));
113 }
115 /**
116 * Add the parameter for the executable member.
117 *
118 * @param member the member to write parameter for.
119 * @param param the parameter that needs to be written.
120 * @param isVarArg true if this is a link to var arg.
121 * @param tree the content tree to which the parameter information will be added.
122 */
123 protected void addParam(ExecutableMemberDoc member, Parameter param,
124 boolean isVarArg, Content tree) {
125 if (param.type() != null) {
126 Content link = new RawHtml(writer.getLink(new LinkInfoImpl(
127 LinkInfoImpl.CONTEXT_EXECUTABLE_MEMBER_PARAM, param.type(),
128 isVarArg)));
129 tree.addContent(link);
130 }
131 if(param.name().length() > 0) {
132 tree.addContent(writer.getSpace());
133 tree.addContent(param.name());
134 }
135 }
137 /**
138 * Add all the parameters for the executable member.
139 *
140 * @param member the member to write parameters for.
141 * @param tree the content tree to which the parameters information will be added.
142 */
143 protected void addParameters(ExecutableMemberDoc member, Content htmltree) {
144 addParameters(member, true, htmltree);
145 }
147 /**
148 * Add all the parameters for the executable member.
149 *
150 * @param member the member to write parameters for.
151 * @param includeAnnotations true if annotation information needs to be added.
152 * @param tree the content tree to which the parameters information will be added.
153 */
154 protected void addParameters(ExecutableMemberDoc member,
155 boolean includeAnnotations, Content htmltree) {
156 htmltree.addContent("(");
157 Parameter[] params = member.parameters();
158 String indent = makeSpace(writer.displayLength);
159 if (configuration().linksource) {
160 //add spaces to offset indentation changes caused by link.
161 indent+= makeSpace(member.name().length());
162 }
163 int paramstart;
164 for (paramstart = 0; paramstart < params.length; paramstart++) {
165 Parameter param = params[paramstart];
166 if (!param.name().startsWith("this$")) {
167 if (includeAnnotations) {
168 boolean foundAnnotations =
169 writer.addAnnotationInfo(indent.length(),
170 member, param, htmltree);
171 if (foundAnnotations) {
172 htmltree.addContent(DocletConstants.NL);
173 htmltree.addContent(indent);
174 }
175 }
176 addParam(member, param,
177 (paramstart == params.length - 1) && member.isVarArgs(), htmltree);
178 break;
179 }
180 }
182 for (int i = paramstart + 1; i < params.length; i++) {
183 htmltree.addContent(",");
184 htmltree.addContent(DocletConstants.NL);
185 htmltree.addContent(indent);
186 if (includeAnnotations) {
187 boolean foundAnnotations =
188 writer.addAnnotationInfo(indent.length(), member, params[i],
189 htmltree);
190 if (foundAnnotations) {
191 htmltree.addContent(DocletConstants.NL);
192 htmltree.addContent(indent);
193 }
194 }
195 addParam(member, params[i], (i == params.length - 1) && member.isVarArgs(),
196 htmltree);
197 }
198 htmltree.addContent(")");
199 }
201 /**
202 * Add exceptions for the executable member.
203 *
204 * @param member the member to write exceptions for.
205 * @param htmltree the content tree to which the exceptions information will be added.
206 */
207 protected void addExceptions(ExecutableMemberDoc member, Content htmltree) {
208 Type[] exceptions = member.thrownExceptionTypes();
209 if(exceptions.length > 0) {
210 LinkInfoImpl memberTypeParam = new LinkInfoImpl(
211 LinkInfoImpl.CONTEXT_MEMBER, member, false);
212 int retlen = getReturnTypeLength(member);
213 writer.getTypeParameterLinks(memberTypeParam);
214 retlen += memberTypeParam.displayLength == 0 ?
215 0 : memberTypeParam.displayLength + 1;
216 String indent = makeSpace(modifierString(member).length() +
217 member.name().length() + retlen - 4);
218 htmltree.addContent(DocletConstants.NL);
219 htmltree.addContent(indent);
220 htmltree.addContent("throws ");
221 indent += " ";
222 Content link = new RawHtml(writer.getLink(new LinkInfoImpl(
223 LinkInfoImpl.CONTEXT_MEMBER, exceptions[0])));
224 htmltree.addContent(link);
225 for(int i = 1; i < exceptions.length; i++) {
226 htmltree.addContent(",");
227 htmltree.addContent(DocletConstants.NL);
228 htmltree.addContent(indent);
229 Content exceptionLink = new RawHtml(writer.getLink(new LinkInfoImpl(
230 LinkInfoImpl.CONTEXT_MEMBER, exceptions[i])));
231 htmltree.addContent(exceptionLink);
232 }
233 }
234 }
236 protected int getReturnTypeLength(ExecutableMemberDoc member) {
237 if (member instanceof MethodDoc) {
238 MethodDoc method = (MethodDoc)member;
239 Type rettype = method.returnType();
240 if (rettype.isPrimitive()) {
241 return rettype.typeName().length() +
242 rettype.dimension().length();
243 } else {
244 LinkInfoImpl linkInfo = new LinkInfoImpl(
245 LinkInfoImpl.CONTEXT_MEMBER, rettype);
246 writer.getLink(linkInfo);
247 return linkInfo.displayLength;
248 }
249 } else { // it's a constructordoc
250 return -1;
251 }
252 }
254 protected ClassDoc implementsMethodInIntfac(MethodDoc method,
255 ClassDoc[] intfacs) {
256 for (int i = 0; i < intfacs.length; i++) {
257 MethodDoc[] methods = intfacs[i].methods();
258 if (methods.length > 0) {
259 for (int j = 0; j < methods.length; j++) {
260 if (methods[j].name().equals(method.name()) &&
261 methods[j].signature().equals(method.signature())) {
262 return intfacs[i];
263 }
264 }
265 }
266 }
267 return null;
268 }
270 /**
271 * For backward compatibility, include an anchor using the erasures of the
272 * parameters. NOTE: We won't need this method anymore after we fix
273 * see tags so that they use the type instead of the erasure.
274 *
275 * @param emd the ExecutableMemberDoc to anchor to.
276 * @return the 1.4.x style anchor for the ExecutableMemberDoc.
277 */
278 protected String getErasureAnchor(ExecutableMemberDoc emd) {
279 StringBuffer buf = new StringBuffer(emd.name() + "(");
280 Parameter[] params = emd.parameters();
281 boolean foundTypeVariable = false;
282 for (int i = 0; i < params.length; i++) {
283 if (i > 0) {
284 buf.append(",");
285 }
286 Type t = params[i].type();
287 foundTypeVariable = foundTypeVariable || t.asTypeVariable() != null;
288 buf.append(t.isPrimitive() ?
289 t.typeName() : t.asClassDoc().qualifiedName());
290 buf.append(t.dimension());
291 }
292 buf.append(")");
293 return foundTypeVariable ? buf.toString() : null;
294 }
295 }