*/
/**
- * Interface to make use of the Visitor pattern programming style.
- * I.e. a class that implements this interface can traverse the contents of
- * a Java class just by calling the `accept' method which all classes have.
- *
- * Implemented by wish of
- * <A HREF="http://www.inf.fu-berlin.de/~bokowski">Boris Bokowski</A>.
- *
- * @version $Id: ClassVisitor.java,v 1.2 2008/05/28 23:53:01 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * Interface to make use of the Visitor pattern programming style. I.e. a class that implements this interface can traverse the
+ * contents of a Java class just by calling the `accept' method which all classes have.
+ *
+ * Implemented by wish of <A HREF="http://www.inf.fu-berlin.de/~bokowski">Boris Bokowski</A>.
+ *
+ * @version $Id: ClassVisitor.java,v 1.3 2009/09/10 03:59:33 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
public interface ClassVisitor {
- public void visitCode(Code obj);
- public void visitCodeException(CodeException obj);
- public void visitConstantClass(ConstantClass obj);
- public void visitConstantDouble(ConstantDouble obj);
- public void visitConstantFieldref(ConstantFieldref obj);
- public void visitConstantFloat(ConstantFloat obj);
- public void visitConstantInteger(ConstantInteger obj);
- public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj);
- public void visitConstantLong(ConstantLong obj);
- public void visitConstantMethodref(ConstantMethodref obj);
- public void visitConstantNameAndType(ConstantNameAndType obj);
- public void visitConstantPool(ConstantPool obj);
- public void visitConstantString(ConstantString obj);
- public void visitConstantUtf8(ConstantUtf8 obj);
- public void visitConstantValue(ConstantValue obj);
- public void visitDeprecated(Deprecated obj);
- public void visitExceptionTable(ExceptionTable obj);
- public void visitField(Field obj);
- public void visitInnerClass(InnerClass obj);
- public void visitInnerClasses(InnerClasses obj);
- public void visitJavaClass(JavaClass obj);
- public void visitLineNumber(LineNumber obj);
- public void visitLineNumberTable(LineNumberTable obj);
- public void visitLocalVariable(LocalVariable obj);
- public void visitLocalVariableTable(LocalVariableTable obj);
- public void visitMethod(Method obj);
- public void visitSignature(Signature obj);
- public void visitSourceFile(SourceFile obj);
- public void visitSynthetic(Synthetic obj);
- public void visitUnknown(Unknown obj);
- public void visitStackMap(StackMap obj);
- public void visitStackMapEntry(StackMapEntry obj);
-
- // Java5
- public void visitEnclosingMethod(EnclosingMethod obj);
- public void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations obj);
- public void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations obj);
- public void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations obj);
- public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations obj);
- public void visitAnnotationDefault(AnnotationDefault obj);
- public void visitLocalVariableTypeTable(LocalVariableTypeTable obj);
+ public void visitCode(Code obj);
+
+ public void visitCodeException(CodeException obj);
+
+ public void visitConstantClass(ConstantClass obj);
+
+ public void visitConstantDouble(ConstantDouble obj);
+
+ public void visitConstantFieldref(ConstantFieldref obj);
+
+ public void visitConstantFloat(ConstantFloat obj);
+
+ public void visitConstantInteger(ConstantInteger obj);
+
+ public void visitConstantInterfaceMethodref(ConstantInterfaceMethodref obj);
+
+ public void visitConstantLong(ConstantLong obj);
+
+ public void visitConstantMethodref(ConstantMethodref obj);
+
+ public void visitConstantNameAndType(ConstantNameAndType obj);
+
+ public void visitConstantPool(ConstantPool obj);
+
+ public void visitConstantString(ConstantString obj);
+
+ public void visitConstantUtf8(ConstantUtf8 obj);
+
+ public void visitConstantValue(ConstantValue obj);
+
+ public void visitDeprecated(Deprecated obj);
+
+ public void visitExceptionTable(ExceptionTable obj);
+
+ public void visitField(Field obj);
+
+ public void visitInnerClass(InnerClass obj);
+
+ public void visitInnerClasses(InnerClasses obj);
+
+ public void visitJavaClass(JavaClass obj);
+
+ public void visitLineNumber(LineNumber obj);
+
+ public void visitLineNumberTable(LineNumberTable obj);
+
+ public void visitLocalVariable(LocalVariable obj);
+
+ public void visitLocalVariableTable(LocalVariableTable obj);
+
+ public void visitMethod(Method obj);
+
+ public void visitSignature(Signature obj);
+
+ public void visitSourceFile(SourceFile obj);
+
+ public void visitSynthetic(Synthetic obj);
+
+ public void visitUnknown(Unknown obj);
+
+ public void visitStackMap(StackMap obj);
+
+ public void visitStackMapEntry(StackMapEntry obj);
+
+ public void visitEnclosingMethod(EnclosingMethod obj);
+
+ public void visitRuntimeVisibleAnnotations(RuntimeVisibleAnnotations obj);
+
+ public void visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations obj);
+
+ public void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations obj);
+
+ public void visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations obj);
+
+ public void visitAnnotationDefault(AnnotationDefault obj);
+
+ public void visitLocalVariableTypeTable(LocalVariableTypeTable obj);
}
* <http://www.apache.org/>.
*/
-import org.aspectj.apache.bcel.Constants;
-import java.io.*;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
+import org.aspectj.apache.bcel.Constants;
/**
- * Abstract superclass for classes to represent the different constant types
- * in the constant pool of a class file. The classes keep closely to
- * the JVM specification.
- *
- * @version $Id: Constant.java,v 1.3 2008/05/28 23:53:01 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * Abstract superclass for classes to represent the different constant types in the constant pool of a class file. The classes keep
+ * closely to the JVM specification.
+ *
+ * @version $Id: Constant.java,v 1.4 2009/09/10 03:59:33 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
public abstract class Constant implements Cloneable, Node, Serializable {
- /* In fact this tag is redundant since we can distinguish different
- * `Constant' objects by their type, i.e., via `instanceof'. In some
- * places we will use the tag for switch()es anyway.
- *
- * First, we want match the specification as closely as possible. Second we
- * need the tag as an index to select the corresponding class name from the
- * `CONSTANT_NAMES' array.
- */
- protected byte tag;
- Constant(byte tag) { this.tag = tag; }
+ protected byte tag;
+
+ Constant(byte tag) {
+ this.tag = tag;
+ }
- /**
- * Called by objects that are traversing the nodes of the tree implicitely
- * defined by the contents of a Java class. I.e., the hierarchy of methods,
- * fields, attributes, etc. spawns a tree of objects.
- *
- * @param v Visitor object
- */
- public abstract void accept(ClassVisitor v);
+ /**
+ * Visitor pattern
+ */
+ public abstract void accept(ClassVisitor v);
- public abstract void dump(DataOutputStream file) throws IOException;
+ /**
+ * Serialize the constant to an output stream
+ */
+ public abstract void dump(DataOutputStream dataOutputStream) throws IOException;
- /**
- * @return Tag of constant, i.e., its type. No setTag() method to avoid
- * confusion.
- */
- public final byte getTag() { return tag; }
+ public final byte getTag() {
+ return tag;
+ }
- /**
- * @return String representation.
- */
- public String toString() {
- return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]";
- }
+ @Override
+ public String toString() {
+ return Constants.CONSTANT_NAMES[tag] + "[" + tag + "]";
+ }
- /**
- * @return deep copy of this constant
- */
- public Constant copy() {
- try {
- return (Constant)super.clone();
- } catch(CloneNotSupportedException e) {}
+ /**
+ * @return deep copy of this constant
+ */
+ public Constant copy() {
+ try {
+ return (Constant) super.clone();
+ } catch (CloneNotSupportedException e) {
+ }
- return null;
- }
+ return null;
+ }
- public Object clone() throws CloneNotSupportedException {
- return super.clone();
- }
+ @Override
+ public Object clone() throws CloneNotSupportedException {
+ return super.clone();
+ }
- static final Constant readConstant(DataInputStream file) throws IOException, ClassFormatException {
- byte b = file.readByte();
- switch(b) {
- case Constants.CONSTANT_Class: return new ConstantClass(file);
- case Constants.CONSTANT_NameAndType: return new ConstantNameAndType(file);
- case Constants.CONSTANT_Utf8: return new ConstantUtf8(file);
- case Constants.CONSTANT_Fieldref: return new ConstantFieldref(file);
- case Constants.CONSTANT_Methodref: return new ConstantMethodref(file);
- case Constants.CONSTANT_InterfaceMethodref: return new ConstantInterfaceMethodref(file);
- case Constants.CONSTANT_String: return new ConstantString(file);
- case Constants.CONSTANT_Integer: return new ConstantInteger(file);
- case Constants.CONSTANT_Float: return new ConstantFloat(file);
- case Constants.CONSTANT_Long: return new ConstantLong(file);
- case Constants.CONSTANT_Double: return new ConstantDouble(file);
- default:
- throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
- }
- }
+ static final Constant readConstant(DataInputStream file) throws IOException, ClassFormatException {
+ byte b = file.readByte();
+ switch (b) {
+ case Constants.CONSTANT_Class:
+ return new ConstantClass(file);
+ case Constants.CONSTANT_NameAndType:
+ return new ConstantNameAndType(file);
+ case Constants.CONSTANT_Utf8:
+ return new ConstantUtf8(file);
+ case Constants.CONSTANT_Fieldref:
+ return new ConstantFieldref(file);
+ case Constants.CONSTANT_Methodref:
+ return new ConstantMethodref(file);
+ case Constants.CONSTANT_InterfaceMethodref:
+ return new ConstantInterfaceMethodref(file);
+ case Constants.CONSTANT_String:
+ return new ConstantString(file);
+ case Constants.CONSTANT_Integer:
+ return new ConstantInteger(file);
+ case Constants.CONSTANT_Float:
+ return new ConstantFloat(file);
+ case Constants.CONSTANT_Long:
+ return new ConstantLong(file);
+ case Constants.CONSTANT_Double:
+ return new ConstantDouble(file);
+ default:
+ throw new ClassFormatException("Invalid byte tag in constant pool: " + b);
+ }
+ }
}
* <http://www.apache.org/>.
*/
-import org.aspectj.apache.bcel.Constants;
-import java.io.*;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
-/**
- * This class is derived from the abstract
- * <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class
- * and represents a reference to a (external) class.
- *
- * @version $Id: ConstantClass.java,v 1.3 2008/05/28 23:53:01 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
- * @see Constant
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to a (external) class.
+ *
+ * @version $Id: ConstantClass.java,v 1.4 2009/09/10 03:59:33 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author Andy Clement
*/
public final class ConstantClass extends Constant implements ConstantObject {
- private int name_index; // Identical to ConstantString except for the name
-
- /**
- * Initialize from another object.
- */
- public ConstantClass(ConstantClass c) {
- this(c.getNameIndex());
- }
-
- /**
- * Initialize instance from file data.
- *
- * @param file Input stream
- * @throws IOException
- */
- ConstantClass(DataInputStream file) throws IOException
- {
- super(Constants.CONSTANT_Class);
- this.name_index = file.readUnsignedShort();
-// this(file.readUnsignedShort());
- }
+ private int nameIndex;
- /**
- * @param name_index Name index in constant pool. Should refer to a
- * ConstantUtf8.
- */
- public ConstantClass(int name_index) {
- super(Constants.CONSTANT_Class);
- this.name_index = name_index;
- }
+ public ConstantClass(ConstantClass c) {
+ this(c.getNameIndex());
+ }
- /**
- * Called by objects that are traversing the nodes of the tree implicitely
- * defined by the contents of a Java class. I.e., the hierarchy of methods,
- * fields, attributes, etc. spawns a tree of objects.
- *
- * @param v Visitor object
- */
- public void accept(ClassVisitor v) {
- v.visitConstantClass(this);
- }
+ ConstantClass(DataInputStream file) throws IOException {
+ super(Constants.CONSTANT_Class);
+ this.nameIndex = file.readUnsignedShort();
+ }
- /**
- * Dump constant class to file stream in binary format.
- *
- * @param file Output file stream
- * @throws IOException
- */
- public final void dump(DataOutputStream file) throws IOException
- {
- file.writeByte(tag);
- file.writeShort(name_index);
- }
+ public ConstantClass(int nameIndex) {
+ super(Constants.CONSTANT_Class);
+ this.nameIndex = nameIndex;
+ }
- /**
- * @return Name index in constant pool of class name.
- */
- public final int getNameIndex() { return name_index; }
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantClass(this);
+ }
- /**
- * @param name_index.
- */
- public final void setNameIndex(int name_index) {
- this.name_index = name_index;
- }
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeShort(nameIndex);
+ }
+ public final int getNameIndex() {
+ return nameIndex;
+ }
- /** @return String object
- */
- public Object getConstantValue(ConstantPool cp) {
- Constant c = cp.getConstant(name_index, Constants.CONSTANT_Utf8);
- return ((ConstantUtf8)c).getBytes();
- }
+ public final void setNameIndex(int nameIndex) {
+ this.nameIndex = nameIndex;
+ }
- /** @return dereferenced string
- */
- public String getBytes(ConstantPool cp) {
- return (String)getConstantValue(cp);
- }
+ public String getConstantValue(ConstantPool cp) {
+ return cp.getConstantUtf8(nameIndex).getBytes();
+ // Constant c = cp.getConstant(nameIndex, Constants.CONSTANT_Utf8);
+ // return ((ConstantUtf8) c).getBytes();
+ }
- /**
- * @return String representation.
- */
- public final String toString() {
- return super.toString() + "(name_index = " + name_index + ")";
- }
+ @Override
+ public final String toString() {
+ return super.toString() + "(name_index = " + nameIndex + ")";
+ }
}
* <http://www.apache.org/>.
*/
-import org.aspectj.apache.bcel.Constants;
-import java.io.*;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
-/**
- * This class is derived from the abstract
- * <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class
- * and represents a reference to a Double object.
- *
- * @version $Id: ConstantDouble.java,v 1.3 2008/05/28 23:53:01 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
- * @see Constant
+import org.aspectj.apache.bcel.Constants;
+
+/**
+ * This class is derived from the abstract <A HREF="org.aspectj.apache.bcel.classfile.Constant.html">Constant</A> class and
+ * represents a reference to a Double object.
+ *
+ * @version $Id: ConstantDouble.java,v 1.4 2009/09/10 03:59:33 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author Andy Clement
*/
public final class ConstantDouble extends Constant implements ConstantObject {
- private double bytes;
+ private double value;
+
+ public ConstantDouble(double value) {
+ super(Constants.CONSTANT_Double);
+ this.value = value;
+ }
+
+ public ConstantDouble(ConstantDouble c) {
+ this(c.getBytes());
+ }
+
+ ConstantDouble(DataInputStream file) throws IOException {
+ this(file.readDouble());
+ }
- /**
- * @param bytes Data
- */
- public ConstantDouble(double bytes) {
- super(Constants.CONSTANT_Double);
- this.bytes = bytes;
- }
+ @Override
+ public void accept(ClassVisitor v) {
+ v.visitConstantDouble(this);
+ }
- /**
- * Initialize from another object.
- */
- public ConstantDouble(ConstantDouble c) {
- this(c.getBytes());
- }
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeByte(tag);
+ file.writeDouble(value);
+ }
- /**
- * Initialize instance from file data.
- *
- * @param file Input stream
- * @throws IOException
- */
- ConstantDouble(DataInputStream file) throws IOException
- {
- this(file.readDouble());
- }
+ public final double getBytes() {
+ return value;
+ }
- /**
- * Called by objects that are traversing the nodes of the tree implicitely
- * defined by the contents of a Java class. I.e., the hierarchy of methods,
- * fields, attributes, etc. spawns a tree of objects.
- *
- * @param v Visitor object
- */
- public void accept(ClassVisitor v) {
- v.visitConstantDouble(this);
- }
- /**
- * Dump constant double to file stream in binary format.
- *
- * @param file Output file stream
- * @throws IOException
- */
- public final void dump(DataOutputStream file) throws IOException
- {
- file.writeByte(tag);
- file.writeDouble(bytes);
- }
- /**
- * @return data, i.e., 8 bytes.
- */
- public final double getBytes() { return bytes; }
- /**
- * @param bytes.
- */
- public final void setBytes(double bytes) {
- this.bytes = bytes;
- }
- /**
- * @return String representation.
- */
- public final String toString()
- {
- return super.toString() + "(bytes = " + bytes + ")";
- }
+ @Override
+ public final String toString() {
+ return super.toString() + "(bytes = " + value + ")";
+ }
- /** @return Double object
- */
- public Object getConstantValue(ConstantPool cp) {
- return new Double(bytes);
- }
+ public Double getConstantValue(ConstantPool cp) {
+ return new Double(value);
+ }
}
* <http://www.apache.org/>.
*/
-/**
- * This interface denotes those constants that have a "natural" value,
- * such as ConstantLong, ConstantString, etc..
- *
- * @version $Id: ConstantObject.java,v 1.3 2008/05/28 23:53:02 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
- * @see Constant
+/**
+ * This interface denotes those constants that have a "natural" value, such as ConstantLong, ConstantString, etc..
+ *
+ * @version $Id: ConstantObject.java,v 1.4 2009/09/10 03:59:33 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Constant
*/
public interface ConstantObject {
- /** @return object representing the constant, e.g., Long for ConstantLong
- */
- public abstract Object getConstantValue(ConstantPool cp);
+ public abstract Object getConstantValue(ConstantPool cp);
}
import org.aspectj.apache.bcel.generic.ObjectType;
/**
- * This class represents the constant pool, i.e., a table of constants, of
- * a parsed classfile. It may contain null references, due to the JVM
- * specification that skips an entry after an 8-byte constant (double,
- * long) entry.
+ * This class represents the constant pool, i.e., a table of constants, of a parsed classfile. It may contain null references, due
+ * to the JVM specification that skips an entry after an 8-byte constant (double, long) entry.
*/
public class ConstantPool implements Node {
private Constant[] pool;
- private int poolSize; // number of entries in the pool (could be < pool.length as the array is resized in 'chunks')
-
- private Map<String, Integer> utf8Cache = new HashMap<String, Integer>();
- private Map<String, Integer> methodCache = new HashMap<String, Integer>();
- private Map<String, Integer> fieldCache = new HashMap<String, Integer>();
-
- public int getSize() { return poolSize; }
-
- public ConstantPool() {
+ private int poolSize; // number of entries in the pool (could be < pool.length as the array is resized in 'chunks')
+
+ private Map<String, Integer> utf8Cache = new HashMap<String, Integer>();
+ private Map<String, Integer> methodCache = new HashMap<String, Integer>();
+ private Map<String, Integer> fieldCache = new HashMap<String, Integer>();
+
+ public int getSize() {
+ return poolSize;
+ }
+
+ public ConstantPool() {
pool = new Constant[10];
- poolSize=0;
+ poolSize = 0;
}
-
- public ConstantPool(Constant[] constants) {
- pool = constants;
- poolSize = (constants==null?0:constants.length);
+
+ public ConstantPool(Constant[] constants) {
+ pool = constants;
+ poolSize = (constants == null ? 0 : constants.length);
}
ConstantPool(DataInputStream file) throws IOException {
- byte tag;
- poolSize = file.readUnsignedShort();
- pool = new Constant[poolSize];
- // pool[0] is unused by the compiler and may be used freely by the implementation
- for (int i=1; i<poolSize; i++) {
- pool[i] = Constant.readConstant(file);
- tag = pool[i].getTag();
- if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) i++;
- }
- }
-
- public Constant getConstant(int index, byte tag) {
- Constant c = getConstant(index);
- //if (c == null) throw new ClassFormatException("Constant pool at index " + index + " is null.");
- if(c.tag == tag) return c;
- throw new ClassFormatException("Expected class '"+Constants.CONSTANT_NAMES[tag]+"' at index "+index+" and found "+c);
- }
-
- public Constant getConstant(int index) {
- if (index >= pool.length || index < 0)
- throw new ClassFormatException("Invalid constant pool reference: " +
- index + ". Constant pool size is: " + pool.length);
- return pool[index];
- }
-
- /**
- * @return deep copy of this constant pool
- */
- public ConstantPool copy() {
- Constant[] newConstants = new Constant[poolSize]; // use the correct size
- for (int i=1;i<poolSize;i++) {
- if (pool[i]!=null) {
- newConstants[i] = pool[i].copy();
- }
- }
- return new ConstantPool(newConstants);
- }
-
- /**
- * Get string from constant pool and bypass the indirection of
- * `ConstantClass' and `ConstantString' objects. I.e. these classes have
- * an index field that points to another entry of the constant pool of
- * type `ConstantUtf8' which contains the real data.
- *
- * @param index Index in constant pool
- * @param tag Tag of expected constant, either ConstantClass or ConstantString
- * @return Contents of string reference
- * @see ConstantClass
- * @see ConstantString
- * @throws ClassFormatException
- */
- public String getConstantString(int index, byte tag) throws ClassFormatException {
- Constant c = getConstant(index, tag);
- int i;
- /* This switch() is not that elegant, since the two classes have the
- * same contents, they just differ in the name of the index
- * field variable.
- * But we want to stick to the JVM naming conventions closely though
- * we could have solved these more elegantly by using the same
- * variable name or by subclassing.
- */
- // OPTIMIZE remove the difference - use the an interface and same index methods for string ref id
- switch(tag) {
- case Constants.CONSTANT_Class: i = ((ConstantClass)c).getNameIndex(); break;
- case Constants.CONSTANT_String: i = ((ConstantString)c).getStringIndex(); break;
- default:
- throw new RuntimeException("getConstantString called with illegal tag " + tag);
- }
- // Finally get the string from the constant pool
- c = getConstant(i, Constants.CONSTANT_Utf8);
- return ((ConstantUtf8)c).getBytes();
- }
-
- /**
- * Resolve constant to a string representation.
- */
- public String constantToString(Constant c) {
- String str;
- int i;
-
- switch (c.tag) {
- case Constants.CONSTANT_Class:
- i = ((ConstantClass)c).getNameIndex();
- c = getConstant(i, Constants.CONSTANT_Utf8);
- str = Utility.compactClassName(((ConstantUtf8)c).getBytes(), false);
- break;
-
- case Constants.CONSTANT_String:
- i = ((ConstantString)c).getStringIndex();
- c = getConstant(i, Constants.CONSTANT_Utf8);
- str = "\"" + escape(((ConstantUtf8)c).getBytes()) + "\"";
- break;
-
- case Constants.CONSTANT_Utf8: str = ((ConstantUtf8)c).getBytes(); break;
- case Constants.CONSTANT_Double: str = Double.toString(((ConstantDouble)c).getBytes()); break;
- case Constants.CONSTANT_Float: str = Float.toString(((ConstantFloat)c).getBytes()); break;
- case Constants.CONSTANT_Long: str = Long.toString(((ConstantLong)c).getBytes()); break;
- case Constants.CONSTANT_Integer: str = Integer.toString(((ConstantInteger)c).getBytes()); break;
-
- case Constants.CONSTANT_NameAndType:
- str = (constantToString(((ConstantNameAndType)c).getNameIndex(),
- Constants.CONSTANT_Utf8) + " " +
- constantToString(((ConstantNameAndType)c).getSignatureIndex(),
- Constants.CONSTANT_Utf8));
- break;
-
- case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref:
- case Constants.CONSTANT_Fieldref:
- str = (constantToString(((ConstantCP)c).getClassIndex(),
- Constants.CONSTANT_Class) + "." +
- constantToString(((ConstantCP)c).getNameAndTypeIndex(),
- Constants.CONSTANT_NameAndType));
- break;
-
- default: // Never reached
- throw new RuntimeException("Unknown constant type " + c.tag);
- }
-
- return str;
- }
-
- private static final String escape(String str) {
- int len = str.length();
- StringBuffer buf = new StringBuffer(len + 5);
- char[] ch = str.toCharArray();
-
- for(int i=0; i < len; i++) {
- switch(ch[i]) {
- case '\n' : buf.append("\\n"); break;
- case '\r' : buf.append("\\r"); break;
- case '\t' : buf.append("\\t"); break;
- case '\b' : buf.append("\\b"); break;
- case '"' : buf.append("\\\""); break;
- default: buf.append(ch[i]);
- }
- }
-
- return buf.toString();
- }
-
+ byte tag;
+ poolSize = file.readUnsignedShort();
+ pool = new Constant[poolSize];
+ // pool[0] is unused by the compiler and may be used freely by the implementation
+ for (int i = 1; i < poolSize; i++) {
+ pool[i] = Constant.readConstant(file);
+ tag = pool[i].getTag();
+ if ((tag == Constants.CONSTANT_Double) || (tag == Constants.CONSTANT_Long)) {
+ i++;
+ }
+ }
+ }
+
+ public Constant getConstant(int index, byte tag) {
+ Constant c = getConstant(index);
+ // if (c == null) throw new ClassFormatException("Constant pool at index " + index + " is null.");
+ if (c.tag == tag)
+ return c;
+ throw new ClassFormatException("Expected class '" + Constants.CONSTANT_NAMES[tag] + "' at index " + index + " and found "
+ + c);
+ }
+
+ public Constant getConstant(int index) {
+ if (index >= pool.length || index < 0)
+ throw new ClassFormatException("Invalid constant pool reference: " + index + ". Constant pool size is: " + pool.length);
+ return pool[index];
+ }
+
+ /**
+ * @return deep copy of this constant pool
+ */
+ public ConstantPool copy() {
+ Constant[] newConstants = new Constant[poolSize]; // use the correct size
+ for (int i = 1; i < poolSize; i++) {
+ if (pool[i] != null) {
+ newConstants[i] = pool[i].copy();
+ }
+ }
+ return new ConstantPool(newConstants);
+ }
+
+ /**
+ * Get string from constant pool and bypass the indirection of `ConstantClass' and `ConstantString' objects. I.e. these classes
+ * have an index field that points to another entry of the constant pool of type `ConstantUtf8' which contains the real data.
+ *
+ * @param index Index in constant pool
+ * @param tag Tag of expected constant, either ConstantClass or ConstantString
+ * @return Contents of string reference
+ * @see ConstantClass
+ * @see ConstantString
+ * @throws ClassFormatException
+ */
+ public String getConstantString(int index, byte tag) throws ClassFormatException {
+ Constant c = getConstant(index, tag);
+ int i;
+ /*
+ * This switch() is not that elegant, since the two classes have the same contents, they just differ in the name of the
+ * index field variable. But we want to stick to the JVM naming conventions closely though we could have solved these more
+ * elegantly by using the same variable name or by subclassing.
+ */
+ // OPTIMIZE remove the difference - use the an interface and same index methods for string ref id
+ switch (tag) {
+ case Constants.CONSTANT_Class:
+ i = ((ConstantClass) c).getNameIndex();
+ break;
+ case Constants.CONSTANT_String:
+ i = ((ConstantString) c).getStringIndex();
+ break;
+ default:
+ throw new RuntimeException("getConstantString called with illegal tag " + tag);
+ }
+ // Finally get the string from the constant pool
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ return ((ConstantUtf8) c).getBytes();
+ }
+
+ /**
+ * Resolve constant to a string representation.
+ */
+ public String constantToString(Constant c) {
+ String str;
+ int i;
+
+ switch (c.tag) {
+ case Constants.CONSTANT_Class:
+ i = ((ConstantClass) c).getNameIndex();
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ str = Utility.compactClassName(((ConstantUtf8) c).getBytes(), false);
+ break;
+
+ case Constants.CONSTANT_String:
+ i = ((ConstantString) c).getStringIndex();
+ c = getConstant(i, Constants.CONSTANT_Utf8);
+ str = "\"" + escape(((ConstantUtf8) c).getBytes()) + "\"";
+ break;
+
+ case Constants.CONSTANT_Utf8:
+ str = ((ConstantUtf8) c).getBytes();
+ break;
+ case Constants.CONSTANT_Double:
+ str = Double.toString(((ConstantDouble) c).getBytes());
+ break;
+ case Constants.CONSTANT_Float:
+ str = Float.toString(((ConstantFloat) c).getBytes());
+ break;
+ case Constants.CONSTANT_Long:
+ str = Long.toString(((ConstantLong) c).getBytes());
+ break;
+ case Constants.CONSTANT_Integer:
+ str = Integer.toString(((ConstantInteger) c).getBytes());
+ break;
+
+ case Constants.CONSTANT_NameAndType:
+ str = (constantToString(((ConstantNameAndType) c).getNameIndex(), Constants.CONSTANT_Utf8) + " " + constantToString(
+ ((ConstantNameAndType) c).getSignatureIndex(), Constants.CONSTANT_Utf8));
+ break;
+
+ case Constants.CONSTANT_InterfaceMethodref:
+ case Constants.CONSTANT_Methodref:
+ case Constants.CONSTANT_Fieldref:
+ str = (constantToString(((ConstantCP) c).getClassIndex(), Constants.CONSTANT_Class) + "." + constantToString(
+ ((ConstantCP) c).getNameAndTypeIndex(), Constants.CONSTANT_NameAndType));
+ break;
+
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + c.tag);
+ }
+
+ return str;
+ }
+
+ private static final String escape(String str) {
+ int len = str.length();
+ StringBuffer buf = new StringBuffer(len + 5);
+ char[] ch = str.toCharArray();
+
+ for (int i = 0; i < len; i++) {
+ switch (ch[i]) {
+ case '\n':
+ buf.append("\\n");
+ break;
+ case '\r':
+ buf.append("\\r");
+ break;
+ case '\t':
+ buf.append("\\t");
+ break;
+ case '\b':
+ buf.append("\\b");
+ break;
+ case '"':
+ buf.append("\\\"");
+ break;
+ default:
+ buf.append(ch[i]);
+ }
+ }
+
+ return buf.toString();
+ }
+
public String constantToString(int index, byte tag) {
Constant c = getConstant(index, tag);
return constantToString(c);
}
-
- public void accept(ClassVisitor v) {
- v.visitConstantPool(this);
- }
-
- public Constant[] getConstantPool() { return pool; } // TEMPORARY, DONT LIKE PASSING THIS DATA OUT!
-
- public void dump(DataOutputStream file) throws IOException {
- file.writeShort(poolSize);
- for(int i=1; i < poolSize; i++) if (pool[i]!=null) pool[i].dump(file);
- }
-
+
+ public void accept(ClassVisitor v) {
+ v.visitConstantPool(this);
+ }
+
+ public Constant[] getConstantPool() {
+ return pool;
+ } // TEMPORARY, DONT LIKE PASSING THIS DATA OUT!
+
+ public void dump(DataOutputStream file) throws IOException {
+ file.writeShort(poolSize);
+ for (int i = 1; i < poolSize; i++)
+ if (pool[i] != null)
+ pool[i].dump(file);
+ }
+
public ConstantUtf8 getConstantUtf8(int idx) {
- try {
- Constant c = pool[idx];
- if (c==null)
- throw new ClassFormatException("Constant pool at index " + idx + " is null.");
- if (c.tag!=Constants.CONSTANT_Utf8)
- throw new ClassFormatException("Expected UTF8Constant "+
- " at index " + idx + " and got " + c);
- return (ConstantUtf8)c;
- } catch (ArrayIndexOutOfBoundsException aioobe) {
- throw new ClassFormatException("Index "+idx+" into constant pool (size:"+poolSize+") is invalid");
- }
- }
-
- public String getConstantString_CONSTANTClass(int index) {
- ConstantClass c = (ConstantClass)getConstant(index,Constants.CONSTANT_Class);
- index = c.getNameIndex();
- return ((ConstantUtf8)getConstant(index,Constants.CONSTANT_Utf8)).getBytes();
- }
-
- public int getLength() { return poolSize; }
-
- public String toString() {
- StringBuffer buf = new StringBuffer();
-
- for(int i=1; i < poolSize; i++)
- buf.append(i + ")" + pool[i] + "\n");
-
- return buf.toString();
- }
-
- public int lookupInteger(int n) {
- for (int i=1; i < poolSize; i++) {
- if (pool[i] instanceof ConstantInteger) {
- ConstantInteger c = (ConstantInteger)pool[i];
- if (c.getBytes() == n) return i;
- }
- }
- return -1;
- }
-
-
- public int lookupUtf8(String string) {
- Integer pos = utf8Cache.get(string);
- if (pos!=null) return pos.intValue();
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_Utf8) {
- if (((ConstantUtf8)c).getBytes().equals(string)) {
- utf8Cache.put(string,new Integer(i));
- return i;
- }
- }
- }
- return -1;
- }
-
- public int lookupClass(String classname) {
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_Class) {
- int cIndex = ((ConstantClass)c).getNameIndex();
- String cName = ((ConstantUtf8)pool[cIndex]).getBytes();
- if (cName.equals(classname)) return i;
- }
- }
- return -1;
- }
-
- public int addUtf8(String n) {
- int ret = lookupUtf8(n);
- if (ret != -1) return ret;
- adjustSize();
- ret = poolSize;
- pool[poolSize++] = new ConstantUtf8(n);
- return ret;
- }
-
- public int addInteger(int n) {
- int ret = lookupInteger(n);
- if (ret != -1) return ret;
- adjustSize();
- ret = poolSize;
- pool[poolSize++] = new ConstantInteger(n);
- return ret;
- }
-
- public int addArrayClass(ArrayType type) {
- return addClass(type.getSignature());
- }
-
- public int addClass(ObjectType type) {
- return addClass(type.getClassName());
- }
-
- public int addClass(String classname) {
- String toAdd = classname.replace('.','/');
- int ret = lookupClass(toAdd);
- if(ret != -1) return ret;
- adjustSize();
- ConstantClass c = new ConstantClass(addUtf8(toAdd));
- ret = poolSize;
- pool[poolSize++] = c;
- return ret;
- }
-
- private void adjustSize() {
- if(poolSize + 3 >= pool.length) {
- Constant[] cs = pool;
- pool = new Constant[cs.length+8];
- System.arraycopy(cs, 0, pool, 0, cs.length);
- }
- if (poolSize==0) poolSize = 1; // someone about to do something in here!
- }
-
+ try {
+ Constant c = pool[idx];
+ if (c == null) {
+ throw new ClassFormatException("Constant pool at index " + idx + " is null.");
+ }
+ if (c.tag != Constants.CONSTANT_Utf8) {
+ throw new ClassFormatException("Expected UTF8Constant " + " at index " + idx + " and got " + c);
+ }
+ return (ConstantUtf8) c;
+ } catch (ArrayIndexOutOfBoundsException aioobe) {
+ throw new ClassFormatException("Index " + idx + " into constant pool (size:" + poolSize + ") is invalid");
+ }
+ }
+
+ public String getConstantString_CONSTANTClass(int index) {
+ ConstantClass c = (ConstantClass) getConstant(index, Constants.CONSTANT_Class);
+ index = c.getNameIndex();
+ return ((ConstantUtf8) getConstant(index, Constants.CONSTANT_Utf8)).getBytes();
+ }
+
+ public int getLength() {
+ return poolSize;
+ }
+
+ @Override
+ public String toString() {
+ StringBuffer buf = new StringBuffer();
+
+ for (int i = 1; i < poolSize; i++)
+ buf.append(i + ")" + pool[i] + "\n");
+
+ return buf.toString();
+ }
+
+ public int lookupInteger(int n) {
+ for (int i = 1; i < poolSize; i++) {
+ if (pool[i] instanceof ConstantInteger) {
+ ConstantInteger c = (ConstantInteger) pool[i];
+ if (c.getBytes() == n)
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int lookupUtf8(String string) {
+ Integer pos = utf8Cache.get(string);
+ if (pos != null) {
+ return pos;
+ }
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Utf8) {
+ if (((ConstantUtf8) c).getBytes().equals(string)) {
+ utf8Cache.put(string, i);
+ return i;
+ }
+ }
+ }
+ return -1;
+ }
+
+ public int lookupClass(String classname) {
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Class) {
+ int cIndex = ((ConstantClass) c).getNameIndex();
+ String cName = ((ConstantUtf8) pool[cIndex]).getBytes();
+ if (cName.equals(classname))
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addUtf8(String n) {
+ int ret = lookupUtf8(n);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ret = poolSize;
+ pool[poolSize++] = new ConstantUtf8(n);
+ return ret;
+ }
+
+ public int addInteger(int n) {
+ int ret = lookupInteger(n);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ret = poolSize;
+ pool[poolSize++] = new ConstantInteger(n);
+ return ret;
+ }
+
+ public int addArrayClass(ArrayType type) {
+ return addClass(type.getSignature());
+ }
+
+ public int addClass(ObjectType type) {
+ return addClass(type.getClassName());
+ }
+
+ public int addClass(String classname) {
+ String toAdd = classname.replace('.', '/');
+ int ret = lookupClass(toAdd);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ ConstantClass c = new ConstantClass(addUtf8(toAdd));
+ ret = poolSize;
+ pool[poolSize++] = c;
+ return ret;
+ }
+
+ private void adjustSize() {
+ if (poolSize + 3 >= pool.length) {
+ Constant[] cs = pool;
+ pool = new Constant[cs.length + 8];
+ System.arraycopy(cs, 0, pool, 0, cs.length);
+ }
+ if (poolSize == 0)
+ poolSize = 1; // someone about to do something in here!
+ }
+
public int addFieldref(String class_name, String field_name, String signature) {
- int ret = lookupFieldref(class_name, field_name, signature);
- int class_index, name_and_type_index;
-
- if (ret != -1) return ret;
-
- adjustSize();
-
- class_index = addClass(class_name);
- name_and_type_index = addNameAndType(field_name, signature);
- ret = poolSize;
- pool[poolSize++] = new ConstantFieldref(class_index, name_and_type_index);
-
- return ret;
- }
-
- public int lookupFieldref(String searchClassname, String searchFieldname, String searchSignature) {
- searchClassname = searchClassname.replace('.','/');
- String k = new StringBuffer().append(searchClassname).append(searchFieldname).append(searchSignature).toString();
- Integer pos = fieldCache.get(k);
- if (pos!=null) return pos.intValue();
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_Fieldref) {
- ConstantFieldref cfr = (ConstantFieldref)c;
- ConstantNameAndType cnat = (ConstantNameAndType)pool[cfr.getNameAndTypeIndex()];
-
- // check the class
- int cIndex = cfr.getClassIndex();
- ConstantClass cc = (ConstantClass)pool[cIndex];
- String cName = ((ConstantUtf8)pool[cc.getNameIndex()]).getBytes();
- if (!cName.equals(searchClassname)) continue;
-
- // check the name and type
- String name = ((ConstantUtf8)pool[cnat.getNameIndex()]).getBytes();
- if (!name.equals(searchFieldname)) continue; // not this one
- String typeSignature = ((ConstantUtf8)pool[cnat.getSignatureIndex()]).getBytes();
- if (!typeSignature.equals(searchSignature)) continue;
- fieldCache.put(k,new Integer(i));
- return i;
- }
- }
- return -1;
- }
-
-
-
- public int addNameAndType(String name, String signature) {
- int ret = lookupNameAndType(name, signature);
- if (ret != -1) return ret;
- adjustSize();
- int name_index = addUtf8(name);
- int signature_index = addUtf8(signature);
- ret = poolSize;
- pool[poolSize++] = new ConstantNameAndType(name_index, signature_index);
- return ret;
- }
-
- public int lookupNameAndType(String searchName, String searchTypeSignature) {
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_NameAndType) {
- ConstantNameAndType cnat = (ConstantNameAndType)c;
- String name = ((ConstantUtf8)pool[cnat.getNameIndex()]).getBytes();
- if (!name.equals(searchName)) continue; // not this one
- String typeSignature = ((ConstantUtf8)pool[cnat.getSignatureIndex()]).getBytes();
- if (!typeSignature.equals(searchTypeSignature)) continue;
- return i;
- }
- }
- return -1;
- }
-
+ int ret = lookupFieldref(class_name, field_name, signature);
+ int class_index, name_and_type_index;
+
+ if (ret != -1)
+ return ret;
+
+ adjustSize();
+
+ class_index = addClass(class_name);
+ name_and_type_index = addNameAndType(field_name, signature);
+ ret = poolSize;
+ pool[poolSize++] = new ConstantFieldref(class_index, name_and_type_index);
+
+ return ret;
+ }
+
+ public int lookupFieldref(String searchClassname, String searchFieldname, String searchSignature) {
+ searchClassname = searchClassname.replace('.', '/');
+ String k = new StringBuffer().append(searchClassname).append(searchFieldname).append(searchSignature).toString();
+ Integer pos = fieldCache.get(k);
+ if (pos != null)
+ return pos.intValue();
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Fieldref) {
+ ConstantFieldref cfr = (ConstantFieldref) c;
+ ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()];
+
+ // check the class
+ int cIndex = cfr.getClassIndex();
+ ConstantClass cc = (ConstantClass) pool[cIndex];
+ String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getBytes();
+ if (!cName.equals(searchClassname))
+ continue;
+
+ // check the name and type
+ String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getBytes();
+ if (!name.equals(searchFieldname))
+ continue; // not this one
+ String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getBytes();
+ if (!typeSignature.equals(searchSignature))
+ continue;
+ fieldCache.put(k, new Integer(i));
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int addNameAndType(String name, String signature) {
+ int ret = lookupNameAndType(name, signature);
+ if (ret != -1)
+ return ret;
+ adjustSize();
+ int name_index = addUtf8(name);
+ int signature_index = addUtf8(signature);
+ ret = poolSize;
+ pool[poolSize++] = new ConstantNameAndType(name_index, signature_index);
+ return ret;
+ }
+
+ public int lookupNameAndType(String searchName, String searchTypeSignature) {
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_NameAndType) {
+ ConstantNameAndType cnat = (ConstantNameAndType) c;
+ String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getBytes();
+ if (!name.equals(searchName))
+ continue; // not this one
+ String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getBytes();
+ if (!typeSignature.equals(searchTypeSignature))
+ continue;
+ return i;
+ }
+ }
+ return -1;
+ }
+
public int addFloat(float f) {
- int ret= lookupFloat(f);
- if (ret != -1) return ret;
+ int ret = lookupFloat(f);
+ if (ret != -1)
+ return ret;
adjustSize();
ret = poolSize;
pool[poolSize++] = new ConstantFloat(f);
return ret;
}
-
- public int lookupFloat(float f) {
- int bits = Float.floatToIntBits(f);
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_Float) {
- ConstantFloat cf = (ConstantFloat)c;
- if (Float.floatToIntBits(cf.getBytes())==bits) return i;
- }
+ public int lookupFloat(float f) {
+ int bits = Float.floatToIntBits(f);
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Float) {
+ ConstantFloat cf = (ConstantFloat) c;
+ if (Float.floatToIntBits(cf.getBytes()) == bits)
+ return i;
+ }
+ }
+ return -1;
}
- return -1;
- }
- public int addDouble(double d) {
- int ret= lookupDouble(d);
- if (ret != -1) return ret;
+
+ public int addDouble(double d) {
+ int ret = lookupDouble(d);
+ if (ret != -1)
+ return ret;
adjustSize();
ret = poolSize;
pool[poolSize] = new ConstantDouble(d);
- poolSize+=2;
+ poolSize += 2;
return ret;
}
-
-public int lookupDouble(double d) {
- long bits = Double.doubleToLongBits(d);
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_Double) {
- ConstantDouble cf = (ConstantDouble)c;
- if (Double.doubleToLongBits(cf.getBytes())==bits) return i;
+ public int lookupDouble(double d) {
+ long bits = Double.doubleToLongBits(d);
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Double) {
+ ConstantDouble cf = (ConstantDouble) c;
+ if (Double.doubleToLongBits(cf.getBytes()) == bits)
+ return i;
+ }
}
+ return -1;
}
- return -1;
-}
-public int addLong(long l) {
- int ret= lookupLong(l);
- if (ret != -1) return ret;
+ public int addLong(long l) {
+ int ret = lookupLong(l);
+ if (ret != -1)
+ return ret;
adjustSize();
ret = poolSize;
pool[poolSize] = new ConstantLong(l);
- poolSize+=2;
+ poolSize += 2;
return ret;
}
-
-public int lookupString(String s) {
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_String) {
- ConstantString cs = (ConstantString)c;
- ConstantUtf8 cu8 = (ConstantUtf8)pool[cs.getStringIndex()];
- if (cu8.getBytes().equals(s)) return i;
+ public int lookupString(String s) {
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_String) {
+ ConstantString cs = (ConstantString) c;
+ ConstantUtf8 cu8 = (ConstantUtf8) pool[cs.getStringIndex()];
+ if (cu8.getBytes().equals(s))
+ return i;
+ }
}
+ return -1;
}
- return -1;
-}
public int addString(String str) {
int ret = lookupString(str);
- if (ret!=-1) return ret;
+ if (ret != -1)
+ return ret;
int utf8 = addUtf8(str);
adjustSize();
- ConstantString s = new ConstantString(utf8);
+ ConstantString s = new ConstantString(utf8);
ret = poolSize;
pool[poolSize++] = s;
return ret;
}
-public int lookupLong(long l) {
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_Long) {
- ConstantLong cf = (ConstantLong)c;
- if (cf.getBytes()==l) return i;
+ public int lookupLong(long l) {
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Long) {
+ ConstantLong cf = (ConstantLong) c;
+ if (cf.getBytes() == l)
+ return i;
+ }
}
+ return -1;
}
- return -1;
-}
- public int addConstant(Constant c, ConstantPool cp) {
- Constant[] constants = cp.getConstantPool();
- switch(c.getTag()) {
+ public int addConstant(Constant c, ConstantPool cp) {
+ Constant[] constants = cp.getConstantPool();
+ switch (c.getTag()) {
- case Constants.CONSTANT_String: {
- ConstantString s = (ConstantString)c;
- ConstantUtf8 u8 = (ConstantUtf8)constants[s.getStringIndex()];
-
- return addString(u8.getBytes());
- }
+ case Constants.CONSTANT_String: {
+ ConstantString s = (ConstantString) c;
+ ConstantUtf8 u8 = (ConstantUtf8) constants[s.getStringIndex()];
-case Constants.CONSTANT_Class: {
- ConstantClass s = (ConstantClass)c;
- ConstantUtf8 u8 = (ConstantUtf8)constants[s.getNameIndex()];
+ return addString(u8.getBytes());
+ }
+
+ case Constants.CONSTANT_Class: {
+ ConstantClass s = (ConstantClass) c;
+ ConstantUtf8 u8 = (ConstantUtf8) constants[s.getNameIndex()];
- return addClass(u8.getBytes());
-}
+ return addClass(u8.getBytes());
+ }
-case Constants.CONSTANT_NameAndType: {
- ConstantNameAndType n = (ConstantNameAndType)c;
- ConstantUtf8 u8 = (ConstantUtf8)constants[n.getNameIndex()];
- ConstantUtf8 u8_2 = (ConstantUtf8)constants[n.getSignatureIndex()];
+ case Constants.CONSTANT_NameAndType: {
+ ConstantNameAndType n = (ConstantNameAndType) c;
+ ConstantUtf8 u8 = (ConstantUtf8) constants[n.getNameIndex()];
+ ConstantUtf8 u8_2 = (ConstantUtf8) constants[n.getSignatureIndex()];
- return addNameAndType(u8.getBytes(), u8_2.getBytes());
-}
+ return addNameAndType(u8.getBytes(), u8_2.getBytes());
+ }
-case Constants.CONSTANT_Utf8:
- return addUtf8(((ConstantUtf8)c).getBytes());
+ case Constants.CONSTANT_Utf8:
+ return addUtf8(((ConstantUtf8) c).getBytes());
-case Constants.CONSTANT_Double:
- return addDouble(((ConstantDouble)c).getBytes());
+ case Constants.CONSTANT_Double:
+ return addDouble(((ConstantDouble) c).getBytes());
-case Constants.CONSTANT_Float:
- return addFloat(((ConstantFloat)c).getBytes());
+ case Constants.CONSTANT_Float:
+ return addFloat(((ConstantFloat) c).getBytes());
-case Constants.CONSTANT_Long:
- return addLong(((ConstantLong)c).getBytes());
+ case Constants.CONSTANT_Long:
+ return addLong(((ConstantLong) c).getBytes());
-case Constants.CONSTANT_Integer:
- return addInteger(((ConstantInteger)c).getBytes());
+ case Constants.CONSTANT_Integer:
+ return addInteger(((ConstantInteger) c).getBytes());
-case Constants.CONSTANT_InterfaceMethodref: case Constants.CONSTANT_Methodref:
-case Constants.CONSTANT_Fieldref: {
- ConstantCP m = (ConstantCP)c;
- ConstantClass clazz = (ConstantClass)constants[m.getClassIndex()];
- ConstantNameAndType n = (ConstantNameAndType)constants[m.getNameAndTypeIndex()];
- ConstantUtf8 u8 = (ConstantUtf8)constants[clazz.getNameIndex()];
- String class_name = u8.getBytes().replace('/', '.');
+ case Constants.CONSTANT_InterfaceMethodref:
+ case Constants.CONSTANT_Methodref:
+ case Constants.CONSTANT_Fieldref: {
+ ConstantCP m = (ConstantCP) c;
+ ConstantClass clazz = (ConstantClass) constants[m.getClassIndex()];
+ ConstantNameAndType n = (ConstantNameAndType) constants[m.getNameAndTypeIndex()];
+ ConstantUtf8 u8 = (ConstantUtf8) constants[clazz.getNameIndex()];
+ String class_name = u8.getBytes().replace('/', '.');
- u8 = (ConstantUtf8)constants[n.getNameIndex()];
- String name = u8.getBytes();
+ u8 = (ConstantUtf8) constants[n.getNameIndex()];
+ String name = u8.getBytes();
- u8 = (ConstantUtf8)constants[n.getSignatureIndex()];
- String signature = u8.getBytes();
+ u8 = (ConstantUtf8) constants[n.getSignatureIndex()];
+ String signature = u8.getBytes();
- switch(c.getTag()) {
- case Constants.CONSTANT_InterfaceMethodref:
-return addInterfaceMethodref(class_name, name, signature);
+ switch (c.getTag()) {
+ case Constants.CONSTANT_InterfaceMethodref:
+ return addInterfaceMethodref(class_name, name, signature);
- case Constants.CONSTANT_Methodref:
-return addMethodref(class_name, name, signature); // OPTIMIZE indicate it should be cached!
+ case Constants.CONSTANT_Methodref:
+ return addMethodref(class_name, name, signature); // OPTIMIZE indicate it should be cached!
- case Constants.CONSTANT_Fieldref:
-return addFieldref(class_name, name, signature);
+ case Constants.CONSTANT_Fieldref:
+ return addFieldref(class_name, name, signature);
- default: // Never reached
-throw new RuntimeException("Unknown constant type " + c);
- }
-}
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + c);
+ }
+ }
-default: // Never reached
- throw new RuntimeException("Unknown constant type " + c);
-}
-}
+ default: // Never reached
+ throw new RuntimeException("Unknown constant type " + c);
+ }
+ }
- // OPTIMIZE should put it in the cache now
+ // OPTIMIZE should put it in the cache now
public int addMethodref(String class_name, String method_name, String signature) {
- int ret, class_index, name_and_type_index;
- if((ret = lookupMethodref(class_name, method_name, signature)) != -1)
- return ret; // Already in CP
-
- adjustSize();
-
- name_and_type_index = addNameAndType(method_name, signature);
- class_index = addClass(class_name);
- ret = poolSize;
- pool[poolSize++] = new ConstantMethodref(class_index, name_and_type_index);
- return ret;
- }
-
- public int addInterfaceMethodref(String class_name, String method_name, String signature) {
- int ret = lookupInterfaceMethodref(class_name, method_name, signature);
- int class_index, name_and_type_index;
-
- if( ret != -1) return ret;
- adjustSize();
-
- class_index = addClass(class_name);
- name_and_type_index = addNameAndType(method_name, signature);
- ret = poolSize;
- pool[poolSize++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
- return ret;
- }
-
- public int lookupInterfaceMethodref(String searchClassname, String searchMethodName, String searchSignature) {
- searchClassname = searchClassname.replace('.','/');
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_InterfaceMethodref) {
- ConstantInterfaceMethodref cfr = (ConstantInterfaceMethodref)c;
-
- ConstantClass cc = (ConstantClass)pool[cfr.getClassIndex()];
- String cName = ((ConstantUtf8)pool[cc.getNameIndex()]).getBytes();
- if (!cName.equals(searchClassname)) continue;
-
- // check the name and type
- ConstantNameAndType cnat = (ConstantNameAndType)pool[cfr.getNameAndTypeIndex()];
- String name = ((ConstantUtf8)pool[cnat.getNameIndex()]).getBytes();
- if (!name.equals(searchMethodName)) continue; // not this one
- String typeSignature = ((ConstantUtf8)pool[cnat.getSignatureIndex()]).getBytes();
- if (!typeSignature.equals(searchSignature)) continue;
- return i;
- }
- }
- return -1;
- }
-
-
- public int lookupMethodref(String searchClassname, String searchMethodName, String searchSignature) {
- String key = new StringBuffer().append(searchClassname).append(searchMethodName).append(searchSignature).toString();
- Integer cached = methodCache.get(key);
- if (cached!=null) return cached.intValue();
- searchClassname = searchClassname.replace('.','/');
- for (int i=1;i<poolSize;i++) {
- Constant c = pool[i];
- if (c!=null && c.tag==Constants.CONSTANT_Methodref) {
- ConstantMethodref cfr = (ConstantMethodref)c;
- ConstantNameAndType cnat = (ConstantNameAndType)pool[cfr.getNameAndTypeIndex()];
-
- // check the class
- int cIndex = cfr.getClassIndex();
- ConstantClass cc = (ConstantClass)pool[cIndex];
- String cName = ((ConstantUtf8)pool[cc.getNameIndex()]).getBytes();
- if (!cName.equals(searchClassname)) continue;
-
- // check the name and type
- String name = ((ConstantUtf8)pool[cnat.getNameIndex()]).getBytes();
- if (!name.equals(searchMethodName)) continue; // not this one
- String typeSignature = ((ConstantUtf8)pool[cnat.getSignatureIndex()]).getBytes();
- if (!typeSignature.equals(searchSignature)) continue;
- methodCache.put(key,new Integer(i));
- return i;
- }
- }
- return -1;
- }
-
- public ConstantPool getFinalConstantPool() {
- Constant[] cs = new Constant[poolSize]; // create it the exact size we need
- System.arraycopy(pool, 0, cs, 0, poolSize);
- return new ConstantPool(cs);
- }
+ int ret, class_index, name_and_type_index;
+ if ((ret = lookupMethodref(class_name, method_name, signature)) != -1)
+ return ret; // Already in CP
+
+ adjustSize();
+
+ name_and_type_index = addNameAndType(method_name, signature);
+ class_index = addClass(class_name);
+ ret = poolSize;
+ pool[poolSize++] = new ConstantMethodref(class_index, name_and_type_index);
+ return ret;
+ }
+
+ public int addInterfaceMethodref(String class_name, String method_name, String signature) {
+ int ret = lookupInterfaceMethodref(class_name, method_name, signature);
+ int class_index, name_and_type_index;
+
+ if (ret != -1)
+ return ret;
+ adjustSize();
+
+ class_index = addClass(class_name);
+ name_and_type_index = addNameAndType(method_name, signature);
+ ret = poolSize;
+ pool[poolSize++] = new ConstantInterfaceMethodref(class_index, name_and_type_index);
+ return ret;
+ }
+
+ public int lookupInterfaceMethodref(String searchClassname, String searchMethodName, String searchSignature) {
+ searchClassname = searchClassname.replace('.', '/');
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_InterfaceMethodref) {
+ ConstantInterfaceMethodref cfr = (ConstantInterfaceMethodref) c;
+
+ ConstantClass cc = (ConstantClass) pool[cfr.getClassIndex()];
+ String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getBytes();
+ if (!cName.equals(searchClassname))
+ continue;
+
+ // check the name and type
+ ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()];
+ String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getBytes();
+ if (!name.equals(searchMethodName))
+ continue; // not this one
+ String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getBytes();
+ if (!typeSignature.equals(searchSignature))
+ continue;
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public int lookupMethodref(String searchClassname, String searchMethodName, String searchSignature) {
+ String key = new StringBuffer().append(searchClassname).append(searchMethodName).append(searchSignature).toString();
+ Integer cached = methodCache.get(key);
+ if (cached != null)
+ return cached.intValue();
+ searchClassname = searchClassname.replace('.', '/');
+ for (int i = 1; i < poolSize; i++) {
+ Constant c = pool[i];
+ if (c != null && c.tag == Constants.CONSTANT_Methodref) {
+ ConstantMethodref cfr = (ConstantMethodref) c;
+ ConstantNameAndType cnat = (ConstantNameAndType) pool[cfr.getNameAndTypeIndex()];
+
+ // check the class
+ int cIndex = cfr.getClassIndex();
+ ConstantClass cc = (ConstantClass) pool[cIndex];
+ String cName = ((ConstantUtf8) pool[cc.getNameIndex()]).getBytes();
+ if (!cName.equals(searchClassname))
+ continue;
+
+ // check the name and type
+ String name = ((ConstantUtf8) pool[cnat.getNameIndex()]).getBytes();
+ if (!name.equals(searchMethodName))
+ continue; // not this one
+ String typeSignature = ((ConstantUtf8) pool[cnat.getSignatureIndex()]).getBytes();
+ if (!typeSignature.equals(searchSignature))
+ continue;
+ methodCache.put(key, new Integer(i));
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public ConstantPool getFinalConstantPool() {
+ Constant[] cs = new Constant[poolSize]; // create it the exact size we need
+ System.arraycopy(pool, 0, cs, 0, poolSize);
+ return new ConstantPool(cs);
+ }
}
\ No newline at end of file
* The intent of this class is to represent a parsed or otherwise existing class file. Those interested in programatically
* generating classes should see the <a href="../generic/ClassGen.html">ClassGen</a> class.
*
- * @version $Id: JavaClass.java,v 1.17 2009/09/09 22:18:20 aclement Exp $
+ * @version $Id: JavaClass.java,v 1.18 2009/09/10 03:59:33 aclement Exp $
* @see org.aspectj.apache.bcel.generic.ClassGen
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
public class JavaClass extends Modifiers implements Cloneable, Node {
- private static final String[] NO_INTERFACE_NAMES = new String[0];
+
+ private static final String[] NoInterfaceNames = new String[0];
+ private static final Field[] NoFields = new Field[0];
+ private static final Method[] NoMethod = new Method[0];
+ private static final int[] NoInterfaceIndices = new int[0];
+ private static final Attribute[] NoAttributes = new Attribute[0];
private String fileName;
private String packageName;
*/
private transient org.aspectj.apache.bcel.util.Repository repository = null;
- /**
- * Constructor gets all contents as arguments.
- *
- * @param class_name_index Index into constant pool referencing a ConstantClass that represents this class.
- * @param superclass_name_index Index into constant pool referencing a ConstantClass that represents this class's superclass.
- * @param file_name File name
- * @param major Major compiler version
- * @param minor Minor compiler version
- * @param access_flags Access rights defined by bit flags
- * @param constant_pool Array of constants
- * @param interfaces Implemented interfaces
- * @param fields Class fields
- * @param methods Class methods
- * @param attributes Class attributes
- * @param source Read from file or generated in memory?
- */
- public JavaClass(int class_name_index, int superclass_name_index, String file_name, int major, int minor, int access_flags,
- ConstantPool constant_pool, int[] interfaces, Field[] fields, Method[] methods, Attribute[] attributes) {
+ public JavaClass(int classnameIndex, int superclassnameIndex, String filename, int major, int minor, int access_flags,
+ ConstantPool cpool, int[] interfaces, Field[] fields, Method[] methods, Attribute[] attributes) {
if (interfaces == null) {
- interfaces = new int[0];
- }
- if (attributes == null) {
- this.attributes = Attribute.NoAttributes;
- }
- if (fields == null) {
- fields = new Field[0]; // TODO create a constant for no fields
- }
- if (methods == null) {
- methods = new Method[0]; // TODO create a constant for no methods
+ interfaces = NoInterfaceIndices;
}
- this.classnameIdx = class_name_index;
- this.superclassnameIdx = superclass_name_index;
- this.fileName = file_name;
+ this.classnameIdx = classnameIndex;
+ this.superclassnameIdx = superclassnameIndex;
+ this.fileName = filename;
this.major = major;
this.minor = minor;
this.modifiers = access_flags;
- this.cpool = constant_pool;
+ this.cpool = cpool;
this.interfaces = interfaces;
- this.fields = fields;
- this.methods = methods;
- this.attributes = attributes;
+ this.fields = (fields == null ? NoFields : fields);
+ this.methods = (methods == null ? NoMethod : methods);
+ this.attributes = (attributes == null ? NoAttributes : attributes);
annotationsOutOfDate = true;
// Get source file name if available
* According to the specification the following entries must be of type `ConstantClass' but we check that anyway via the
* `ConstPool.getConstant' method.
*/
- classname = constant_pool.getConstantString(class_name_index, Constants.CONSTANT_Class);
+ classname = cpool.getConstantString(classnameIndex, Constants.CONSTANT_Class);
classname = Utility.compactClassName(classname, false);
int index = classname.lastIndexOf('.');
packageName = classname.substring(0, index);
}
- if (superclass_name_index > 0) { // May be zero -> class is java.lang.Object
- superclassname = constant_pool.getConstantString(superclass_name_index, Constants.CONSTANT_Class);
+ if (superclassnameIndex > 0) { // May be zero -> class is java.lang.Object
+ superclassname = cpool.getConstantString(superclassnameIndex, Constants.CONSTANT_Class);
superclassname = Utility.compactClassName(superclassname, false);
} else {
superclassname = "java.lang.Object";
}
if (interfaces.length == 0) {
- interfacenames = NO_INTERFACE_NAMES;
+ interfacenames = NoInterfaceNames;
} else {
interfacenames = new String[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
- String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
+ String str = cpool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
interfacenames[i] = Utility.compactClassName(str, false);
}
}
return packageName;
}
- /**
- * @return Class name index.
- */
public int getClassNameIndex() {
return classnameIdx;
}
- /**
- * @return Constant pool.
- */
public ConstantPool getConstantPool() {
return cpool;
}
return interfaces;
}
- /**
- * @return Major number of class file version.
- */
public int getMajor() {
return major;
}
public Method getMethod(java.lang.reflect.Constructor c) {
for (int i = 0; i < methods.length; i++) {
Method method = methods[i];
-
if (method.getName().equals("<init>") && c.getModifiers() == method.getModifiers()
&& Type.getSignature(c).equals(method.getSignature())) {
return method;
}
public Field getField(java.lang.reflect.Field field) {
- for (int i = 0; i < fields.length; i++) {
- if (fields[i].getName().equals(field.getName())) {
- return fields[i];
+ String fieldName = field.getName();
+ for (Field f : fields) {
+ if (f.getName().equals(fieldName)) {
+ return f;
}
}
return null;
this.interfaces = interfaces;
}
- /**
- * @param major .
- */
public void setMajor(int major) {
this.major = major;
}
- /**
- * @param methods .
- */
public void setMethods(Method[] methods) {
this.methods = methods;
}
- /**
- * @param minor .
- */
public void setMinor(int minor) {
this.minor = minor;
}
import org.aspectj.apache.bcel.classfile.annotation.RuntimeParameterAnnotations;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleParameterAnnotations;
+import org.aspectj.apache.bcel.generic.Type;
import org.aspectj.apache.bcel.util.ByteSequence;
/**
* Utility functions that do not really belong to any class in particular.
*
- * @version $Id: Utility.java,v 1.9 2009/09/09 22:18:20 aclement Exp $
+ * @version $Id: Utility.java,v 1.10 2009/09/10 03:59:33 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*
* modified: Andy Clement 2-mar-05 Removed unnecessary static and optimized
public static final String compactClassName(String str, String prefix, boolean chopit) {
int len = prefix.length();
- str = str.replace('/', '.'); // Is '/' on all systems, even DOS
+ str = str.replace('/', '.');
if (chopit) {
// If string starts with 'prefix' and contains no further dots
/**
* This method converts such a string into a Java type declaration like 'void main(String[])' and throws a
* 'ClassFormatException' when the parsed type is invalid.
- *
- * @param signature Method signature
- * @param name Method name
- * @param access Method access rights
- * @return Java type declaration
- * @throws ClassFormatException
*/
public static final String methodSignatureToString(String signature, String name, String access, boolean chopit,
LocalVariableTable vars) throws ClassFormatException {
- //
- //
- // if (signature.charAt(0)!='(')
- // throw new ClassFormatException("Invalid method signature: " + signature);
- //
- // // Break the signature into two pieces: ([PARAMS])[RETURNTYPE]
- // int lastBracketPos = signature.lastIndexOf(")");
- // String parameters = signature.substring(1,lastBracketPos);
- // String returnType = signature.substring(lastBracketPos+1);
- //
- // // e.g. parameters="Ljava/util/List<Ljava/lang/String;>;"
- // // returnType="V"
- //
- // // Break signature into its parts
- // // dont want lots of substringing so lets use an index
- // int posn=0;
- // StringBuffer piece;
- // while (posn<parameters.length()) {
- // piece = new StringBuffer();
- // posn+=getSignatureFrom(parameters,piece);
- // }
- //
StringBuffer buf = new StringBuffer("(");
String type;
int index;
/**
* This method converts this string into a Java type declaration such as 'String[]' and throws a `ClassFormatException' when the
* parsed type is invalid.
- *
- * @param signature Class signature
- * @param chopit Flag that determines whether chopping is executed or not
- * @return Java type declaration
*/
public static final ResultHolder signatureToStringInternal(String signature, boolean chopit) {
int processedChars = 1; // This is the default, read just one char
return ResultHolder.INT;
case 'J':
return ResultHolder.LONG;
-
case 'L': { // Full class name
- int index = signature.indexOf(';'); // Look for closing `;'
- // Jump to the correct ';'
- if (index != -1 && signature.length() > index + 1 && signature.charAt(index + 1) == '>')
+ int index = signature.indexOf(';'); // Look for closing ';'
+
+ if (index != -1 && signature.length() > index + 1 && signature.charAt(index + 1) == '>') {
index = index + 2;
+ }
if (index < 0)
throw new ClassFormatException("Invalid signature: " + signature);
*/
public static final byte typeOfMethodSignature(String signature) throws ClassFormatException {
int index;
-
try {
- if (signature.charAt(0) != '(')
+ if (signature.charAt(0) != '(') {
throw new ClassFormatException("Invalid method signature: " + signature);
+ }
index = signature.lastIndexOf(')') + 1;
return typeOfSignature(signature.substring(index));
} catch (StringIndexOutOfBoundsException e) {
* Converts a list of AnnotationGen objects into a set of attributes that can be attached to the class file.
*
* @param cp The constant pool gen where we can create the necessary name refs
- * @param vec A list of AnnotationGen objects
+ * @param annotations A list of AnnotationGen objects
*/
- public static Collection<RuntimeAnnotations> getAnnotationAttributes(ConstantPool cp, List<AnnotationGen> vec) {
+ public static Collection<RuntimeAnnotations> getAnnotationAttributes(ConstantPool cp, List<AnnotationGen> annotations) {
- if (vec.size() == 0)
+ if (annotations.size() == 0)
return null;
try {
int countInvisible = 0;
// put the annotations in the right output stream
- for (int i = 0; i < vec.size(); i++) {
- AnnotationGen a = vec.get(i);
- if (a.isRuntimeVisible())
+ for (AnnotationGen a : annotations) {
+ if (a.isRuntimeVisible()) {
countVisible++;
- else
+ } else {
countInvisible++;
+ }
}
ByteArrayOutputStream rvaBytes = new ByteArrayOutputStream();
riaDos.writeShort(countInvisible);
// put the annotations in the right output stream
- for (int i = 0; i < vec.size(); i++) {
- AnnotationGen a = vec.get(i);
+ for (AnnotationGen a : annotations) {
if (a.isRuntimeVisible())
a.dump(rvaDos);
else
private static final int pow2(int n) {
return 1 << n;
}
+
+ /**
+ * Convert type to Java method signature, e.g. int[] f(java.lang.String x) becomes (Ljava/lang/String;)[I
+ *
+ * @param returnType what the method returns
+ * @param argTypes what are the argument types
+ * @return method signature for given type(s).
+ */
+ public static String toMethodSignature(Type returnType, Type[] argTypes) {
+ StringBuffer buf = new StringBuffer("(");
+ int length = (argTypes == null) ? 0 : argTypes.length;
+ for (int i = 0; i < length; i++) {
+ buf.append(argTypes[i].getSignature());
+ }
+ buf.append(')');
+ buf.append(returnType.getSignature());
+ return buf.toString();
+ }
}
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.ArrayList;
-import java.util.Iterator;
+import java.util.Collections;
import java.util.List;
-import org.aspectj.apache.bcel.classfile.ConstantUtf8;
import org.aspectj.apache.bcel.classfile.ConstantPool;
-import org.aspectj.apache.bcel.generic.ObjectType;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
import org.aspectj.apache.bcel.classfile.Utility;
+import org.aspectj.apache.bcel.generic.ObjectType;
public class AnnotationGen {
public static final AnnotationGen[] NO_ANNOTATIONS = new AnnotationGen[0];
-
+
private int typeIndex;
- private List /* ElementNameValuePairGen */<ElementNameValuePairGen> evs;
+ private List<ElementNameValuePairGen> pairs = Collections.emptyList();
private ConstantPool cpool;
private boolean isRuntimeVisible = false;
-
+
/**
- * Here we are taking a fixed annotation of type Annotation and building a
- * modifiable AnnotationGen object. If the pool passed in is for a different
- * class file, then copyPoolEntries should have been passed as true as that
- * will force us to do a deep copy of the annotation and move the cpool entries
- * across.
- * We need to copy the type and the element name value pairs and the visibility.
+ * Here we are taking a fixed annotation of type Annotation and building a modifiable AnnotationGen object. If the pool passed
+ * in is for a different class file, then copyPoolEntries should have been passed as true as that will force us to do a deep
+ * copy of the annotation and move the cpool entries across. We need to copy the type and the element name value pairs and the
+ * visibility.
*/
- public AnnotationGen(AnnotationGen a,ConstantPool cpool,boolean copyPoolEntries) {
+ public AnnotationGen(AnnotationGen a, ConstantPool cpool, boolean copyPoolEntries) {
this.cpool = cpool;
-
if (copyPoolEntries) {
- typeIndex = cpool.addUtf8(a.getTypeSignature());
+ typeIndex = cpool.addUtf8(a.getTypeSignature());
} else {
typeIndex = a.getTypeIndex();
}
-
- isRuntimeVisible = a.isRuntimeVisible();
-
- evs = copyValues(a.getValues(),cpool,copyPoolEntries);
+ isRuntimeVisible = a.isRuntimeVisible();
+ pairs = copyValues(a.getValues(), cpool, copyPoolEntries);
}
-
- private List<ElementNameValuePairGen> copyValues(List<ElementNameValuePairGen> in,ConstantPool cpool,boolean copyPoolEntries) {
+
+ private List<ElementNameValuePairGen> copyValues(List<ElementNameValuePairGen> in, ConstantPool cpool, boolean copyPoolEntries) {
List<ElementNameValuePairGen> out = new ArrayList<ElementNameValuePairGen>();
- for (Iterator<ElementNameValuePairGen> iter = in.iterator(); iter.hasNext();) {
- ElementNameValuePairGen nvp = iter.next();
- out.add(new ElementNameValuePairGen(nvp,cpool,copyPoolEntries));
+ for (ElementNameValuePairGen nvp : in) {
+ out.add(new ElementNameValuePairGen(nvp, cpool, copyPoolEntries));
}
return out;
}
-
+
private AnnotationGen(ConstantPool cpool) {
this.cpool = cpool;
- this.evs=new ArrayList<ElementNameValuePairGen>();
}
-
+
/**
* Retrieve an immutable version of this AnnotationGen
*/
-// public AnnotationGen getAnnotation() {
-// return this;
-//// AnnotationGen a = new AnnotationGen(typeIndex,cpool,isRuntimeVisible);
-//// for (Iterator iter = evs.iterator(); iter.hasNext();) {
-//// ElementNameValuePairGen element = (ElementNameValuePairGen) iter.next();
-//// a.addElementNameValuePair(element.getElementNameValuePair());
-//// }
-//// return a;
-// }
-
- public AnnotationGen(ObjectType type,List /*ElementNameValuePairGen*/<ElementNameValuePairGen> elements,boolean vis,ConstantPool cpool) {
+ public AnnotationGen(ObjectType type, List<ElementNameValuePairGen> pairs, boolean runtimeVisible, ConstantPool cpool) {
this.cpool = cpool;
- if (type!=null) this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects
- evs = elements;
- isRuntimeVisible = vis;
+ if (type != null) {
+ this.typeIndex = cpool.addUtf8(type.getSignature()); // Only null for funky *temporary* FakeAnnotation objects
+ }
+ this.pairs = pairs;
+ isRuntimeVisible = runtimeVisible;
}
-
- public static AnnotationGen read(DataInputStream dis,ConstantPool cpool,boolean b) throws IOException {
+
+ public static AnnotationGen read(DataInputStream dis, ConstantPool cpool, boolean b) throws IOException {
AnnotationGen a = new AnnotationGen(cpool);
a.typeIndex = dis.readUnsignedShort();
int elemValuePairCount = dis.readUnsignedShort();
- for (int i=0;i<elemValuePairCount;i++) {
- int nidx = dis.readUnsignedShort();
- a.addElementNameValuePair(
- new ElementNameValuePairGen(nidx,ElementValueGen.readElementValue(dis,cpool),cpool));
+ for (int i = 0; i < elemValuePairCount; i++) {
+ int nidx = dis.readUnsignedShort();
+ a.addElementNameValuePair(new ElementNameValuePairGen(nidx, ElementValueGen.readElementValue(dis, cpool), cpool));
}
a.isRuntimeVisible(b);
return a;
}
-
+
public void dump(DataOutputStream dos) throws IOException {
- dos.writeShort(typeIndex); // u2 index of type name in cpool
- dos.writeShort(evs.size()); // u2 element_value pair count
- for (int i = 0 ; i<evs.size();i++) {
- ElementNameValuePairGen envp = evs.get(i);
+ dos.writeShort(typeIndex); // u2 index of type name in cpool
+ dos.writeShort(pairs.size()); // u2 element_value pair count
+ for (int i = 0; i < pairs.size(); i++) {
+ ElementNameValuePairGen envp = pairs.get(i);
envp.dump(dos);
}
}
-
+
public void addElementNameValuePair(ElementNameValuePairGen evp) {
- if (evs == null) evs = new ArrayList<ElementNameValuePairGen>();
- evs.add(evp);
+ if (pairs == Collections.EMPTY_LIST) {
+ pairs = new ArrayList<ElementNameValuePairGen>();
+ }
+ pairs.add(evp);
}
-
-
+
public int getTypeIndex() {
return typeIndex;
}
-
+
public String getTypeSignature() {
-// ConstantClass c = (ConstantClass)cpool.getConstant(typeIndex);
- ConstantUtf8 utf8 = (ConstantUtf8)cpool.getConstant(typeIndex/*c.getNameIndex()*/);
- return utf8.getBytes();
+ ConstantUtf8 utf8 = (ConstantUtf8) cpool.getConstant(typeIndex);
+ return utf8.getBytes();
}
-
+
public String getTypeName() {
return Utility.signatureToString(getTypeSignature());
}
-
- /**
- * Returns list of ElementNameValuePair objects
- */
+
public List<ElementNameValuePairGen> getValues() {
- return evs;
+ return pairs;
}
-
+
+ @Override
public String toString() {
StringBuffer s = new StringBuffer();
- s.append("AnnotationGen:["+getTypeName()+" #"+evs.size()+" {");
- for (int i = 0; i<evs.size();i++) {
- s.append(evs.get(i));
- if (i+1<evs.size()) s.append(",");
+ s.append("AnnotationGen:[" + getTypeName() + " #" + pairs.size() + " {");
+ for (int i = 0; i < pairs.size(); i++) {
+ s.append(pairs.get(i));
+ if (i + 1 < pairs.size())
+ s.append(",");
}
s.append("}]");
return s.toString();
}
-
+
public String toShortString() {
StringBuffer s = new StringBuffer();
- s.append("@"+getTypeName()+"(");
- for (int i = 0; i<evs.size();i++) {
- s.append(evs.get(i));
- if (i+1<evs.size()) s.append(",");
+ s.append("@" + getTypeName() + "(");
+ for (int i = 0; i < pairs.size(); i++) {
+ s.append(pairs.get(i));
+ if (i + 1 < pairs.size())
+ s.append(",");
}
s.append(")");
return s.toString();
}
private void isRuntimeVisible(boolean b) {
- isRuntimeVisible = b;
+ isRuntimeVisible = b;
}
-
+
public boolean isRuntimeVisible() {
return isRuntimeVisible;
}
-
+
/**
- * Return true if the annotation has a value with the specified name (n) and value (v)
- */
- public boolean hasNameValuePair(String n, String v) {
- for (int i=0;i<evs.size();i++) {
- ElementNameValuePairGen pair = evs.get(i);
- if (pair.getNameString().equals(n)) {
- if (pair.getValue().stringifyValue().equals(v)) return true;
+ * @return true if the annotation has a value with the specified name and (toString'd) value
+ */
+ public boolean hasNameValuePair(String name, String value) {
+ for (ElementNameValuePairGen pair : pairs) {
+ if (pair.getNameString().equals(name)) {
+ if (pair.getValue().stringifyValue().equals(value)) {
+ return true;
+ }
}
}
return false;
}
- /**
- * Return true if the annotation has a value with the specified name (n)
- */
- public boolean hasNamedValue(String n) {
- for (int i=0;i<evs.size();i++) {
- ElementNameValuePairGen pair = evs.get(i);
- if (pair.getNameString().equals(n)) return true;
+ /**
+ * @return true if the annotation has a value with the specified name
+ */
+ public boolean hasNamedValue(String name) {
+ for (ElementNameValuePairGen pair : pairs) {
+ if (pair.getNameString().equals(name)) {
+ return true;
+ }
}
return false;
}
import java.io.DataOutputStream;
import java.io.IOException;
-import org.aspectj.apache.bcel.classfile.ConstantUtf8;
import org.aspectj.apache.bcel.classfile.ConstantPool;
-
public class ElementNameValuePairGen {
private int nameIdx;
private ElementValueGen value;
private ConstantPool cpool;
- public ElementNameValuePairGen(ElementNameValuePairGen nvp, ConstantPool cpool, boolean copyPoolEntries) {
+ public ElementNameValuePairGen(ElementNameValuePairGen pair, ConstantPool cpool, boolean copyPoolEntries) {
this.cpool = cpool;
// J5ASSERT:
// Could assert nvp.getNameString() points to the same thing as cpool.getConstant(nvp.getNameIndex())
-// if (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes())) {
-// throw new RuntimeException("envp buggered");
-// }
- if (copyPoolEntries) {
- nameIdx = cpool.addUtf8(nvp.getNameString());
+ // if (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes())) {
+ // throw new RuntimeException("envp buggered");
+ // }
+ if (copyPoolEntries) {
+ nameIdx = cpool.addUtf8(pair.getNameString());
} else {
- nameIdx = nvp.getNameIndex();
+ nameIdx = pair.getNameIndex();
}
- value = ElementValueGen.copy(nvp.getValue(),cpool,copyPoolEntries);
+ value = ElementValueGen.copy(pair.getValue(), cpool, copyPoolEntries);
}
-
- /**
- * Retrieve an immutable version of this ElementNameValuePairGen
- */
-// public ElementNameValuePairGen getElementNameValuePair() {
-// ElementValueGen immutableValue = value.getElementValue();
-// return new ElementNameValuePairGen(nameIdx,immutableValue,cpool);
-// }
-
- protected ElementNameValuePairGen(int idx,ElementValueGen value,ConstantPool cpool) {
+ protected ElementNameValuePairGen(int idx, ElementValueGen value, ConstantPool cpool) {
this.nameIdx = idx;
- this.value = value;
- this.cpool = cpool;
+ this.value = value;
+ this.cpool = cpool;
}
-
- public ElementNameValuePairGen(String name,ElementValueGen value,ConstantPool cpool) {
+
+ public ElementNameValuePairGen(String name, ElementValueGen value, ConstantPool cpool) {
this.nameIdx = cpool.addUtf8(name);
- this.value = value;
- this.cpool = cpool;
+ this.value = value;
+ this.cpool = cpool;
}
-
+
protected void dump(DataOutputStream dos) throws IOException {
dos.writeShort(nameIdx); // u2 name of the element
value.dump(dos);
}
-
+
public int getNameIndex() {
return nameIdx;
}
-
+
public final String getNameString() {
-// ConstantString cu8 = (ConstantString)cpool.getConstant(nameIdx);
- return ((ConstantUtf8)cpool.getConstant(nameIdx)).getBytes();
+ return cpool.getConstantUtf8(nameIdx).getBytes();
}
-
+
public final ElementValueGen getValue() {
return value;
}
-
+
+ @Override
public String toString() {
StringBuffer sb = new StringBuffer();
- sb.append(getNameString()+"="+value.stringifyValue());
+ sb.append(getNameString()).append("=").append(value.stringifyValue());
return sb.toString();
}
}
import java.io.DataOutputStream;
import java.io.IOException;
+import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.ConstantDouble;
import org.aspectj.apache.bcel.classfile.ConstantFloat;
import org.aspectj.apache.bcel.classfile.ConstantInteger;
import org.aspectj.apache.bcel.classfile.ConstantLong;
-import org.aspectj.apache.bcel.classfile.ConstantUtf8;
import org.aspectj.apache.bcel.classfile.ConstantPool;
-import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.ConstantUtf8;
+
+public class SimpleElementValueGen extends ElementValueGen {
-public class SimpleElementValueGen extends ElementValueGen {
-
// For primitive types and string type, this points to the value entry in the cpGen
// For 'class' this points to the class entry in the cpGen
private int idx;
-
-
- // ctors for each supported type... type could be inferred but for now lets
+
+ // ctors for each supported type... type could be inferred but for now lets
// force it to be passed
-
+
/**
- * Protected ctor used for deserialization, doesn't *put* an entry in the constant pool,
- * assumes the one at the supplied index is correct.
+ * Protected ctor used for deserialization, doesn't *put* an entry in the constant pool, assumes the one at the supplied index
+ * is correct.
*/
- protected SimpleElementValueGen(int type,int idx,ConstantPool cpGen) {
- super(type,cpGen);
- this.idx = idx;
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,int value) {
- super(type,cpGen);
- idx = cpGen.addInteger(value);
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,long value) {
- super(type,cpGen);
- idx = cpGen.addLong(value);
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,double value) {
- super(type,cpGen);
- idx = cpGen.addDouble(value);
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,float value) {
- super(type,cpGen);
- idx = cpGen.addFloat(value);
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,short value) {
- super(type,cpGen);
- idx = cpGen.addInteger(value);
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,byte value) {
- super(type,cpGen);
- idx = cpGen.addInteger(value);
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,char value) {
- super(type,cpGen);
- idx = cpGen.addInteger(value);
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,boolean value) {
- super(type,cpGen);
- if (value) idx = cpGen.addInteger(1);
- else idx = cpGen.addInteger(0);
- }
-
- public SimpleElementValueGen(int type,ConstantPool cpGen,String value) {
- super(type,cpGen);
- idx = cpGen.addUtf8(value);
- }
-
-
- public byte getValueByte() {
- if (type != PRIMITIVE_BYTE)
- throw new RuntimeException("Dont call getValueByte() on a non BYTE ElementValue");
- ConstantInteger c = (ConstantInteger)cpGen.getConstant(idx,Constants.CONSTANT_Integer);
- return (byte)c.getBytes();
- }
-
- public char getValueChar() {
- if (type != PRIMITIVE_CHAR)
- throw new RuntimeException("Dont call getValueChar() on a non CHAR ElementValue");
- ConstantInteger c = (ConstantInteger)cpGen.getConstant(idx,Constants.CONSTANT_Integer);
- return (char)c.getBytes();
- }
-
- public long getValueLong() {
- if (type != PRIMITIVE_LONG)
- throw new RuntimeException("Dont call getValueLong() on a non LONG ElementValue");
- ConstantLong j = (ConstantLong)cpGen.getConstant(idx);
- return j.getBytes();
- }
-
- public float getValueFloat() {
- if (type != PRIMITIVE_FLOAT)
- throw new RuntimeException("Dont call getValueFloat() on a non FLOAT ElementValue");
- ConstantFloat f = (ConstantFloat)cpGen.getConstant(idx);
- return f.getBytes();
- }
-
-
- public double getValueDouble() {
- if (type != PRIMITIVE_DOUBLE)
- throw new RuntimeException("Dont call getValueDouble() on a non DOUBLE ElementValue");
- ConstantDouble d = (ConstantDouble)cpGen.getConstant(idx);
- return d.getBytes();
- }
-
- public boolean getValueBoolean() {
- if (type != PRIMITIVE_BOOLEAN)
- throw new RuntimeException("Dont call getValueBoolean() on a non BOOLEAN ElementValue");
- ConstantInteger bo = (ConstantInteger)cpGen.getConstant(idx);
- return (bo.getBytes()!=0);
- }
-
- public short getValueShort() {
- if (type != PRIMITIVE_SHORT)
- throw new RuntimeException("Dont call getValueShort() on a non SHORT ElementValue");
- ConstantInteger s = (ConstantInteger)cpGen.getConstant(idx);
- return (short)s.getBytes();
- }
- /**
- * The boolean controls whether we copy info from the 'old' constant pool
- * to the 'new'. You need to use this ctor if the annotation is
- * being copied from one file to another.
- */
- public SimpleElementValueGen(SimpleElementValueGen value,ConstantPool cpool,boolean copyPoolEntries) {
- super(value.getElementValueType(),cpool);
+ protected SimpleElementValueGen(int type, int idx, ConstantPool cpGen) {
+ super(type, cpGen);
+ this.idx = idx;
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, int value) {
+ super(type, cpGen);
+ idx = cpGen.addInteger(value);
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, long value) {
+ super(type, cpGen);
+ idx = cpGen.addLong(value);
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, double value) {
+ super(type, cpGen);
+ idx = cpGen.addDouble(value);
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, float value) {
+ super(type, cpGen);
+ idx = cpGen.addFloat(value);
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, short value) {
+ super(type, cpGen);
+ idx = cpGen.addInteger(value);
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, byte value) {
+ super(type, cpGen);
+ idx = cpGen.addInteger(value);
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, char value) {
+ super(type, cpGen);
+ idx = cpGen.addInteger(value);
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, boolean value) {
+ super(type, cpGen);
+ if (value)
+ idx = cpGen.addInteger(1);
+ else
+ idx = cpGen.addInteger(0);
+ }
+
+ public SimpleElementValueGen(int type, ConstantPool cpGen, String value) {
+ super(type, cpGen);
+ idx = cpGen.addUtf8(value);
+ }
+
+ public byte getValueByte() {
+ if (type != PRIMITIVE_BYTE)
+ throw new RuntimeException("Dont call getValueByte() on a non BYTE ElementValue");
+ ConstantInteger c = (ConstantInteger) cpGen.getConstant(idx, Constants.CONSTANT_Integer);
+ return (byte) c.getBytes();
+ }
+
+ public char getValueChar() {
+ if (type != PRIMITIVE_CHAR)
+ throw new RuntimeException("Dont call getValueChar() on a non CHAR ElementValue");
+ ConstantInteger c = (ConstantInteger) cpGen.getConstant(idx, Constants.CONSTANT_Integer);
+ return (char) c.getBytes();
+ }
+
+ public long getValueLong() {
+ if (type != PRIMITIVE_LONG)
+ throw new RuntimeException("Dont call getValueLong() on a non LONG ElementValue");
+ ConstantLong j = (ConstantLong) cpGen.getConstant(idx);
+ return j.getBytes();
+ }
+
+ public float getValueFloat() {
+ if (type != PRIMITIVE_FLOAT)
+ throw new RuntimeException("Dont call getValueFloat() on a non FLOAT ElementValue");
+ ConstantFloat f = (ConstantFloat) cpGen.getConstant(idx);
+ return f.getBytes();
+ }
+
+ public double getValueDouble() {
+ if (type != PRIMITIVE_DOUBLE)
+ throw new RuntimeException("Dont call getValueDouble() on a non DOUBLE ElementValue");
+ ConstantDouble d = (ConstantDouble) cpGen.getConstant(idx);
+ return d.getBytes();
+ }
+
+ public boolean getValueBoolean() {
+ if (type != PRIMITIVE_BOOLEAN)
+ throw new RuntimeException("Dont call getValueBoolean() on a non BOOLEAN ElementValue");
+ ConstantInteger bo = (ConstantInteger) cpGen.getConstant(idx);
+ return (bo.getBytes() != 0);
+ }
+
+ public short getValueShort() {
+ if (type != PRIMITIVE_SHORT)
+ throw new RuntimeException("Dont call getValueShort() on a non SHORT ElementValue");
+ ConstantInteger s = (ConstantInteger) cpGen.getConstant(idx);
+ return (short) s.getBytes();
+ }
+
+ /**
+ * The boolean controls whether we copy info from the 'old' constant pool to the 'new'. You need to use this ctor if the
+ * annotation is being copied from one file to another.
+ */
+ public SimpleElementValueGen(SimpleElementValueGen value, ConstantPool cpool, boolean copyPoolEntries) {
+ super(value.getElementValueType(), cpool);
if (!copyPoolEntries) {
// J5ASSERT: Could assert value.stringifyValue() is the same as
// cpool.getConstant(SimpleElementValuevalue.getIndex())
idx = value.getIndex();
} else {
switch (value.getElementValueType()) {
- case STRING: idx = cpool.addUtf8(value.getValueString()); break;
- case PRIMITIVE_INT: idx = cpool.addInteger(value.getValueInt()); break;
- case PRIMITIVE_BYTE: idx = cpool.addInteger(value.getValueByte()); break;
- case PRIMITIVE_CHAR: idx = cpool.addInteger(value.getValueChar()); break;
- case PRIMITIVE_LONG: idx = cpool.addLong(value.getValueLong()); break;
- case PRIMITIVE_FLOAT: idx = cpool.addFloat(value.getValueFloat());break;
- case PRIMITIVE_DOUBLE:idx = cpool.addDouble(value.getValueDouble());break;
- case PRIMITIVE_BOOLEAN:
- if (value.getValueBoolean()) { idx = cpool.addInteger(1);
- } else { idx = cpool.addInteger(0);}
- break;
- case PRIMITIVE_SHORT: idx = cpool.addInteger(value.getValueShort());break;
- default:
- throw new RuntimeException("SimpleElementValueGen class does not know how "+
- "to copy this type "+type);
+ case STRING:
+ idx = cpool.addUtf8(value.getValueString());
+ break;
+ case PRIMITIVE_INT:
+ idx = cpool.addInteger(value.getValueInt());
+ break;
+ case PRIMITIVE_BYTE:
+ idx = cpool.addInteger(value.getValueByte());
+ break;
+ case PRIMITIVE_CHAR:
+ idx = cpool.addInteger(value.getValueChar());
+ break;
+ case PRIMITIVE_LONG:
+ idx = cpool.addLong(value.getValueLong());
+ break;
+ case PRIMITIVE_FLOAT:
+ idx = cpool.addFloat(value.getValueFloat());
+ break;
+ case PRIMITIVE_DOUBLE:
+ idx = cpool.addDouble(value.getValueDouble());
+ break;
+ case PRIMITIVE_BOOLEAN:
+ if (value.getValueBoolean()) {
+ idx = cpool.addInteger(1);
+ } else {
+ idx = cpool.addInteger(0);
+ }
+ break;
+ case PRIMITIVE_SHORT:
+ idx = cpool.addInteger(value.getValueShort());
+ break;
+ default:
+ throw new RuntimeException("SimpleElementValueGen class does not know how " + "to copy this type " + type);
}
}
}
-
+
/**
- * Return immutable variant
- */
+ * Return immutable variant
+ */
public ElementValueGen getElementValue() {
- return new SimpleElementValueGen(type,idx,cpGen);
+ return new SimpleElementValueGen(type, idx, cpGen);
}
public int getIndex() {
- return idx;
- }
+ return idx;
+ }
- public String getValueString() {
- if (type != STRING)
- throw new RuntimeException("Dont call getValueString() on a non STRING ElementValue");
- ConstantUtf8 c = (ConstantUtf8)cpGen.getConstant(idx);
+ public String getValueString() {
+ if (type != STRING)
+ throw new RuntimeException("Dont call getValueString() on a non STRING ElementValue");
+ ConstantUtf8 c = (ConstantUtf8) cpGen.getConstant(idx);
return c.getBytes();
- }
-
- public int getValueInt() {
- if (type != PRIMITIVE_INT)
- throw new RuntimeException("Dont call getValueString() on a non STRING ElementValue");
- ConstantInteger c = (ConstantInteger)cpGen.getConstant(idx);
+ }
+
+ public int getValueInt() {
+ if (type != PRIMITIVE_INT)
+ throw new RuntimeException("Dont call getValueString() on a non STRING ElementValue");
+ ConstantInteger c = (ConstantInteger) cpGen.getConstant(idx);
return c.getBytes();
- }
-
- // Whatever kind of value it is, return it as a string
- public String stringifyValue() {
- switch (type) {
- case PRIMITIVE_INT:
- ConstantInteger c = (ConstantInteger)cpGen.getConstant(idx);
- return Integer.toString(c.getBytes());
- case PRIMITIVE_LONG:
- ConstantLong j = (ConstantLong)cpGen.getConstant(idx);
- return Long.toString(j.getBytes());
- case PRIMITIVE_DOUBLE:
- ConstantDouble d = (ConstantDouble)cpGen.getConstant(idx);
- return Double.toString(d.getBytes());
- case PRIMITIVE_FLOAT:
- ConstantFloat f = (ConstantFloat)cpGen.getConstant(idx);
- return Float.toString(f.getBytes());
- case PRIMITIVE_SHORT:
- ConstantInteger s = (ConstantInteger)cpGen.getConstant(idx);
- return Integer.toString(s.getBytes());
- case PRIMITIVE_BYTE:
- ConstantInteger b = (ConstantInteger)cpGen.getConstant(idx);
- return Integer.toString(b.getBytes());
- case PRIMITIVE_CHAR:
- ConstantInteger ch = (ConstantInteger)cpGen.getConstant(idx);
- return new Character((char)ch.getBytes()).toString();
- case PRIMITIVE_BOOLEAN:
- ConstantInteger bo = (ConstantInteger)cpGen.getConstant(idx);
- if (bo.getBytes() == 0) return "false";
- else return "true";
- case STRING:
- ConstantUtf8 cu8 = (ConstantUtf8)cpGen.getConstant(idx);
- return cu8.getBytes();
-
- default:
- throw new RuntimeException("SimpleElementValueGen class does not know how to stringify type "+type);
- }
- }
-
- public void dump(DataOutputStream dos) throws IOException {
- dos.writeByte(type); // u1 kind of value
- switch (type) {
- case PRIMITIVE_INT:
- case PRIMITIVE_BYTE:
- case PRIMITIVE_CHAR:
- case PRIMITIVE_FLOAT:
- case PRIMITIVE_LONG:
- case PRIMITIVE_BOOLEAN:
- case PRIMITIVE_SHORT:
- case PRIMITIVE_DOUBLE:
- case STRING:
- dos.writeShort(idx);
- break;
- default:
- throw new RuntimeException("SimpleElementValueGen doesnt know how to write out type "+type);
- }
- }
-
+ }
+
+ // Whatever kind of value it is, return it as a string
+ @Override
+ public String stringifyValue() {
+ switch (type) {
+ case PRIMITIVE_INT:
+ ConstantInteger c = (ConstantInteger) cpGen.getConstant(idx);
+ return Integer.toString(c.getBytes());
+ case PRIMITIVE_LONG:
+ ConstantLong j = (ConstantLong) cpGen.getConstant(idx);
+ return Long.toString(j.getBytes());
+ case PRIMITIVE_DOUBLE:
+ ConstantDouble d = (ConstantDouble) cpGen.getConstant(idx);
+ return Double.toString(d.getBytes());
+ case PRIMITIVE_FLOAT:
+ ConstantFloat f = (ConstantFloat) cpGen.getConstant(idx);
+ return Float.toString(f.getBytes());
+ case PRIMITIVE_SHORT:
+ ConstantInteger s = (ConstantInteger) cpGen.getConstant(idx);
+ return Integer.toString(s.getBytes());
+ case PRIMITIVE_BYTE:
+ ConstantInteger b = (ConstantInteger) cpGen.getConstant(idx);
+ return Integer.toString(b.getBytes());
+ case PRIMITIVE_CHAR:
+ ConstantInteger ch = (ConstantInteger) cpGen.getConstant(idx);
+ return new Character((char) ch.getBytes()).toString();
+ case PRIMITIVE_BOOLEAN:
+ ConstantInteger bo = (ConstantInteger) cpGen.getConstant(idx);
+ if (bo.getBytes() == 0)
+ return "false";
+ else
+ return "true";
+ case STRING:
+ ConstantUtf8 cu8 = (ConstantUtf8) cpGen.getConstant(idx);
+ return cu8.getBytes();
+
+ default:
+ throw new RuntimeException("SimpleElementValueGen class does not know how to stringify type " + type);
+ }
+ }
+
+ @Override
+ public void dump(DataOutputStream dos) throws IOException {
+ dos.writeByte(type); // u1 kind of value
+ switch (type) {
+ case PRIMITIVE_INT:
+ case PRIMITIVE_BYTE:
+ case PRIMITIVE_CHAR:
+ case PRIMITIVE_FLOAT:
+ case PRIMITIVE_LONG:
+ case PRIMITIVE_BOOLEAN:
+ case PRIMITIVE_SHORT:
+ case PRIMITIVE_DOUBLE:
+ case STRING:
+ dos.writeShort(idx);
+ break;
+ default:
+ throw new RuntimeException("SimpleElementValueGen doesnt know how to write out type " + type);
+ }
+ }
+
}
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Iterator;
import java.util.List;
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.Attribute;
import org.aspectj.apache.bcel.classfile.ConstantPool;
import org.aspectj.apache.bcel.classfile.Field;
-import org.aspectj.apache.bcel.classfile.FieldOrMethod;
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.classfile.Method;
import org.aspectj.apache.bcel.classfile.Modifiers;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
/**
- * Template class for building up a java class. May be initialized with an existing java class (file).
+ * Template class for building up a java class. May be initialized with an existing java class.
*
* @see JavaClass
- * @version $Id: ClassGen.java,v 1.13 2009/09/09 23:13:20 aclement Exp $
+ * @version $Id: ClassGen.java,v 1.14 2009/09/10 03:59:34 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*
* Upgraded, Andy Clement 9th Mar 06 - calculates SUID
*/
public class ClassGen extends Modifiers implements Cloneable {
- private String class_name, super_class_name, file_name;
- private int class_name_index = -1, superclass_name_index = -1;
- private int major = Constants.MAJOR_1_1, minor = Constants.MINOR_1_1;
-
- private ConstantPool cp;
-
- private List<Field> field_vec = new ArrayList<Field>();
- private List<Method> method_vec = new ArrayList<Method>();
+ private String classname;
+ private String superclassname;
+ private String filename;
+ private int classnameIndex = -1;
+ private int superclassnameIndex = -1;
+ private int major = Constants.MAJOR_1_1;
+ private int minor = Constants.MINOR_1_1;
+ private ConstantPool cpool;
+ private List<Field> fieldsList = new ArrayList<Field>();
+ private List<Method> methodsList = new ArrayList<Method>();
private List<Attribute> attributesList = new ArrayList<Attribute>();
- private List<String> interface_vec = new ArrayList<String>();
+ private List<String> interfaceList = new ArrayList<String>();
private List<AnnotationGen> annotationsList = new ArrayList<AnnotationGen>();
- /**
- * Convenience constructor to set up some important values initially.
- *
- * @param class_name fully qualified class name
- * @param super_class_name fully qualified superclass name
- * @param file_name source file name
- * @param access_flags access qualifiers
- * @param interfaces implemented interfaces
- * @param cp constant pool to use
- */
- public ClassGen(String class_name, String super_class_name, String file_name, int access_flags, String[] interfaces,
- ConstantPool cp) {
- this.class_name = class_name;
- this.super_class_name = super_class_name;
- this.file_name = file_name;
- this.modifiers = access_flags;
- this.cp = cp;
-
- // Put everything needed by default into the constant pool and the vectors
- if (file_name != null) {
- addAttribute(new SourceFile(cp.addUtf8("SourceFile"), 2, cp.addUtf8(file_name), cp));
+ public ClassGen(String classname, String superclassname, String filename, int modifiers, String[] interfacenames,
+ ConstantPool cpool) {
+ this.classname = classname;
+ this.superclassname = superclassname;
+ this.filename = filename;
+ this.modifiers = modifiers;
+ this.cpool = cpool;
+ if (filename != null) {
+ addAttribute(new SourceFile(cpool.addUtf8("SourceFile"), 2, cpool.addUtf8(filename), cpool));
}
-
- class_name_index = cp.addClass(class_name);
- superclass_name_index = cp.addClass(super_class_name);
-
- if (interfaces != null) {
- for (int i = 0; i < interfaces.length; i++)
- addInterface(interfaces[i]);
+ this.classnameIndex = cpool.addClass(classname);
+ this.superclassnameIndex = cpool.addClass(superclassname);
+ if (interfacenames != null) {
+ for (String interfacename : interfacenames) {
+ addInterface(interfacename);
+ }
}
}
- /**
- * Convenience constructor to set up some important values initially.
- *
- * @param class_name fully qualified class name
- * @param super_class_name fully qualified superclass name
- * @param file_name source file name
- * @param access_flags access qualifiers
- * @param interfaces implemented interfaces
- */
- public ClassGen(String class_name, String super_class_name, String file_name, int access_flags, String[] interfaces) {
- this(class_name, super_class_name, file_name, access_flags, interfaces, new ConstantPool());
+ public ClassGen(String classname, String superclassname, String filename, int modifiers, String[] interfacenames) {
+ this(classname, superclassname, filename, modifiers, interfacenames, new ConstantPool());
}
- /**
- * Initialize with existing class.
- *
- * @param clazz JavaClass object (e.g. read from file)
- */
public ClassGen(JavaClass clazz) {
- class_name_index = clazz.getClassNameIndex();
- superclass_name_index = clazz.getSuperclassNameIndex();
- class_name = clazz.getClassName();
- super_class_name = clazz.getSuperclassName();
- file_name = clazz.getSourceFileName();
+ classnameIndex = clazz.getClassNameIndex();
+ superclassnameIndex = clazz.getSuperclassNameIndex();
+ classname = clazz.getClassName();
+ superclassname = clazz.getSuperclassName();
+ filename = clazz.getSourceFileName();
modifiers = clazz.getModifiers();
- cp = clazz.getConstantPool().copy();
+ cpool = clazz.getConstantPool().copy();
major = clazz.getMajor();
minor = clazz.getMinor();
- Attribute[] attributes = clazz.getAttributes();
- // J5TODO: Could make unpacking lazy, done on first reference
- AnnotationGen[] annotations = unpackAnnotations(attributes);
Method[] methods = clazz.getMethods();
Field[] fields = clazz.getFields();
String[] interfaces = clazz.getInterfaceNames();
- for (int i = 0; i < interfaces.length; i++)
+ for (int i = 0; i < interfaces.length; i++) {
addInterface(interfaces[i]);
-
- // Attribute[] attrs = attributes.getAttributes();
- for (int i = 0; i < attributes.length; i++) {
- // Dont add attributes for annotations as those will have been unpacked
- if (annotations.length == 0) {
- addAttribute(attributes[i]);
- } else if (!attributes[i].getName().equals("RuntimeVisibleAnnotations")
- && !attributes[i].getName().equals("RuntimeInvisibleAnnotations")) {
- addAttribute(attributes[i]);
- }
- }
- for (int i = 0; i < annotations.length; i++)
- addAnnotation(annotations[i]);
-
- for (int i = 0; i < methods.length; i++) {
- Method m = methods[i];
- addMethod(m);
}
- for (int i = 0; i < fields.length; i++)
- addField(fields[i]);
- }
-
- /**
- * Look for attributes representing annotations and unpack them.
- */
- private AnnotationGen[] unpackAnnotations(Attribute[] attrs) {
- List<AnnotationGen> annotationGenObjs = new ArrayList<AnnotationGen>();
- for (int i = 0; i < attrs.length; i++) {
- Attribute attr = attrs[i];
+ // OPTIMIZE Could make unpacking lazy, done on first reference
+ Attribute[] attributes = clazz.getAttributes();
+ for (Attribute attr : attributes) {
if (attr instanceof RuntimeVisibleAnnotations) {
RuntimeVisibleAnnotations rva = (RuntimeVisibleAnnotations) attr;
List<AnnotationGen> annos = rva.getAnnotations();
- for (Iterator<AnnotationGen> iter = annos.iterator(); iter.hasNext();) {
- AnnotationGen a = iter.next();
- annotationGenObjs.add(new AnnotationGen(a, getConstantPool(), false));
+ for (AnnotationGen a : annos) {
+ annotationsList.add(new AnnotationGen(a, cpool, false));
}
} else if (attr instanceof RuntimeInvisibleAnnotations) {
RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations) attr;
List<AnnotationGen> annos = ria.getAnnotations();
- for (Iterator<AnnotationGen> iter = annos.iterator(); iter.hasNext();) {
- AnnotationGen a = iter.next();
- annotationGenObjs.add(new AnnotationGen(a, getConstantPool(), false));
+ for (AnnotationGen anno : annos) {
+ annotationsList.add(new AnnotationGen(anno, cpool, false));
}
+ } else {
+ attributesList.add(attr);
}
}
- return annotationGenObjs.toArray(new AnnotationGen[] {});
+
+ for (int i = 0; i < methods.length; i++) {
+ addMethod(methods[i]);
+ }
+
+ for (int i = 0; i < fields.length; i++) {
+ addField(fields[i]);
+ }
}
/**
- * @return the (finally) built up Java class object.
+ * @return build and return a JavaClass
*/
public JavaClass getJavaClass() {
int[] interfaces = getInterfaces();
} else {
// TODO: Sometime later, trash any attributes called 'RuntimeVisibleAnnotations' or 'RuntimeInvisibleAnnotations'
attributes = new ArrayList<Attribute>();
- attributes.addAll(Utility.getAnnotationAttributes(cp, annotationsList));
+ attributes.addAll(Utility.getAnnotationAttributes(cpool, annotationsList));
attributes.addAll(attributesList);
}
// Must be last since the above calls may still add something to it
- ConstantPool cp = this.cp.getFinalConstantPool();
+ ConstantPool cp = this.cpool.getFinalConstantPool();
- return new JavaClass(class_name_index, superclass_name_index, file_name, major, minor, modifiers, cp, interfaces, fields,
+ return new JavaClass(classnameIndex, superclassnameIndex, filename, major, minor, modifiers, cp, interfaces, fields,
methods, attributes.toArray(new Attribute[attributes.size()]));// OPTIMIZE avoid toArray()?
}
- /**
- * Add an interface to this class, i.e., this class has to implement it.
- *
- * @param name interface to implement (fully qualified class name)
- */
public void addInterface(String name) {
- interface_vec.add(name);
+ interfaceList.add(name);
}
- /**
- * Remove an interface from this class.
- *
- * @param name interface to remove (fully qualified name)
- */
public void removeInterface(String name) {
- interface_vec.remove(name);
+ interfaceList.remove(name);
}
- /**
- * @return major version number of class file
- */
public int getMajor() {
return major;
}
- /**
- * Set major version number of class file, default value is 45 (JDK 1.1)
- *
- * @param major major version number
- */
public void setMajor(int major) {
this.major = major;
}
- /**
- * Set minor version number of class file, default value is 3 (JDK 1.1)
- *
- * @param minor minor version number
- */
public void setMinor(int minor) {
this.minor = minor;
}
- /**
- * @return minor version number of class file
- */
public int getMinor() {
return minor;
}
- /**
- * Add an attribute to this class.
- *
- * @param a attribute to add
- */
public void addAttribute(Attribute a) {
attributesList.add(a);
}
annotationsList.add(a);
}
- /**
- * Add a method to this class.
- *
- * @param m method to add
- */
public void addMethod(Method m) {
- method_vec.add(m);
+ methodsList.add(m);
}
/**
public void addEmptyConstructor(int access_flags) {
InstructionList il = new InstructionList();
il.append(InstructionConstants.THIS); // Push `this'
- il.append(new InvokeInstruction(Constants.INVOKESPECIAL, cp.addMethodref(super_class_name, "<init>", "()V")));
+ il.append(new InvokeInstruction(Constants.INVOKESPECIAL, cpool.addMethodref(superclassname, "<init>", "()V")));
il.append(InstructionConstants.RETURN);
- MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "<init>", class_name, il, cp);
+ MethodGen mg = new MethodGen(access_flags, Type.VOID, Type.NO_ARGS, null, "<init>", classname, il, cpool);
mg.setMaxStack(1);
mg.setMaxLocals();
addMethod(mg.getMethod());
* @param f field to add
*/
public void addField(Field f) {
- field_vec.add(f);
+ fieldsList.add(f);
}
public boolean containsField(Field f) {
- return field_vec.contains(f);
+ return fieldsList.contains(f);
}
/**
- * @return field object with given name, or null
+ * @return field object with given name, or null if not found
*/
public Field containsField(String name) {
- for (Iterator<Field> e = field_vec.iterator(); e.hasNext();) {
- Field f = e.next();
- if (f.getName().equals(name))
- return f;
+ for (Field field : fieldsList) {
+ if (field.getName().equals(name)) {
+ return field;
+ }
}
-
return null;
}
/**
- * @return method object with given name and signature, or null
+ * @return method object with given name and signature, or null if not found
*/
public Method containsMethod(String name, String signature) {
- for (Iterator<Method> e = method_vec.iterator(); e.hasNext();) {
- Method m = e.next();
- if (m.getName().equals(name) && m.getSignature().equals(signature))
- return m;
+ for (Method method : methodsList) {
+ if (method.getName().equals(name) && method.getSignature().equals(signature)) {
+ return method;
+ }
}
-
return null;
}
- /**
- * Remove an attribute from this class.
- *
- * @param a attribute to remove
- */
public void removeAttribute(Attribute a) {
attributesList.remove(a);
}
annotationsList.remove(a);
}
- /**
- * Remove a method from this class.
- *
- * @param m method to remove
- */
public void removeMethod(Method m) {
- method_vec.remove(m);
+ methodsList.remove(m);
}
/**
if (new_ == null)
throw new ClassGenException("Replacement method must not be null");
- int i = method_vec.indexOf(old);
+ int i = methodsList.indexOf(old);
if (i < 0)
- method_vec.add(new_);
+ methodsList.add(new_);
else
- method_vec.set(i, new_);
+ methodsList.set(i, new_);
}
/**
if (new_ == null)
throw new ClassGenException("Replacement method must not be null");
- int i = field_vec.indexOf(old);
+ int i = fieldsList.indexOf(old);
if (i < 0)
- field_vec.add(new_);
+ fieldsList.add(new_);
else
- field_vec.set(i, new_);
+ fieldsList.set(i, new_);
}
- /**
- * Remove a field to this class.
- *
- * @param f field to remove
- */
public void removeField(Field f) {
- field_vec.remove(f);
+ fieldsList.remove(f);
}
public String getClassName() {
- return class_name;
+ return classname;
}
public String getSuperclassName() {
- return super_class_name;
+ return superclassname;
}
public String getFileName() {
- return file_name;
+ return filename;
}
public void setClassName(String name) {
- class_name = name.replace('/', '.');
- class_name_index = cp.addClass(name);
+ classname = name.replace('/', '.');
+ classnameIndex = cpool.addClass(name);
}
public void setSuperclassName(String name) {
- super_class_name = name.replace('/', '.');
- superclass_name_index = cp.addClass(name);
+ superclassname = name.replace('/', '.');
+ superclassnameIndex = cpool.addClass(name);
}
public Method[] getMethods() {
- Method[] methods = new Method[method_vec.size()];
- method_vec.toArray(methods);
+ Method[] methods = new Method[methodsList.size()];
+ methodsList.toArray(methods);
return methods;
}
public void setMethods(Method[] methods) {
- method_vec.clear();
+ methodsList.clear();
for (int m = 0; m < methods.length; m++)
addMethod(methods[m]);
}
public void setFields(Field[] fs) {
- field_vec.clear();
+ fieldsList.clear();
for (int m = 0; m < fs.length; m++)
addField(fs[m]);
}
public void setMethodAt(Method method, int pos) {
- method_vec.set(pos, method);
+ methodsList.set(pos, method);
}
public Method getMethodAt(int pos) {
- return method_vec.get(pos);
+ return methodsList.get(pos);
}
public String[] getInterfaceNames() {
- int size = interface_vec.size();
+ int size = interfaceList.size();
String[] interfaces = new String[size];
- interface_vec.toArray(interfaces);
+ interfaceList.toArray(interfaces);
return interfaces;
}
public int[] getInterfaces() {
- int size = interface_vec.size();
+ int size = interfaceList.size();
int[] interfaces = new int[size];
for (int i = 0; i < size; i++)
- interfaces[i] = cp.addClass(interface_vec.get(i));
+ interfaces[i] = cpool.addClass(interfaceList.get(i));
return interfaces;
}
public Field[] getFields() {
- Field[] fields = new Field[field_vec.size()];
- field_vec.toArray(fields);
+ Field[] fields = new Field[fieldsList.size()];
+ fieldsList.toArray(fields);
return fields;
}
}
public ConstantPool getConstantPool() {
- return cp;
+ return cpool;
}
public void setConstantPool(ConstantPool constant_pool) {
- cp = constant_pool;
+ cpool = constant_pool;
}
public void setClassNameIndex(int class_name_index) {
- this.class_name_index = class_name_index;
- class_name = cp.getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.');
+ this.classnameIndex = class_name_index;
+ classname = cpool.getConstantString(class_name_index, Constants.CONSTANT_Class).replace('/', '.');
}
public void setSuperclassNameIndex(int superclass_name_index) {
- this.superclass_name_index = superclass_name_index;
- super_class_name = cp.getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.');
+ this.superclassnameIndex = superclass_name_index;
+ superclassname = cpool.getConstantString(superclass_name_index, Constants.CONSTANT_Class).replace('/', '.');
}
public int getSuperclassNameIndex() {
- return superclass_name_index;
+ return superclassnameIndex;
}
public int getClassNameIndex() {
- return class_name_index;
+ return classnameIndex;
}
@Override
}
}
- // J5SUPPORT:
-
- /**
- * Returns true if this class represents an annotation type
- */
public final boolean isAnnotation() {
return (modifiers & Constants.ACC_ANNOTATION) != 0;
}
- /**
- * Returns true if this class represents an enum type
- */
public final boolean isEnum() {
return (modifiers & Constants.ACC_ENUM) != 0;
}
*/
public long getSUID() {
try {
- Field[] fields = getFields();
- Method[] methods = getMethods();
ByteArrayOutputStream baos = new ByteArrayOutputStream();
DataOutputStream dos = new DataOutputStream(baos);
if (isAbstract()) {
// if an interface then abstract is only set if it has methods
if (isInterface()) {
- if (methods.length > 0)
+ if (methodsList.size() > 0)
classmods |= Constants.ACC_ABSTRACT;
} else {
classmods |= Constants.ACC_ABSTRACT;
dos.writeInt(classmods);
// 3. ordered list of interfaces
- List<FieldOrMethod> list = new ArrayList<FieldOrMethod>();
String[] names = getInterfaceNames();
if (names != null) {
Arrays.sort(names);
// (relevant modifiers are ACC_PUBLIC, ACC_PRIVATE,
// ACC_PROTECTED, ACC_STATIC, ACC_FINAL, ACC_VOLATILE,
// ACC_TRANSIENT)
- list.clear();
- for (int i = 0; i < fields.length; i++) {
- Field field = fields[i];
- if (!(field.isPrivate() && field.isStatic()) && !(field.isPrivate() && field.isTransient()))
- list.add(field);
+ List<Field> relevantFields = new ArrayList<Field>();
+ for (Field field : fieldsList) {
+ if (!(field.isPrivate() && field.isStatic()) && !(field.isPrivate() && field.isTransient())) {
+ relevantFields.add(field);
+ }
}
- Collections.sort(list, new FieldComparator());
+ Collections.sort(relevantFields, new FieldComparator());
int relevantFlags = Constants.ACC_PUBLIC | Constants.ACC_PRIVATE | Constants.ACC_PROTECTED | Constants.ACC_STATIC
| Constants.ACC_FINAL | Constants.ACC_VOLATILE | Constants.ACC_TRANSIENT;
- for (Iterator<FieldOrMethod> iter = list.iterator(); iter.hasNext();) {
- Field f = (Field) iter.next();
+ for (Field f : relevantFields) {
dos.writeUTF(f.getName());
dos.writeInt(relevantFlags & f.getModifiers());
dos.writeUTF(f.getType().getSignature());
}
// some up front method processing: discover clinit, init and ordinary methods of interest:
- list.clear(); // now used for methods
- List<Method> ctors = new ArrayList<Method>();
+ List<Method> relevantMethods = new ArrayList<Method>();
+ List<Method> relevantCtors = new ArrayList<Method>();
boolean hasClinit = false;
- for (int i = 0; i < methods.length; i++) {
- Method m = methods[i];
+ for (Method m : methodsList) {
boolean couldBeInitializer = m.getName().charAt(0) == '<';
if (couldBeInitializer && m.getName().equals("<clinit>")) {
hasClinit = true;
} else if (couldBeInitializer && m.getName().equals("<init>")) {
if (!m.isPrivate())
- ctors.add(m);
+ relevantCtors.add(m);
} else {
if (!m.isPrivate())
- list.add(m);
+ relevantMethods.add(m);
}
}
- Collections.sort(ctors, new ConstructorComparator());
- Collections.sort(list, new MethodComparator());
+ Collections.sort(relevantCtors, new ConstructorComparator());
+ Collections.sort(relevantMethods, new MethodComparator());
// 5. If a class initializer exists, write out the following:
// 1. The name of the method, <clinit>.
| Constants.ACC_STRICT;
// 6. sorted non-private constructors
- for (Iterator<Method> iter = ctors.iterator(); iter.hasNext();) {
- Method m = iter.next();
- dos.writeUTF(m.getName()); // <init>
- dos.writeInt(relevantFlags & m.getModifiers());
- dos.writeUTF(m.getSignature().replace('/', '.'));
+ for (Method ctor : relevantCtors) {
+ dos.writeUTF(ctor.getName()); // <init>
+ dos.writeInt(relevantFlags & ctor.getModifiers());
+ dos.writeUTF(ctor.getSignature().replace('/', '.'));
}
// 7. sorted non-private methods
- for (Iterator<FieldOrMethod> iter = list.iterator(); iter.hasNext();) {
- Method m = (Method) iter.next();
+ for (Method m : relevantMethods) {
dos.writeUTF(m.getName());
dos.writeInt(relevantFlags & m.getModifiers());
dos.writeUTF(m.getSignature().replace('/', '.'));
// (long)(sha[6]&0xff) << 48 | (long)(sha[7]&0xff) << 56);
return suid;
} catch (Exception e) {
- System.err.println("Unable to calculate suid for " + getClassName());
e.printStackTrace();
throw new RuntimeException("Unable to calculate suid for " + getClassName() + ": " + e.toString());
}
}
- private static class FieldComparator implements Comparator {
- public int compare(Object arg0, Object arg1) {
- return ((Field) arg0).getName().compareTo(((Field) arg1).getName());
+ private static class FieldComparator implements Comparator<Field> {
+ public int compare(Field f0, Field f1) {
+ return f0.getName().compareTo(f1.getName());
}
}
- private static class ConstructorComparator implements Comparator {
- public int compare(Object arg0, Object arg1) {
+ private static class ConstructorComparator implements Comparator<Method> {
+ public int compare(Method m0, Method m1) {
// can ignore the name...
- return ((Method) arg0).getSignature().compareTo(((Method) arg1).getSignature());
+ return (m0).getSignature().compareTo(m1.getSignature());
}
}
- private static class MethodComparator implements Comparator {
- public int compare(Object arg0, Object arg1) {
- Method m1 = (Method) arg0;
- Method m2 = (Method) arg1;
- int result = m1.getName().compareTo(m2.getName());
- if (result != 0)
- return result;
- return m1.getSignature().compareTo(m2.getSignature());
+ private static class MethodComparator implements Comparator<Method> {
+ public int compare(Method m0, Method m1) {
+ int result = m0.getName().compareTo(m1.getName());
+ if (result == 0) {
+ result = m0.getSignature().compareTo(m1.getSignature());
+ }
+ return result;
}
}
}
public Attribute getAttribute(String attributeName) {
- for (Iterator<Attribute> iter = attributesList.iterator(); iter.hasNext();) {
- Attribute attr = iter.next();
- if (attr.getName().equals(attributeName))
+ for (Attribute attr : attributesList) {
+ if (attr.getName().equals(attributeName)) {
return attr;
+ }
}
return null;
}
*/
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.ConstantPool;
+import org.aspectj.apache.bcel.classfile.Utility;
/**
* Instances of this class may be used, e.g., to generate typed
* byte code generating backend of a compiler. You can subclass it to
* add your own create methods.
*
- * @version $Id: InstructionFactory.java,v 1.5 2008/08/28 00:03:24 aclement Exp $
+ * @version $Id: InstructionFactory.java,v 1.6 2009/09/10 03:59:34 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @see Constants
*/
public InvokeInstruction createInvoke(String class_name, String name, Type ret_type,
Type[] arg_types, short kind) {
- String signature = Type.getMethodSignature(ret_type, arg_types);
+ String signature = Utility.toMethodSignature(ret_type, arg_types);
int index;
if (kind == Constants.INVOKEINTERFACE)
*
* A list is finally dumped to a byte code array with <a href="#getByteCode()">getByteCode</a>.
*
- * @version $Id: InstructionList.java,v 1.8 2009/09/09 19:56:20 aclement Exp $
+ * @version $Id: InstructionList.java,v 1.9 2009/09/10 03:59:33 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @see Instruction
* @see InstructionHandle
*/
public class InstructionList implements Serializable {
private InstructionHandle start = null, end = null;
- private int length = 0; // number of elements in list
- private int[] byte_positions; // byte code offsets corresponding to instructions
+ private int length = 0;
+ private int[] positions; // byte code offsets corresponding to instructions
- /**
- * Create (empty) instruction list.
- */
public InstructionList() {
}
- /**
- * Create instruction list containing one instruction.
- *
- * @param i initial instruction
- */
public InstructionList(Instruction i) {
append(i);
}
- /**
- * Test for empty list.
- */
public boolean isEmpty() {
return start == null;
} // && end == null
*/
public InstructionHandle findHandle(int pos) {
InstructionHandle[] ihs = getInstructionHandles();
- return findHandle(ihs, byte_positions, length, pos);
+ return findHandle(ihs, positions, length, pos);
}
public InstructionHandle[] getInstructionsAsArray() {
}
public InstructionHandle findHandle(int pos, InstructionHandle[] instructionArray) {
- return findHandle(instructionArray, byte_positions, length, pos);
+ return findHandle(instructionArray, positions, length, pos);
}
public InstructionHandle findHandle(int pos, InstructionHandle[] instructionArray, boolean useClosestApproximationIfNoExactFound) {
- return findHandle(instructionArray, byte_positions, length, pos, useClosestApproximationIfNoExactFound);
+ return findHandle(instructionArray, positions, length, pos, useClosestApproximationIfNoExactFound);
}
/**
throw new ClassGenException(e.toString());
}
- byte_positions = new int[count]; // Trim to proper size
- System.arraycopy(pos, 0, byte_positions, 0, count);
+ positions = new int[count]; // Trim to proper size
+ System.arraycopy(pos, 0, positions, 0, count);
/*
* Pass 2: Look for BranchInstruction and update their targets, i.e., convert offsets to instruction handles.
index += i.getLength();
}
- byte_positions = new int[count]; // Trim to proper size
- System.arraycopy(pos, 0, byte_positions, 0, count);
+ positions = new int[count]; // Trim to proper size
+ System.arraycopy(pos, 0, positions, 0, count);
}
/**
return result;
}
+ @Override
public String toString() {
return toString(true);
}
* @return array containing all instruction's offset in byte code
*/
public int[] getInstructionPositions() {
- return byte_positions;
+ return positions;
}
/**
* While generating code it may be necessary to insert NOP operations. You can use the `removeNOPs' method to get rid off them. The
* resulting method object can be obtained via the `getMethod()' method.
*
- * @version $Id: MethodGen.java,v 1.12 2009/09/09 19:56:20 aclement Exp $
+ * @version $Id: MethodGen.java,v 1.13 2009/09/10 03:59:34 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @author <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()]
* @see InstructionList
}
public String getSignature() {
- return Type.getMethodSignature(type, parameterTypes);
+ return Utility.toMethodSignature(type, parameterTypes);
}
/**
*/
public final String toString() {
String access = Utility.accessToString(modifiers);
- String signature = Type.getMethodSignature(type, parameterTypes);
+ String signature = Utility.toMethodSignature(type, parameterTypes);
signature = Utility.methodSignatureToString(signature, name, access, true, getLocalVariableTable(cp));
import java.util.ArrayList;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import org.aspectj.apache.bcel.Constants;
* Abstract super class for all possible java types, namely basic types such as int, object types like String and array types, e.g.
* int[]
*
- * @version $Id: Type.java,v 1.11 2009/09/09 19:56:20 aclement Exp $
+ * @version $Id: Type.java,v 1.12 2009/09/10 03:59:34 aclement Exp $
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*
* modified: AndyClement 2-mar-05: Removed unnecessary static and optimized
*/
-public abstract class Type implements java.io.Serializable {
+public abstract class Type {
protected byte type;
- protected String signature; // signature for the type
+ protected String signature;
/* Predefined constants */
public static final BasicType VOID = new BasicType(Constants.T_VOID);
signature = s;
}
- /**
- * @return signature for given type.
- */
public String getSignature() {
return signature;
}
- /**
- * @return type as defined in Constants
- */
public byte getType() {
return type;
}
.signatureToString(signature, false);
}
- /**
- * Convert type to Java method signature, e.g. int[] f(java.lang.String x) becomes (Ljava/lang/String;)[I
- *
- * @param return_type what the method returns
- * @param arg_types what are the argument types
- * @return method signature for given type(s).
- */
- public static String getMethodSignature(Type return_type, Type[] arg_types) {
- StringBuffer buf = new StringBuffer("(");
- int length = (arg_types == null) ? 0 : arg_types.length;
- for (int i = 0; i < length; i++) {
- buf.append(arg_types[i].getSignature());
- }
- buf.append(')');
- buf.append(return_type.getSignature());
- return buf.toString();
- }
-
public static final Type getType(String signature) {
Type t = commonTypes.get(signature);
if (t != null)
*/
public static Type getReturnType(String signature) {
try {
- // Read return type after `)'
+ // Read return type after ')'
int index = signature.lastIndexOf(')') + 1;
return getType(signature.substring(index));
} catch (StringIndexOutOfBoundsException e) { // Should never occur
*/
// OPTIMIZE crap impl
public static Type[] getArgumentTypes(String signature) {
- ArrayList<Type> vec = new ArrayList<Type>();
+ List<Type> argumentTypes = new ArrayList<Type>();
int index;
Type[] types;
while (signature.charAt(index) != ')') {
TypeHolder th = getTypeInternal(signature.substring(index));
- vec.add(th.getType());
+ argumentTypes.add(th.getType());
index += th.getConsumed(); // update position
}
} catch (StringIndexOutOfBoundsException e) { // Should never occur
throw new ClassFormatException("Invalid method signature: " + signature);
}
- types = new Type[vec.size()];
- vec.toArray(types);
+ types = new Type[argumentTypes.size()];
+ argumentTypes.toArray(types);
return types;
}
import org.aspectj.apache.bcel.classfile.JavaClass;
import org.aspectj.apache.bcel.util.SyntheticRepository;
-
public class EnclosingMethodAttributeTest extends BcelTestCase {
-
+
+ @Override
protected void setUp() throws Exception {
super.setUp();
}
-
-
+
/**
- * Verify for an inner class declared inside the 'main' method that the enclosing method
- * attribute is set correctly.
+ * Verify for an inner class declared inside the 'main' method that the enclosing method attribute is set correctly.
*/
public void testCheckMethodLevelNamedInnerClass() throws ClassNotFoundException {
SyntheticRepository repos = createRepos("testcode.jar");
JavaClass clazz = repos.loadClass("AttributeTestClassEM01$1S");
ConstantPool pool = clazz.getConstantPool();
- Attribute[] encMethodAttrs = findAttribute("EnclosingMethod",clazz);
- assertTrue("Expected 1 EnclosingMethod attribute but found "+encMethodAttrs.length,
- encMethodAttrs.length==1);
- EnclosingMethod em = (EnclosingMethod)encMethodAttrs[0];
- String enclosingClassName = em.getEnclosingClass().getBytes(pool);
- String enclosingMethodName= em.getEnclosingMethod().getName(pool);
- assertTrue("Expected class name to be 'AttributeTestClassEM01' but was "+enclosingClassName,
- enclosingClassName.equals("AttributeTestClassEM01"));
- assertTrue("Expected method name to be 'main' but was "+enclosingMethodName,
- enclosingMethodName.equals("main"));
+ Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz);
+ assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1);
+ EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0];
+ String enclosingClassName = em.getEnclosingClass().getConstantValue(pool);
+ String enclosingMethodName = em.getEnclosingMethod().getName(pool);
+ assertTrue("Expected class name to be 'AttributeTestClassEM01' but was " + enclosingClassName, enclosingClassName
+ .equals("AttributeTestClassEM01"));
+ assertTrue("Expected method name to be 'main' but was " + enclosingMethodName, enclosingMethodName.equals("main"));
}
-
+
/**
- * Verify for an inner class declared at the type level that the EnclosingMethod attribute
- * is set correctly (i.e. to a null value)
+ * Verify for an inner class declared at the type level that the EnclosingMethod attribute is set correctly (i.e. to a null
+ * value)
*/
public void testCheckClassLevelNamedInnerClass() throws ClassNotFoundException {
SyntheticRepository repos = createRepos("testcode.jar");
JavaClass clazz = repos.loadClass("AttributeTestClassEM02$1");
ConstantPool pool = clazz.getConstantPool();
- Attribute[] encMethodAttrs = findAttribute("EnclosingMethod",clazz);
- assertTrue("Expected 1 EnclosingMethod attribute but found "+encMethodAttrs.length,
- encMethodAttrs.length==1);
- EnclosingMethod em = (EnclosingMethod)encMethodAttrs[0];
- String enclosingClassName = em.getEnclosingClass().getBytes(pool);
- assertTrue("The class is not within a method, so method_index should be null, but it is "+
- em.getEnclosingMethodIndex(),em.getEnclosingMethodIndex() == 0);
- assertTrue("Expected class name to be 'AttributeTestClassEM02' but was "+enclosingClassName,
- enclosingClassName.equals("AttributeTestClassEM02"));
+ Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz);
+ assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1);
+ EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0];
+ String enclosingClassName = em.getEnclosingClass().getConstantValue(pool);
+ assertTrue("The class is not within a method, so method_index should be null, but it is " + em.getEnclosingMethodIndex(),
+ em.getEnclosingMethodIndex() == 0);
+ assertTrue("Expected class name to be 'AttributeTestClassEM02' but was " + enclosingClassName, enclosingClassName
+ .equals("AttributeTestClassEM02"));
}
-
+
/**
* Check that we can save and load the attribute correctly.
*/
- public void testAttributeSerializtion() throws ClassNotFoundException,IOException {
+ public void testAttributeSerializtion() throws ClassNotFoundException, IOException {
// Read in the class
SyntheticRepository repos = createRepos("testcode.jar");
JavaClass clazz = repos.loadClass("AttributeTestClassEM02$1");
ConstantPool pool = clazz.getConstantPool();
- Attribute[] encMethodAttrs = findAttribute("EnclosingMethod",clazz);
- assertTrue("Expected 1 EnclosingMethod attribute but found "+encMethodAttrs.length,
- encMethodAttrs.length==1);
-
+ Attribute[] encMethodAttrs = findAttribute("EnclosingMethod", clazz);
+ assertTrue("Expected 1 EnclosingMethod attribute but found " + encMethodAttrs.length, encMethodAttrs.length == 1);
+
// Write it out
File tfile = createTestdataFile("AttributeTestClassEM02$1.class");
clazz.dump(tfile);
-
+
// Read in the new version and check it is OK
SyntheticRepository repos2 = createRepos(".");
JavaClass clazz2 = repos2.loadClass("AttributeTestClassEM02$1");
- EnclosingMethod em = (EnclosingMethod)encMethodAttrs[0];
- String enclosingClassName = em.getEnclosingClass().getBytes(pool);
- assertTrue("The class is not within a method, so method_index should be null, but it is "+
- em.getEnclosingMethodIndex(),em.getEnclosingMethodIndex() == 0);
- assertTrue("Expected class name to be 'AttributeTestClassEM02' but was "+enclosingClassName,
- enclosingClassName.equals("AttributeTestClassEM02"));
+ EnclosingMethod em = (EnclosingMethod) encMethodAttrs[0];
+ String enclosingClassName = em.getEnclosingClass().getConstantValue(pool);
+ assertTrue("The class is not within a method, so method_index should be null, but it is " + em.getEnclosingMethodIndex(),
+ em.getEnclosingMethodIndex() == 0);
+ assertTrue("Expected class name to be 'AttributeTestClassEM02' but was " + enclosingClassName, enclosingClassName
+ .equals("AttributeTestClassEM02"));
assertTrue(tfile.delete());
}
-
+ @Override
protected void tearDown() throws Exception {
super.tearDown();
}
}
public void testTypeUtilMethods1() {
- String s = Type.getMethodSignature(Type.DOUBLE,new Type[]{Type.INT,Type.STRING,Type.SHORT});
+ String s = Utility.toMethodSignature(Type.DOUBLE,new Type[]{Type.INT,Type.STRING,Type.SHORT});
System.err.println(s);
}