264 lines
8.5 KiB
Java
264 lines
8.5 KiB
Java
package com.de22.javabytecode;
|
|
|
|
import java.io.IOException;
|
|
import com.common.util.*;
|
|
import com.de22.javabytecode.constant.*;
|
|
|
|
/**
|
|
* Copyright Wynne Crisman 1999,2006<p>
|
|
*/
|
|
public class Method extends Component {
|
|
private short accessFlags = 0; //The modifiers and visibility for the method.//
|
|
private short nameIndex = 0; //The index within the constant collection of the name constant for this method.//
|
|
private short descriptorIndex = 0; //The index within the constant collection of the descriptor for this method.//
|
|
private IList attributes = new LiteList(10, 30); //The attributes associated with this method.//
|
|
/**
|
|
* Gets the return type in class file format (ie: [I for int[] and Ljava.lang.Object; for java.lang.Object).
|
|
* @param descriptor The descriptor in class file format.
|
|
* @return The return type in class file format.
|
|
*/
|
|
public static String getReturnType(String descriptor) {
|
|
return descriptor.substring(descriptor.lastIndexOf(')') + 1);
|
|
}//getReturnType()//
|
|
/**
|
|
* Gets the method parameters in class file format (ie: [I for int[] and Ljava.lang.Object; for java.lang.Object).
|
|
* @param descriptor The descriptor in class file format.
|
|
* @return The collection of parameters in order and in class file format.
|
|
*/
|
|
public static String[] getParamterTypes(String descriptor) {
|
|
int descriptorIndex = 1;
|
|
int parameterIndex = 0;
|
|
String[] result = null;
|
|
int startIndex = 1;
|
|
|
|
//First count the parameters.//
|
|
while(descriptor.charAt(descriptorIndex) != ')') {
|
|
if(descriptor.charAt(descriptorIndex) == 'L') {
|
|
descriptorIndex = descriptor.indexOf(';', descriptorIndex);
|
|
parameterIndex++;
|
|
}//if//
|
|
else if(descriptor.charAt(descriptorIndex) != '[') {
|
|
parameterIndex++;
|
|
}//else if//
|
|
|
|
descriptorIndex++;
|
|
}//while//
|
|
|
|
result = new String[parameterIndex];
|
|
parameterIndex = 0;
|
|
descriptorIndex = 1;
|
|
|
|
//Next load the parameter class names.//
|
|
while(descriptor.charAt(descriptorIndex) != ')') {
|
|
if(descriptor.charAt(descriptorIndex) == 'L') {
|
|
descriptorIndex = descriptor.indexOf(';', descriptorIndex);
|
|
result[parameterIndex++] = descriptor.substring(startIndex, descriptorIndex + 1);
|
|
startIndex = descriptorIndex + 1;
|
|
}//if//
|
|
else if(descriptor.charAt(descriptorIndex) != '[') {
|
|
result[parameterIndex++] = descriptor.substring(startIndex, descriptorIndex + 1);
|
|
startIndex = descriptorIndex + 1;
|
|
}//else if//
|
|
|
|
descriptorIndex++;
|
|
}//while//
|
|
|
|
return result;
|
|
}//getParamterTypes()//
|
|
/**
|
|
* Method constructor.
|
|
*/
|
|
protected Method(Type type) {
|
|
super(type);
|
|
}//Method()//
|
|
/**
|
|
* Adds an attribute to the method.
|
|
* An attribute describes some property of the method.
|
|
* @param attribute The attribute to add to the method. The attribute's name will automatically be added to the constant pool.
|
|
* @return The index of the attribute in the attribute pool.
|
|
*/
|
|
public short addAttribute(CodeAttribute attribute) {
|
|
short nameIndex = getType().addConstant(new ConstantUtf8(getType(), attribute.getDefaultName()), false);
|
|
|
|
attribute.setNameIndex(nameIndex);
|
|
attributes.add(attribute);
|
|
|
|
return (short) (attributes.getSize() - 1);
|
|
}//addAttribute()//
|
|
/**
|
|
* Gets the attribute referenced by the index.
|
|
* <p>Warning: This is a one based index, but the method to get the count will return the actual number of values.</p>
|
|
* @param index The one based index of the attribute to retrieve.
|
|
* @return The attribute at the index. An array index out of bounds exception will be thrown if there is not an attribute at that index.
|
|
*/
|
|
public CodeAttribute getAttribute(short index) {
|
|
int constant = index - 1;
|
|
|
|
return (CodeAttribute) attributes.get(constant);
|
|
}//getAttribute()//
|
|
/**
|
|
* Removes the attribute referenced by the index.
|
|
* <p>Warning: This is a one based index, but the method to get the count will return the actual number of values.</p>
|
|
* @param index The one based index of the attribute to remove.
|
|
* @return The attribute at the index. An array index out of bounds exception will be thrown if there is not an attribute at that index.
|
|
*/
|
|
public CodeAttribute removeAttribute(short index) {
|
|
int constant = index - 1;
|
|
|
|
return (CodeAttribute) attributes.remove(constant);
|
|
}//getAttribute()//
|
|
/**
|
|
* Gets the count of attributes associated with the type.
|
|
* @return The number of attributes for this type.
|
|
*/
|
|
public int getAttributeCount() {
|
|
return attributes.getSize();
|
|
}//getAttributeCount()//
|
|
/**
|
|
* Gets the method's access flags.
|
|
* @return The method's access flags.
|
|
* @see #ACC_PUBLIC
|
|
* @see #ACC_PRIVATE
|
|
* @see #ACC_PROTECTED
|
|
* @see #ACC_STATIC
|
|
* @see #ACC_ABSTRACT
|
|
* @see #ACC_SYNCHRONIZED
|
|
* @see #ACC_NATIVE
|
|
* @see #ACC_FINAL
|
|
*/
|
|
public short getAccessFlags() {
|
|
return accessFlags;
|
|
}//getAccessFlags()//
|
|
/**
|
|
* Gets the index of constant in the classes constant pool for the method descriptor.
|
|
* @return The method descriptor's constant pool index.
|
|
*/
|
|
public short getDescriptorIndex() {
|
|
return descriptorIndex;
|
|
}//getDescriptorIndex()//
|
|
/**
|
|
* Gets the index of constant in the classes constant pool for the method name.
|
|
* @return The methods name's constant pool index.
|
|
*/
|
|
public short getNameIndex() {
|
|
return nameIndex;
|
|
}//getNameIndex()//
|
|
/**
|
|
* Gets the size in number of bytes of the component and all subcomponents.
|
|
* @return The number of bytes required to represent the component and all subcomponents.
|
|
*/
|
|
public int getSize() {
|
|
return 0;
|
|
}//getSize()//
|
|
/**
|
|
* Reads this object from the given stream.
|
|
* @param in The input stream to read this object from.
|
|
*/
|
|
public void readExternal(java.io.ObjectInput in) throws IOException, ClassNotFoundException {
|
|
short length;
|
|
|
|
accessFlags = in.readShort();
|
|
nameIndex = in.readShort();
|
|
descriptorIndex = in.readShort();
|
|
length = in.readShort();
|
|
attributes = length > 0 ? new LiteList((int) length, 10) : LiteList.EMPTY_LIST;
|
|
|
|
while(length-- > 0) {
|
|
addAttribute(CodeAttribute.readAttribute(getType(), in));
|
|
}//while//
|
|
}//readExternal()//
|
|
/**
|
|
* Reads a method from the given stream.
|
|
* @param type The type object that the method will belong to.
|
|
* @param in The input stream to read the method from.
|
|
*/
|
|
protected static Method readMethod(Type type, java.io.ObjectInput in) throws java.io.IOException, ClassNotFoundException {
|
|
Method method = new Method(type);
|
|
|
|
method.readExternal(in);
|
|
|
|
return method;
|
|
}//readMethod()//
|
|
/**
|
|
* Sets the method's access flags.
|
|
* @param accessFlags The method's access flags.
|
|
* @see #ACC_PUBLIC
|
|
* @see #ACC_PRIVATE
|
|
* @see #ACC_PROTECTED
|
|
* @see #ACC_STATIC
|
|
* @see #ACC_ABSTRACT
|
|
* @see #ACC_SYNCHRONIZED
|
|
* @see #ACC_NATIVE
|
|
* @see #ACC_FINAL
|
|
*/
|
|
public void setAccessFlags(short accessFlags) {
|
|
this.accessFlags = accessFlags;
|
|
}//setAccessFlags()//
|
|
/**
|
|
* Sets the index of constant in the classes constant pool for the method descriptor.
|
|
* @param descriptorIndex The method descriptor's constant pool index.
|
|
*/
|
|
public void setDescriptorIndex(short descriptorIndex) {
|
|
this.descriptorIndex = descriptorIndex;
|
|
}//setDescriptorIndex()//
|
|
/**
|
|
* Sets the index of constant in the classes constant pool for the method name.
|
|
* @param nameIndex The methods name's constant pool index.
|
|
*/
|
|
public void setNameIndex(short nameIndex) {
|
|
this.nameIndex = nameIndex;
|
|
}//setNameIndex()//
|
|
/**
|
|
* @see Component.toString(StringBuffer, int)
|
|
*/
|
|
public void toString(StringBuffer buffer, int tabCount) {
|
|
IIterator iterator = null;
|
|
|
|
appendTabs(buffer, tabCount);
|
|
buffer.append("Method (accessFlags=");
|
|
buffer.append(accessFlags);
|
|
buffer.append(" nameIndex=");
|
|
buffer.append(nameIndex);
|
|
buffer.append(" descriptorIndex=");
|
|
buffer.append(descriptorIndex);
|
|
buffer.append(" Name='");
|
|
buffer.append(getType().getConstant(nameIndex));
|
|
buffer.append("' Signature='");
|
|
buffer.append(getType().getConstant(descriptorIndex));
|
|
buffer.append("')");
|
|
|
|
if(attributes.getSize() > 0) {
|
|
buffer.append(' ');
|
|
buffer.append('{');
|
|
appendEndOfLine(buffer);
|
|
iterator = attributes.iterator();
|
|
|
|
while(iterator.hasNext()) {
|
|
CodeAttribute attribute = (CodeAttribute) iterator.next();
|
|
|
|
attribute.toString(buffer, tabCount + 1);
|
|
}//while//
|
|
|
|
appendTabs(buffer, tabCount);
|
|
buffer.append('}');
|
|
}//if//
|
|
|
|
appendEndOfLine(buffer);
|
|
}//toString()//
|
|
/**
|
|
* Writes this object to the given stream.
|
|
* @param out The output stream to write this object to.
|
|
*/
|
|
public void writeExternal(java.io.ObjectOutput out) throws IOException {
|
|
short length = (short) (attributes != null ? attributes.getSize() : 0);
|
|
|
|
out.writeShort(accessFlags);
|
|
out.writeShort(nameIndex);
|
|
out.writeShort(descriptorIndex);
|
|
out.writeShort(length);
|
|
|
|
for(int index = 0; index < length; index++) {
|
|
((CodeAttribute) attributes.get(index)).writeExternal(out);
|
|
}//for//
|
|
}//writeExternal()//
|
|
}//Method// |