1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.bcel.classfile;
18
19 import java.io.DataInputStream;
20 import java.io.IOException;
21 import org.apache.bcel.Constants;
22 import org.apache.bcel.generic.Type;
23 import org.apache.bcel.util.BCELComparator;
24
25 /***
26 * This class represents the method info structure, i.e., the representation
27 * for a method in the class. See JVM specification for details.
28 * A method has access flags, a name, a signature and a number of attributes.
29 *
30 * @version $Id: Method.java 386056 2006-03-15 11:31:56Z tcurdt $
31 * @author <A HREF="mailto:m.dahm@gmx.de">M. Dahm</A>
32 */
33 public final class Method extends FieldOrMethod {
34
35 private static BCELComparator _cmp = new BCELComparator() {
36
37 public boolean equals( Object o1, Object o2 ) {
38 Method THIS = (Method) o1;
39 Method THAT = (Method) o2;
40 return THIS.getName().equals(THAT.getName())
41 && THIS.getSignature().equals(THAT.getSignature());
42 }
43
44
45 public int hashCode( Object o ) {
46 Method THIS = (Method) o;
47 return THIS.getSignature().hashCode() ^ THIS.getName().hashCode();
48 }
49 };
50
51
52 /***
53 * Empty constructor, all attributes have to be defined via `setXXX'
54 * methods. Use at your own risk.
55 */
56 public Method() {
57 }
58
59
60 /***
61 * Initialize from another object. Note that both objects use the same
62 * references (shallow copy). Use clone() for a physical copy.
63 */
64 public Method(Method c) {
65 super(c);
66 }
67
68
69 /***
70 * Construct object from file stream.
71 * @param file Input stream
72 * @throws IOException
73 * @throws ClassFormatException
74 */
75 Method(DataInputStream file, ConstantPool constant_pool) throws IOException,
76 ClassFormatException {
77 super(file, constant_pool);
78 }
79
80
81 /***
82 * @param access_flags Access rights of method
83 * @param name_index Points to field name in constant pool
84 * @param signature_index Points to encoded signature
85 * @param attributes Collection of attributes
86 * @param constant_pool Array of constants
87 */
88 public Method(int access_flags, int name_index, int signature_index, Attribute[] attributes,
89 ConstantPool constant_pool) {
90 super(access_flags, name_index, signature_index, attributes, constant_pool);
91 }
92
93
94 /***
95 * Called by objects that are traversing the nodes of the tree implicitely
96 * defined by the contents of a Java class. I.e., the hierarchy of methods,
97 * fields, attributes, etc. spawns a tree of objects.
98 *
99 * @param v Visitor object
100 */
101 public void accept( Visitor v ) {
102 v.visitMethod(this);
103 }
104
105
106 /***
107 * @return Code attribute of method, if any
108 */
109 public final Code getCode() {
110 for (int i = 0; i < attributes_count; i++) {
111 if (attributes[i] instanceof Code) {
112 return (Code) attributes[i];
113 }
114 }
115 return null;
116 }
117
118
119 /***
120 * @return ExceptionTable attribute of method, if any, i.e., list all
121 * exceptions the method may throw not exception handlers!
122 */
123 public final ExceptionTable getExceptionTable() {
124 for (int i = 0; i < attributes_count; i++) {
125 if (attributes[i] instanceof ExceptionTable) {
126 return (ExceptionTable) attributes[i];
127 }
128 }
129 return null;
130 }
131
132
133 /*** @return LocalVariableTable of code attribute if any, i.e. the call is forwarded
134 * to the Code atribute.
135 */
136 public final LocalVariableTable getLocalVariableTable() {
137 Code code = getCode();
138 if (code == null) {
139 return null;
140 }
141 return code.getLocalVariableTable();
142 }
143
144
145 /*** @return LineNumberTable of code attribute if any, i.e. the call is forwarded
146 * to the Code atribute.
147 */
148 public final LineNumberTable getLineNumberTable() {
149 Code code = getCode();
150 if (code == null) {
151 return null;
152 }
153 return code.getLineNumberTable();
154 }
155
156
157 /***
158 * Return string representation close to declaration format,
159 * `public static void main(String[] args) throws IOException', e.g.
160 *
161 * @return String representation of the method.
162 */
163 public final String toString() {
164 ConstantUtf8 c;
165 String name, signature, access;
166 StringBuffer buf;
167 access = Utility.accessToString(access_flags);
168
169 c = (ConstantUtf8) constant_pool.getConstant(signature_index, Constants.CONSTANT_Utf8);
170 signature = c.getBytes();
171 c = (ConstantUtf8) constant_pool.getConstant(name_index, Constants.CONSTANT_Utf8);
172 name = c.getBytes();
173 signature = Utility.methodSignatureToString(signature, name, access, true,
174 getLocalVariableTable());
175 buf = new StringBuffer(signature);
176 for (int i = 0; i < attributes_count; i++) {
177 Attribute a = attributes[i];
178 if (!((a instanceof Code) || (a instanceof ExceptionTable))) {
179 buf.append(" [").append(a.toString()).append("]");
180 }
181 }
182 ExceptionTable e = getExceptionTable();
183 if (e != null) {
184 String str = e.toString();
185 if (!str.equals("")) {
186 buf.append("\n\t\tthrows ").append(str);
187 }
188 }
189 return buf.toString();
190 }
191
192
193 /***
194 * @return deep copy of this method
195 */
196 public final Method copy( ConstantPool _constant_pool ) {
197 return (Method) copy_(_constant_pool);
198 }
199
200
201 /***
202 * @return return type of method
203 */
204 public Type getReturnType() {
205 return Type.getReturnType(getSignature());
206 }
207
208
209 /***
210 * @return array of method argument types
211 */
212 public Type[] getArgumentTypes() {
213 return Type.getArgumentTypes(getSignature());
214 }
215
216
217 /***
218 * @return Comparison strategy object
219 */
220 public static BCELComparator getComparator() {
221 return _cmp;
222 }
223
224
225 /***
226 * @param comparator Comparison strategy object
227 */
228 public static void setComparator( BCELComparator comparator ) {
229 _cmp = comparator;
230 }
231
232
233 /***
234 * Return value as defined by given BCELComparator strategy.
235 * By default two method objects are said to be equal when
236 * their names and signatures are equal.
237 *
238 * @see java.lang.Object#equals(java.lang.Object)
239 */
240 public boolean equals( Object obj ) {
241 return _cmp.equals(this, obj);
242 }
243
244
245 /***
246 * Return value as defined by given BCELComparator strategy.
247 * By default return the hashcode of the method's name XOR signature.
248 *
249 * @see java.lang.Object#hashCode()
250 */
251 public int hashCode() {
252 return _cmp.hashCode(this);
253 }
254 }