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