Tue, 11 Dec 2012 15:05:55 -0800
8004828: refactor init of *DocImpl classes
Reviewed-by: darcy
1 /*
2 * Copyright (c) 1997, 2012, 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 com.sun.javadoc.*;
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;
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 */
54 public abstract class ExecutableMemberDocImpl
55 extends MemberDocImpl implements ExecutableMemberDoc {
57 protected final MethodSymbol sym;
59 /**
60 * Constructor.
61 */
62 public ExecutableMemberDocImpl(DocEnv env, MethodSymbol sym, TreePath treePath) {
63 super(env, sym, treePath);
64 this.sym = sym;
65 }
67 /**
68 * Constructor.
69 */
70 public ExecutableMemberDocImpl(DocEnv env, MethodSymbol sym) {
71 this(env, sym, null);
72 }
74 /**
75 * Returns the flags in terms of javac's flags
76 */
77 protected long getFlags() {
78 return sym.flags();
79 }
81 /**
82 * Identify the containing class
83 */
84 protected ClassSymbol getContainingClass() {
85 return sym.enclClass();
86 }
88 /**
89 * Return true if this method is native
90 */
91 public boolean isNative() {
92 return Modifier.isNative(getModifiers());
93 }
95 /**
96 * Return true if this method is synchronized
97 */
98 public boolean isSynchronized() {
99 return Modifier.isSynchronized(getModifiers());
100 }
102 /**
103 * Return true if this method was declared to take a variable number
104 * of arguments.
105 */
106 public boolean isVarArgs() {
107 return ((sym.flags() & Flags.VARARGS) != 0
108 && !env.legacyDoclet);
109 }
111 /**
112 * Returns true if this field was synthesized by the compiler.
113 */
114 public boolean isSynthetic() {
115 return ((sym.flags() & Flags.SYNTHETIC) != 0);
116 }
118 public boolean isIncluded() {
119 return containingClass().isIncluded() && env.shouldDocument(sym);
120 }
122 /**
123 * Return the throws tags in this method.
124 *
125 * @return an array of ThrowTagImpl containing all {@code @exception}
126 * and {@code @throws} tags.
127 */
128 public ThrowsTag[] throwsTags() {
129 return comment().throwsTags();
130 }
132 /**
133 * Return the param tags in this method, excluding the type
134 * parameter tags.
135 *
136 * @return an array of ParamTagImpl containing all {@code @param} tags.
137 */
138 public ParamTag[] paramTags() {
139 return comment().paramTags();
140 }
142 /**
143 * Return the type parameter tags in this method.
144 */
145 public ParamTag[] typeParamTags() {
146 return env.legacyDoclet
147 ? new ParamTag[0]
148 : comment().typeParamTags();
149 }
151 /**
152 * Return exceptions this method or constructor throws.
153 *
154 * @return an array of ClassDoc[] representing the exceptions
155 * thrown by this method.
156 */
157 public ClassDoc[] thrownExceptions() {
158 ListBuffer<ClassDocImpl> l = new ListBuffer<ClassDocImpl>();
159 for (Type ex : sym.type.getThrownTypes()) {
160 ex = env.types.erasure(ex);
161 //### Will these casts succeed in the face of static semantic
162 //### errors in the documented code?
163 ClassDocImpl cdi = env.getClassDoc((ClassSymbol)ex.tsym);
164 if (cdi != null) l.append(cdi);
165 }
166 return l.toArray(new ClassDocImpl[l.length()]);
167 }
169 /**
170 * Return exceptions this method or constructor throws.
171 * Each array element is either a <code>ClassDoc</code> or a
172 * <code>TypeVariable</code>.
173 */
174 public com.sun.javadoc.Type[] thrownExceptionTypes() {
175 return TypeMaker.getTypes(env, sym.type.getThrownTypes());
176 }
178 /**
179 * Get argument information.
180 *
181 * @see ParameterImpl
182 *
183 * @return an array of ParameterImpl, one element per argument
184 * in the order the arguments are present.
185 */
186 public Parameter[] parameters() {
187 // generate the parameters on the fly: they're not cached
188 List<VarSymbol> params = sym.params();
189 Parameter result[] = new Parameter[params.length()];
191 int i = 0;
192 for (VarSymbol param : params) {
193 result[i++] = new ParameterImpl(env, param);
194 }
195 return result;
196 }
198 /**
199 * Return the formal type parameters of this method or constructor.
200 * Return an empty array if there are none.
201 */
202 public TypeVariable[] typeParameters() {
203 if (env.legacyDoclet) {
204 return new TypeVariable[0];
205 }
206 TypeVariable res[] = new TypeVariable[sym.type.getTypeArguments().length()];
207 TypeMaker.getTypes(env, sym.type.getTypeArguments(), res);
208 return res;
209 }
211 /**
212 * Get the signature. It is the parameter list, type is qualified.
213 * For instance, for a method <code>mymethod(String x, int y)</code>,
214 * it will return <code>(java.lang.String,int)</code>.
215 */
216 public String signature() {
217 return makeSignature(true);
218 }
220 /**
221 * Get flat signature. All types are not qualified.
222 * Return a String, which is the flat signiture of this member.
223 * It is the parameter list, type is not qualified.
224 * For instance, for a method <code>mymethod(String x, int y)</code>,
225 * it will return <code>(String, int)</code>.
226 */
227 public String flatSignature() {
228 return makeSignature(false);
229 }
231 private String makeSignature(boolean full) {
232 StringBuilder result = new StringBuilder();
233 result.append("(");
234 for (List<Type> types = sym.type.getParameterTypes(); types.nonEmpty(); ) {
235 Type t = types.head;
236 result.append(TypeMaker.getTypeString(env, t, full));
237 types = types.tail;
238 if (types.nonEmpty()) {
239 result.append(", ");
240 }
241 }
242 if (isVarArgs()) {
243 int len = result.length();
244 result.replace(len - 2, len, "...");
245 }
246 result.append(")");
247 return result.toString();
248 }
250 protected String typeParametersString() {
251 return TypeMaker.typeParametersString(env, sym, true);
252 }
254 /**
255 * Generate a key for sorting.
256 */
257 @Override
258 CollationKey generateKey() {
259 String k = name() + flatSignature() + typeParametersString();
260 // ',' and '&' are between '$' and 'a': normalize to spaces.
261 k = k.replace(',', ' ').replace('&', ' ');
262 // System.out.println("COLLATION KEY FOR " + this + " is \"" + k + "\"");
263 return env.doclocale.collator.getCollationKey(k);
264 }
266 /**
267 * Return the source position of the entity, or null if
268 * no position is available.
269 */
270 @Override
271 public SourcePosition position() {
272 if (sym.enclClass().sourcefile == null) return null;
273 return SourcePositionImpl.make(sym.enclClass().sourcefile,
274 (tree==null) ? 0 : tree.pos,
275 lineMap);
276 }
277 }