Sun, 17 Feb 2013 16:44:55 -0500
Merge
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 public AnnotationDesc[] receiverAnnotations() {
203 // TODO: change how receiver annotations are output!
204 Type recvtype = sym.type.asMethodType().recvtype;
205 if (recvtype == null) {
206 return new AnnotationDesc[0];
207 }
208 if (recvtype.getKind() != TypeKind.ANNOTATED) {
209 return new AnnotationDesc[0];
210 }
211 List<? extends Compound> typeAnnos = ((com.sun.tools.javac.code.Type.AnnotatedType)recvtype).typeAnnotations;
212 AnnotationDesc result[] = new AnnotationDesc[typeAnnos.length()];
213 int i = 0;
214 for (Attribute.Compound a : typeAnnos) {
215 result[i++] = new AnnotationDescImpl(env, a);
216 }
217 return result;
218 }
220 /**
221 * Return the formal type parameters of this method or constructor.
222 * Return an empty array if there are none.
223 */
224 public TypeVariable[] typeParameters() {
225 if (env.legacyDoclet) {
226 return new TypeVariable[0];
227 }
228 TypeVariable res[] = new TypeVariable[sym.type.getTypeArguments().length()];
229 TypeMaker.getTypes(env, sym.type.getTypeArguments(), res);
230 return res;
231 }
233 /**
234 * Get the signature. It is the parameter list, type is qualified.
235 * For instance, for a method <code>mymethod(String x, int y)</code>,
236 * it will return <code>(java.lang.String,int)</code>.
237 */
238 public String signature() {
239 return makeSignature(true);
240 }
242 /**
243 * Get flat signature. All types are not qualified.
244 * Return a String, which is the flat signiture of this member.
245 * It is the parameter list, type is not qualified.
246 * For instance, for a method <code>mymethod(String x, int y)</code>,
247 * it will return <code>(String, int)</code>.
248 */
249 public String flatSignature() {
250 return makeSignature(false);
251 }
253 private String makeSignature(boolean full) {
254 StringBuilder result = new StringBuilder();
255 result.append("(");
256 for (List<Type> types = sym.type.getParameterTypes(); types.nonEmpty(); ) {
257 Type t = types.head;
258 result.append(TypeMaker.getTypeString(env, t, full));
259 types = types.tail;
260 if (types.nonEmpty()) {
261 result.append(", ");
262 }
263 }
264 if (isVarArgs()) {
265 int len = result.length();
266 result.replace(len - 2, len, "...");
267 }
268 result.append(")");
269 return result.toString();
270 }
272 protected String typeParametersString() {
273 return TypeMaker.typeParametersString(env, sym, true);
274 }
276 /**
277 * Generate a key for sorting.
278 */
279 @Override
280 CollationKey generateKey() {
281 String k = name() + flatSignature() + typeParametersString();
282 // ',' and '&' are between '$' and 'a': normalize to spaces.
283 k = k.replace(',', ' ').replace('&', ' ');
284 // System.out.println("COLLATION KEY FOR " + this + " is \"" + k + "\"");
285 return env.doclocale.collator.getCollationKey(k);
286 }
288 /**
289 * Return the source position of the entity, or null if
290 * no position is available.
291 */
292 @Override
293 public SourcePosition position() {
294 if (sym.enclClass().sourcefile == null) return null;
295 return SourcePositionImpl.make(sym.enclClass().sourcefile,
296 (tree==null) ? 0 : tree.pos,
297 lineMap);
298 }
299 }