@@ -64,7 +64,7 @@ import java.util.List; | |||
/** | |||
* Abstract super class for fields and methods. | |||
* | |||
* @version $Id: FieldOrMethod.java,v 1.2 2004/11/19 16:45:18 aclement Exp $ | |||
* @version $Id: FieldOrMethod.java,v 1.3 2005/03/10 12:15:04 aclement Exp $ | |||
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> | |||
*/ | |||
public abstract class FieldOrMethod extends AccessFlags implements Cloneable, Node { | |||
@@ -231,12 +231,13 @@ public abstract class FieldOrMethod extends AccessFlags implements Cloneable, No | |||
return c; | |||
} | |||
/** | |||
* Ensure we have unpacked any attributes that contain annotations. | |||
* We don't remove these annotation attributes from the attributes list, they | |||
* remain there. | |||
*/ | |||
public Annotation[] getAnnotations() { | |||
private void ensureAnnotationsUpToDate() { | |||
if (annotationsOutOfDate) { | |||
// Find attributes that contain annotation data | |||
Attribute[] attrs = getAttributes(); | |||
@@ -251,6 +252,19 @@ public abstract class FieldOrMethod extends AccessFlags implements Cloneable, No | |||
annotations = (Annotation[])accumulatedAnnotations.toArray(new Annotation[]{}); | |||
annotationsOutOfDate = false; | |||
} | |||
} | |||
public Annotation[] getAnnotations() { | |||
ensureAnnotationsUpToDate(); | |||
return annotations; | |||
} | |||
public void addAnnotation(Annotation a) { | |||
ensureAnnotationsUpToDate(); | |||
int len = annotations.length; | |||
Annotation[] newAnnotations = new Annotation[len+1]; | |||
System.arraycopy(annotations, 0, newAnnotations, 0, len); | |||
newAnnotations[len] = a; | |||
annotations = newAnnotations; | |||
} | |||
} |
@@ -77,7 +77,7 @@ import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
* existing java class (file). | |||
* | |||
* @see JavaClass | |||
* @version $Id: ClassGen.java,v 1.4 2004/12/09 15:19:39 aclement Exp $ | |||
* @version $Id: ClassGen.java,v 1.5 2005/03/10 12:15:04 aclement Exp $ | |||
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> | |||
*/ | |||
public class ClassGen extends AccessFlags implements Cloneable { | |||
@@ -199,14 +199,14 @@ public class ClassGen extends AccessFlags implements Cloneable { | |||
List annos = rva.getAnnotations(); | |||
for (Iterator iter = annos.iterator(); iter.hasNext();) { | |||
Annotation a = (Annotation) iter.next(); | |||
annotationGenObjs.add(new AnnotationGen(a,getConstantPool())); | |||
annotationGenObjs.add(new AnnotationGen(a,getConstantPool(),false)); | |||
} | |||
} else if (attr instanceof RuntimeInvisibleAnnotations) { | |||
RuntimeInvisibleAnnotations ria = (RuntimeInvisibleAnnotations)attr; | |||
List annos = ria.getAnnotations(); | |||
for (Iterator iter = annos.iterator(); iter.hasNext();) { | |||
Annotation a = (Annotation) iter.next(); | |||
annotationGenObjs.add(new AnnotationGen(a,getConstantPool())); | |||
annotationGenObjs.add(new AnnotationGen(a,getConstantPool(),false)); | |||
} | |||
} | |||
} |
@@ -75,7 +75,7 @@ import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
* one can do is to add a constant value attribute to a field (which must of | |||
* course be compatible with to the declared type). | |||
* | |||
* @version $Id: FieldGen.java,v 1.3 2004/11/22 08:31:27 aclement Exp $ | |||
* @version $Id: FieldGen.java,v 1.4 2005/03/10 12:15:04 aclement Exp $ | |||
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> | |||
* @see Field | |||
*/ | |||
@@ -118,7 +118,7 @@ public class FieldGen extends FieldGenOrMethodGen { | |||
List l = runtimeAnnotations.getAnnotations(); | |||
for (Iterator it = l.iterator(); it.hasNext();) { | |||
Annotation element = (Annotation) it.next(); | |||
addAnnotation(new AnnotationGen(element,cp)); | |||
addAnnotation(new AnnotationGen(element,cp,false)); | |||
} | |||
} else { | |||
addAttribute(attrs[i]); |
@@ -86,7 +86,7 @@ import org.aspectj.apache.bcel.generic.annotation.AnnotationGen; | |||
* use the `removeNOPs' method to get rid off them. | |||
* The resulting method object can be obtained via the `getMethod()' method. | |||
* | |||
* @version $Id: MethodGen.java,v 1.3 2005/01/26 14:01:30 aclement Exp $ | |||
* @version $Id: MethodGen.java,v 1.4 2005/03/10 12:15:04 aclement Exp $ | |||
* @author <A HREF="mailto:markus.dahm@berlin.de">M. Dahm</A> | |||
* @author <A HREF="http://www.vmeng.com/beard">Patrick C. Beard</A> [setMaxStack()] | |||
* @see InstructionList | |||
@@ -288,7 +288,7 @@ public class MethodGen extends FieldGenOrMethodGen { | |||
List l = runtimeAnnotations.getAnnotations(); | |||
for (Iterator it = l.iterator(); it.hasNext();) { | |||
Annotation element = (Annotation) it.next(); | |||
addAnnotation(new AnnotationGen(element,cp)); | |||
addAnnotation(new AnnotationGen(element,cp,false)); | |||
} | |||
} else { | |||
addAttribute(a); | |||
@@ -1085,7 +1085,7 @@ public class MethodGen extends FieldGenOrMethodGen { | |||
private List /*AnnotationGen*/ makeMutableVersion(Annotation[] mutableArray) { | |||
List result = new ArrayList(); | |||
for (int i = 0; i < mutableArray.length; i++) { | |||
result.add(new AnnotationGen(mutableArray[i],getConstantPool())); | |||
result.add(new AnnotationGen(mutableArray[i],getConstantPool(),false)); | |||
} | |||
return result; | |||
} |
@@ -36,9 +36,9 @@ public class AnnotationElementValueGen extends ElementValueGen { | |||
this.a = annotation; | |||
} | |||
public AnnotationElementValueGen(AnnotationElementValue value, ConstantPoolGen cpool) { | |||
public AnnotationElementValueGen(AnnotationElementValue value, ConstantPoolGen cpool,boolean copyPoolEntries) { | |||
super(ANNOTATION,cpool); | |||
a = new AnnotationGen(value.getAnnotation(),cpool); | |||
a = new AnnotationGen(value.getAnnotation(),cpool,copyPoolEntries); | |||
} | |||
public void dump(DataOutputStream dos) throws IOException { |
@@ -33,25 +33,31 @@ public class AnnotationGen { | |||
/** | |||
* Here we are taking a fixed annotation of type Annotation and building a | |||
* modifiable AnnotationGen object. The ConstantPool entries should already | |||
* be correct, we could assert that ... | |||
* modifiable AnnotationGen object. If the pool passed in is for a different | |||
* class file, then copyPoolEntries should have been passed as true as that | |||
* will force us to do a deep copy of the annotation and move the cpool entries | |||
* across. | |||
* We need to copy the type and the element name value pairs and the visibility. | |||
*/ | |||
public AnnotationGen(Annotation a,ConstantPoolGen cpool) { | |||
public AnnotationGen(Annotation a,ConstantPoolGen cpool,boolean copyPoolEntries) { | |||
this.cpool = cpool; | |||
// Could assert a.getTypeSignature() == (ConstantUtf8)cpool.getConstant(a.getTypeIndex())).getBytes() | |||
typeIndex = a.getTypeIndex(); | |||
if (copyPoolEntries) { | |||
typeIndex = cpool.addUtf8(a.getTypeSignature()); | |||
} else { | |||
typeIndex = a.getTypeIndex(); | |||
} | |||
isRuntimeVisible = a.isRuntimeVisible(); | |||
evs = copyValues(a.getValues(),cpool); | |||
evs = copyValues(a.getValues(),cpool,copyPoolEntries); | |||
} | |||
private List copyValues(List in,ConstantPoolGen cpool) { | |||
private List copyValues(List in,ConstantPoolGen cpool,boolean copyPoolEntries) { | |||
List out = new ArrayList(); | |||
for (Iterator iter = in.iterator(); iter.hasNext();) { | |||
ElementNameValuePair nvp = (ElementNameValuePair) iter.next(); | |||
out.add(new ElementNameValuePairGen(nvp,cpool)); | |||
out.add(new ElementNameValuePairGen(nvp,cpool,copyPoolEntries)); | |||
} | |||
return out; | |||
} |
@@ -47,12 +47,12 @@ public class ArrayElementValueGen extends ElementValueGen { | |||
* @param value | |||
* @param cpool | |||
*/ | |||
public ArrayElementValueGen(ArrayElementValue value, ConstantPoolGen cpool) { | |||
public ArrayElementValueGen(ArrayElementValue value, ConstantPoolGen cpool,boolean copyPoolEntries) { | |||
super(ARRAY,cpool); | |||
evalues = new ArrayList(); | |||
ElementValue[] in = value.getElementValuesArray(); | |||
for (int i = 0; i < in.length; i++) { | |||
evalues.add(ElementValueGen.copy(in[i],cpool)); | |||
evalues.add(ElementValueGen.copy(in[i],cpool,copyPoolEntries)); | |||
} | |||
} | |||
@@ -15,7 +15,6 @@ package org.aspectj.apache.bcel.generic.annotation; | |||
import java.io.DataOutputStream; | |||
import java.io.IOException; | |||
import org.aspectj.apache.bcel.classfile.ConstantClass; | |||
import org.aspectj.apache.bcel.classfile.ConstantUtf8; | |||
import org.aspectj.apache.bcel.classfile.annotation.ClassElementValue; | |||
import org.aspectj.apache.bcel.generic.ConstantPoolGen; | |||
@@ -35,12 +34,19 @@ public class ClassElementValueGen extends ElementValueGen { | |||
public ClassElementValueGen(ObjectType t,ConstantPoolGen cpool) { | |||
super(ElementValueGen.CLASS,cpool); | |||
this.idx = cpool.addClass(t); | |||
//this.idx = cpool.addClass(t); | |||
idx = cpool.addUtf8(t.getSignature()); | |||
} | |||
public ClassElementValueGen(ClassElementValue value, ConstantPoolGen cpool) { | |||
public ClassElementValueGen(ClassElementValue value, ConstantPoolGen cpool,boolean copyPoolEntries) { | |||
super(CLASS,cpool); | |||
idx = value.getIndex(); | |||
if (copyPoolEntries) { | |||
//idx = cpool.addClass(value.getClassString()); | |||
idx = cpool.addUtf8(value.getClassString()); | |||
} else { | |||
idx = value.getIndex(); | |||
} | |||
} | |||
public int getIndex() { | |||
@@ -48,9 +54,11 @@ public class ClassElementValueGen extends ElementValueGen { | |||
} | |||
public String getClassString() { | |||
ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx); | |||
ConstantUtf8 utf8 = (ConstantUtf8)getConstantPool().getConstant(c.getNameIndex()); | |||
return utf8.getBytes(); | |||
ConstantUtf8 cu8 = (ConstantUtf8)getConstantPool().getConstant(idx); | |||
return cu8.getBytes(); | |||
// ConstantClass c = (ConstantClass)getConstantPool().getConstant(idx); | |||
// ConstantUtf8 utf8 = (ConstantUtf8)getConstantPool().getConstant(c.getNameIndex()); | |||
// return utf8.getBytes(); | |||
} | |||
public String stringifyValue() { |
@@ -25,12 +25,19 @@ public class ElementNameValuePairGen { | |||
private ElementValueGen value; | |||
private ConstantPoolGen cpool; | |||
public ElementNameValuePairGen(ElementNameValuePair nvp, ConstantPoolGen cpool) { | |||
public ElementNameValuePairGen(ElementNameValuePair nvp, ConstantPoolGen cpool, boolean copyPoolEntries) { | |||
this.cpool = cpool; | |||
// J5ASSERT: | |||
// Could assert nvp.getNameString() points to the same thing as cpool.getConstant(nvp.getNameIndex()) | |||
nameIdx = nvp.getNameIndex(); | |||
value = ElementValueGen.copy(nvp.getValue(),cpool); | |||
// if (!nvp.getNameString().equals(((ConstantUtf8)cpool.getConstant(nvp.getNameIndex())).getBytes())) { | |||
// throw new RuntimeException("envp buggered"); | |||
// } | |||
if (copyPoolEntries) { | |||
nameIdx = cpool.addUtf8(nvp.getNameString()); | |||
} else { | |||
nameIdx = nvp.getNameIndex(); | |||
} | |||
value = ElementValueGen.copy(nvp.getValue(),cpool,copyPoolEntries); | |||
} | |||
@@ -109,7 +109,7 @@ public abstract class ElementValueGen { | |||
/** | |||
* Creates an (modifiable) ElementValueGen copy of an (immutable) ElementValue - constant pool is assumed correct. | |||
*/ | |||
public static ElementValueGen copy(ElementValue value,ConstantPoolGen cpool) { | |||
public static ElementValueGen copy(ElementValue value,ConstantPoolGen cpool,boolean copyPoolEntries) { | |||
switch (value.getElementValueType()) { | |||
case 'B': // byte | |||
case 'C': // char | |||
@@ -120,19 +120,19 @@ public abstract class ElementValueGen { | |||
case 'S': // short | |||
case 'Z': // boolean | |||
case 's': // String | |||
return new SimpleElementValueGen((SimpleElementValue)value,cpool); | |||
return new SimpleElementValueGen((SimpleElementValue)value,cpool,copyPoolEntries); | |||
case 'e': // Enum constant | |||
return new EnumElementValueGen((EnumElementValue)value,cpool); | |||
return new EnumElementValueGen((EnumElementValue)value,cpool,copyPoolEntries); | |||
case '@': // Annotation | |||
return new AnnotationElementValueGen((AnnotationElementValue)value,cpool); | |||
return new AnnotationElementValueGen((AnnotationElementValue)value,cpool,copyPoolEntries); | |||
case '[': // Array | |||
return new ArrayElementValueGen((ArrayElementValue)value,cpool); | |||
return new ArrayElementValueGen((ArrayElementValue)value,cpool,copyPoolEntries); | |||
case 'c': // Class | |||
return new ClassElementValueGen((ClassElementValue)value,cpool); | |||
return new ClassElementValueGen((ClassElementValue)value,cpool,copyPoolEntries); | |||
default: | |||
throw new RuntimeException("Not implemented yet! ("+value.getElementValueType()+")"); |
@@ -43,14 +43,19 @@ public class EnumElementValueGen extends ElementValueGen { | |||
public EnumElementValueGen(ObjectType t,String value,ConstantPoolGen cpool) { | |||
super(ElementValueGen.ENUM_CONSTANT,cpool); | |||
typeIdx = cpool.addClass(t); | |||
valueIdx= cpool.addString(value); | |||
typeIdx = cpool.addUtf8(t.getSignature());// was addClass(t); | |||
valueIdx= cpool.addUtf8(value);// was addString(value); | |||
} | |||
public EnumElementValueGen(EnumElementValue value, ConstantPoolGen cpool) { | |||
public EnumElementValueGen(EnumElementValue value, ConstantPoolGen cpool, boolean copyPoolEntries) { | |||
super(ENUM_CONSTANT,cpool); | |||
typeIdx = value.getTypeIndex(); | |||
valueIdx = value.getValueIndex(); | |||
if (copyPoolEntries) { | |||
typeIdx = cpool.addUtf8(value.getEnumTypeString());// was addClass(value.getEnumTypeString()); | |||
valueIdx = cpool.addUtf8(value.getEnumValueString()); // was addString(value.getEnumValueString()); | |||
} else { | |||
typeIdx = value.getTypeIndex(); | |||
valueIdx = value.getValueIndex(); | |||
} | |||
} | |||
public void dump(DataOutputStream dos) throws IOException { | |||
@@ -60,8 +65,10 @@ public class EnumElementValueGen extends ElementValueGen { | |||
} | |||
public String stringifyValue() { | |||
ConstantString cu8 = (ConstantString)getConstantPool().getConstant(valueIdx); | |||
return ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); | |||
ConstantUtf8 cu8 = (ConstantUtf8)getConstantPool().getConstant(valueIdx); | |||
return cu8.getBytes(); | |||
// ConstantString cu8 = (ConstantString)getConstantPool().getConstant(valueIdx); | |||
// return ((ConstantUtf8)getConstantPool().getConstant(cu8.getStringIndex())).getBytes(); | |||
} | |||
@@ -89,11 +89,36 @@ public class SimpleElementValueGen extends ElementValueGen { | |||
idx = cpGen.addUtf8(value); | |||
} | |||
public SimpleElementValueGen(SimpleElementValue value,ConstantPoolGen cpool) { | |||
/** | |||
* The boolean controls whether we copy info from the 'old' constant pool | |||
* to the 'new'. You need to use this ctor if the annotation is | |||
* being copied from one file to another. | |||
*/ | |||
public SimpleElementValueGen(SimpleElementValue value,ConstantPoolGen cpool,boolean copyPoolEntries) { | |||
super(value.getElementValueType(),cpool); | |||
// J5ASSERT: Could assert value.stringifyValue() is the same as | |||
// cpool.getConstant(SimpleElementValuevalue.getIndex()) | |||
idx = value.getIndex(); | |||
if (!copyPoolEntries) { | |||
// J5ASSERT: Could assert value.stringifyValue() is the same as | |||
// cpool.getConstant(SimpleElementValuevalue.getIndex()) | |||
idx = value.getIndex(); | |||
} else { | |||
switch (value.getElementValueType()) { | |||
case STRING: idx = cpool.addUtf8(value.getValueString()); break; | |||
case PRIMITIVE_INT: idx = cpool.addInteger(value.getValueInt()); break; | |||
case PRIMITIVE_BYTE: idx = cpool.addInteger(value.getValueByte()); break; | |||
case PRIMITIVE_CHAR: idx = cpool.addInteger(value.getValueChar()); break; | |||
case PRIMITIVE_LONG: idx = cpool.addLong(value.getValueLong()); break; | |||
case PRIMITIVE_FLOAT: idx = cpool.addFloat(value.getValueFloat());break; | |||
case PRIMITIVE_DOUBLE:idx = cpool.addDouble(value.getValueDouble());break; | |||
case PRIMITIVE_BOOLEAN: | |||
if (value.getValueBoolean()) { idx = cpool.addInteger(1); | |||
} else { idx = cpool.addInteger(0);} | |||
break; | |||
case PRIMITIVE_SHORT: idx = cpool.addInteger(value.getValueShort());break; | |||
default: | |||
throw new RuntimeException("SimpleElementValueGen class does not know how "+ | |||
"to copy this type "+type); | |||
} | |||
} | |||
} | |||
public int getIndex() { |