comparison src/com/go/trove/classfile/MethodInfo.java @ 0:3dc0c5604566

Initial checkin of blitz 2.0 fcs - no installer yet.
author Dan Creswell <dan.creswell@gmail.com>
date Sat, 21 Mar 2009 11:00:06 +0000
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:3dc0c5604566
1 /* ====================================================================
2 * Trove - Copyright (c) 1997-2000 Walt Disney Internet Group
3 * ====================================================================
4 * The Tea Software License, Version 1.1
5 *
6 * Copyright (c) 2000 Walt Disney Internet Group. All rights reserved.
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
18 * distribution.
19 *
20 * 3. The end-user documentation included with the redistribution,
21 * if any, must include the following acknowledgment:
22 * "This product includes software developed by the
23 * Walt Disney Internet Group (http://opensource.go.com/)."
24 * Alternately, this acknowledgment may appear in the software itself,
25 * if and wherever such third-party acknowledgments normally appear.
26 *
27 * 4. The names "Tea", "TeaServlet", "Kettle", "Trove" and "BeanDoc" must
28 * not be used to endorse or promote products derived from this
29 * software without prior written permission. For written
30 * permission, please contact opensource@dig.com.
31 *
32 * 5. Products derived from this software may not be called "Tea",
33 * "TeaServlet", "Kettle" or "Trove", nor may "Tea", "TeaServlet",
34 * "Kettle", "Trove" or "BeanDoc" appear in their name, without prior
35 * written permission of the Walt Disney Internet Group.
36 *
37 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
38 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
39 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
40 * DISCLAIMED. IN NO EVENT SHALL THE WALT DISNEY INTERNET GROUP OR ITS
41 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
42 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
43 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
44 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
45 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
46 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
47 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
48 * ====================================================================
49 *
50 * For more information about Tea, please see http://opensource.go.com/.
51 */
52
53 package com.go.trove.classfile;
54
55 import java.util.*;
56 import java.io.*;
57 import java.lang.reflect.Modifier;
58
59 /******************************************************************************
60 * This class corresponds to the method_info data structure as defined in
61 * section 4.6 of <i>The Java Virtual Machine Specification</i>.
62 * To make it easier to create bytecode for a method's CodeAttr, the
63 * CodeBuilder class is provided.
64 *
65 * @author Brian S O'Neill
66 * @version
67 * <!--$$Revision: 1.1 $-->, <!--$$JustDate:--> 00/11/27 <!-- $-->
68 * @see ClassFile
69 * @see CodeBuilder
70 */
71 public class MethodInfo {
72 private ClassFile mParent;
73 private ConstantPool mCp;
74
75 private String mName;
76 private MethodDescriptor mDesc;
77
78 private int mAccessFlags;
79
80 private ConstantUTFInfo mNameConstant;
81 private ConstantUTFInfo mDescriptorConstant;
82
83 private List mAttributes = new ArrayList(2);
84
85 private CodeAttr mCode;
86 private ExceptionsAttr mExceptions;
87
88 MethodInfo(ClassFile parent,
89 AccessFlags flags,
90 String name,
91 MethodDescriptor desc) {
92
93 mParent = parent;
94 mCp = parent.getConstantPool();
95 mName = name;
96 mDesc = desc;
97
98 mAccessFlags = flags.getModifier();
99 mNameConstant = ConstantUTFInfo.make(mCp, name);
100 mDescriptorConstant = ConstantUTFInfo.make(mCp, desc.toString());
101
102 if (!flags.isAbstract()) {
103 addAttribute(new CodeAttr(mCp));
104 }
105 }
106
107 private MethodInfo(ClassFile parent,
108 int flags,
109 ConstantUTFInfo nameConstant,
110 ConstantUTFInfo descConstant) {
111
112 mParent = parent;
113 mCp = parent.getConstantPool();
114 mName = nameConstant.getValue();
115 mDesc = MethodDescriptor.parseMethodDesc(descConstant.getValue());
116
117 mAccessFlags = flags;
118 mNameConstant = nameConstant;
119 mDescriptorConstant = descConstant;
120 }
121
122 /**
123 * Returns the parent ClassFile for this MethodInfo.
124 */
125 public ClassFile getClassFile() {
126 return mParent;
127 }
128
129 /**
130 * Returns the name of this method.
131 */
132 public String getName() {
133 return mName;
134 }
135
136 /**
137 * Returns a MethodDescriptor which describes return and parameter types
138 * of this method.
139 */
140 public MethodDescriptor getMethodDescriptor() {
141 return mDesc;
142 }
143
144 /**
145 * Returns a copy of this method's access flags.
146 */
147 public AccessFlags getAccessFlags() {
148 return new AccessFlags(mAccessFlags);
149 }
150
151 /**
152 * Returns a constant from the constant pool with this method's name.
153 */
154 public ConstantUTFInfo getNameConstant() {
155 return mNameConstant;
156 }
157
158 /**
159 * Returns a constant from the constant pool with this method's type
160 * descriptor string.
161 * @see TypeDescriptor
162 */
163 public ConstantUTFInfo getDescriptorConstant() {
164 return mDescriptorConstant;
165 }
166
167 /**
168 * Returns the exceptions that this method is declared to throw.
169 */
170 public String[] getExceptions() {
171 if (mExceptions == null) {
172 return new String[0];
173 }
174 else {
175 return mExceptions.getExceptions();
176 }
177 }
178
179 /**
180 * Returns a CodeAttr object used to manipulate the method code body, or
181 * null if this method is abstract.
182 */
183 public CodeAttr getCodeAttr() {
184 return mCode;
185 }
186
187 public boolean isSynthetic() {
188 for (int i = mAttributes.size(); --i >= 0; ) {
189 Object obj = mAttributes.get(i);
190 if (obj instanceof SyntheticAttr) {
191 return true;
192 }
193 }
194 return false;
195 }
196
197 public boolean isDeprecated() {
198 for (int i = mAttributes.size(); --i >= 0; ) {
199 Object obj = mAttributes.get(i);
200 if (obj instanceof DeprecatedAttr) {
201 return true;
202 }
203 }
204 return false;
205 }
206
207 /**
208 * Add a declared exception that this method may throw.
209 */
210 public void addException(String className) {
211 if (mExceptions == null) {
212 addAttribute(new ExceptionsAttr(mCp));
213 }
214
215 ConstantClassInfo cci = ConstantClassInfo.make(mCp, className);
216 mExceptions.addException(cci);
217 }
218
219 /**
220 * Mark this method as being synthetic by adding a special attribute.
221 */
222 public void markSynthetic() {
223 addAttribute(new SyntheticAttr(mCp));
224 }
225
226 /**
227 * Mark this method as being deprecated by adding a special attribute.
228 */
229 public void markDeprecated() {
230 addAttribute(new DeprecatedAttr(mCp));
231 }
232
233 public void addAttribute(Attribute attr) {
234 if (attr instanceof CodeAttr) {
235 if (mCode != null) {
236 mAttributes.remove(mCode);
237 }
238 mCode = (CodeAttr)attr;
239 }
240 else if (attr instanceof ExceptionsAttr) {
241 if (mExceptions != null) {
242 mAttributes.remove(mExceptions);
243 }
244 mExceptions = (ExceptionsAttr)attr;
245 }
246
247 mAttributes.add(attr);
248 }
249
250 public Attribute[] getAttributes() {
251 Attribute[] attrs = new Attribute[mAttributes.size()];
252 return (Attribute[])mAttributes.toArray(attrs);
253 }
254
255 /**
256 * Returns the length (in bytes) of this object in the class file.
257 */
258 public int getLength() {
259 int length = 8;
260
261 int size = mAttributes.size();
262 for (int i=0; i<size; i++) {
263 length += ((Attribute)mAttributes.get(i)).getLength();
264 }
265
266 return length;
267 }
268
269 public void writeTo(DataOutput dout) throws IOException {
270 dout.writeShort(mAccessFlags);
271 dout.writeShort(mNameConstant.getIndex());
272 dout.writeShort(mDescriptorConstant.getIndex());
273
274 int size = mAttributes.size();
275 dout.writeShort(size);
276 for (int i=0; i<size; i++) {
277 Attribute attr = (Attribute)mAttributes.get(i);
278 attr.writeTo(dout);
279 }
280 }
281
282 public String toString() {
283 String modStr = Modifier.toString(mAccessFlags);
284 if (modStr.length() == 0) {
285 return String.valueOf(mDesc) + ' ' + getName();
286 }
287 else {
288 return modStr + ' ' + mDesc + ' ' + getName();
289 }
290 }
291
292 static MethodInfo readFrom(ClassFile parent,
293 DataInput din,
294 AttributeFactory attrFactory)
295 throws IOException
296 {
297 ConstantPool cp = parent.getConstantPool();
298
299 int flags = din.readUnsignedShort();
300 int index = din.readUnsignedShort();
301 ConstantUTFInfo nameConstant = (ConstantUTFInfo)cp.getConstant(index);
302 index = din.readUnsignedShort();
303 ConstantUTFInfo descConstant = (ConstantUTFInfo)cp.getConstant(index);
304
305 MethodInfo info = new MethodInfo(parent, flags,
306 nameConstant, descConstant);
307
308 // Read attributes.
309 int size = din.readUnsignedShort();
310 for (int i=0; i<size; i++) {
311 info.addAttribute(Attribute.readFrom(cp, din, attrFactory));
312 }
313
314 return info;
315 }
316 }