001: /*
002: * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004: *
005: * This code is free software; you can redistribute it and/or modify it
006: * under the terms of the GNU General Public License version 2 only, as
007: * published by the Free Software Foundation. Sun designates this
008: * particular file as subject to the "Classpath" exception as provided
009: * by Sun in the LICENSE file that accompanied this code.
010: *
011: * This code is distributed in the hope that it will be useful, but WITHOUT
012: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014: * version 2 for more details (a copy is included in the LICENSE file that
015: * accompanied this code).
016: *
017: * You should have received a copy of the GNU General Public License version
018: * 2 along with this work; if not, write to the Free Software Foundation,
019: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022: * CA 95054 USA or visit www.sun.com if you need additional information or
023: * have any questions.
024: */
025:
026: package com.sun.tools.javadoc;
027:
028: import com.sun.javadoc.*;
029:
030: import com.sun.tools.javac.util.List;
031: import com.sun.tools.javac.util.ListBuffer;
032: import com.sun.tools.javac.util.Position;
033: import com.sun.tools.javac.code.Flags;
034: import com.sun.tools.javac.code.Type;
035: import com.sun.tools.javac.code.Symbol;
036: import com.sun.tools.javac.code.Symbol.*;
037: import com.sun.tools.javac.tree.JCTree.JCMethodDecl;
038:
039: import java.text.CollationKey;
040:
041: import java.lang.reflect.Modifier;
042:
043: /**
044: * Represents a method or constructor of a java class.
045: *
046: * @since 1.2
047: * @author Robert Field
048: * @author Neal Gafter (rewrite)
049: * @author Scott Seligman (generics, annotations)
050: */
051:
052: public abstract class ExecutableMemberDocImpl extends MemberDocImpl
053: implements ExecutableMemberDoc {
054:
055: protected final MethodSymbol sym;
056:
057: /**
058: * Constructor.
059: */
060: public ExecutableMemberDocImpl(DocEnv env, MethodSymbol sym,
061: String rawDocs, JCMethodDecl tree, Position.LineMap lineMap) {
062: super (env, sym, rawDocs, tree, lineMap);
063: this .sym = sym;
064: }
065:
066: /**
067: * Constructor.
068: */
069: public ExecutableMemberDocImpl(DocEnv env, MethodSymbol sym) {
070: this (env, sym, null, null, null);
071: }
072:
073: /**
074: * Returns the flags in terms of javac's flags
075: */
076: protected long getFlags() {
077: return sym.flags();
078: }
079:
080: /**
081: * Identify the containing class
082: */
083: protected ClassSymbol getContainingClass() {
084: return sym.enclClass();
085: }
086:
087: /**
088: * Return true if this method is native
089: */
090: public boolean isNative() {
091: return Modifier.isNative(getModifiers());
092: }
093:
094: /**
095: * Return true if this method is synchronized
096: */
097: public boolean isSynchronized() {
098: return Modifier.isSynchronized(getModifiers());
099: }
100:
101: /**
102: * Return true if this method was declared to take a variable number
103: * of arguments.
104: */
105: public boolean isVarArgs() {
106: return ((sym.flags() & Flags.VARARGS) != 0 && !env.legacyDoclet);
107: }
108:
109: /**
110: * Returns true if this field was synthesized by the compiler.
111: */
112: public boolean isSynthetic() {
113: return ((sym.flags() & Flags.SYNTHETIC) != 0);
114: }
115:
116: public boolean isIncluded() {
117: return containingClass().isIncluded()
118: && env.shouldDocument(sym);
119: }
120:
121: /**
122: * Return the throws tags in this method.
123: *
124: * @return an array of ThrowTagImpl containing all {@code @exception}
125: * and {@code @throws} tags.
126: */
127: public ThrowsTag[] throwsTags() {
128: return comment().throwsTags();
129: }
130:
131: /**
132: * Return the param tags in this method, excluding the type
133: * parameter tags.
134: *
135: * @return an array of ParamTagImpl containing all {@code @param} tags.
136: */
137: public ParamTag[] paramTags() {
138: return comment().paramTags();
139: }
140:
141: /**
142: * Return the type parameter tags in this method.
143: */
144: public ParamTag[] typeParamTags() {
145: return env.legacyDoclet ? new ParamTag[0] : comment()
146: .typeParamTags();
147: }
148:
149: /**
150: * Return exceptions this method or constructor throws.
151: *
152: * @return an array of ClassDoc[] representing the exceptions
153: * thrown by this method.
154: */
155: public ClassDoc[] thrownExceptions() {
156: ListBuffer<ClassDocImpl> l = new ListBuffer<ClassDocImpl>();
157: for (Type ex : sym.type.getThrownTypes()) {
158: ex = env.types.erasure(ex);
159: //### Will these casts succeed in the face of static semantic
160: //### errors in the documented code?
161: ClassDocImpl cdi = env.getClassDoc((ClassSymbol) ex.tsym);
162: if (cdi != null)
163: l.append(cdi);
164: }
165: return l.toArray(new ClassDocImpl[l.length()]);
166: }
167:
168: /**
169: * Return exceptions this method or constructor throws.
170: * Each array element is either a <code>ClassDoc</code> or a
171: * <code>TypeVariable</code>.
172: */
173: public com.sun.javadoc.Type[] thrownExceptionTypes() {
174: return TypeMaker.getTypes(env, sym.type.getThrownTypes());
175: }
176:
177: /**
178: * Get argument information.
179: *
180: * @see ParameterImpl
181: *
182: * @return an array of ParameterImpl, one element per argument
183: * in the order the arguments are present.
184: */
185: public Parameter[] parameters() {
186: // generate the parameters on the fly: they're not cached
187: List<VarSymbol> params = sym.params();
188: Parameter result[] = new Parameter[params.length()];
189:
190: int i = 0;
191: for (VarSymbol param : params) {
192: result[i++] = new ParameterImpl(env, param);
193: }
194: return result;
195: }
196:
197: /**
198: * Return the formal type parameters of this method or constructor.
199: * Return an empty array if there are none.
200: */
201: public TypeVariable[] typeParameters() {
202: if (env.legacyDoclet) {
203: return new TypeVariable[0];
204: }
205: TypeVariable res[] = new TypeVariable[sym.type
206: .getTypeArguments().length()];
207: TypeMaker.getTypes(env, sym.type.getTypeArguments(), res);
208: return res;
209: }
210:
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: }
219:
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: }
230:
231: private String makeSignature(boolean full) {
232: StringBuffer result = new StringBuffer();
233: result.append("(");
234: for (List<Type> types = sym.type.getParameterTypes(); types
235: .nonEmpty();) {
236: Type t = (Type) types.head;
237: result.append(TypeMaker.getTypeString(env, t, full));
238: types = types.tail;
239: if (types.nonEmpty()) {
240: result.append(", ");
241: }
242: }
243: if (isVarArgs()) {
244: int len = result.length();
245: result.replace(len - 2, len, "...");
246: }
247: result.append(")");
248: return result.toString();
249: }
250:
251: protected String typeParametersString() {
252: return TypeMaker.typeParametersString(env, sym, true);
253: }
254:
255: /**
256: * Generate a key for sorting.
257: */
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: }
265:
266: /**
267: * Return the source position of the entity, or null if
268: * no position is available.
269: */
270: public SourcePosition position() {
271: if (sym.enclClass().sourcefile == null)
272: return null;
273: return SourcePositionImpl.make(sym.enclClass().sourcefile
274: .toString(), (tree == null) ? 0 : tree.pos, lineMap);
275: }
276: }
|