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