From f51bf240ff8a1744d34ff77b2e8c63071fce2ea1 Mon Sep 17 00:00:00 2001 From: aclement Date: Thu, 10 Mar 2005 12:15:04 +0000 Subject: [PATCH] Declare annotation: infrastructure upgrade. Mainly to ensure we copy entries between constant pools correctly - required when annotations move from one class to another (as is typical with declare annotation) --- .../apache/bcel/classfile/FieldOrMethod.java | 18 ++++++++-- .../aspectj/apache/bcel/generic/ClassGen.java | 6 ++-- .../aspectj/apache/bcel/generic/FieldGen.java | 4 +-- .../apache/bcel/generic/MethodGen.java | 6 ++-- .../annotation/AnnotationElementValueGen.java | 4 +-- .../generic/annotation/AnnotationGen.java | 22 ++++++++----- .../annotation/ArrayElementValueGen.java | 4 +-- .../annotation/ClassElementValueGen.java | 22 +++++++++---- .../annotation/ElementNameValuePairGen.java | 13 ++++++-- .../generic/annotation/ElementValueGen.java | 12 +++---- .../annotation/EnumElementValueGen.java | 21 ++++++++---- .../annotation/SimpleElementValueGen.java | 33 ++++++++++++++++--- 12 files changed, 116 insertions(+), 49 deletions(-) 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 647c2211a..2780e7c44 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/classfile/FieldOrMethod.java @@ -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 M. Dahm */ 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; + } } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGen.java index a4fd19d13..bec436bf6 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/ClassGen.java @@ -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 M. Dahm */ 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)); } } } 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 af579c4ff..71e453dfd 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/FieldGen.java @@ -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 M. Dahm * @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]); diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java index 5b66be328..6f021e024 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/MethodGen.java @@ -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 M. Dahm * @author Patrick C. Beard [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; } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/AnnotationElementValueGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/AnnotationElementValueGen.java index 0ddee226f..ad7a08de9 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/AnnotationElementValueGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/AnnotationElementValueGen.java @@ -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 { diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/AnnotationGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/AnnotationGen.java index 94236bc36..d017668fb 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/AnnotationGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/AnnotationGen.java @@ -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; } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ArrayElementValueGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ArrayElementValueGen.java index f5b176437..3fb54096c 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ArrayElementValueGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ArrayElementValueGen.java @@ -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)); } } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ClassElementValueGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ClassElementValueGen.java index 051d2d8df..5241fd353 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ClassElementValueGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ClassElementValueGen.java @@ -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() { diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ElementNameValuePairGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ElementNameValuePairGen.java index 23b84e6b7..d64ad0d72 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ElementNameValuePairGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ElementNameValuePairGen.java @@ -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); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ElementValueGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ElementValueGen.java index 054e1cbf8..386320c75 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ElementValueGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/ElementValueGen.java @@ -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()+")"); diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/EnumElementValueGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/EnumElementValueGen.java index f30283601..2f66ac8fd 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/EnumElementValueGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/EnumElementValueGen.java @@ -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(); } diff --git a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/SimpleElementValueGen.java b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/SimpleElementValueGen.java index 49e5c57d2..d36abe648 100644 --- a/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/SimpleElementValueGen.java +++ b/bcel-builder/src/org/aspectj/apache/bcel/generic/annotation/SimpleElementValueGen.java @@ -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() { -- 2.39.5