* <http://www.apache.org/>.
*/
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.Serializable;
+
import org.aspectj.apache.bcel.Constants;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisibleAnnotations;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeInvisibleParameterAnnotations;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleAnnotations;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeVisibleParameterAnnotations;
-import java.io.*;
-
/**
- * Abstract super class for <em>Attribute</em> objects. Currently the
- * <em>ConstantValue</em>, <em>SourceFile</em>, <em>Code</em>,
- * <em>Exceptiontable</em>, <em>LineNumberTable</em>,
- * <em>LocalVariableTable</em>, <em>InnerClasses</em> and
- * <em>Synthetic</em> attributes are supported. The
- * <em>Unknown</em> attribute stands for non-standard-attributes.
- *
- * @version $Id: Attribute.java,v 1.4 2008/08/26 14:59:38 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
- * @see ConstantValue
- * @see SourceFile
- * @see Code
- * @see Unknown
- * @see ExceptionTable
- * @see LineNumberTable
- * @see LocalVariableTable
- * @see InnerClasses
- * @see Synthetic
- * @see Deprecated
- * @see Signature
-*/
+ * Abstract super class for <em>Attribute</em> objects. Currently the <em>ConstantValue</em>, <em>SourceFile</em>, <em>Code</em>,
+ * <em>Exceptiontable</em>, <em>LineNumberTable</em>, <em>LocalVariableTable</em>, <em>InnerClasses</em> and <em>Synthetic</em>
+ * attributes are supported. The <em>Unknown</em> attribute stands for non-standard-attributes.
+ *
+ * @version $Id: Attribute.java,v 1.5 2009/09/09 21:26:54 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see ConstantValue
+ * @see SourceFile
+ * @see Code
+ * @see Unknown
+ * @see ExceptionTable
+ * @see LineNumberTable
+ * @see LocalVariableTable
+ * @see InnerClasses
+ * @see Synthetic
+ * @see Deprecated
+ * @see Signature
+ */
public abstract class Attribute implements Cloneable, Node, Serializable {
public final static Attribute[] NoAttributes = new Attribute[0];
-
- protected byte tag; // Tag to distinguish subclasses
- protected int nameIndex; // Points to attribute name in constant pool
- protected int length; // Content length of attribute field
+ protected byte tag; // Tag to distinguish subclasses
+ protected int nameIndex; // Points to attribute name in constant pool
+ protected int length; // Content length of attribute field
protected ConstantPool constantPool;
-
-
- protected Attribute(byte tag, int nameIndex, int length, ConstantPool constantPool) {
- this.tag = tag;
- this.nameIndex = nameIndex;
- this.length = length;
- this.constantPool = constantPool;
- }
-
-
- /** Dump attribute to file stream in binary format */
- public void dump(DataOutputStream file) throws IOException {
- file.writeShort(nameIndex);
- file.writeInt(length);
- }
-
-
- public static final Attribute readAttribute(DataInputStream file, ConstantPool cpool) throws IOException {
- byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute
- int idx = file.readUnsignedShort();
- String name = cpool.getConstantUtf8(idx).getBytes();
- int len = file.readInt();
-
- // Compare strings to find known attribute
- for (byte i=0; i < Constants.KNOWN_ATTRIBUTES; i++) {
- if (name.equals(Constants.ATTRIBUTE_NAMES[i])) { tag = i; break; }
- }
- switch(tag) {
- case Constants.ATTR_UNKNOWN: return new Unknown(idx, len, file, cpool);
- case Constants.ATTR_CONSTANT_VALUE: return new ConstantValue(idx, len, file, cpool);
- case Constants.ATTR_SOURCE_FILE: return new SourceFile(idx, len, file, cpool);
- case Constants.ATTR_CODE: return new Code(idx, len, file, cpool);
- case Constants.ATTR_EXCEPTIONS: return new ExceptionTable(idx, len, file, cpool);
- case Constants.ATTR_LINE_NUMBER_TABLE: return new LineNumberTable(idx, len, file, cpool);
- case Constants.ATTR_LOCAL_VARIABLE_TABLE: return new LocalVariableTable(idx, len, file, cpool);
- case Constants.ATTR_INNER_CLASSES: return new InnerClasses(idx, len, file, cpool);
- case Constants.ATTR_SYNTHETIC: return new Synthetic(idx, len, file, cpool);
- case Constants.ATTR_DEPRECATED: return new Deprecated(idx, len, file, cpool);
- case Constants.ATTR_PMG: return new PMGClass(idx, len, file, cpool);
- case Constants.ATTR_SIGNATURE: return new Signature(idx, len, file, cpool);
- case Constants.ATTR_STACK_MAP: return new StackMap(idx, len, file, cpool);
- case Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS:
- return new RuntimeVisibleAnnotations(idx,len,file,cpool);
- case Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS:
- return new RuntimeInvisibleAnnotations(idx,len,file,cpool);
- case Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS:
- return new RuntimeVisibleParameterAnnotations(idx,len,file,cpool);
- case Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS:
- return new RuntimeInvisibleParameterAnnotations(idx,len,file,cpool);
- case Constants.ATTR_ANNOTATION_DEFAULT:
- return new AnnotationDefault(idx,len,file,cpool);
- case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE:
- return new LocalVariableTypeTable(idx,len,file,cpool);
- case Constants.ATTR_ENCLOSING_METHOD:
- return new EnclosingMethod(idx,len,file,cpool);
- default: throw new IllegalStateException();
- }
- }
-
- public String getName() {
- return constantPool.getConstantUtf8(nameIndex).getBytes();
- }
-
- public final int getLength() { return length; }
-
- public final int getNameIndex() { return nameIndex; }
-
- public final byte getTag() { return tag; }
-
- public final ConstantPool getConstantPool() { return constantPool; }
-
- /**
- * Use copy() if you want to have a deep copy(), ie. with all references
- * copied correctly.
- *
- * @return shallow copy of this attribute
- */
- public Object clone() {
- Object o = null;
-
- try {
- o = super.clone();
- } catch(CloneNotSupportedException e) {
- e.printStackTrace(); // Never occurs
- }
-
- return o;
- }
-
- /**
- * @return deep copy of this attribute
- */
- public abstract Attribute copy(ConstantPool constant_pool);
-
- public String toString() {
- return Constants.ATTRIBUTE_NAMES[tag];
- }
-
- public abstract void accept(ClassVisitor v);
+
+ protected Attribute(byte tag, int nameIndex, int length, ConstantPool constantPool) {
+ this.tag = tag;
+ this.nameIndex = nameIndex;
+ this.length = length;
+ this.constantPool = constantPool;
+ }
+
+ /** Dump attribute to file stream in binary format */
+ public void dump(DataOutputStream file) throws IOException {
+ file.writeShort(nameIndex);
+ file.writeInt(length);
+ }
+
+ public static final Attribute readAttribute(DataInputStream file, ConstantPool cpool) throws IOException {
+ byte tag = Constants.ATTR_UNKNOWN; // Unknown attribute
+ int idx = file.readUnsignedShort();
+ String name = cpool.getConstantUtf8(idx).getBytes();
+ int len = file.readInt();
+
+ // Compare strings to find known attribute
+ for (byte i = 0; i < Constants.KNOWN_ATTRIBUTES; i++) {
+ if (name.equals(Constants.ATTRIBUTE_NAMES[i])) {
+ tag = i;
+ break;
+ }
+ }
+ switch (tag) {
+ case Constants.ATTR_UNKNOWN:
+ return new Unknown(idx, len, file, cpool);
+ case Constants.ATTR_CONSTANT_VALUE:
+ return new ConstantValue(idx, len, file, cpool);
+ case Constants.ATTR_SOURCE_FILE:
+ return new SourceFile(idx, len, file, cpool);
+ case Constants.ATTR_CODE:
+ return new Code(idx, len, file, cpool);
+ case Constants.ATTR_EXCEPTIONS:
+ return new ExceptionTable(idx, len, file, cpool);
+ case Constants.ATTR_LINE_NUMBER_TABLE:
+ return new LineNumberTable(idx, len, file, cpool);
+ case Constants.ATTR_LOCAL_VARIABLE_TABLE:
+ return new LocalVariableTable(idx, len, file, cpool);
+ case Constants.ATTR_INNER_CLASSES:
+ return new InnerClasses(idx, len, file, cpool);
+ case Constants.ATTR_SYNTHETIC:
+ return new Synthetic(idx, len, file, cpool);
+ case Constants.ATTR_DEPRECATED:
+ return new Deprecated(idx, len, file, cpool);
+ case Constants.ATTR_SIGNATURE:
+ return new Signature(idx, len, file, cpool);
+ case Constants.ATTR_STACK_MAP:
+ return new StackMap(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_VISIBLE_ANNOTATIONS:
+ return new RuntimeVisibleAnnotations(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_INVISIBLE_ANNOTATIONS:
+ return new RuntimeInvisibleAnnotations(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_VISIBLE_PARAMETER_ANNOTATIONS:
+ return new RuntimeVisibleParameterAnnotations(idx, len, file, cpool);
+ case Constants.ATTR_RUNTIME_INVISIBLE_PARAMETER_ANNOTATIONS:
+ return new RuntimeInvisibleParameterAnnotations(idx, len, file, cpool);
+ case Constants.ATTR_ANNOTATION_DEFAULT:
+ return new AnnotationDefault(idx, len, file, cpool);
+ case Constants.ATTR_LOCAL_VARIABLE_TYPE_TABLE:
+ return new LocalVariableTypeTable(idx, len, file, cpool);
+ case Constants.ATTR_ENCLOSING_METHOD:
+ return new EnclosingMethod(idx, len, file, cpool);
+ default:
+ throw new IllegalStateException();
+ }
+ }
+
+ public String getName() {
+ return constantPool.getConstantUtf8(nameIndex).getBytes();
+ }
+
+ public final int getLength() {
+ return length;
+ }
+
+ public final int getNameIndex() {
+ return nameIndex;
+ }
+
+ public final byte getTag() {
+ return tag;
+ }
+
+ public final ConstantPool getConstantPool() {
+ return constantPool;
+ }
+
+ /**
+ * Use copy() if you want to have a deep copy(), ie. with all references copied correctly.
+ *
+ * @return shallow copy of this attribute
+ */
+ @Override
+ public Object clone() {
+ Object o = null;
+
+ try {
+ o = super.clone();
+ } catch (CloneNotSupportedException e) {
+ e.printStackTrace(); // Never occurs
+ }
+
+ return o;
+ }
+
+ /**
+ * @return deep copy of this attribute
+ */
+ public abstract Attribute copy(ConstantPool constant_pool);
+
+ @Override
+ public String toString() {
+ return Constants.ATTRIBUTE_NAMES[tag];
+ }
+
+ public abstract void accept(ClassVisitor v);
}
* information on the Apache Software Foundation, please see
* <http://www.apache.org/>.
*/
-import org.aspectj.apache.bcel.Constants;
-import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
-import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations;
-
-import java.io.*;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
-/**
+import org.aspectj.apache.bcel.Constants;
+import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
+import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations;
+
+/**
* Abstract super class for fields and methods.
- *
- * @version $Id: FieldOrMethod.java,v 1.8 2009/09/09 19:56:20 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ *
+ * @version $Id: FieldOrMethod.java,v 1.9 2009/09/09 21:26:54 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
*/
public abstract class FieldOrMethod extends Modifiers implements Cloneable, Node {
- protected int nameIndex;
- protected int signatureIndex;
- protected Attribute[] attributes;
-
- protected ConstantPool cpool;
- private String name; // lazily initialized
- private String signature; // lazily initialized
- private AnnotationGen[] annotations; // lazily initialized
- private String signatureAttributeString = null;
- private boolean searchedForSignatureAttribute = false;
-
-
-
- protected FieldOrMethod() {}
-
- /**
- * Initialize from another object. Note that both objects use the same
- * references (shallow copy). Use clone() for a physical copy.
- */
- protected FieldOrMethod(FieldOrMethod c) {
- this(c.getModifiers(), c.getNameIndex(), c.getSignatureIndex(),c.getAttributes(), c.getConstantPool());
- }
-
- protected FieldOrMethod(DataInputStream file, ConstantPool cpool) throws IOException {
- this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, cpool);
- attributes = AttributeUtils.readAttributes(file,cpool);
- }
-
- protected FieldOrMethod(int accessFlags, int nameIndex, int signatureIndex, Attribute[] attributes, ConstantPool cpool) {
- this.modifiers = accessFlags;
- this.nameIndex = nameIndex;
- this.signatureIndex = signatureIndex;
- this.cpool = cpool;
- this.attributes = attributes;
- }
-
-
- /**
- * @param attributes Collection of object attributes.
- */
- public void setAttributes(Attribute[] attributes) {
- this.attributes = attributes;
- }
-
-
-
- public final void dump(DataOutputStream file) throws IOException {
- file.writeShort(modifiers);
- file.writeShort(nameIndex);
- file.writeShort(signatureIndex);
- AttributeUtils.writeAttributes(attributes,file);
- }
-
- public final Attribute[] getAttributes() { return attributes; }
- public final ConstantPool getConstantPool() { return cpool; }
- public final int getNameIndex() { return nameIndex; }
- public final int getSignatureIndex() { return signatureIndex; }
-
- public final String getName() {
- if (name==null) {
- ConstantUtf8 c = (ConstantUtf8)cpool.getConstant(nameIndex,Constants.CONSTANT_Utf8);
- name = c.getBytes();
- }
- return name;
- }
-
- public final String getSignature() {
- if (signature==null) {
- ConstantUtf8 c = (ConstantUtf8)cpool.getConstant(signatureIndex,Constants.CONSTANT_Utf8);
- signature = c.getBytes();
- }
- return signature;
- }
-
- /**
- * This will return the contents of a signature attribute attached to a member, or if there
- * is none it will return the same as 'getSignature()'. Signature attributes are attached
- * to members that were declared generic.
- */
- public final String getDeclaredSignature() {
- if (getGenericSignature()!=null) return getGenericSignature();
- return getSignature();
- }
-
- /**
- * @return deep copy of this field
- */
- protected FieldOrMethod copy_(ConstantPool constant_pool) {
- FieldOrMethod c = null;
-
- try {
- c = (FieldOrMethod)clone();
- } catch(CloneNotSupportedException e) {}
-
- c.cpool = constant_pool;
- c.attributes = AttributeUtils.copy(attributes,constant_pool);
- return c;
- }
-
- public AnnotationGen[] getAnnotations() {
- // Ensure we have unpacked any attributes that contain annotations.
- // We don't remove these annotation attributes from the attributes list, they
- // remain there.
- if (annotations==null) {
- // Find attributes that contain annotation data
- List<AnnotationGen> accumulatedAnnotations = new ArrayList<AnnotationGen>();
- for (int i = 0; i < attributes.length; i++) {
- Attribute attribute = attributes[i];
- if (attribute instanceof RuntimeAnnotations) {
- RuntimeAnnotations runtimeAnnotations = (RuntimeAnnotations)attribute;
- accumulatedAnnotations.addAll(runtimeAnnotations.getAnnotations());
+ protected int nameIndex;
+ protected int signatureIndex;
+ protected Attribute[] attributes;
+
+ protected ConstantPool cpool;
+ private String name; // lazily initialized
+ private String signature; // lazily initialized
+ private AnnotationGen[] annotations; // lazily initialized
+ private String signatureAttributeString = null;
+ private boolean searchedForSignatureAttribute = false;
+
+ protected FieldOrMethod() {
+ }
+
+ /**
+ * Initialize from another object. Note that both objects use the same references (shallow copy). Use clone() for a physical
+ * copy.
+ */
+ protected FieldOrMethod(FieldOrMethod c) {
+ this(c.getModifiers(), c.getNameIndex(), c.getSignatureIndex(), c.getAttributes(), c.getConstantPool());
+ }
+
+ protected FieldOrMethod(DataInputStream file, ConstantPool cpool) throws IOException {
+ this(file.readUnsignedShort(), file.readUnsignedShort(), file.readUnsignedShort(), null, cpool);
+ attributes = AttributeUtils.readAttributes(file, cpool);
+ }
+
+ protected FieldOrMethod(int accessFlags, int nameIndex, int signatureIndex, Attribute[] attributes, ConstantPool cpool) {
+ this.modifiers = accessFlags;
+ this.nameIndex = nameIndex;
+ this.signatureIndex = signatureIndex;
+ this.cpool = cpool;
+ this.attributes = attributes;
+ }
+
+ /**
+ * @param attributes Collection of object attributes.
+ */
+ public void setAttributes(Attribute[] attributes) {
+ this.attributes = attributes;
+ }
+
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeShort(modifiers);
+ file.writeShort(nameIndex);
+ file.writeShort(signatureIndex);
+ AttributeUtils.writeAttributes(attributes, file);
+ }
+
+ public final Attribute[] getAttributes() {
+ return attributes;
+ }
+
+ public final ConstantPool getConstantPool() {
+ return cpool;
+ }
+
+ public final int getNameIndex() {
+ return nameIndex;
+ }
+
+ public final int getSignatureIndex() {
+ return signatureIndex;
+ }
+
+ public final String getName() {
+ if (name == null) {
+ ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(nameIndex, Constants.CONSTANT_Utf8);
+ name = c.getBytes();
+ }
+ return name;
+ }
+
+ public final String getSignature() {
+ if (signature == null) {
+ ConstantUtf8 c = (ConstantUtf8) cpool.getConstant(signatureIndex, Constants.CONSTANT_Utf8);
+ signature = c.getBytes();
+ }
+ return signature;
+ }
+
+ /**
+ * This will return the contents of a signature attribute attached to a member, or if there is none it will return the same as
+ * 'getSignature()'. Signature attributes are attached to members that were declared generic.
+ */
+ public final String getDeclaredSignature() {
+ if (getGenericSignature() != null)
+ return getGenericSignature();
+ return getSignature();
+ }
+
+ /**
+ * @return deep copy of this field
+ */
+ protected FieldOrMethod copy_(ConstantPool constant_pool) {
+ FieldOrMethod c = null;
+
+ try {
+ c = (FieldOrMethod) clone();
+ } catch (CloneNotSupportedException e) {
+ }
+
+ c.cpool = constant_pool;
+ c.attributes = AttributeUtils.copy(attributes, constant_pool);
+ return c;
+ }
+
+ public AnnotationGen[] getAnnotations() {
+ // Ensure we have unpacked any attributes that contain annotations.
+ // We don't remove these annotation attributes from the attributes list, they
+ // remain there.
+ if (annotations == null) {
+ // Find attributes that contain annotation data
+ List<AnnotationGen> accumulatedAnnotations = new ArrayList<AnnotationGen>();
+ for (int i = 0; i < attributes.length; i++) {
+ Attribute attribute = attributes[i];
+ if (attribute instanceof RuntimeAnnotations) {
+ RuntimeAnnotations runtimeAnnotations = (RuntimeAnnotations) attribute;
+ accumulatedAnnotations.addAll(runtimeAnnotations.getAnnotations());
+ }
}
+ if (accumulatedAnnotations.size() == 0) {
+ annotations = AnnotationGen.NO_ANNOTATIONS;
+ } else {
+ annotations = accumulatedAnnotations.toArray(new AnnotationGen[] {});
+ }
+ }
+ return annotations;
+ }
+
+ /**
+ * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature may be
+ * (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector<Ljava/lang/String>;' Coded for performance -
+ * searches for the attribute only when requested - only searches for it once.
+ */
+ public final String getGenericSignature() {
+ if (!searchedForSignatureAttribute) {
+ Signature sig = AttributeUtils.getSignatureAttribute(attributes);
+ signatureAttributeString = (sig == null ? null : sig.getSignature());
+ searchedForSignatureAttribute = true;
}
- if (accumulatedAnnotations.size()==0) {
- annotations = AnnotationGen.NO_ANNOTATIONS;
- } else {
- annotations = accumulatedAnnotations.toArray(new AnnotationGen[]{});
- }
- }
- return annotations;
- }
-
- /**
- * Hunts for a signature attribute on the member and returns its contents. So where the 'regular' signature
- * may be (Ljava/util/Vector;)V the signature attribute may in fact say 'Ljava/lang/Vector<Ljava/lang/String>;'
- * Coded for performance - searches for the attribute only when requested - only searches for it once.
- */
- public final String getGenericSignature() {
- if (!searchedForSignatureAttribute) {
- Signature sig = AttributeUtils.getSignatureAttribute(attributes);
- signatureAttributeString = (sig==null?null:sig.getSignature());
- searchedForSignatureAttribute=true;
- }
- return signatureAttributeString;
- }
-
+ return signatureAttributeString;
+ }
+
}
* 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.15 2009/09/09 19:56:20 aclement Exp $
+ * @version $Id: JavaClass.java,v 1.16 2009/09/09 21:26:54 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 String file_name;
- private String package_name;
- private String source_file_name;
- private int class_name_index;
- private int superclass_name_index;
- private String class_name;
- private String superclass_name;
- private int major, minor; // Compiler version
- private ConstantPool constant_pool; // Constant pool
- private int[] interfaces; // implemented interfaces
- private String[] interface_names;
- private Field[] fields; // Fields, i.e., variables of class
- private Method[] methods; // methods defined in the class
- private Attribute[] attributes; // attributes defined in the class
- private AnnotationGen[] annotations; // annotations defined on the class
+ private static final String[] NO_INTERFACE_NAMES = new String[0];
+
+ private String fileName;
+ private String packageName;
+ private String sourcefileName;
+ private int classnameIdx;
+ private int superclassnameIdx;
+ private String classname;
+ private String superclassname;
+ private int major, minor;
+ private ConstantPool cpool;
+ private int[] interfaces;
+ private String[] interfacenames;
+ private Field[] fields;
+ private Method[] methods;
+ private Attribute[] attributes;
+ private AnnotationGen[] annotations;
+
private boolean isGeneric = false;
private boolean isAnonymous = false;
private boolean isNested = false;
private boolean computedNestedTypeStatus = false;
- public static final byte HEAP = 1;
- public static final byte FILE = 2;
- public static final byte ZIP = 3;
-
- static boolean debug = false; // Debugging on/off
- static char sep = '/'; // directory separator
-
// Annotations are collected from certain attributes, don't do it more than necessary!
private boolean annotationsOutOfDate = true;
private Signature signatureAttribute = null;
private boolean searchedForSignatureAttribute = false;
- private static final String[] NO_INTERFACE_NAMES = new String[] {};
-
/**
* In cases where we go ahead and create something, use the default SyntheticRepository, because we don't know any better.
*/
methods = new Method[0]; // TODO create a constant for no methods
}
- this.class_name_index = class_name_index;
- this.superclass_name_index = superclass_name_index;
- this.file_name = file_name;
+ this.classnameIdx = class_name_index;
+ this.superclassnameIdx = superclass_name_index;
+ this.fileName = file_name;
this.major = major;
this.minor = minor;
this.modifiers = access_flags;
- this.constant_pool = constant_pool;
+ this.cpool = constant_pool;
this.interfaces = interfaces;
this.fields = fields;
this.methods = methods;
// Get source file name if available
SourceFile sfAttribute = AttributeUtils.getSourceFileAttribute(attributes);
- source_file_name = sfAttribute == null ? "<Unknown>" : sfAttribute.getSourceFileName();
+ sourcefileName = sfAttribute == null ? "<Unknown>" : sfAttribute.getSourceFileName();
/*
* According to the specification the following entries must be of type `ConstantClass' but we check that anyway via the
* `ConstPool.getConstant' method.
*/
- class_name = constant_pool.getConstantString(class_name_index, Constants.CONSTANT_Class);
- class_name = Utility.compactClassName(class_name, false);
+ classname = constant_pool.getConstantString(class_name_index, Constants.CONSTANT_Class);
+ classname = Utility.compactClassName(classname, false);
- int index = class_name.lastIndexOf('.');
+ int index = classname.lastIndexOf('.');
if (index < 0) {
- package_name = "";
+ packageName = "";
} else {
- package_name = class_name.substring(0, index);
+ packageName = classname.substring(0, index);
}
if (superclass_name_index > 0) { // May be zero -> class is java.lang.Object
- superclass_name = constant_pool.getConstantString(superclass_name_index, Constants.CONSTANT_Class);
- superclass_name = Utility.compactClassName(superclass_name, false);
+ superclassname = constant_pool.getConstantString(superclass_name_index, Constants.CONSTANT_Class);
+ superclassname = Utility.compactClassName(superclassname, false);
} else {
- superclass_name = "java.lang.Object";
+ superclassname = "java.lang.Object";
}
if (interfaces.length == 0) {
- interface_names = NO_INTERFACE_NAMES;
+ interfacenames = NO_INTERFACE_NAMES;
} else {
- interface_names = new String[interfaces.length];
+ interfacenames = new String[interfaces.length];
for (int i = 0; i < interfaces.length; i++) {
String str = constant_pool.getConstantString(interfaces[i], Constants.CONSTANT_Class);
- interface_names[i] = Utility.compactClassName(str, false);
+ interfacenames[i] = Utility.compactClassName(str, false);
}
}
}
v.visitJavaClass(this);
}
- /*
- * Print debug information depending on `JavaClass.debug'
- */
- static final void Debug(String str) {
- if (debug) {
- System.out.println(str);
- }
- }
-
/**
* Dump class to a file.
*
file.writeShort(minor);
file.writeShort(major);
- constant_pool.dump(file);
+ cpool.dump(file);
file.writeShort(modifiers);
- file.writeShort(class_name_index);
- file.writeShort(superclass_name_index);
+ file.writeShort(classnameIdx);
+ file.writeShort(superclassnameIdx);
file.writeShort(interfaces.length);
for (int i = 0; i < interfaces.length; i++) {
* @return Class name.
*/
public String getClassName() {
- return class_name;
+ return classname;
}
/**
* @return Package name.
*/
public String getPackageName() {
- return package_name;
+ return packageName;
}
/**
* @return Class name index.
*/
public int getClassNameIndex() {
- return class_name_index;
+ return classnameIdx;
}
/**
* @return Constant pool.
*/
public ConstantPool getConstantPool() {
- return constant_pool;
+ return cpool;
}
/**
* @return File name of class, aka SourceFile attribute value
*/
public String getFileName() {
- return file_name;
+ return fileName;
}
/**
* @return Names of implemented interfaces.
*/
public String[] getInterfaceNames() {
- return interface_names;
+ return interfacenames;
}
/**
* @return sbsolute path to file where this class was read from
*/
public String getSourceFileName() {
- return source_file_name;
+ return sourcefileName;
}
/**
* @return Superclass name.
*/
public String getSuperclassName() {
- return superclass_name;
+ return superclassname;
}
/**
* @return Class name index.
*/
public int getSuperclassNameIndex() {
- return superclass_name_index;
- }
-
- static {
- // Debugging ... on/off
- String debug = System.getProperty("JavaClass.debug");
-
- if (debug != null) {
- JavaClass.debug = new Boolean(debug).booleanValue();
- }
-
- // Get path separator either / or \ usually
- String sep = System.getProperty("file.separator");
-
- if (sep != null) {
- try {
- JavaClass.sep = sep.charAt(0);
- } catch (StringIndexOutOfBoundsException e) {
- } // Never reached
- }
+ return superclassnameIdx;
}
/**
* @param class_name .
*/
public void setClassName(String class_name) {
- this.class_name = class_name;
+ this.classname = class_name;
}
/**
* @param class_name_index .
*/
public void setClassNameIndex(int class_name_index) {
- this.class_name_index = class_name_index;
+ this.classnameIdx = class_name_index;
}
/**
* @param constant_pool .
*/
public void setConstantPool(ConstantPool constant_pool) {
- this.constant_pool = constant_pool;
+ this.cpool = constant_pool;
}
/**
* Set File name of class, aka SourceFile attribute value
*/
public void setFileName(String file_name) {
- this.file_name = file_name;
+ this.fileName = file_name;
}
/**
* @param interface_names .
*/
public void setInterfaceNames(String[] interface_names) {
- this.interface_names = interface_names;
+ this.interfacenames = interface_names;
}
/**
* Set absolute path to file this class was read from.
*/
public void setSourceFileName(String source_file_name) {
- this.source_file_name = source_file_name;
+ this.sourcefileName = source_file_name;
}
/**
* @param superclass_name .
*/
public void setSuperclassName(String superclass_name) {
- this.superclass_name = superclass_name;
+ this.superclassname = superclass_name;
}
/**
* @param superclass_name_index .
*/
public void setSuperclassNameIndex(int superclass_name_index) {
- this.superclass_name_index = superclass_name_index;
+ this.superclassnameIdx = superclass_name_index;
}
/**
String access = Utility.accessToString(modifiers, true);
access = access.equals("") ? "" : access + " ";
- StringBuffer buf = new StringBuffer(access + Utility.classOrInterface(modifiers) + " " + class_name + " extends "
- + Utility.compactClassName(superclass_name, false) + '\n');
+ StringBuffer buf = new StringBuffer(access + Utility.classOrInterface(modifiers) + " " + classname + " extends "
+ + Utility.compactClassName(superclassname, false) + '\n');
int size = interfaces.length;
if (size > 0) {
buf.append("implements\t\t");
for (int i = 0; i < size; i++) {
- buf.append(interface_names[i]);
+ buf.append(interfacenames[i]);
if (i < size - 1) {
buf.append(", ");
}
buf.append('\n');
}
- buf.append("filename\t\t" + file_name + '\n');
- buf.append("compiled from\t\t" + source_file_name + '\n');
+ buf.append("filename\t\t" + fileName + '\n');
+ buf.append("compiled from\t\t" + sourcefileName + '\n');
buf.append("compiler version\t" + major + "." + minor + '\n');
buf.append("access flags\t\t" + modifiers + '\n');
- buf.append("constant pool\t\t" + constant_pool.getLength() + " entries\n");
+ buf.append("constant pool\t\t" + cpool.getLength() + " entries\n");
buf.append("ACC_SUPER flag\t\t" + isSuper() + "\n");
if (attributes.length > 0) {
} catch (CloneNotSupportedException e) {
}
- c.constant_pool = constant_pool.copy();
+ c.cpool = cpool.copy();
c.interfaces = interfaces.clone();
- c.interface_names = interface_names.clone();
+ c.interfacenames = interfacenames.clone();
c.fields = new Field[fields.length];
for (int i = 0; i < fields.length; i++) {
- c.fields[i] = fields[i].copy(c.constant_pool);
+ c.fields[i] = fields[i].copy(c.cpool);
}
c.methods = new Method[methods.length];
for (int i = 0; i < methods.length; i++) {
- c.methods[i] = methods[i].copy(c.constant_pool);
+ c.methods[i] = methods[i].copy(c.cpool);
}
- c.attributes = AttributeUtils.copy(attributes, c.constant_pool);
+ c.attributes = AttributeUtils.copy(attributes, c.cpool);
// J5SUPPORT: As the annotations exist as attributes against the class, copying
// the attributes will copy the annotations across, so we don't have to
InnerClass[] innerClasses = ((InnerClasses) attributes[i]).getInnerClasses();
for (int j = 0; j < innerClasses.length; j++) {
boolean innerClassAttributeRefersToMe = false;
- String inner_class_name = constant_pool.getConstantString(innerClasses[j].getInnerClassIndex(),
+ String inner_class_name = cpool.getConstantString(innerClasses[j].getInnerClassIndex(),
Constants.CONSTANT_Class);
inner_class_name = Utility.compactClassName(inner_class_name);
if (inner_class_name.equals(getClassName())) {
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
-import java.io.Serializable;
/**
- * This class represents a (PC offset, line number) pair, i.e., a line number in
- * the source that corresponds to a relative address in the byte code. This
- * is used for debugging purposes.
- *
- * @version $Id: LineNumber.java,v 1.5 2008/05/28 23:53:02 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
- * @see LineNumberTable
+ * This class represents a (PC offset, line number) pair, i.e., a line number in the source that corresponds to a relative address
+ * in the byte code. This is used for debugging purposes.
+ *
+ * @version $Id: LineNumber.java,v 1.6 2009/09/09 21:26:54 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @author Andy Clement
+ * @see LineNumberTable
*/
-public final class LineNumber implements Cloneable, Node, Serializable {
- private int start_pc; // Program Counter (PC) corresponds to line
- private int line_number; // number in source file
-
- /**
- * Initialize from another object.
- */
- public LineNumber(LineNumber c) {
- this(c.getStartPC(), c.getLineNumber());
- }
-
- /**
- * Construct object from file stream.
- * @param file Input stream
- * @throws IOException
- */
- LineNumber(DataInputStream file) throws IOException
- {
- this(file.readUnsignedShort(), file.readUnsignedShort());
- }
+public final class LineNumber implements Node {
+ private int startPC;
+ private int lineNumber;
- /**
- * @param start_pc Program Counter (PC) corresponds to
- * @param line_number line number in source file
- */
- public LineNumber(int start_pc, int line_number)
- {
- this.start_pc = start_pc;
- this.line_number = line_number;
- }
+ public LineNumber(LineNumber c) {
+ this(c.getStartPC(), c.getLineNumber());
+ }
- /**
- * 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.visitLineNumber(this);
- }
+ LineNumber(DataInputStream file) throws IOException {
+ this(file.readUnsignedShort(), file.readUnsignedShort());
+ }
- /**
- * Dump line number/pc pair to file stream in binary format.
- *
- * @param file Output file stream
- * @throws IOException
- */
- public final void dump(DataOutputStream file) throws IOException
- {
- file.writeShort(start_pc);
- file.writeShort(line_number);
+ public LineNumber(int startPC, int lineNumber) {
+ this.startPC = startPC;
+ this.lineNumber = lineNumber;
+ }
- }
- /**
- * @return Corresponding source line
- */
- public final int getLineNumber() { return line_number; }
+ public void accept(ClassVisitor v) {
+ v.visitLineNumber(this);
+ }
- /**
- * @return PC in code
- */
- public final int getStartPC() { return start_pc; }
+ public final void dump(DataOutputStream file) throws IOException {
+ file.writeShort(startPC);
+ file.writeShort(lineNumber);
+ }
- /**
- * @param line_number.
- */
- public final void setLineNumber(int line_number) {
- this.line_number = line_number;
- }
+ public final int getLineNumber() {
+ return lineNumber;
+ }
- /**
- * @param start_pc.
- */
- public final void setStartPC(int start_pc) {
- this.start_pc = start_pc;
- }
+ public final int getStartPC() {
+ return startPC;
+ }
- /**
- * @return String representation
- */
- public final String toString() {
- return "LineNumber(" + start_pc + ", " + line_number + ")";
- }
+ // public final void setLineNumber(int line_number) {
+ // this.lineNumber = line_number;
+ // }
+ //
+ // public final void setStartPC(int start_pc) {
+ // this.startPC = start_pc;
+ // }
- /**
- * @return deep copy of this object
- */
- public LineNumber copy() {
- try {
- return (LineNumber)clone();
- } catch(CloneNotSupportedException e) {}
+ @Override
+ public final String toString() {
+ return "LineNumber(" + startPC + ", " + lineNumber + ")";
+ }
- return null;
- }
+ public LineNumber copy() {
+ return new LineNumber(this);
+ }
}
* <http://www.apache.org/>.
*/
-import org.aspectj.apache.bcel.Constants;
-import java.io.*;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+
+import org.aspectj.apache.bcel.Constants;
/**
- * This class represents a table of line numbers for debugging
- * purposes. This attribute is used by the <em>Code</em> attribute. It
+ * This class represents a table of line numbers for debugging purposes. This attribute is used by the <em>Code</em> attribute. It
* contains pairs of PCs and line numbers.
- *
- * @version $Id: LineNumberTable.java,v 1.5 2008/08/26 15:00:39 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
- * @see Code
- *
- * changes:
- * asc Feb06 Made unpacking lazy
+ *
+ * @version $Id: LineNumberTable.java,v 1.6 2009/09/09 21:26:54 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+ * @see Code changes: asc Feb06 Made unpacking lazy
*/
public final class LineNumberTable extends Attribute {
-
-
- // if 'isInPackedState' then this data needs unpacking
- private boolean isInPackedState = false;
- private byte[] data;
-
- private int line_number_table_length;
- private LineNumber[] line_number_table; // Table of line/numbers pairs
- /*
- * Initialize from another object. Note that both objects use the same
- * references (shallow copy). Use copy() for a physical copy.
- */
- public LineNumberTable(LineNumberTable c) {
- this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool());
- }
+ // if 'isInPackedState' then this data needs unpacking
+ private boolean isInPackedState = false;
+ private byte[] data; // discarded once unpacked
+
+ private int tableLength;
+ private LineNumber[] table;
+
+ /*
+ * Initialize from another object. Note that both objects use the same references (shallow copy). Use copy() for a physical
+ * copy.
+ */
+ public LineNumberTable(LineNumberTable c) {
+ this(c.getNameIndex(), c.getLength(), c.getLineNumberTable(), c.getConstantPool());
+ }
+
+ public LineNumberTable(int nameIndex, int length, LineNumber[] lineNumberTable, ConstantPool constantPool) {
+ super(Constants.ATTR_LINE_NUMBER_TABLE, nameIndex, length, constantPool);
+ setLineNumberTable(lineNumberTable);
+ isInPackedState = false;
+ }
+
+ /**
+ * Construct object from file stream.
+ *
+ * @param name_index Index of name
+ * @param length Content length in bytes
+ * @param file Input stream
+ * @throws IOException
+ * @param constant_pool Array of constants
+ */
+ LineNumberTable(int name_index, int length, DataInputStream file, ConstantPool constant_pool) throws IOException {
+ this(name_index, length, (LineNumber[]) null, constant_pool);
+ data = new byte[length];
+ file.read(data);
+ isInPackedState = true;
+ // assert(bytesRead==length)
+ }
- /*
- * @param name_index Index of name
- * @param length Content length in bytes
- * @param line_number_table Table of line/numbers pairs
- * @param constant_pool Array of constants
- */
- public LineNumberTable(int name_index, int length,
- LineNumber[] line_number_table, ConstantPool constant_pool) {
- super(Constants.ATTR_LINE_NUMBER_TABLE, name_index, length, constant_pool);
- setLineNumberTable(line_number_table);
- isInPackedState=false;
- }
-
- /**
- * Construct object from file stream.
- * @param name_index Index of name
- * @param length Content length in bytes
- * @param file Input stream
- * @throws IOException
- * @param constant_pool Array of constants
- */
- LineNumberTable(int name_index, int length, DataInputStream file,
- ConstantPool constant_pool) throws IOException
- {
- this(name_index, length, (LineNumber[])null, constant_pool);
- data = new byte[length];
- file.read(data);
- isInPackedState = true;
- // assert(bytesRead==length)
- }
-
- // Unpacks the byte array into the table
- private void unpack() {
- if (!isInPackedState) return;
+ // Unpacks the byte array into the table
+ private void unpack() {
+ if (isInPackedState) {
+ try {
+ ByteArrayInputStream bs = new ByteArrayInputStream(data);
+ DataInputStream dis = new DataInputStream(bs);
+ tableLength = (dis.readUnsignedShort());
+ table = new LineNumber[tableLength];
+ for (int i = 0; i < tableLength; i++) {
+ table[i] = new LineNumber(dis);
+ }
+ dis.close();
+ data = null; // throw it away now
+ } catch (IOException e) {
+ throw new RuntimeException("Unpacking of LineNumberTable attribute failed");
+ }
+ isInPackedState = false;
+ }
+ }
- try {
- ByteArrayInputStream bs = new ByteArrayInputStream(data);
- DataInputStream dis = new DataInputStream(bs);
- line_number_table_length = (dis.readUnsignedShort());
- line_number_table = new LineNumber[line_number_table_length];
- for (int i=0; i < line_number_table_length; i++)
- line_number_table[i] = new LineNumber(dis);
- dis.close();
- data = null; // throw it away now
- } catch (IOException e) {
- throw new RuntimeException("Unpacking of LineNumberTable attribute failed");
- }
- isInPackedState=false;
- }
-
- /**
- * 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) {
- unpack();
- v.visitLineNumberTable(this);
- }
-
- /**
- * Dump line number table attribute to file stream in binary format.
- *
- * @param file Output file stream
- * @throws IOException
- */
- public final void dump(DataOutputStream file) throws IOException
- {
- super.dump(file);
- if (isInPackedState) {
- file.write(data);
- } else {
- file.writeShort(line_number_table_length);
- for(int i=0; i < line_number_table_length; i++)
- line_number_table[i].dump(file);
- }
- }
-
- /**
- * @return Array of (pc offset, line number) pairs.
- */
- public final LineNumber[] getLineNumberTable() { unpack();return line_number_table; }
+ /**
+ * 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
+ */
+ @Override
+ public void accept(ClassVisitor v) {
+ unpack();
+ v.visitLineNumberTable(this);
+ }
- /**
- * @param line_number_table.
- */
- public final void setLineNumberTable(LineNumber[] line_number_table) {
- this.data = null;
- this.isInPackedState=false;
- this.line_number_table = line_number_table;
+ /**
+ * Dump line number table attribute to file stream in binary format.
+ *
+ * @param file Output file stream
+ * @throws IOException
+ */
+ @Override
+ public final void dump(DataOutputStream file) throws IOException {
+ super.dump(file);
+ if (isInPackedState) {
+ file.write(data);
+ } else {
+ file.writeShort(tableLength);
+ for (int i = 0; i < tableLength; i++) {
+ table[i].dump(file);
+ }
+ }
+ }
- line_number_table_length = (line_number_table == null)? 0 :
- line_number_table.length;
- }
+ /**
+ * @return Array of (pc offset, line number) pairs.
+ */
+ public final LineNumber[] getLineNumberTable() {
+ unpack();
+ return table;
+ }
- /**
- * @return String representation.
- */
- public final String toString() {
- unpack();
- StringBuffer buf = new StringBuffer();
- StringBuffer line = new StringBuffer();
+ /**
+ * @param line_number_table.
+ */
+ public final void setLineNumberTable(LineNumber[] line_number_table) {
+ this.data = null;
+ this.isInPackedState = false;
+ this.table = line_number_table;
+ this.tableLength = (line_number_table == null) ? 0 : line_number_table.length;
+ }
- for(int i=0; i < line_number_table_length; i++) {
- line.append(line_number_table[i].toString());
+ /**
+ * @return String representation.
+ */
+ @Override
+ public final String toString() {
+ unpack();
+ StringBuffer buf = new StringBuffer();
+ StringBuffer line = new StringBuffer();
- if(i < line_number_table_length - 1)
- line.append(", ");
+ for (int i = 0; i < tableLength; i++) {
+ line.append(table[i].toString());
- if(line.length() > 72) {
- line.append('\n');
- buf.append(line);
- line.setLength(0);
- }
- }
+ if (i < tableLength - 1) {
+ line.append(", ");
+ }
- buf.append(line);
+ if (line.length() > 72) {
+ line.append('\n');
+ buf.append(line);
+ line.setLength(0);
+ }
+ }
- return buf.toString();
- }
+ buf.append(line);
- /**
- * Map byte code positions to source code lines.
- *
- * @param pos byte code offset
- * @return corresponding line in source code
- */
- public int getSourceLine(int pos) {
- unpack();
- int l = 0, r = line_number_table_length-1;
+ return buf.toString();
+ }
- if(r < 0) // array is empty
- return -1;
+ /**
+ * Map byte code positions to source code lines.
+ *
+ * @param pos byte code offset
+ * @return corresponding line in source code
+ */
+ public int getSourceLine(int pos) {
+ unpack();
+ int l = 0, r = tableLength - 1;
- int min_index = -1, min=-1;
-
- /* Do a binary search since the array is ordered.
- */
- do {
- int i = (l + r) / 2;
- int j = line_number_table[i].getStartPC();
+ if (r < 0) // array is empty
+ return -1;
- if(j == pos)
- return line_number_table[i].getLineNumber();
- else if(pos < j) // else constrain search area
- r = i - 1;
- else // pos > j
- l = i + 1;
+ int min_index = -1, min = -1;
- /* If exact match can't be found (which is the most common case)
- * return the line number that corresponds to the greatest index less
- * than pos.
- */
- if(j < pos && j > min) {
- min = j;
- min_index = i;
- }
- } while(l <= r);
+ /*
+ * Do a binary search since the array is ordered.
+ */
+ do {
+ int i = (l + r) / 2;
+ int j = table[i].getStartPC();
- /* It's possible that we did not find any valid entry for the bytecode
- * offset we were looking for.
- */
- if (min_index < 0)
- return -1;
+ if (j == pos)
+ return table[i].getLineNumber();
+ else if (pos < j) // else constrain search area
+ r = i - 1;
+ else
+ // pos > j
+ l = i + 1;
- return line_number_table[min_index].getLineNumber();
- }
+ /*
+ * If exact match can't be found (which is the most common case) return the line number that corresponds to the greatest
+ * index less than pos.
+ */
+ if (j < pos && j > min) {
+ min = j;
+ min_index = i;
+ }
+ } while (l <= r);
- /**
- * @return deep copy of this attribute
- */
- public Attribute copy(ConstantPool constant_pool) {
- unpack();
- LineNumberTable c = (LineNumberTable)clone();
+ /*
+ * It's possible that we did not find any valid entry for the bytecode offset we were looking for.
+ */
+ if (min_index < 0)
+ return -1;
- c.line_number_table = new LineNumber[line_number_table_length];
- for(int i=0; i < line_number_table_length; i++)
- c.line_number_table[i] = line_number_table[i].copy();
+ return table[min_index].getLineNumber();
+ }
- c.constantPool = constant_pool;
- return c;
- }
+ /**
+ * @return deep copy of this attribute
+ */
+ @Override
+ public Attribute copy(ConstantPool constant_pool) {
+ unpack();
+ LineNumberTable newTable = (LineNumberTable) clone();
+ newTable.table = new LineNumber[tableLength];
+ for (int i = 0; i < tableLength; i++) {
+ newTable.table[i] = table[i].copy();
+ }
+ newTable.constantPool = constant_pool;
+ return newTable;
+ }
- public final int getTableLength() { unpack();return line_number_table_length; }
+ public final int getTableLength() {
+ unpack();
+ return tableLength;
+ }
}
+++ /dev/null
-package org.aspectj.apache.bcel.classfile;
-
-/* ====================================================================
- * The Apache Software License, Version 1.1
- *
- * Copyright (c) 2001 The Apache Software Foundation. All rights
- * reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in
- * the documentation and/or other materials provided with the
- * distribution.
- *
- * 3. The end-user documentation included with the redistribution,
- * if any, must include the following acknowledgment:
- * "This product includes software developed by the
- * Apache Software Foundation (http://www.apache.org/)."
- * Alternately, this acknowledgment may appear in the software itself,
- * if and wherever such third-party acknowledgments normally appear.
- *
- * 4. The names "Apache" and "Apache Software Foundation" and
- * "Apache BCEL" must not be used to endorse or promote products
- * derived from this software without prior written permission. For
- * written permission, please contact apache@apache.org.
- *
- * 5. Products derived from this software may not be called "Apache",
- * "Apache BCEL", nor may "Apache" appear in their name, without
- * prior written permission of the Apache Software Foundation.
- *
- * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
- * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
- * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
- * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- * ====================================================================
- *
- * This software consists of voluntary contributions made by many
- * individuals on behalf of the Apache Software Foundation. For more
- * information on the Apache Software Foundation, please see
- * <http://www.apache.org/>.
- */
-
-import org.aspectj.apache.bcel.Constants;
-import java.io.*;
-
-/**
- * This class is derived from <em>Attribute</em> and represents a reference
- * to a <a href="http://www.inf.fu-berlin.de/~bokowski/pmgjava/index.html">PMG</a>
- * attribute.
- *
- * @version $Id: PMGClass.java,v 1.3 2008/05/28 23:53:02 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
- * @see Attribute
- */
-public final class PMGClass extends Attribute {
- private int pmg_class_index, pmg_index;
-
- /**
- * Initialize from another object. Note that both objects use the same
- * references (shallow copy). Use clone() for a physical copy.
- */
- public PMGClass(PMGClass c) {
- this(c.getNameIndex(), c.getLength(), c.getPMGIndex(), c.getPMGClassIndex(),
- c.getConstantPool());
- }
-
- /**
- * Construct object from file stream.
- * @param name_index Index in constant pool to CONSTANT_Utf8
- * @param length Content length in bytes
- * @param file Input stream
- * @param constant_pool Array of constants
- * @throws IOException
- */
- PMGClass(int name_index, int length, DataInputStream file,
- ConstantPool constant_pool) throws IOException
- {
- this(name_index, length, file.readUnsignedShort(), file.readUnsignedShort(),
- constant_pool);
- }
-
- /**
- * @param name_index Index in constant pool to CONSTANT_Utf8
- * @param length Content length in bytes
- * @param constant_pool Array of constants
- * @param PMGClass_index Index in constant pool to CONSTANT_Utf8
- */
- public PMGClass(int name_index, int length, int pmg_index, int pmg_class_index,
- ConstantPool constant_pool)
- {
- super(Constants.ATTR_PMG, name_index, length, constant_pool);
- this.pmg_index = pmg_index;
- this.pmg_class_index = pmg_class_index;
- }
-
- /**
- * 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) {
- System.err.println("Visiting non-standard PMGClass object");
- }
-
- /**
- * Dump source file attribute to file stream in binary format.
- *
- * @param file Output file stream
- * @throws IOException
- */
- public final void dump(DataOutputStream file) throws IOException
- {
- super.dump(file);
- file.writeShort(pmg_index);
- file.writeShort(pmg_class_index);
- }
-
- /**
- * @return Index in constant pool of source file name.
- */
- public final int getPMGClassIndex() { return pmg_class_index; }
-
- /**
- * @param PMGClass_index.
- */
- public final void setPMGClassIndex(int pmg_class_index) {
- this.pmg_class_index = pmg_class_index;
- }
-
- /**
- * @return Index in constant pool of source file name.
- */
- public final int getPMGIndex() { return pmg_index; }
-
- /**
- * @param PMGClass_index.
- */
- public final void setPMGIndex(int pmg_index) {
- this.pmg_index = pmg_index;
- }
-
- /**
- * @return PMG name.
- */
- public final String getPMGName() {
- ConstantUtf8 c = (ConstantUtf8)constantPool.getConstant(pmg_index,
- Constants.CONSTANT_Utf8);
- return c.getBytes();
- }
-
- /**
- * @return PMG class name.
- */
- public final String getPMGClassName() {
- ConstantUtf8 c = (ConstantUtf8)constantPool.getConstant(pmg_class_index,
- Constants.CONSTANT_Utf8);
- return c.getBytes();
- }
-
- /**
- * @return String representation
- */
- public final String toString() {
- return "PMGClass(" + getPMGName() + ", " + getPMGClassName() + ")";
- }
-
- /**
- * @return deep copy of this attribute
- */
- public Attribute copy(ConstantPool constant_pool) {
- return (PMGClass)clone();
- }
-}
import org.aspectj.apache.bcel.classfile.annotation.AnnotationGen;
import org.aspectj.apache.bcel.classfile.annotation.RuntimeAnnotations;
-/**
- * Template class for building up a field. The only extraordinary thing
- * one can do is to add a constant value attribute to a field (which must of
- * course be compatible with the declared type).
- *
- * @version $Id: FieldGen.java,v 1.6 2009/09/09 19:56:20 aclement Exp $
- * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
+/**
+ * Template class for building up a field. The only extraordinary thing one can do is to add a constant value attribute to a field
+ * (which must of course be compatible with the declared type).
+ *
+ * @version $Id: FieldGen.java,v 1.7 2009/09/09 21:26:54 aclement Exp $
+ * @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A>
* @see Field
*/
public class FieldGen extends FieldGenOrMethodGen {
- private Object value = null;
-
- /**
- * Declare a field. If it is static (isStatic() == true) and has a
- * basic type like int or String it may have an initial value
- * associated with it as defined by setInitValue().
- *
- * @param access_flags access qualifiers
- * @param type field type
- * @param name field name
- * @param cp constant pool
- */
- public FieldGen(int access_flags, Type type, String name, ConstantPool cp) {
- setModifiers(access_flags);
- setType(type);
- setName(name);
- setConstantPool(cp);
- }
-
- /**
- * Instantiate from existing field.
- *
- * @param field Field object
- * @param cp constant pool (must contain the same entries as the field's constant pool)
- */
- public FieldGen(Field field, ConstantPool cp) {
- this(field.getModifiers(), Type.getType(field.getSignature()), field.getName(), cp);
-
- Attribute[] attrs = field.getAttributes();
-
- for(int i=0; i < attrs.length; i++) {
- if(attrs[i] instanceof ConstantValue) {
- setValue(((ConstantValue)attrs[i]).getConstantValueIndex());
- } else if (attrs[i] instanceof RuntimeAnnotations) {
- RuntimeAnnotations runtimeAnnotations = (RuntimeAnnotations)attrs[i];
- List<AnnotationGen> l = runtimeAnnotations.getAnnotations();
- for (Iterator<AnnotationGen> it = l.iterator(); it.hasNext();) {
- AnnotationGen element = it.next();
- addAnnotation(new AnnotationGen(element,cp,false));
+ private Object value = null;
+
+ /**
+ * Declare a field. If it is static (isStatic() == true) and has a basic type like int or String it may have an initial value
+ * associated with it as defined by setInitValue().
+ *
+ * @param modifiers access qualifiers
+ * @param type field type
+ * @param name field name
+ * @param cpool constant pool
+ */
+ public FieldGen(int modifiers, Type type, String name, ConstantPool cpool) {
+ setModifiers(modifiers);
+ setType(type);
+ setName(name);
+ setConstantPool(cpool);
+ }
+
+ /**
+ * Instantiate from existing field.
+ *
+ * @param field Field object
+ * @param cp constant pool (must contain the same entries as the field's constant pool)
+ */
+ public FieldGen(Field field, ConstantPool cp) {
+ this(field.getModifiers(), Type.getType(field.getSignature()), field.getName(), cp);
+
+ Attribute[] attrs = field.getAttributes();
+
+ for (int i = 0; i < attrs.length; i++) {
+ if (attrs[i] instanceof ConstantValue) {
+ setValue(((ConstantValue) attrs[i]).getConstantValueIndex());
+ } else if (attrs[i] instanceof RuntimeAnnotations) {
+ RuntimeAnnotations runtimeAnnotations = (RuntimeAnnotations) attrs[i];
+ List<AnnotationGen> l = runtimeAnnotations.getAnnotations();
+ for (Iterator<AnnotationGen> it = l.iterator(); it.hasNext();) {
+ AnnotationGen element = it.next();
+ addAnnotation(new AnnotationGen(element, cp, false));
+ }
+ } else {
+ addAttribute(attrs[i]);
+ }
+ }
+ }
+
+ private void setValue(int index) {
+ ConstantPool cp = this.cp;
+ Constant c = cp.getConstant(index);
+ value = ((ConstantObject) c).getConstantValue(cp);
+ }
+
+ public void wipeValue() {
+ value = null;
+ }
+
+ private void checkType(Type atype) {
+ if (type == null)
+ throw new ClassGenException("You haven't defined the type of the field yet");
+
+ if (!isFinal())
+ throw new ClassGenException("Only final fields may have an initial value!");
+
+ if (!type.equals(atype))
+ throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype);
+ }
+
+ /**
+ * Get field object after having set up all necessary values.
+ */
+ public Field getField() {
+ String signature = getSignature();
+ int name_index = cp.addUtf8(name);
+ int signature_index = cp.addUtf8(signature);
+
+ if (value != null) {
+ checkType(type);
+ int index = addConstant();
+ addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"), 2, index, cp));
+ }
+
+ addAnnotationsAsAttribute(cp);
+
+ return new Field(modifiers, name_index, signature_index, getAttributesImmutable(), cp);
+ }
+
+ private int addConstant() {
+ switch (type.getType()) {
+ case Constants.T_INT:
+ case Constants.T_CHAR:
+ case Constants.T_BYTE:
+ case Constants.T_BOOLEAN:
+ case Constants.T_SHORT:
+ return cp.addInteger(((Integer) value).intValue());
+
+ case Constants.T_FLOAT:
+ return cp.addFloat(((Float) value).floatValue());
+
+ case Constants.T_DOUBLE:
+ return cp.addDouble(((Double) value).doubleValue());
+
+ case Constants.T_LONG:
+ return cp.addLong(((Long) value).longValue());
+
+ case Constants.T_REFERENCE:
+ return cp.addString(((String) value));
+
+ default:
+ throw new RuntimeException("Oops: Unhandled : " + type.getType());
}
- } else {
- addAttribute(attrs[i]);
- }
- }
- }
-
- private void setValue(int index) {
- ConstantPool cp = this.cp;
- Constant c = cp.getConstant(index);
- value = ((ConstantObject)c).getConstantValue(cp);
- }
-
-
- public void wipeValue() {
- value = null;
- }
-
- private void checkType(Type atype) {
- if(type == null)
- throw new ClassGenException("You haven't defined the type of the field yet");
-
- if(!isFinal())
- throw new ClassGenException("Only final fields may have an initial value!");
-
- if(!type.equals(atype))
- throw new ClassGenException("Types are not compatible: " + type + " vs. " + atype);
- }
-
- /**
- * Get field object after having set up all necessary values.
- */
- public Field getField() {
- String signature = getSignature();
- int name_index = cp.addUtf8(name);
- int signature_index = cp.addUtf8(signature);
-
- if(value != null) {
- checkType(type);
- int index = addConstant();
- addAttribute(new ConstantValue(cp.addUtf8("ConstantValue"),
- 2, index, cp));
- }
-
- addAnnotationsAsAttribute(cp);
-
- return new Field(modifiers, name_index, signature_index, getAttributesImmutable(), cp);
- }
-
- private int addConstant() {
- switch(type.getType()) {
- case Constants.T_INT: case Constants.T_CHAR: case Constants.T_BYTE:
- case Constants.T_BOOLEAN: case Constants.T_SHORT:
- return cp.addInteger(((Integer)value).intValue());
-
- case Constants.T_FLOAT:
- return cp.addFloat(((Float)value).floatValue());
-
- case Constants.T_DOUBLE:
- return cp.addDouble(((Double)value).doubleValue());
-
- case Constants.T_LONG:
- return cp.addLong(((Long)value).longValue());
-
- case Constants.T_REFERENCE:
- return cp.addString(((String)value));
-
- default:
- throw new RuntimeException("Oops: Unhandled : " + type.getType());
- }
- }
-
- public String getSignature() { return type.getSignature(); }
-
-
- public String getInitialValue() {
- if(value != null) {
- return value.toString();
- } else
- return null;
- }
-
- /**
- * Return string representation close to declaration format,
- * `public static final short MAX = 100', e.g..
- *
- * @return String representation of field
- */
- public final String toString() {
- String name, signature, access; // Short cuts to constant pool
-
- access = Utility.accessToString(modifiers);
- access = access.equals("")? "" : (access + " ");
- signature = type.toString();
- name = getName();
-
- StringBuffer buf = new StringBuffer(access + signature + " " + name);
- String value = getInitialValue();
-
- if(value != null)
- buf.append(" = " + value);
-
-
- // TODO: Add attributes and annotations to the string
-
- return buf.toString();
- }
-
- /** @return deep copy of this field
- */
- public FieldGen copy(ConstantPool cp) {
- FieldGen fg = (FieldGen)clone();
-
- fg.setConstantPool(cp);
- return fg;
- }
+ }
+
+ @Override
+ public String getSignature() {
+ return type.getSignature();
+ }
+
+ public String getInitialValue() {
+ if (value != null) {
+ return value.toString();
+ } else
+ return null;
+ }
+
+ /**
+ * Return string representation close to declaration format, `public static final short MAX = 100', e.g..
+ *
+ * @return String representation of field
+ */
+ @Override
+ public final String toString() {
+ String name, signature, access; // Short cuts to constant pool
+
+ access = Utility.accessToString(modifiers);
+ access = access.equals("") ? "" : (access + " ");
+ signature = type.toString();
+ name = getName();
+
+ StringBuffer buf = new StringBuffer(access + signature + " " + name);
+ String value = getInitialValue();
+
+ if (value != null)
+ buf.append(" = " + value);
+
+ // TODO: Add attributes and annotations to the string
+
+ return buf.toString();
+ }
+
+ /**
+ * @return deep copy of this field
+ */
+ public FieldGen copy(ConstantPool cp) {
+ FieldGen fg = (FieldGen) clone();
+
+ fg.setConstantPool(cp);
+ return fg;
+ }
}
package org.aspectj.apache.bcel.generic;
/**
- * A tag is an instruction-targeter that does not remember its target
+ * A tag is an instruction-targeter that does not remember its target. Instruction handles will maintain a list of targeters but
+ * there won't be a way to get back from the tag to the instruction. Maintaining these backward/forward links just slows everything
+ * down.
*/
public abstract class Tag implements InstructionTargeter, Cloneable {
- public Tag() {
- }
+ public Tag() {
+ }
- // ---- from InstructionTargeter
- public boolean containsTarget(InstructionHandle ih) {
- return false;
- }
+ // ---- from InstructionTargeter
+ public boolean containsTarget(InstructionHandle ih) {
+ return false;
+ }
- public void updateTarget(InstructionHandle oldHandle, InstructionHandle newHandle) {
- oldHandle.removeTargeter(this);
- if (newHandle != null) {
- newHandle.addTargeter(this);
- }
- }
-
- public Tag copy() {
- try {
- return (Tag)clone();
- } catch (CloneNotSupportedException e) {
- throw new RuntimeException("Sanity check, can't clone me");
- }
- }
+ public void updateTarget(InstructionHandle oldHandle, InstructionHandle newHandle) {
+ oldHandle.removeTargeter(this);
+ if (newHandle != null) {
+ newHandle.addTargeter(this);
+ }
+ }
+
+ public Tag copy() {
+ try {
+ return (Tag) clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException("Sanity check, can't clone me");
+ }
+ }
}