1 /* 2 * Copyright (c) 1997, 2018, 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.javadoc.main; 27 28 import java.lang.reflect.Modifier; 29 import java.text.CollationKey; 30 31 import com.sun.javadoc.*; 32 33 import com.sun.source.util.TreePath; 34 import com.sun.tools.javac.code.Flags; 35 import com.sun.tools.javac.code.Symbol.*; 36 import com.sun.tools.javac.code.Type; 37 import com.sun.tools.javac.util.List; 38 import com.sun.tools.javac.util.ListBuffer; 39 40 /** 41 * Represents a method or constructor of a java class. 42 * 43 * <p><b>This is NOT part of any supported API. 44 * If you write code that depends on this, you do so at your own risk. 45 * This code and its internal interfaces are subject to change or 46 * deletion without notice.</b> 47 * 48 * @since 1.2 49 * @author Robert Field 50 * @author Neal Gafter (rewrite) 51 * @author Scott Seligman (generics, annotations) 52 */ 53 54 @Deprecated(since="9", forRemoval=true) 55 @SuppressWarnings("removal") 56 public abstract class ExecutableMemberDocImpl 57 extends MemberDocImpl implements ExecutableMemberDoc { 58 59 protected final MethodSymbol sym; 60 61 /** 62 * Constructor. 63 */ ExecutableMemberDocImpl(DocEnv env, MethodSymbol sym, TreePath treePath)64 public ExecutableMemberDocImpl(DocEnv env, MethodSymbol sym, TreePath treePath) { 65 super(env, sym, treePath); 66 this.sym = sym; 67 } 68 69 /** 70 * Constructor. 71 */ ExecutableMemberDocImpl(DocEnv env, MethodSymbol sym)72 public ExecutableMemberDocImpl(DocEnv env, MethodSymbol sym) { 73 this(env, sym, null); 74 } 75 76 /** 77 * Returns the flags in terms of javac's flags 78 */ getFlags()79 protected long getFlags() { 80 return sym.flags(); 81 } 82 83 /** 84 * Identify the containing class 85 */ getContainingClass()86 protected ClassSymbol getContainingClass() { 87 return sym.enclClass(); 88 } 89 90 /** 91 * Return true if this method is native 92 */ isNative()93 public boolean isNative() { 94 return Modifier.isNative(getModifiers()); 95 } 96 97 /** 98 * Return true if this method is synchronized 99 */ isSynchronized()100 public boolean isSynchronized() { 101 return Modifier.isSynchronized(getModifiers()); 102 } 103 104 /** 105 * Return true if this method was declared to take a variable number 106 * of arguments. 107 */ isVarArgs()108 public boolean isVarArgs() { 109 return ((sym.flags() & Flags.VARARGS) != 0 110 && !env.legacyDoclet); 111 } 112 113 /** 114 * Returns true if this field was synthesized by the compiler. 115 */ isSynthetic()116 public boolean isSynthetic() { 117 return ((sym.flags() & Flags.SYNTHETIC) != 0); 118 } 119 isIncluded()120 public boolean isIncluded() { 121 return containingClass().isIncluded() && env.shouldDocument(sym); 122 } 123 124 /** 125 * Return the throws tags in this method. 126 * 127 * @return an array of ThrowTagImpl containing all {@code @exception} 128 * and {@code @throws} tags. 129 */ throwsTags()130 public ThrowsTag[] throwsTags() { 131 return comment().throwsTags(); 132 } 133 134 /** 135 * Return the param tags in this method, excluding the type 136 * parameter tags. 137 * 138 * @return an array of ParamTagImpl containing all {@code @param} tags. 139 */ paramTags()140 public ParamTag[] paramTags() { 141 return comment().paramTags(); 142 } 143 144 /** 145 * Return the type parameter tags in this method. 146 */ typeParamTags()147 public ParamTag[] typeParamTags() { 148 return env.legacyDoclet 149 ? new ParamTag[0] 150 : comment().typeParamTags(); 151 } 152 153 /** 154 * Return exceptions this method or constructor throws. 155 * 156 * @return an array of ClassDoc[] representing the exceptions 157 * thrown by this method. 158 */ thrownExceptions()159 public ClassDoc[] thrownExceptions() { 160 ListBuffer<ClassDocImpl> l = new ListBuffer<>(); 161 for (Type ex : sym.type.getThrownTypes()) { 162 ex = env.types.erasure(ex); 163 //### Will these casts succeed in the face of static semantic 164 //### errors in the documented code? 165 ClassDocImpl cdi = env.getClassDoc((ClassSymbol)ex.tsym); 166 if (cdi != null) l.append(cdi); 167 } 168 return l.toArray(new ClassDocImpl[l.length()]); 169 } 170 171 /** 172 * Return exceptions this method or constructor throws. 173 * Each array element is either a <code>ClassDoc</code> or a 174 * <code>TypeVariable</code>. 175 */ thrownExceptionTypes()176 public com.sun.javadoc.Type[] thrownExceptionTypes() { 177 return TypeMaker.getTypes(env, sym.type.getThrownTypes()); 178 } 179 180 /** 181 * Get argument information. 182 * 183 * @see ParameterImpl 184 * 185 * @return an array of ParameterImpl, one element per argument 186 * in the order the arguments are present. 187 */ parameters()188 public Parameter[] parameters() { 189 // generate the parameters on the fly: they're not cached 190 List<VarSymbol> params = sym.params(); 191 Parameter result[] = new Parameter[params.length()]; 192 193 int i = 0; 194 for (VarSymbol param : params) { 195 result[i++] = new ParameterImpl(env, param); 196 } 197 return result; 198 } 199 200 /** 201 * Get the receiver type of this executable element. 202 * 203 * @return the receiver type of this executable element. 204 * @since 1.8 205 */ receiverType()206 public com.sun.javadoc.Type receiverType() { 207 Type recvtype = sym.type.asMethodType().recvtype; 208 return (recvtype != null) ? TypeMaker.getType(env, recvtype, false, true) : null; 209 } 210 211 /** 212 * Return the formal type parameters of this method or constructor. 213 * Return an empty array if there are none. 214 */ typeParameters()215 public TypeVariable[] typeParameters() { 216 if (env.legacyDoclet) { 217 return new TypeVariable[0]; 218 } 219 TypeVariable res[] = new TypeVariable[sym.type.getTypeArguments().length()]; 220 TypeMaker.getTypes(env, sym.type.getTypeArguments(), res); 221 return res; 222 } 223 224 /** 225 * Get the signature. It is the parameter list, type is qualified. 226 * For instance, for a method <code>mymethod(String x, int y)</code>, 227 * it will return <code>(java.lang.String,int)</code>. 228 */ signature()229 public String signature() { 230 return makeSignature(true); 231 } 232 233 /** 234 * Get flat signature. All types are not qualified. 235 * Return a String, which is the flat signiture of this member. 236 * It is the parameter list, type is not qualified. 237 * For instance, for a method <code>mymethod(String x, int y)</code>, 238 * it will return <code>(String, int)</code>. 239 */ flatSignature()240 public String flatSignature() { 241 return makeSignature(false); 242 } 243 makeSignature(boolean full)244 private String makeSignature(boolean full) { 245 StringBuilder result = new StringBuilder(); 246 result.append("("); 247 for (List<Type> types = sym.type.getParameterTypes(); types.nonEmpty(); ) { 248 Type t = types.head; 249 result.append(TypeMaker.getTypeString(env, t, full)); 250 types = types.tail; 251 if (types.nonEmpty()) { 252 result.append(", "); 253 } 254 } 255 if (isVarArgs()) { 256 int len = result.length(); 257 result.replace(len - 2, len, "..."); 258 } 259 result.append(")"); 260 return result.toString(); 261 } 262 typeParametersString()263 protected String typeParametersString() { 264 return TypeMaker.typeParametersString(env, sym, true); 265 } 266 267 /** 268 * Generate a key for sorting. 269 */ 270 @Override generateKey()271 CollationKey generateKey() { 272 String k = name() + flatSignature() + typeParametersString(); 273 // ',' and '&' are between '$' and 'a': normalize to spaces. 274 k = k.replace(',', ' ').replace('&', ' '); 275 // System.out.println("COLLATION KEY FOR " + this + " is \"" + k + "\""); 276 return env.doclocale.collator.getCollationKey(k); 277 } 278 279 /** 280 * Return the source position of the entity, or null if 281 * no position is available. 282 */ 283 @Override position()284 public SourcePosition position() { 285 if (sym.enclClass().sourcefile == null) return null; 286 return SourcePositionImpl.make(sym.enclClass().sourcefile, 287 (tree==null) ? 0 : tree.pos, 288 lineMap); 289 } 290 } 291