AbstractExecutableMemberWriter.java revision 3233:b5d08bc0d224
1/* 2 * Copyright (c) 1997, 2016, 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 26package jdk.javadoc.internal.doclets.formats.html; 27 28import java.util.List; 29 30import javax.lang.model.element.AnnotationMirror; 31import javax.lang.model.element.Element; 32import javax.lang.model.element.ElementKind; 33import javax.lang.model.element.ExecutableElement; 34import javax.lang.model.element.TypeElement; 35import javax.lang.model.element.VariableElement; 36import javax.lang.model.type.ArrayType; 37import javax.lang.model.type.DeclaredType; 38import javax.lang.model.type.TypeMirror; 39import javax.lang.model.type.TypeVariable; 40import javax.lang.model.util.SimpleTypeVisitor9; 41 42import com.sun.tools.javac.util.DefinedBy; 43import com.sun.tools.javac.util.DefinedBy.Api; 44import jdk.javadoc.internal.doclets.formats.html.markup.HtmlStyle; 45import jdk.javadoc.internal.doclets.formats.html.markup.HtmlTree; 46import jdk.javadoc.internal.doclets.toolkit.Content; 47import jdk.javadoc.internal.doclets.toolkit.util.DocletConstants; 48 49import static jdk.javadoc.internal.doclets.formats.html.LinkInfoImpl.Kind.*; 50 51/** 52 * Print method and constructor info. 53 * 54 * <p><b>This is NOT part of any supported API. 55 * If you write code that depends on this, you do so at your own risk. 56 * This code and its internal interfaces are subject to change or 57 * deletion without notice.</b> 58 * 59 * @author Robert Field 60 * @author Atul M Dambalkar 61 * @author Bhavesh Patel (Modified) 62 */ 63public abstract class AbstractExecutableMemberWriter extends AbstractMemberWriter { 64 65 public AbstractExecutableMemberWriter(SubWriterHolderWriter writer, TypeElement typeElement) { 66 super(writer, typeElement); 67 } 68 69 public AbstractExecutableMemberWriter(SubWriterHolderWriter writer) { 70 super(writer); 71 } 72 73 /** 74 * Add the type parameters for the executable member. 75 * 76 * @param member the member to write type parameters for. 77 * @param htmltree the content tree to which the parameters will be added. 78 */ 79 protected void addTypeParameters(ExecutableElement member, Content htmltree) { 80 Content typeParameters = getTypeParameters(member); 81 if (!typeParameters.isEmpty()) { 82 htmltree.addContent(typeParameters); 83 htmltree.addContent(writer.getSpace()); 84 } 85 } 86 87 /** 88 * Get the type parameters for the executable member. 89 * 90 * @param member the member for which to get the type parameters. 91 * @return the type parameters. 92 */ 93 protected Content getTypeParameters(ExecutableElement member) { 94 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, MEMBER_TYPE_PARAMS, member); 95 return writer.getTypeParameterLinks(linkInfo); 96 } 97 98 /** 99 * {@inheritDoc} 100 */ 101 @Override 102 protected Content getDeprecatedLink(Element member) { 103 StringBuilder sb = new StringBuilder(); 104 sb.append(utils.getFullyQualifiedName(member)); 105 if (!utils.isConstructor(member)) { 106 sb.append("."); 107 sb.append(member.getSimpleName().toString()); 108 } 109 sb.append(utils.flatSignature((ExecutableElement) member)); 110 111 return writer.getDocLink(MEMBER, member, sb.toString()); 112 } 113 114 /** 115 * Add the summary link for the member. 116 * 117 * @param context the id of the context where the link will be printed 118 * @param te the classDoc that we should link to 119 * @param member the member being linked to 120 * @param tdSummary the content tree to which the link will be added 121 */ 122 @Override 123 protected void addSummaryLink(LinkInfoImpl.Kind context, TypeElement te, Element member, 124 Content tdSummary) { 125 ExecutableElement ee = (ExecutableElement)member; 126 Content memberLink = HtmlTree.SPAN(HtmlStyle.memberNameLink, 127 writer.getDocLink(context, te, ee, 128 name(ee), false)); 129 Content code = HtmlTree.CODE(memberLink); 130 addParameters(ee, false, code, name(ee).length() - 1); 131 tdSummary.addContent(code); 132 } 133 134 /** 135 * Add the inherited summary link for the member. 136 * 137 * @param te the type element that we should link to 138 * @param member the member being linked to 139 * @param linksTree the content tree to which the link will be added 140 */ 141 @Override 142 protected void addInheritedSummaryLink(TypeElement te, Element member, Content linksTree) { 143 linksTree.addContent(writer.getDocLink(MEMBER, te, member, name(member), false)); 144 } 145 146 /** 147 * Add the parameter for the executable member. 148 * 149 * @param member the member to write parameter for. 150 * @param param the parameter that needs to be written. 151 * @param isVarArg true if this is a link to var arg. 152 * @param tree the content tree to which the parameter information will be added. 153 */ 154 protected void addParam(ExecutableElement member, VariableElement param, 155 boolean isVarArg, Content tree) { 156 Content link = writer.getLink(new LinkInfoImpl(configuration, EXECUTABLE_MEMBER_PARAM, 157 param.asType()).varargs(isVarArg)); 158 tree.addContent(link); 159 if(name(param).length() > 0) { 160 tree.addContent(writer.getSpace()); 161 tree.addContent(name(param)); 162 } 163 } 164 165 /** 166 * Add the receiver annotations information. 167 * 168 * @param member the member to write receiver annotations for. 169 * @param rcvrType the receiver type. 170 * @param descList list of annotation description. 171 * @param tree the content tree to which the information will be added. 172 */ 173 protected void addReceiverAnnotations(ExecutableElement member, TypeMirror rcvrType, 174 List<? extends AnnotationMirror> annotationMirrors, Content tree) { 175 writer.addReceiverAnnotationInfo(member, rcvrType, annotationMirrors, tree); 176 tree.addContent(writer.getSpace()); 177 tree.addContent(utils.getTypeName(rcvrType, false)); 178 LinkInfoImpl linkInfo = new LinkInfoImpl(configuration, RECEIVER_TYPE, rcvrType); 179 tree.addContent(writer.getTypeParameterLinks(linkInfo)); 180 tree.addContent(writer.getSpace()); 181 tree.addContent("this"); 182 } 183 184 185 /** 186 * Add all the parameters for the executable member. 187 * 188 * @param member the member to write parameters for. 189 * @param htmltree the content tree to which the parameters information will be added. 190 */ 191 protected void addParameters(ExecutableElement member, Content htmltree, int indentSize) { 192 addParameters(member, true, htmltree, indentSize); 193 } 194 195 /** 196 * Add all the parameters for the executable member. 197 * 198 * @param member the member to write parameters for. 199 * @param includeAnnotations true if annotation information needs to be added. 200 * @param htmltree the content tree to which the parameters information will be added. 201 */ 202 protected void addParameters(ExecutableElement member, 203 boolean includeAnnotations, Content htmltree, int indentSize) { 204 htmltree.addContent("("); 205 String sep = ""; 206 List<? extends VariableElement> parameters = member.getParameters(); 207 String indent = makeSpace(indentSize + 1); 208 TypeMirror rcvrType = member.getReceiverType(); 209 if (includeAnnotations && rcvrType != null && utils.isAnnotated(rcvrType)) { 210 List<? extends AnnotationMirror> annotationMirrors = rcvrType.getAnnotationMirrors(); 211 addReceiverAnnotations(member, rcvrType, annotationMirrors, htmltree); 212 sep = "," + DocletConstants.NL + indent; 213 } 214 int paramstart; 215 for (paramstart = 0; paramstart < parameters.size(); paramstart++) { 216 htmltree.addContent(sep); 217 VariableElement param = parameters.get(paramstart); 218 219 if (param.getKind() != ElementKind.INSTANCE_INIT) { 220 if (includeAnnotations) { 221 boolean foundAnnotations = 222 writer.addAnnotationInfo(indent.length(), 223 member, param, htmltree); 224 if (foundAnnotations) { 225 htmltree.addContent(DocletConstants.NL); 226 htmltree.addContent(indent); 227 } 228 } 229 addParam(member, param, 230 (paramstart == parameters.size() - 1) && member.isVarArgs(), htmltree); 231 break; 232 } 233 } 234 235 for (int i = paramstart + 1; i < parameters.size(); i++) { 236 htmltree.addContent(","); 237 htmltree.addContent(DocletConstants.NL); 238 htmltree.addContent(indent); 239 if (includeAnnotations) { 240 boolean foundAnnotations = 241 writer.addAnnotationInfo(indent.length(), member, parameters.get(i), 242 htmltree); 243 if (foundAnnotations) { 244 htmltree.addContent(DocletConstants.NL); 245 htmltree.addContent(indent); 246 } 247 } 248 addParam(member, parameters.get(i), (i == parameters.size() - 1) && member.isVarArgs(), 249 htmltree); 250 } 251 htmltree.addContent(")"); 252 } 253 254 /** 255 * Add exceptions for the executable member. 256 * 257 * @param member the member to write exceptions for. 258 * @param htmltree the content tree to which the exceptions information will be added. 259 */ 260 protected void addExceptions(ExecutableElement member, Content htmltree, int indentSize) { 261 List<? extends TypeMirror> exceptions = member.getThrownTypes(); 262 if (!exceptions.isEmpty()) { 263 String indent = makeSpace(indentSize + 1 - 7); 264 htmltree.addContent(DocletConstants.NL); 265 htmltree.addContent(indent); 266 htmltree.addContent("throws "); 267 indent = makeSpace(indentSize + 1); 268 Content link = writer.getLink(new LinkInfoImpl(configuration, MEMBER, exceptions.get(0))); 269 htmltree.addContent(link); 270 for(int i = 1; i < exceptions.size(); i++) { 271 htmltree.addContent(","); 272 htmltree.addContent(DocletConstants.NL); 273 htmltree.addContent(indent); 274 Content exceptionLink = writer.getLink(new LinkInfoImpl(configuration, MEMBER, 275 exceptions.get(i))); 276 htmltree.addContent(exceptionLink); 277 } 278 } 279 } 280 281 protected TypeElement implementsMethodInIntfac(ExecutableElement method, 282 List<TypeElement> intfacs) { 283 for (TypeElement intf : intfacs) { 284 List<ExecutableElement> methods = utils.getMethods(intf); 285 if (!methods.isEmpty()) { 286 for (ExecutableElement md : methods) { 287 if (name(md).equals(name(method)) && 288 md.toString().equals(method.toString())) { 289 return intf; 290 } 291 } 292 } 293 } 294 return null; 295 } 296 297 /** 298 * For backward compatibility, include an anchor using the erasures of the 299 * parameters. NOTE: We won't need this method anymore after we fix 300 * see tags so that they use the type instead of the erasure. 301 * 302 * @param executableElement the ExecutableElement to anchor to. 303 * @return the 1.4.x style anchor for the executable element. 304 */ 305 protected String getErasureAnchor(ExecutableElement executableElement) { 306 final StringBuilder buf = new StringBuilder(name(executableElement) + "("); 307 List<? extends VariableElement> parameters = executableElement.getParameters(); 308 boolean foundTypeVariable = false; 309 for (int i = 0; i < parameters.size(); i++) { 310 if (i > 0) { 311 buf.append(","); 312 } 313 TypeMirror t = parameters.get(i).asType(); 314 SimpleTypeVisitor9<Boolean, Void> stv = new SimpleTypeVisitor9<Boolean, Void>() { 315 boolean foundTypeVariable = false; 316 317 @Override @DefinedBy(Api.LANGUAGE_MODEL) 318 public Boolean visitArray(ArrayType t, Void p) { 319 visit(t.getComponentType()); 320 buf.append(utils.getDimension(t)); 321 return foundTypeVariable; 322 } 323 324 @Override @DefinedBy(Api.LANGUAGE_MODEL) 325 public Boolean visitTypeVariable(TypeVariable t, Void p) { 326 buf.append(utils.asTypeElement(t).getQualifiedName()); 327 foundTypeVariable = true; 328 return foundTypeVariable; 329 } 330 331 @Override @DefinedBy(Api.LANGUAGE_MODEL) 332 public Boolean visitDeclared(DeclaredType t, Void p) { 333 buf.append(utils.getQualifiedTypeName(t)); 334 return foundTypeVariable; 335 } 336 337 @Override @DefinedBy(Api.LANGUAGE_MODEL) 338 protected Boolean defaultAction(TypeMirror e, Void p) { 339 buf.append(e.toString()); 340 return foundTypeVariable; 341 } 342 }; 343 344 boolean isTypeVariable = stv.visit(t); 345 if (!foundTypeVariable) { 346 foundTypeVariable = isTypeVariable; 347 } 348 } 349 buf.append(")"); 350 return foundTypeVariable ? writer.getName(buf.toString()) : null; 351 } 352} 353