diff options
author | aclement <aclement> | 2009-09-09 21:26:54 +0000 |
---|---|---|
committer | aclement <aclement> | 2009-09-09 21:26:54 +0000 |
commit | 40de2e7d33e9b0ff18760e996cfe8efaf0614e54 (patch) | |
tree | ccbcbda7841acf1249ce7dc9c968bec06be9bd43 /bcel-builder | |
parent | f3c1fd6938cb0857e491d6bf8812204dae60c3b1 (diff) | |
download | aspectj-40de2e7d33e9b0ff18760e996cfe8efaf0614e54.tar.gz aspectj-40de2e7d33e9b0ff18760e996cfe8efaf0614e54.zip |
refactoring
Diffstat (limited to 'bcel-builder')
8 files changed, 791 insertions, 1026 deletions
diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java index 234bb0326..2c385c964 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/Attribute.java @@ -54,142 +54,162 @@ package org.aspectj.apache.bcel.classfile; * <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); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java index f38f31633..4841b9b51 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java @@ -53,155 +53,165 @@ package org.aspectj.apache.bcel.classfile; * 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; + } + } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/JavaClass.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/JavaClass.java index d0b94928b..ac3fae655 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/JavaClass.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/JavaClass.java @@ -79,38 +79,34 @@ import org.aspectj.apache.bcel.util.SyntheticRepository; * 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; @@ -119,8 +115,6 @@ public class JavaClass extends Modifiers implements Cloneable, Node { 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. */ @@ -157,13 +151,13 @@ public class JavaClass extends Modifiers implements Cloneable, Node { 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; @@ -172,36 +166,36 @@ public class JavaClass extends Modifiers implements Cloneable, Node { // 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); } } } @@ -216,15 +210,6 @@ public class JavaClass extends Modifiers implements Cloneable, Node { 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. * @@ -293,11 +278,11 @@ public class JavaClass extends Modifiers implements Cloneable, Node { 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++) { @@ -347,28 +332,28 @@ public class JavaClass extends Modifiers implements Cloneable, Node { * @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; } /** @@ -383,14 +368,14 @@ public class JavaClass extends Modifiers implements Cloneable, Node { * @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; } /** @@ -463,40 +448,21 @@ public class JavaClass extends Modifiers implements Cloneable, Node { * @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; } /** @@ -511,21 +477,21 @@ public class JavaClass extends Modifiers implements Cloneable, Node { * @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; } /** @@ -539,14 +505,14 @@ public class JavaClass extends Modifiers implements Cloneable, Node { * 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; } /** @@ -581,21 +547,21 @@ public class JavaClass extends Modifiers implements Cloneable, Node { * 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; } /** @@ -606,15 +572,15 @@ public class JavaClass extends Modifiers implements Cloneable, Node { 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(", "); } @@ -623,11 +589,11 @@ public class JavaClass extends Modifiers implements Cloneable, Node { 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) { @@ -683,21 +649,21 @@ public class JavaClass extends Modifiers implements Cloneable, Node { } 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 @@ -734,7 +700,7 @@ public class JavaClass extends Modifiers implements Cloneable, Node { 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())) { diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumber.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumber.java index 81b3b4f49..6b2a64877 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumber.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumber.java @@ -57,110 +57,64 @@ package org.aspectj.apache.bcel.classfile; 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); + } } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumberTable.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumberTable.java index 46c406917..83a9f7110 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumberTable.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/LineNumberTable.java @@ -54,223 +54,224 @@ package org.aspectj.apache.bcel.classfile; * <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; + } } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/classfile/PMGClass.java b/bcel-builder/src/org/aspectj/apache/bcel/classfile/PMGClass.java deleted file mode 100644 index 004043852..000000000 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/PMGClass.java +++ /dev/null @@ -1,189 +0,0 @@ -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(); - } -} diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java index 20c5af83f..07f276b12 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java @@ -68,169 +68,170 @@ import org.aspectj.apache.bcel.classfile.Utility; 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; + } } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java index 15b39473a..1d6935e6d 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/Tag.java @@ -14,30 +14,32 @@ 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"); + } + } } |