Files
Brainstorm/Class File Services/src/com/de22/javabytecode/Method.java
2014-05-30 10:31:51 -07:00

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//