1 /* 2 * Copyright (c) 1997, 2013, 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 */ 25 26 package com.sun.tools.doclets.formats.html; 27 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.*; 32 33 /** 34 * Print method and constructor info. 35 * 36 * <p><b>This is NOT part of any supported API. 37 * If you write code that depends on this, you do so at your own risk. 38 * This code and its internal interfaces are subject to change or 39 * deletion without notice.</b> 40 * 41 * @author Robert Field 42 * @author Atul M Dambalkar 43 * @author Bhavesh Patel (Modified) 44 */ 45 public abstract class AbstractExecutableMemberWriter extends AbstractMemberWriter { 46 47 public AbstractExecutableMemberWriter(SubWriterHolderWriter writer, 48 ClassDoc classdoc) { 49 super(writer, classdoc); 50 } 51 52 public AbstractExecutableMemberWriter(SubWriterHolderWriter writer) { 53 super(writer); 54 } 55 56 /** 57 * Add the type parameters for the executable member. 58 * 59 * @param member the member to write type parameters for. 60 * @param htmltree the content tree to which the parameters will be added. 61 */ 62 protected void addTypeParameters(ExecutableMemberDoc member, Content htmltree) { 63 Content typeParameters = getTypeParameters(member); 64 if (!typeParameters.isEmpty()) { 65 htmltree.addContent(typeParameters); 66 htmltree.addContent(writer.getSpace()); 67 } 68 } 69 70 /** 71 * Get the type parameters for the executable member. 72 * 73 * @param member the member for which to get the type parameters. 74 * @return the type parameters. 75 */ 76 protected Content getTypeParameters(ExecutableMemberDoc member) { 77 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, 78 LinkInfoImpl.Kind.MEMBER_TYPE_PARAMS, member); 79 return writer.getTypeParameterLinks(linkInfo); 80 } 81 82 /** 83 * {@inheritDoc} 84 */ 85 protected Content getDeprecatedLink(ProgramElementDoc member) { 86 ExecutableMemberDoc emd = (ExecutableMemberDoc)member; 87 return writer.getDocLink(LinkInfoImpl.Kind.MEMBER, (MemberDoc) emd, 88 emd.qualifiedName() + emd.flatSignature()); 89 } 90 91 /** 92 * Add the summary link for the member. 93 * 94 * @param context the id of the context where the link will be printed 95 * @param cd the classDoc that we should link to 96 * @param member the member being linked to 97 * @param tdSummary the content tree to which the link will be added 98 */ 99 protected void addSummaryLink(LinkInfoImpl.Kind context, ClassDoc cd, ProgramElementDoc member, 100 Content tdSummary) { 101 ExecutableMemberDoc emd = (ExecutableMemberDoc)member; 102 String name = emd.name(); 103 Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink, 104 writer.getDocLink(context, cd, (MemberDoc) emd, 105 name, false)); 106 Content code = HtmlTree.CODE(memberLink); 107 addParameters(emd, false, code, name.length() - 1); 108 tdSummary.addContent(code); 109 } 110 111 /** 112 * Add the inherited summary link for the member. 113 * 114 * @param cd the classDoc that we should link to 115 * @param member the member being linked to 116 * @param linksTree the content tree to which the link will be added 117 */ 118 protected void addInheritedSummaryLink(ClassDoc cd, 119 ProgramElementDoc member, Content linksTree) { 120 linksTree.addContent( 121 writer.getDocLink(LinkInfoImpl.Kind.MEMBER, cd, (MemberDoc) member, 122 member.name(), false)); 123 } 124 125 /** 126 * Add the parameter for the executable member. 127 * 128 * @param member the member to write parameter for. 129 * @param param the parameter that needs to be written. 130 * @param isVarArg true if this is a link to var arg. 131 * @param tree the content tree to which the parameter information will be added. 132 */ 133 protected void addParam(ExecutableMemberDoc member, Parameter param, 134 boolean isVarArg, Content tree) { 135 if (param.type() != null) { 136 Content link = writer.getLink(new LinkInfoImpl( 137 configuration, LinkInfoImpl.Kind.EXECUTABLE_MEMBER_PARAM, 138 param.type()).varargs(isVarArg)); 139 tree.addContent(link); 140 } 141 if(param.name().length() > 0) { 142 tree.addContent(writer.getSpace()); 143 tree.addContent(param.name()); 144 } 145 } 146 147 /** 148 * Add the receiver annotations information. 149 * 150 * @param member the member to write receiver annotations for. 151 * @param rcvrType the receiver type. 152 * @param descList list of annotation description. 153 * @param tree the content tree to which the information will be added. 154 */ 155 protected void addReceiverAnnotations(ExecutableMemberDoc member, Type rcvrType, 156 AnnotationDesc[] descList, Content tree) { 157 writer.addReceiverAnnotationInfo(member, descList, tree); 158 tree.addContent(writer.getSpace()); 159 tree.addContent(rcvrType.typeName()); 160 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, 161 LinkInfoImpl.Kind.CLASS_SIGNATURE, rcvrType); 162 tree.addContent(writer.getTypeParameterLinks(linkInfo)); 163 tree.addContent(writer.getSpace()); 164 tree.addContent("this"); 165 } 166 167 168 /** 169 * Add all the parameters for the executable member. 170 * 171 * @param member the member to write parameters for. 172 * @param htmltree the content tree to which the parameters information will be added. 173 */ 174 protected void addParameters(ExecutableMemberDoc member, Content htmltree, int indentSize) { 175 addParameters(member, true, htmltree, indentSize); 176 } 177 178 /** 179 * Add all the parameters for the executable member. 180 * 181 * @param member the member to write parameters for. 182 * @param includeAnnotations true if annotation information needs to be added. 183 * @param htmltree the content tree to which the parameters information will be added. 184 */ 185 protected void addParameters(ExecutableMemberDoc member, 186 boolean includeAnnotations, Content htmltree, int indentSize) { 187 htmltree.addContent("("); 188 String sep = ""; 189 Parameter[] params = member.parameters(); 190 String indent = makeSpace(indentSize + 1); 191 Type rcvrType = member.receiverType(); 192 if (includeAnnotations && rcvrType instanceof AnnotatedType) { 193 AnnotationDesc[] descList = rcvrType.asAnnotatedType().annotations(); 194 if (descList.length > 0) { 195 addReceiverAnnotations(member, rcvrType, descList, htmltree); 196 sep = "," + DocletConstants.NL + indent; 197 } 198 } 199 int paramstart; 200 for (paramstart = 0; paramstart < params.length; paramstart++) { 201 htmltree.addContent(sep); 202 Parameter param = params[paramstart]; 203 if (!param.name().startsWith("this$")) { 204 if (includeAnnotations) { 205 boolean foundAnnotations = 206 writer.addAnnotationInfo(indent.length(), 207 member, param, htmltree); 208 if (foundAnnotations) { 209 htmltree.addContent(DocletConstants.NL); 210 htmltree.addContent(indent); 211 } 212 } 213 addParam(member, param, 214 (paramstart == params.length - 1) && member.isVarArgs(), htmltree); 215 break; 216 } 217 } 218 219 for (int i = paramstart + 1; i < params.length; i++) { 220 htmltree.addContent(","); 221 htmltree.addContent(DocletConstants.NL); 222 htmltree.addContent(indent); 223 if (includeAnnotations) { 224 boolean foundAnnotations = 225 writer.addAnnotationInfo(indent.length(), member, params[i], 226 htmltree); 227 if (foundAnnotations) { 228 htmltree.addContent(DocletConstants.NL); 229 htmltree.addContent(indent); 230 } 231 } 232 addParam(member, params[i], (i == params.length - 1) && member.isVarArgs(), 233 htmltree); 234 } 235 htmltree.addContent(")"); 236 } 237 238 /** 239 * Add exceptions for the executable member. 240 * 241 * @param member the member to write exceptions for. 242 * @param htmltree the content tree to which the exceptions information will be added. 243 */ 244 protected void addExceptions(ExecutableMemberDoc member, Content htmltree, int indentSize) { 245 Type[] exceptions = member.thrownExceptionTypes(); 246 if (exceptions.length > 0) { 247 LinkInfoImpl memberTypeParam = new LinkInfoImpl(configuration, 248 LinkInfoImpl.Kind.MEMBER, member); 249 String indent = makeSpace(indentSize + 1 - 7); 250 htmltree.addContent(DocletConstants.NL); 251 htmltree.addContent(indent); 252 htmltree.addContent("throws "); 253 indent = makeSpace(indentSize + 1); 254 Content link = writer.getLink(new LinkInfoImpl(configuration, 255 LinkInfoImpl.Kind.MEMBER, exceptions[0])); 256 htmltree.addContent(link); 257 for(int i = 1; i < exceptions.length; i++) { 258 htmltree.addContent(","); 259 htmltree.addContent(DocletConstants.NL); 260 htmltree.addContent(indent); 261 Content exceptionLink = writer.getLink(new LinkInfoImpl( 262 configuration, LinkInfoImpl.Kind.MEMBER, exceptions[i])); 263 htmltree.addContent(exceptionLink); 264 } 265 } 266 } 267 268 protected ClassDoc implementsMethodInIntfac(MethodDoc method, 269 ClassDoc[] intfacs) { 270 for (ClassDoc intf : intfacs) { 271 MethodDoc[] methods = intf.methods(); 272 if (methods.length > 0) { 273 for (MethodDoc md : methods) { 274 if (md.name().equals(method.name()) && 275 md.signature().equals(method.signature())) { 276 return intf; 277 } 278 } 279 } 280 } 281 return null; 282 } 283 284 /** 285 * For backward compatibility, include an anchor using the erasures of the 286 * parameters. NOTE: We won't need this method anymore after we fix 287 * see tags so that they use the type instead of the erasure. 288 * 289 * @param emd the ExecutableMemberDoc to anchor to. 290 * @return the 1.4.x style anchor for the ExecutableMemberDoc. 291 */ 292 protected String getErasureAnchor(ExecutableMemberDoc emd) { 293 StringBuilder buf = new StringBuilder(emd.name() + "("); 294 Parameter[] params = emd.parameters(); 295 boolean foundTypeVariable = false; 296 for (int i = 0; i < params.length; i++) { 297 if (i > 0) { 298 buf.append(","); 299 } 300 Type t = params[i].type(); 301 foundTypeVariable = foundTypeVariable || t.asTypeVariable() != null; 302 buf.append(t.isPrimitive() ? 303 t.typeName() : t.asClassDoc().qualifiedName()); 304 buf.append(t.dimension()); 305 } 306 buf.append(")"); 307 return foundTypeVariable ? writer.getName(buf.toString()) : null; 308 } 309 }