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