]> source.dussan.org Git - aspectj.git/commitdiff
optimizationasm: the asm visitors and actual delegate classes
authoraclement <aclement>
Wed, 22 Feb 2006 15:04:01 +0000 (15:04 +0000)
committeraclement <aclement>
Wed, 22 Feb 2006 15:04:01 +0000 (15:04 +0000)
weaver/src/org/aspectj/weaver/asm/AjASMAttribute.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/AnnVisitor.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/ArrayAnnotationVisitor.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/AsmConstants.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/AsmDelegate.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/AsmField.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/AsmMethod.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/EmptyVisitor.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/FdVisitor.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/MethVisitor.java [new file with mode: 0644]
weaver/src/org/aspectj/weaver/asm/TypeVisitor.java [new file with mode: 0644]

diff --git a/weaver/src/org/aspectj/weaver/asm/AjASMAttribute.java b/weaver/src/org/aspectj/weaver/asm/AjASMAttribute.java
new file mode 100644 (file)
index 0000000..2a13514
--- /dev/null
@@ -0,0 +1,66 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.BCException;
+import org.aspectj.org.objectweb.asm.Attribute;
+import org.aspectj.org.objectweb.asm.ByteVector;
+import org.aspectj.org.objectweb.asm.ClassReader;
+import org.aspectj.org.objectweb.asm.ClassWriter;
+import org.aspectj.org.objectweb.asm.Label;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+class AjASMAttribute extends Attribute {
+       
+       private boolean unpacked = false;
+       private byte[] data;
+       
+       protected AjASMAttribute(String type) {
+               super(type);
+       }
+       
+       protected AjASMAttribute(String type,byte[] data) {
+               super(type);
+               this.data=data;
+       }
+
+       /** 
+        * Initial read of the attribute is super lightweight - no unpacking
+        */
+    protected Attribute read(ClassReader cr, int off, int len, char[] buf,
+                     int codeOff, Label[] labels) {
+             byte[] data = new byte[len];
+             System.arraycopy(cr.b, off, data, 0, len);
+             return new AjASMAttribute(this.type, data);
+    }
+
+    /**
+     * These attributes are read only, an attempt to write them violates this fundamental assumption.
+     */
+    protected ByteVector write(ClassWriter cw, byte[] code, int len, int maxStack, int maxLocals) {
+       throw new NotImplementedException();// "Attempt to write out the AjASMAttribute for "+this.type);
+        // return new ByteVector().putByteArray(data, 0, data.length);
+    }
+     
+        public boolean isUnknown() { return false; }
+        
+        // ---
+        
+        public AjAttribute unpack(AsmDelegate relatedDelegate) {
+                if (unpacked) throw new BCException("Don't unpack an attribute twice!");
+                AjAttribute attr = AjAttribute.read(relatedDelegate.weaverVersion,type,data,relatedDelegate.getSourceContext(),relatedDelegate.getWorld().getMessageHandler());
+                unpacked=true;
+                return attr;
+        }
+}
\ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/asm/AnnVisitor.java b/weaver/src/org/aspectj/weaver/asm/AnnVisitor.java
new file mode 100644 (file)
index 0000000..e27a6dd
--- /dev/null
@@ -0,0 +1,80 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import org.aspectj.weaver.AnnotationAJ;
+import org.aspectj.weaver.AnnotationAnnotationValue;
+import org.aspectj.weaver.AnnotationNameValuePair;
+import org.aspectj.weaver.AnnotationValue;
+import org.aspectj.weaver.ArrayAnnotationValue;
+import org.aspectj.weaver.ClassAnnotationValue;
+import org.aspectj.weaver.EnumAnnotationValue;
+import org.aspectj.weaver.SimpleAnnotationValue;
+import org.aspectj.org.objectweb.asm.AnnotationVisitor;
+import org.aspectj.org.objectweb.asm.Type;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+/**
+ * Constructed with an annotation to 'fill in' with the values we encounter whilst visting it.
+ */
+class AnnVisitor implements AnnotationVisitor {
+  private AnnotationAJ a;
+
+  public AnnVisitor(AnnotationAJ annotationToPopulate) {
+         a = annotationToPopulate;
+  }
+
+  public void visitEnum(String name, String type, String value) {
+         AnnotationValue val = new EnumAnnotationValue(type,value);
+         a.addNameValuePair(new AnnotationNameValuePair(name,val));
+  }
+    
+  public void visit(String name, Object value) {
+         AnnotationValue val = null;
+         if (value instanceof Integer) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_INT,value);
+         if (value instanceof Boolean) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_BOOLEAN,value);
+         if (value instanceof Long) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_LONG,value);
+         if (value instanceof Short) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_SHORT,value);
+         if (value instanceof Double) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_DOUBLE,value);
+         if (value instanceof Float) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_FLOAT,value);
+         if (value instanceof Character) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_CHAR,value);
+         if (value instanceof Byte) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_BYTE,value);
+         if (value instanceof String) val = new SimpleAnnotationValue(AnnotationValue.STRING,value); 
+
+         if (val==null && value instanceof Type) {
+                String classSignature = ((Type)value).getDescriptor();
+                val = new ClassAnnotationValue(classSignature);
+         }
+         if (val!=null) {
+                 a.addNameValuePair(new AnnotationNameValuePair(name,val));
+         } else {
+                 System.err.println("Choking on "+name+" = "+value);
+                 throw new NotImplementedException();
+         }
+  }
+
+  public AnnotationVisitor visitAnnotation(String name, String desc) {
+         AnnotationAJ annotation = new AnnotationAJ(desc,a.isRuntimeVisible());
+         AnnotationValue val = new AnnotationAnnotationValue(annotation);
+         a.addNameValuePair(new AnnotationNameValuePair(name,val));
+         return new AnnVisitor(annotation);
+  }
+
+  public AnnotationVisitor visitArray(String name) {
+         ArrayAnnotationValue val = new ArrayAnnotationValue();
+         a.addNameValuePair(new AnnotationNameValuePair(name,val));
+         return new ArrayAnnotationVisitor(val,a.isRuntimeVisible());
+  }
+    
+  public void visitEnd() {}
+}
\ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/asm/ArrayAnnotationVisitor.java b/weaver/src/org/aspectj/weaver/asm/ArrayAnnotationVisitor.java
new file mode 100644 (file)
index 0000000..4f0a3a5
--- /dev/null
@@ -0,0 +1,77 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.aspectj.weaver.AnnotationAJ;
+import org.aspectj.weaver.AnnotationAnnotationValue;
+import org.aspectj.weaver.AnnotationValue;
+import org.aspectj.weaver.ArrayAnnotationValue;
+import org.aspectj.weaver.ClassAnnotationValue;
+import org.aspectj.weaver.EnumAnnotationValue;
+import org.aspectj.weaver.SimpleAnnotationValue;
+import org.aspectj.org.objectweb.asm.AnnotationVisitor;
+import org.aspectj.org.objectweb.asm.Type;
+
+import sun.reflect.generics.reflectiveObjects.NotImplementedException;
+
+class ArrayAnnotationVisitor implements AnnotationVisitor {
+       List arrayValues = new ArrayList();
+       boolean vis;
+       ArrayAnnotationValue val;
+       
+       public ArrayAnnotationVisitor(ArrayAnnotationValue val,boolean visibility) {this.val = val;this.vis = visibility;}
+       
+       public void visit(String name, Object value) {
+                 AnnotationValue val = null;
+                 if (value instanceof Integer) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_INT,value);
+                 if (value instanceof Boolean) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_BOOLEAN,value);
+                 if (value instanceof String) val = new SimpleAnnotationValue(AnnotationValue.STRING,value); 
+                 if (value instanceof Long) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_LONG,value);
+                 if (value instanceof Short) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_SHORT,value);
+                 if (value instanceof Double) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_DOUBLE,value);
+                 if (value instanceof Float) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_FLOAT,value);
+                 if (value instanceof Character) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_CHAR,value);
+                 if (value instanceof Byte) val = new SimpleAnnotationValue(AnnotationValue.PRIMITIVE_BYTE,value);
+                 if (val==null && value instanceof Type) {
+                       String classSignature = ((Type)value).getDescriptor();
+                   val = new ClassAnnotationValue(classSignature);
+                 }                       
+                 if (val!=null) {
+                         arrayValues.add(val);
+                 } else {
+                         System.err.println("Choking on "+name+" = "+value);
+                         throw new NotImplementedException();
+                 }
+         }
+       
+    public void visitEnum(String name, String type, String value) {
+         AnnotationValue val = new EnumAnnotationValue(type,value);
+         arrayValues.add(val);//new AnnotationNameValuePair(name,val));
+    }
+    public AnnotationVisitor visitAnnotation(String name, String desc) {
+         AnnotationAJ annotation = new AnnotationAJ(desc,vis);
+         AnnotationValue val = new AnnotationAnnotationValue(annotation);
+         arrayValues.add(val);
+         return new AnnVisitor(annotation);
+    }
+       public AnnotationVisitor visitArray(String arg0) {
+                 ArrayAnnotationValue val = new ArrayAnnotationValue();
+                 arrayValues.add(val);
+                 return new ArrayAnnotationVisitor(val,vis);
+       }
+       public void visitEnd() {
+               val.setValues((AnnotationValue[])arrayValues.toArray(new AnnotationValue[]{}));
+       }
+}
\ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/asm/AsmConstants.java b/weaver/src/org/aspectj/weaver/asm/AsmConstants.java
new file mode 100644 (file)
index 0000000..483e920
--- /dev/null
@@ -0,0 +1,39 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import org.aspectj.weaver.AjAttribute.Aspect;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
+import org.aspectj.org.objectweb.asm.Attribute;
+
+public class AsmConstants {
+
+       public static Attribute[] ajAttributes; // attributes ASM needs to know about
+       
+       static {
+               ajAttributes = new Attribute[]{
+                 new AjASMAttribute(Aspect.AttributeName),
+          new AjASMAttribute(WeaverVersionInfo.AttributeName),
+          new AjASMAttribute("org.aspectj.weaver.WeaverState"),
+          new AjASMAttribute("org.aspectj.weaver.PointcutDeclaration"),
+          new AjASMAttribute("org.aspectj.weaver.Declare"),
+          new AjASMAttribute("org.aspectj.weaver.TypeMunger"),
+          new AjASMAttribute("org.aspectj.weaver.Privileged"),
+          new AjASMAttribute("org.aspectj.weaver.MethodDeclarationLineNumber"),
+          new AjASMAttribute("org.aspectj.weaver.SourceContext"),
+          new AjASMAttribute("org.aspectj.weaver.Advice"),
+          new AjASMAttribute("org.aspectj.weaver.EffectiveSignature"),
+          new AjASMAttribute("org.aspectj.weaver.AjSynthetic")
+           };
+       }
+
+}
diff --git a/weaver/src/org/aspectj/weaver/asm/AsmDelegate.java b/weaver/src/org/aspectj/weaver/asm/AsmDelegate.java
new file mode 100644 (file)
index 0000000..d73edc0
--- /dev/null
@@ -0,0 +1,634 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.apache.bcel.classfile.GenericSignatureParser;
+import org.aspectj.apache.bcel.classfile.Signature;
+import org.aspectj.weaver.AbstractReferenceTypeDelegate;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AnnotationAJ;
+import org.aspectj.weaver.AnnotationTargetKind;
+import org.aspectj.weaver.AnnotationX;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ReferenceType;
+import org.aspectj.weaver.ReferenceTypeDelegate;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.ResolvedMemberImpl;
+import org.aspectj.weaver.ResolvedPointcutDefinition;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.SourceContextImpl;
+import org.aspectj.weaver.TypeVariable;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.WeaverStateInfo;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.AjAttribute.DeclareAttribute;
+import org.aspectj.weaver.AjAttribute.PointcutDeclarationAttribute;
+import org.aspectj.weaver.AjAttribute.PrivilegedAttribute;
+import org.aspectj.weaver.AjAttribute.SourceContextAttribute;
+import org.aspectj.weaver.AjAttribute.TypeMunger;
+import org.aspectj.weaver.AjAttribute.WeaverState;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
+import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter;
+import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;
+import org.aspectj.weaver.patterns.PerClause;
+import org.aspectj.org.objectweb.asm.Attribute;
+import org.aspectj.org.objectweb.asm.ClassReader;
+import org.aspectj.org.objectweb.asm.Opcodes;
+
+/**
+ * A lightweight fast delegate that is an alternative to a BCEL delegate.
+ * The type being represented is being referenced during a compile
+ * or weave but is not exposed to the weaver, for example java.lang.String.  
+ * Unnecessary information is not processed - for example the linenumbertable.
+ * 
+ * What might need visiting that currently isnt?
+ * - methods so we can get their annotations
+ * 
+ * Implementation:
+ * The state in this type is populated by an ASM ClassVisitor, attributes and
+ * annotations are mostly unpacked lazily. 
+ * 
+ * @author AndyClement
+ */
+public class AsmDelegate extends AbstractReferenceTypeDelegate {
+
+       public static boolean careAboutMemberAnnotationsAndAttributes = true;
+
+       private World w;
+       
+       int classModifiers;
+
+       ResolvedPointcutDefinition[] pointcuts = null;
+       TypeVariable[]   typeVariables; // filled in when signature is parsed
+
+       ResolvedType[]   annotationTypes;
+       AnnotationX[]    annotationXs;
+       List annotations = Collections.EMPTY_LIST;
+
+       ResolvedMember[] methods;
+       ResolvedMember[] fields;
+       List attributes  = Collections.EMPTY_LIST;
+       Collection /*of Declare*/ declares  = null;
+       Collection /*of ConcreteTypeMunger*/ typeMungers  = null;
+       Collection /*of ResolvedMember*/ privilegedAccesses  = null;
+
+       private int bitflag = 0; // see below for the relevant bits
+       
+       private final static int DISCOVERED_POINTCUTS           = 0x0001;// guard for lazy initialization of pointcuts
+       private final static int DISCOVERED_DECLARES            = 0x0002;// guard for lazy initialization of declares
+       private final static int DISCOVERED_TYPEMUNGERS         = 0x0004;// guard for lazy initialization of type mungers
+       private final static int DISCOVERED_PRIVILEGEDACCESSES  = 0x0008;// guard for lazy initialization of privileged access list
+       private final static int DISCOVERED_SOURCECONTEXT       = 0x0010;// Sourcecontext is actually held in supertype
+       private final static int DISCOVERED_WEAVERSTATEINFO     = 0x0020;
+       private final static int SIGNATURE_UNPACKED             = 0x0040;
+       private final static int ANNOTATION_TYPES_CORRECT       = 0x0080;
+       private final static int ANNOTATIONX_CORRECT            = 0x0100;
+       private final static int SUPERSET                       = 0x0200;
+       private final static int FIELDSFIXEDUP                  = 0x0400;
+       private final static int METHODSFIXEDUP                 = 0x0800;
+
+       private ResolvedType superclassType = null;     
+       String                superclassName = null;
+       
+       private ResolvedType[] interfaceTypes = null;
+       String[]                interfaceNames = null;
+       
+       // For the fields below, which are set based on attribute or annotation values, 
+       // some are 'eager' and set as the visitor goes through the type.  Some are 
+       // lazy and only set when someone requests their value
+       
+       // eager: populated from the 'Aspect' attribute
+       boolean isAspect    = false;
+       PerClause perClause = null;
+       
+       // eager: populated from the 'WeaverVersionInfo' attribute
+       WeaverVersionInfo weaverVersion = AjAttribute.WeaverVersionInfo.UNKNOWN;
+       
+       // lazy: populated from the 'WeaverStateInfo' attribute
+       WeaverStateInfo weaverStateInfo = null;
+       
+       // eager: populated from the visitInnerClass method in the TypeVisitor
+       boolean isAnonymous = false;
+       boolean isNested = false;
+       
+       // eager: populated from the visit method in the TypeVisitor
+       boolean isGenericType = false;
+       String declaredSignature = null;
+               
+       // eager: populated from the 'Retention' annotation
+       boolean isRuntimeRetention = false;
+       String retentionPolicy = null;
+       
+       // eager: populated from the 'Target' annotation
+       boolean canAnnotationTargetType = true; // true unless we learn otherwise
+       AnnotationTargetKind[] targetKinds = null;
+
+       // -----
+       
+       public AsmDelegate(ReferenceType rt,InputStream inputStream) {
+               super(rt,false);
+               w = rt.getWorld();
+               try {
+                         new ClassReader(inputStream).accept(new TypeVisitor(this),AsmConstants.ajAttributes,true);
+                         inputStream.close();
+                         // why-o-why-o-why ?
+                         if ((classModifiers&4096)>0) classModifiers-=4096; // remove SYNTHETIC
+                         if ((classModifiers&131072)>0) classModifiers-=131072; // remove DEPRECATED
+               } catch (IOException ioe) {
+                       ioe.printStackTrace();
+               }
+        setSourceContext(new SourceContextImpl(this));
+       }
+       
+       
+       public boolean isAnnotationStyleAspect() {
+               return false;
+       }
+
+
+       public boolean canAnnotationTargetType() {
+               return canAnnotationTargetType;
+       }
+
+       public AnnotationTargetKind[] getAnnotationTargetKinds() {
+               return targetKinds;
+       }
+
+       public boolean isGeneric() {
+               return isGenericType;
+       }
+
+       public boolean isAnonymous() {
+               return isAnonymous;
+       }
+
+       public boolean isNested() {
+               return isNested;
+       }
+
+       public boolean hasAnnotation(UnresolvedType ofType) {
+               ensureAnnotationsUnpacked();
+               for (int i = 0; i < annotationTypes.length; i++) {
+                       if (annotationTypes[i].equals(ofType)) return true;
+               }
+               return false;
+       }
+
+       public AnnotationX[] getAnnotations() {
+               ensureAnnotationXsUnpacked();
+               return annotationXs;
+       }
+
+       public ResolvedType[] getAnnotationTypes() {
+               ensureAnnotationsUnpacked();
+               return annotationTypes;
+       }
+       
+       private void ensureAnnotationXsUnpacked() {
+               if ( (bitflag&ANNOTATION_TYPES_CORRECT)!=0 && (bitflag&ANNOTATIONX_CORRECT)!=0) return;
+               ensureAnnotationsUnpacked();
+               if (annotations.size()==0) {
+                       annotationXs = AnnotationX.NONE;
+               } else {
+                       annotationXs = new AnnotationX[annotations.size()];
+                       int pos = 0;
+                       for (Iterator iter = annotations.iterator(); iter.hasNext();) {
+                               AnnotationAJ element = (AnnotationAJ) iter.next();
+                               annotationXs[pos++] = new AnnotationX(element,w);
+                       }
+                       annotations = null; // dont need them any more!
+               }
+               bitflag|=ANNOTATIONX_CORRECT;
+       }
+       
+       private void ensureAnnotationsUnpacked() {
+               if ((bitflag&ANNOTATION_TYPES_CORRECT)!=0) return;
+               if (annotations.size()==0) {
+                       annotationTypes = ResolvedType.NONE;
+               } else {
+                       annotationTypes = new ResolvedType[annotations.size()];
+                       int pos = 0;
+                       for (Iterator iter = annotations.iterator(); iter.hasNext();) {
+                               AnnotationAJ element = (AnnotationAJ) iter.next();
+                               annotationTypes[pos++] = w.resolve(UnresolvedType.forSignature(element.getTypeSignature()));
+                       }
+               }
+               bitflag|=ANNOTATION_TYPES_CORRECT;
+       }
+       
+       public Signature.FormalTypeParameter[] getAllFormals() {
+               ensureSignatureUnpacked();
+               if (formalsForResolution == null) {
+                       return new Signature.FormalTypeParameter[0];
+               } else {
+                       return formalsForResolution;
+               }
+       }
+       
+       // for testing - if we have this attribute, return it - will return null if it doesnt know anything 
+       public AjAttribute[] getAttributes(String name) {
+               List results = new ArrayList();
+               for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                       Attribute element = (Attribute) iter.next();
+                       if (element.type.equals(name) && (element instanceof AjASMAttribute)) {
+                               results.add(((AjASMAttribute)element).unpack(this));
+                       }
+               }
+               if (results.size()>0) {
+                       return (AjAttribute[])results.toArray(new AjAttribute[]{});
+               }
+               return null;
+       }
+       
+       // for testing - use with the method above
+       public String[] getAttributeNames() {
+               String[] strs = new String[attributes.size()];
+               int i = 0;
+               for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                       Attribute element = (Attribute) iter.next();
+                       strs[i++] = element.type;
+               }
+               return strs;
+       }
+       
+
+
+       public ISourceContext getSourceContext() {
+               if ((bitflag&DISCOVERED_SOURCECONTEXT)==0) {
+                       bitflag|=DISCOVERED_SOURCECONTEXT;
+                       Attribute foundIt = null;
+                       for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (o instanceof AjASMAttribute) {
+                                       AjASMAttribute element = (AjASMAttribute) o;
+                                       if (element.type.equals(AjAttribute.SourceContextAttribute.AttributeName)) {
+                                               foundIt = element;
+                                               SourceContextAttribute sca = (SourceContextAttribute)((AjASMAttribute)element).unpack(this);
+                                               if (super.getSourceContext()==SourceContextImpl.UNKNOWN_SOURCE_CONTEXT) {
+                                                       super.setSourceContext(new SourceContextImpl(this));
+                                               }
+                                               ((SourceContextImpl)super.getSourceContext()).configureFromAttribute(sca.getSourceFileName(),sca.getLineBreaks());
+                                               break;
+                                       }
+                               }
+                       }
+                       if (foundIt!=null) attributes.remove(foundIt); // Save space
+               }
+               return super.getSourceContext();
+       }
+       
+       public WeaverStateInfo getWeaverState() {
+               if ((bitflag&DISCOVERED_WEAVERSTATEINFO)==0) {
+                       for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (o instanceof AjASMAttribute) {
+                                       AjASMAttribute element = (AjASMAttribute) o;
+                                       if (element.type.equals(AjAttribute.WeaverState.AttributeName)) {
+                                               WeaverState wsInfo = (WeaverState)((AjASMAttribute)element).unpack(this);
+                                               weaverStateInfo = wsInfo.reify();
+                                               break;
+                                       }
+                               }
+                       }
+                       bitflag|=DISCOVERED_WEAVERSTATEINFO;
+               }
+               return weaverStateInfo;
+       }
+
+       public String getDeclaredGenericSignature() {
+               return declaredSignature;
+       }
+       
+       public Collection getTypeMungers() {
+               if ((bitflag&DISCOVERED_TYPEMUNGERS)==0) {
+                       typeMungers = new ArrayList();
+                       for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (o instanceof AjASMAttribute) {
+                                       AjASMAttribute element = (AjASMAttribute) o;
+                                       if (element.type.equals(AjAttribute.TypeMunger.AttributeName)) {
+                                               TypeMunger typeMunger = (TypeMunger)((AjASMAttribute)element).unpack(this);
+                                               typeMungers.add(typeMunger.reify(w,getResolvedTypeX()));
+                                       }
+                               }
+                       }
+                       bitflag|=DISCOVERED_TYPEMUNGERS;
+               }
+               return typeMungers;
+       }
+
+       public Collection getPrivilegedAccesses() {
+               if ((bitflag&DISCOVERED_PRIVILEGEDACCESSES)==0) {
+                       privilegedAccesses = new ArrayList();
+                       for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (o instanceof AjASMAttribute) {
+                                       AjASMAttribute element = (AjASMAttribute) o;
+                                       if (element.type.equals(AjAttribute.PrivilegedAttribute.AttributeName)) {
+                                               PrivilegedAttribute privilegedAttribute = (PrivilegedAttribute)((AjASMAttribute)element).unpack(this);
+                                               ResolvedMember[] pas =privilegedAttribute.getAccessedMembers();
+                                               for (int i = 0; i < pas.length; i++) {
+                                                       privilegedAccesses.add(pas[i]);
+                                               }
+                                       }
+                               }
+                       }
+                       bitflag|=DISCOVERED_PRIVILEGEDACCESSES;
+               }
+               return privilegedAccesses;
+       }
+       
+       public TypeVariable[] getTypeVariables() {
+               ensureSignatureUnpacked();
+               return typeVariables;
+       }
+       
+       private Signature.FormalTypeParameter[] formalsForResolution = null;
+
+       private void ensureSignatureUnpacked() {
+               if ((bitflag&SIGNATURE_UNPACKED)!=0) return;
+               typeVariables=TypeVariable.NONE;
+               if (!getResolvedTypeX().getWorld().isInJava5Mode()) {
+                       bitflag|=SIGNATURE_UNPACKED;
+                       return;
+               }
+               if (declaredSignature!=null) {
+                 GenericSignatureParser parser = new GenericSignatureParser();
+                 Signature.ClassSignature cSig = parser.parseAsClassSignature(declaredSignature);
+                 typeVariables = new TypeVariable[cSig.formalTypeParameters.length];
+         for (int i = 0; i < typeVariables.length; i++) {
+                       Signature.FormalTypeParameter ftp = cSig.formalTypeParameters[i];
+                       try {
+                               typeVariables[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable(
+                                               ftp, 
+                                               cSig.formalTypeParameters,
+                                               getResolvedTypeX().getWorld());
+                       } catch (GenericSignatureFormatException e) {
+                               // this is a development bug, so fail fast with good info
+                               throw new IllegalStateException(
+                                               "While getting the type variables for type " + this.toString()
+                                               + " with generic signature " + cSig + 
+                                               " the following error condition was detected: " + e.getMessage());
+                       }
+                 }
+         if (cSig != null) {
+                       formalsForResolution = cSig.formalTypeParameters;
+                       if (isNested()) {
+                               // we have to find any type variables from the outer type before proceeding with resolution.
+                               Signature.FormalTypeParameter[] extraFormals = getFormalTypeParametersFromOuterClass();
+                               if (extraFormals.length > 0) {
+                                       List allFormals = new ArrayList();
+                                       for (int i = 0; i < formalsForResolution.length; i++) {
+                                               allFormals.add(formalsForResolution[i]);
+                                       }
+                                       for (int i = 0; i < extraFormals.length; i++) {
+                                               allFormals.add(extraFormals[i]);
+                                       }
+                                       formalsForResolution = new Signature.FormalTypeParameter[allFormals.size()];
+                                       allFormals.toArray(formalsForResolution);
+                               }
+                       }
+                       Signature.ClassTypeSignature superSig = cSig.superclassSignature;
+                       try {
+                               this.superclassType = 
+                                       BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(
+                                                       superSig, formalsForResolution, getResolvedTypeX().getWorld());
+                               bitflag|=SUPERSET;
+                       } catch (GenericSignatureFormatException e) {
+                               // development bug, fail fast with good info
+                               throw new IllegalStateException(
+                                               "While determing the generic superclass of " + getResolvedTypeX()
+                                               + " with generic signature " + declaredSignature + " the following error was detected: "
+                                               + e.getMessage());
+                       }
+                       this.interfaceTypes = new ResolvedType[cSig.superInterfaceSignatures.length];
+                       for (int i = 0; i < cSig.superInterfaceSignatures.length; i++) {
+                               try {
+                                       this.interfaceTypes[i] = 
+                                               BcelGenericSignatureToTypeXConverter.classTypeSignature2TypeX(
+                                                               cSig.superInterfaceSignatures[i],
+                                                               formalsForResolution, 
+                                                               getResolvedTypeX().getWorld());
+                                       
+                               } catch (GenericSignatureFormatException e) {
+                                       // development bug, fail fast with good info
+                                       throw new IllegalStateException(
+                                                       "While determing the generic superinterfaces of " + getResolvedTypeX()
+                                                       + " with generic signature " + declaredSignature + " the following error was detected: "
+                                                       + e.getMessage());
+                               }
+                       }
+                       if (isGeneric()) {
+                               // update resolved typex to point at generic type not raw type.
+                               ReferenceType genericType = (ReferenceType) this.resolvedTypeX.getGenericType();
+                               //genericType.setSourceContext(this.resolvedTypeX.getSourceContext());
+                               genericType.setStartPos(this.resolvedTypeX.getStartPos());
+                               this.resolvedTypeX = genericType;
+                       }
+         }
+         
+               } 
+               bitflag|=SIGNATURE_UNPACKED;
+       }
+
+
+       private ReferenceType getOuterClass() {
+               if (!isNested()) throw new IllegalStateException("Can't get the outer class of a non-nested type");
+               int lastDollar = getResolvedTypeX().getName().lastIndexOf('$');
+               String superClassName = getResolvedTypeX().getName().substring(0,lastDollar);
+               UnresolvedType outer = UnresolvedType.forName(superClassName);
+               return (ReferenceType) outer.resolve(getResolvedTypeX().getWorld());
+       }
+       
+       private Signature.FormalTypeParameter[] getFormalTypeParametersFromOuterClass() {
+               List typeParameters = new ArrayList();
+               ReferenceType outer = getOuterClass();
+               ReferenceTypeDelegate outerDelegate = outer.getDelegate();
+               if (!(outerDelegate instanceof AsmDelegate)) {
+                       throw new IllegalStateException("How come we're in AsmObjectType resolving an inner type of something that is NOT a AsmObjectType??");
+               }
+               AsmDelegate outerObjectType = (AsmDelegate) outerDelegate;
+               if (outerObjectType.isNested()) {
+                       Signature.FormalTypeParameter[] parentParams = outerObjectType.getFormalTypeParametersFromOuterClass();
+                       for (int i = 0; i < parentParams.length; i++) {
+                               typeParameters.add(parentParams[i]);
+                       }
+               }
+                 GenericSignatureParser parser = new GenericSignatureParser();
+                 String sig = outerObjectType.getDeclaredGenericSignature();
+                 if (sig!=null) {
+                 Signature.ClassSignature outerSig = parser.parseAsClassSignature(sig);
+               if (outerSig != null) {
+                       for (int i = 0; i < outerSig.formalTypeParameters .length; i++) {
+                               typeParameters.add(outerSig.formalTypeParameters[i]);
+                       }
+               } 
+         }
+               
+               Signature.FormalTypeParameter[] ret = new Signature.FormalTypeParameter[typeParameters.size()];
+               typeParameters.toArray(ret);
+               return ret;
+       }
+       // ---
+
+       public boolean isInterface() {
+               return (classModifiers & Opcodes.ACC_INTERFACE)!=0;
+       }
+
+       public String getRetentionPolicy() {
+               return retentionPolicy;
+       }
+       
+       public boolean isAnnotationWithRuntimeRetention() {
+               return isRuntimeRetention;
+       }
+
+       public boolean isAnnotation() {
+               return (classModifiers & Opcodes.ACC_ANNOTATION)!=0;
+       }
+       
+       public boolean isEnum() {
+               return(classModifiers & Opcodes.ACC_ENUM)!=0;
+       }
+       
+       public int getModifiers() {
+               return classModifiers;
+       }
+
+       
+       public ResolvedMember[] getDeclaredFields() {
+               ensureSignatureUnpacked();
+               if ((bitflag&FIELDSFIXEDUP)==0) {
+                       for (int i = 0; i < fields.length; i++) {
+                               ((ResolvedMemberImpl)fields[i]).setDeclaringType(getResolvedTypeX());
+                       }
+                       bitflag|=FIELDSFIXEDUP;
+               }
+               return fields;
+       }
+
+       public ResolvedType[] getDeclaredInterfaces() {
+               if (interfaceTypes == null) {
+                       if (interfaceNames==null || interfaceNames.length==0) {
+                               interfaceTypes = new ResolvedType[0];
+                       } else {
+                               interfaceTypes = new ResolvedType[interfaceNames.length];
+                               for (int i = 0; i < interfaceNames.length; i++) {
+                                       interfaceTypes[i] = w.resolve(interfaceNames[i].replace('/','.'));
+                               }
+                       }
+                       interfaceNames=null;
+                       ensureSignatureUnpacked();
+               }
+               return interfaceTypes;
+       }
+
+       
+       
+       public ResolvedMember[] getDeclaredMethods() {
+               ensureSignatureUnpacked();
+               if ((bitflag&METHODSFIXEDUP)==0) {
+                       for (int i = 0; i < methods.length; i++) {
+                               ((ResolvedMemberImpl)methods[i]).setDeclaringType(getResolvedTypeX());
+                       }
+                       bitflag|=METHODSFIXEDUP;
+               }
+               return methods;
+       }
+
+       public ResolvedMember[] getDeclaredPointcuts() {
+               if ((bitflag & DISCOVERED_POINTCUTS)==0) {
+                       List pcts = new ArrayList();
+                       List forRemoval = new ArrayList();
+                       for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (o instanceof AjASMAttribute) {
+                                       AjASMAttribute element = (AjASMAttribute) o;
+                                       if (element.type.equals(AjAttribute.PointcutDeclarationAttribute.AttributeName)) {
+                                               PointcutDeclarationAttribute pointcut = (PointcutDeclarationAttribute)((AjASMAttribute)element).unpack(this);
+                                               pcts.add(pointcut.reify());
+                                               forRemoval.add(element);
+                                       }
+                               }
+                       }
+                       pointcuts = (ResolvedPointcutDefinition[])pcts.toArray(new ResolvedPointcutDefinition[]{});
+                       attributes.removeAll(forRemoval);
+                       bitflag|=DISCOVERED_POINTCUTS;
+               }
+               return pointcuts;
+       }
+
+       public Collection getDeclares() {
+               if ((bitflag & DISCOVERED_DECLARES)==0) {
+                       declares = new ArrayList();
+                       List forRemoval = new ArrayList();
+                       for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                               Object o = iter.next();
+                               if (o instanceof AjASMAttribute) {
+                                       AjASMAttribute element = (AjASMAttribute) o;
+                                       if (element.type.equals(AjAttribute.DeclareAttribute.AttributeName)) {
+                                               DeclareAttribute declare = (DeclareAttribute)((AjASMAttribute)element).unpack(this);
+                                               declares.add(declare.getDeclare());
+                                               forRemoval.add(element);
+                                       }
+                               }
+                       }
+                       attributes.removeAll(forRemoval);
+                       bitflag|=DISCOVERED_DECLARES;//discoveredDeclares=true;
+               }
+               return declares;
+       }
+
+       public ResolvedType getSuperclass() {
+               if ((bitflag&SUPERSET)==0) {
+                       if (superclassName == null) {
+                               // this type must be jlObject
+                               superclassType = null;
+                       } else {
+                               superclassType = w.resolve(superclassName.replace('/','.'));
+                       }
+                       ensureSignatureUnpacked();
+                       superclassName=null;
+                       bitflag|=SUPERSET;
+               }
+               return superclassType;
+       }
+       
+       public PerClause getPerClause() {
+               return perClause;
+       }
+
+       public boolean isAspect() {
+               return isAspect;
+       }
+       
+       World getWorld() { return w; }
+
+       // ---
+       // 14-Feb-06 the AsmDelegate is only for types that won't be 'woven', so they can't be a target 
+       //           to have new annotations added
+       public void addAnnotation(AnnotationX annotationX) { /* this method left blank on purpose*/ }
+
+       public void ensureDelegateConsistent() {
+               // doesnt need to do anything until methods like addAnnotation() are implemented (i.e. methods that 
+               // modify the delegate such that it differs from the on-disk contents)
+       }
+       
+}
diff --git a/weaver/src/org/aspectj/weaver/asm/AsmField.java b/weaver/src/org/aspectj/weaver/asm/AsmField.java
new file mode 100644 (file)
index 0000000..d841a17
--- /dev/null
@@ -0,0 +1,110 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+
+import org.aspectj.apache.bcel.classfile.GenericSignatureParser;
+import org.aspectj.apache.bcel.classfile.Signature;
+import org.aspectj.weaver.AnnotationAJ;
+import org.aspectj.weaver.AnnotationX;
+import org.aspectj.weaver.AnnotationsForMemberHolder;
+import org.aspectj.weaver.ResolvedMemberImpl;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter;
+import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;
+
+public class AsmField extends ResolvedMemberImpl {
+
+       private AsmDelegate classDelegate;
+       private AnnotationsForMemberHolder annos;
+       
+       private String genericSignature = null;
+    private boolean unpackedGenericSignature = false;
+       private UnresolvedType genericFieldType = null;
+       
+       public void setClassDelegate(AsmDelegate del) { classDelegate = del;}
+       public void setGenericSignature(String sig) { genericSignature = sig; }
+        
+       public AsmField(Kind kind,      UnresolvedType declaringType,int modifiers,String name,String signature) {
+               super(kind,declaringType,modifiers,name,signature);
+       }
+               
+       public UnresolvedType getGenericReturnType() {
+               unpackGenericSignature();
+               return genericFieldType;
+       }
+       
+       private void unpackGenericSignature() {
+               if (unpackedGenericSignature) { return; }
+               if (!classDelegate.getWorld().isInJava5Mode()) {
+                       this.genericFieldType = getReturnType();
+                       return; 
+               }
+               unpackedGenericSignature = true;
+               String gSig = genericSignature;
+               if (gSig != null) {
+                       // get from generic
+                       Signature.FieldTypeSignature fts = new GenericSignatureParser().parseAsFieldSignature(gSig);
+//                     Signature.ClassSignature genericTypeSig = classDelegate.getGenericClassTypeSignature();
+//
+//                     Signature.ClassSignature cSig = parser.parseAsClassSignature(declaredSignature);
+                       
+                       Signature.FormalTypeParameter[] parentFormals = classDelegate.getAllFormals();
+                       Signature.FormalTypeParameter[] typeVars = 
+                               ((parentFormals == null) ? new Signature.FormalTypeParameter[0] : parentFormals);//.formalTypeParameters);
+                       Signature.FormalTypeParameter[] formals = 
+                               new Signature.FormalTypeParameter[parentFormals.length + typeVars.length];
+                       // put method formal in front of type formals for overriding in
+                       // lookup
+                       System.arraycopy(typeVars, 0, formals, 0, typeVars.length);
+                       System.arraycopy(parentFormals, 0, formals, typeVars.length,parentFormals.length);
+
+                       try {
+                               genericFieldType = BcelGenericSignatureToTypeXConverter
+                                               .fieldTypeSignature2TypeX(fts, formals, classDelegate.getWorld());
+                       } catch (GenericSignatureFormatException e) {
+                               // development bug, fail fast with good info
+                               throw new IllegalStateException(
+                                               "While determing the generic field type of "
+                                                               + this.toString() + " with generic signature "
+                                                               + gSig + " the following error was detected: "
+                                                               + e.getMessage());
+                       }
+               } else {
+                       genericFieldType = getReturnType();
+               }
+       }
+       
+       
+    //  --- 
+       // annotation manipulation
+       public void addAnAnnotation(AnnotationAJ oneAnnotation) {
+               if (annos==null) annos = new AnnotationsForMemberHolder(classDelegate.getWorld());
+               annos.addAnnotation(oneAnnotation);
+       }
+
+       public AnnotationX[] getAnnotations() {
+               if (annos==null) return AnnotationX.NONE;
+               return annos.getAnnotations();
+       }
+
+       public ResolvedType[] getAnnotationTypes() {
+               if (annos==null) return ResolvedType.NONE;
+               return annos.getAnnotationTypes();
+       }
+
+       public boolean hasAnnotation(UnresolvedType ofType) {
+               if (annos==null) return false;
+               return annos.hasAnnotation(ofType);
+       }
+}
diff --git a/weaver/src/org/aspectj/weaver/asm/AsmMethod.java b/weaver/src/org/aspectj/weaver/asm/AsmMethod.java
new file mode 100644 (file)
index 0000000..896e8d3
--- /dev/null
@@ -0,0 +1,272 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.apache.bcel.classfile.GenericSignatureParser;
+import org.aspectj.apache.bcel.classfile.Signature;
+import org.aspectj.apache.bcel.classfile.Signature.TypeVariableSignature;
+import org.aspectj.weaver.AjAttribute;
+import org.aspectj.weaver.AnnotationAJ;
+import org.aspectj.weaver.AnnotationX;
+import org.aspectj.weaver.AnnotationsForMemberHolder;
+import org.aspectj.weaver.ISourceContext;
+import org.aspectj.weaver.ResolvedMemberImpl;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.ShadowMunger;
+import org.aspectj.weaver.TypeVariable;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+import org.aspectj.weaver.AjAttribute.AdviceAttribute;
+import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute;
+import org.aspectj.weaver.AjAttribute.MethodDeclarationLineNumberAttribute;
+import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter;
+import org.aspectj.weaver.bcel.Utility;
+import org.aspectj.weaver.bcel.BcelGenericSignatureToTypeXConverter.GenericSignatureFormatException;
+import org.aspectj.org.objectweb.asm.Attribute;
+
+public class AsmMethod extends ResolvedMemberImpl {
+
+       // genericized version of return and parameter types
+       private boolean unpackedGenericSignature = false;
+       private String genericSignature = null;
+       private UnresolvedType genericReturnType = null;
+       private UnresolvedType[] genericParameterTypes = null;
+       private boolean canBeParameterized = false;
+        
+       private AnnotationsForMemberHolder annos;
+        
+       private EffectiveSignatureAttribute esAttribute = null;
+       private MethodDeclarationLineNumberAttribute mdlnAttribute = null;
+       private ShadowMunger shadowMunger = null;
+       private AsmDelegate classDelegate;
+       public List /*Attribute*/ attributes       = Collections.EMPTY_LIST;
+       private boolean unpackedAspectJAttributes = false;
+
+
+       public AsmMethod(Kind kind,     UnresolvedType declaringType,int modifiers,String name,String signature) {
+               super(kind,declaringType,modifiers,name,signature);
+       }
+       
+       public void setClassDelegate(AsmDelegate del) { classDelegate = del;}
+       public void setGenericSignature(String sig) { genericSignature = sig; }
+
+        public boolean canBeParameterized() {
+               unpackGenericSignature();
+               return canBeParameterized;
+        }
+
+        public UnresolvedType[] getGenericParameterTypes() {
+                unpackGenericSignature();
+                return genericParameterTypes;
+        }
+        
+        public UnresolvedType getGenericReturnType() {
+                unpackGenericSignature();
+                return genericReturnType;
+        }
+        
+
+       public World getWorld() {
+               return classDelegate.getWorld();
+       }
+               
+
+       private void unpackGenericSignature() {
+                if (unpackedGenericSignature) return;
+                if (!getWorld().isInJava5Mode()) { 
+                        this.genericReturnType = getReturnType();
+                        this.genericParameterTypes = getParameterTypes();
+                        return;
+                }
+                // ok, we have work to do...
+                unpackedGenericSignature = true;
+                String gSig = genericSignature;
+                if (gSig != null) {
+                        Signature.MethodTypeSignature mSig = new GenericSignatureParser().parseAsMethodSignature(gSig);
+                        if (mSig.formalTypeParameters.length > 0) {
+                               // generic method declaration
+                               canBeParameterized = true;
+                        }
+                        Signature.FormalTypeParameter[] parentFormals = classDelegate.getAllFormals();
+                        Signature.FormalTypeParameter[] formals = new
+                               Signature.FormalTypeParameter[parentFormals.length + mSig.formalTypeParameters.length];
+                        // put method formal in front of type formals for overriding in lookup
+                        System.arraycopy(mSig.formalTypeParameters,0,formals,0,mSig.formalTypeParameters.length);
+                        System.arraycopy(parentFormals,0,formals,mSig.formalTypeParameters.length,parentFormals.length);
+                        
+                        typeVariables = new TypeVariable[mSig.formalTypeParameters.length];
+                 for (int i = 0; i < typeVariables.length; i++) {
+                               Signature.FormalTypeParameter methodFtp = mSig.formalTypeParameters[i];
+                               try {
+                                       typeVariables[i] = BcelGenericSignatureToTypeXConverter.formalTypeParameter2TypeVariable(
+                                                       methodFtp, 
+                                                       mSig.formalTypeParameters,
+                                                       getWorld());
+                               } catch (GenericSignatureFormatException e) {
+                                       // this is a development bug, so fail fast with good info
+                                       throw new IllegalStateException(
+                                                       "While getting the type variables for method " + this.toString()
+                                                       + " with generic signature " + mSig + 
+                                                       " the following error condition was detected: " + e.getMessage());
+                               }
+                         }
+                        
+                        
+                        
+                        Signature.TypeSignature returnTypeSignature = mSig.returnType;
+                        try {
+                               genericReturnType = BcelGenericSignatureToTypeXConverter.typeSignature2TypeX(
+                                                returnTypeSignature, formals,
+                                                getWorld());
+                       } catch (GenericSignatureFormatException e) {
+//                              development bug, fail fast with good info
+                               throw new IllegalStateException(
+                                               "While determing the generic return type of " + this.toString()
+                                               + " with generic signature " + gSig + " the following error was detected: "
+                                               + e.getMessage());
+                       }
+                        Signature.TypeSignature[] paramTypeSigs = mSig.parameters;
+                        genericParameterTypes = new UnresolvedType[paramTypeSigs.length];
+                        for (int i = 0; i < paramTypeSigs.length; i++) {
+                               try {
+                                       genericParameterTypes[i] = 
+                                               BcelGenericSignatureToTypeXConverter.typeSignature2TypeX(
+                                                               paramTypeSigs[i],formals,getWorld());
+                               } catch (GenericSignatureFormatException e) {
+//                                      development bug, fail fast with good info
+                                       throw new IllegalStateException(
+                                                       "While determining the generic parameter types of " + this.toString()
+                                                       + " with generic signature " + gSig + " the following error was detected: "
+                                                       + e.getMessage());
+                               }
+                               if (paramTypeSigs[i] instanceof TypeVariableSignature) {
+                                       canBeParameterized = true;
+                               }
+                        }
+                } else {
+                        genericReturnType = getReturnType();
+                        genericParameterTypes = getParameterTypes();
+                }
+        }
+       
+       public EffectiveSignatureAttribute getEffectiveSignature() {
+               unpackAspectJAttributes();
+               return esAttribute;
+       }
+       
+       public ShadowMunger getAssociatedShadowMunger() {
+               unpackAspectJAttributes();
+               return shadowMunger;
+       }
+       
+       public int getDeclarationLineNumber() {
+               unpackAspectJAttributes();
+               if (mdlnAttribute==null) return -1;
+               else return (mdlnAttribute.getLineNumber());
+       }
+       
+       public boolean isAjSynthetic() {
+               unpackAspectJAttributes();
+               return super.isAjSynthetic();
+       }
+       
+       private void unpackAspectJAttributes() {
+               if (unpackedAspectJAttributes) return;
+               List forRemoval = new ArrayList();
+               for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                       Attribute element = (Attribute) iter.next();
+                       if (element instanceof AjASMAttribute) {
+                               if (element.type.equals(AjAttribute.AjSynthetic.AttributeName)) { 
+                                       setAjSynthetic(true); 
+                                       forRemoval.add(element); 
+                               }
+                               if (element.type.equals(AjAttribute.MethodDeclarationLineNumberAttribute.AttributeName)) { 
+                                       mdlnAttribute = (MethodDeclarationLineNumberAttribute)((AjASMAttribute)element).unpack(classDelegate); 
+                                       forRemoval.add(element); 
+                               }
+                               if (element.type.equals(AjAttribute.AdviceAttribute.AttributeName)) { 
+                                       shadowMunger = ((AdviceAttribute)((AjASMAttribute)element).unpack(classDelegate)).reify(this,getWorld()); 
+                                       forRemoval.add(element); 
+                               }
+                               if (element.type.equals(AjAttribute.EffectiveSignatureAttribute.AttributeName)) { 
+                                       esAttribute = (EffectiveSignatureAttribute)((AjASMAttribute)element).unpack(classDelegate); 
+                                       forRemoval.add(element); 
+                               }
+                       }
+               }
+               attributes.remove(forRemoval);
+               unpackedAspectJAttributes = true;
+       }
+
+       // for testing - if we have this attribute, return it
+       public AjAttribute[] getAttributes(String name) {
+               List results = new ArrayList();
+               for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                       Attribute element = (Attribute) iter.next();
+                       if (element.type.equals(name) && (element instanceof AjASMAttribute)) {
+                               results.add(((AjASMAttribute)element).unpack(this.classDelegate));
+                       }
+               }
+               return (AjAttribute[])results.toArray(new AjAttribute[]{});
+       }
+       
+       // for testing - use with the method above
+    public String[] getAttributeNames(boolean onlyIncludeAjOnes) {
+               List strs = new ArrayList();
+               int i = 0;
+               for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                       Attribute element = (Attribute) iter.next();
+                       if (!onlyIncludeAjOnes || (element.type.startsWith(AjAttribute.AttributePrefix) && element instanceof AjASMAttribute))
+                         strs.add(element.type);
+               }
+               return (String[])strs.toArray(new String[]{});
+       }
+
+       public String[] getParameterNames() {
+               if (super.getParameterNames()==null) setParameterNames(Utility.makeArgNames(getArity()));
+               return super.getParameterNames();
+       }
+
+       public ISourceContext getSourceContext() {
+               return classDelegate.getSourceContext();
+       }
+       
+       // --- 
+       // annotation manipulation
+
+       public void addAnAnnotation(AnnotationAJ oneAnnotation) {
+               if (annos==null) annos = new AnnotationsForMemberHolder(getWorld());
+               annos.addAnnotation(oneAnnotation);
+       }
+
+       public AnnotationX[] getAnnotations() {
+               if (annos==null) return AnnotationX.NONE;
+               return annos.getAnnotations();
+       }
+
+       public ResolvedType[] getAnnotationTypes() {
+               if (annos==null) return ResolvedType.NONE;
+               return annos.getAnnotationTypes();
+       }
+
+       public boolean hasAnnotation(UnresolvedType ofType) {
+               if (annos==null) return false;
+               return annos.hasAnnotation(ofType);
+       }
+       // ---
+    
+}
diff --git a/weaver/src/org/aspectj/weaver/asm/EmptyVisitor.java b/weaver/src/org/aspectj/weaver/asm/EmptyVisitor.java
new file mode 100644 (file)
index 0000000..8977602
--- /dev/null
@@ -0,0 +1,28 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import org.aspectj.org.objectweb.asm.AnnotationVisitor;
+
+class EmptyVisitor implements AnnotationVisitor {
+
+       public void visit(String arg0, Object arg1) {}
+
+       public void visitEnum(String arg0, String arg1, String arg2) {}
+
+       public AnnotationVisitor visitAnnotation(String arg0, String arg1) {return this;}
+
+       public AnnotationVisitor visitArray(String arg0) {return this;}
+
+       public void visitEnd() {}
+       
+}
\ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/asm/FdVisitor.java b/weaver/src/org/aspectj/weaver/asm/FdVisitor.java
new file mode 100644 (file)
index 0000000..7263f02
--- /dev/null
@@ -0,0 +1,38 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import org.aspectj.org.objectweb.asm.AnnotationVisitor;
+import org.aspectj.org.objectweb.asm.Attribute;
+import org.aspectj.org.objectweb.asm.FieldVisitor;
+import org.aspectj.weaver.AnnotationAJ;
+
+/**
+ * Constructed with an AsmField to 'fill in' with attributes and annotations 
+ */
+class FdVisitor implements FieldVisitor {
+       AsmField field;
+       public FdVisitor(AsmField rm) { field = rm;}
+
+       public AnnotationVisitor visitAnnotation(String desc, boolean isVisible) {
+               AnnotationAJ annotation = new AnnotationAJ(desc,isVisible);
+               field.addAnAnnotation(annotation);
+//             if (am.annotations==null) am.annotations = new ArrayList();
+//             am.annotations.add(annotation); 
+               return new AnnVisitor(annotation);
+       }
+
+       public void visitAttribute(Attribute arg0) {}
+       public void visitEnd() {}
+       
+}
\ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/asm/MethVisitor.java b/weaver/src/org/aspectj/weaver/asm/MethVisitor.java
new file mode 100644 (file)
index 0000000..74a5107
--- /dev/null
@@ -0,0 +1,72 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import java.util.ArrayList;
+import java.util.Collections;
+
+import org.aspectj.weaver.AnnotationAJ;
+import org.aspectj.org.objectweb.asm.AnnotationVisitor;
+import org.aspectj.org.objectweb.asm.Attribute;
+import org.aspectj.org.objectweb.asm.Label;
+import org.aspectj.org.objectweb.asm.MethodVisitor;
+
+/**
+ * Constructed with an AsmMethod to 'fill in' with attributes and annotations.
+ * Bit of a shame we can't "terminate" before visiting the code as we know
+ * we aren't interested in any of it.
+ */
+class MethVisitor implements MethodVisitor {
+       AsmMethod am;
+       
+       public MethVisitor(AsmMethod rm) { am = rm;}
+
+       public AnnotationVisitor visitAnnotationDefault() {
+               return new EmptyVisitor(); // means we are ignoring default values - is that a problem?
+       }
+
+       public AnnotationVisitor visitAnnotation(String desc, boolean isVisible) {
+               AnnotationAJ annotation = new AnnotationAJ(desc,isVisible);
+               am.addAnAnnotation(annotation);
+               return new AnnVisitor(annotation);
+       }
+
+       public void visitAttribute(Attribute attr) {
+               if (am.attributes==Collections.EMPTY_LIST) am.attributes = new ArrayList();
+               am.attributes.add(attr);
+       }
+       
+       public AnnotationVisitor visitParameterAnnotation(int arg0, String arg1, boolean arg2) {
+               return null; // AJ doesnt support these yet
+       }
+       
+       public void visitCode() {}
+       public void visitInsn(int arg0) {}
+       public void visitIntInsn(int arg0, int arg1) {}
+       public void visitVarInsn(int arg0, int arg1) {}
+       public void visitTypeInsn(int arg0, String arg1) {}
+       public void visitFieldInsn(int arg0, String arg1, String arg2, String arg3) {}
+       public void visitMethodInsn(int arg0, String arg1, String arg2, String arg3) {}
+       public void visitJumpInsn(int arg0, Label arg1) {}
+       public void visitLabel(Label arg0) {}
+       public void visitLdcInsn(Object arg0) {}
+       public void visitIincInsn(int arg0, int arg1) {}
+       public void visitTableSwitchInsn(int arg0, int arg1, Label arg2, Label[] arg3) {}
+       public void visitLookupSwitchInsn(Label arg0, int[] arg1, Label[] arg2) {}
+       public void visitMultiANewArrayInsn(String arg0, int arg1) {}
+       public void visitTryCatchBlock(Label arg0, Label arg1, Label arg2, String arg3) {}
+       public void visitLocalVariable(String arg0, String arg1, String arg2, Label arg3, Label arg4, int arg5) {}
+       public void visitLineNumber(int arg0, Label arg1) {}
+       public void visitMaxs(int arg0, int arg1) {}
+       public void visitEnd() {}
+       
+}
\ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/asm/TypeVisitor.java b/weaver/src/org/aspectj/weaver/asm/TypeVisitor.java
new file mode 100644 (file)
index 0000000..31cac4d
--- /dev/null
@@ -0,0 +1,222 @@
+/* *******************************************************************
+ * Copyright (c) 2006 Contributors
+ * All rights reserved. 
+ * This program and the accompanying materials are made available 
+ * under the terms of the Eclipse Public License v1.0 
+ * which accompanies this distribution and is available at 
+ * http://www.eclipse.org/legal/epl-v10.html 
+ *  
+ * Contributors: 
+ *     Andy Clement IBM     initial implementation 
+ * ******************************************************************/
+package org.aspectj.weaver.asm;
+
+import java.lang.reflect.Modifier;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.aspectj.weaver.AnnotationAJ;
+import org.aspectj.weaver.AnnotationNameValuePair;
+import org.aspectj.weaver.AnnotationTargetKind;
+import org.aspectj.weaver.AnnotationValue;
+import org.aspectj.weaver.ArrayAnnotationValue;
+import org.aspectj.weaver.ResolvedMember;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.AjAttribute.Aspect;
+import org.aspectj.weaver.AjAttribute.WeaverVersionInfo;
+import org.aspectj.org.objectweb.asm.AnnotationVisitor;
+import org.aspectj.org.objectweb.asm.Attribute;
+import org.aspectj.org.objectweb.asm.ClassVisitor;
+import org.aspectj.org.objectweb.asm.FieldVisitor;
+import org.aspectj.org.objectweb.asm.MethodVisitor;
+
+
+public class TypeVisitor implements ClassVisitor {
+
+       private final AsmDelegate relatedDelegate;
+       
+       // Populated as we go along, then dealt with at the end of the visit - setting
+       // state on the relatedDelegate as appropriate
+       private List methodsList = new ArrayList();
+       private List fieldsList  = new ArrayList();
+       private List attributes  = new ArrayList();
+    protected List annotations = new ArrayList();
+       
+    private String name = null;
+    
+       TypeVisitor(AsmDelegate delegate) {
+               relatedDelegate = delegate;
+       }
+       
+       public void visit(int version, int mods, String name, String signature, String superclassname, String[] interfacenames) {
+               relatedDelegate.superclassName = superclassname;
+               relatedDelegate.interfaceNames = interfacenames;
+               relatedDelegate.classModifiers = mods;
+               relatedDelegate.declaredSignature  = signature; // <E:Ljava/lang/Object;>Ljava/lang/Object;Ljava/util/Collection<TE;>;
+               relatedDelegate.isGenericType  = (signature!=null && signature.charAt(0)=='<');
+//             relatedDelegate.erasureSignature=name;      // java/util/List;
+               this.name = name;
+       }
+
+       public AnnotationVisitor visitAnnotation(String typeSignature, boolean vis) {
+               AnnotationAJ annotation = new AnnotationAJ(typeSignature,vis);
+               annotations.add(annotation); 
+               return new AnnVisitor(annotation);
+       }
+
+       /**
+        * Store up the attributes - the only one to look out for is the version one, 
+        * as it will tell us the format of all the others.
+        */
+       public void visitAttribute(Attribute attr) {
+//             System.err.println("encountered attribute "+attr.type);
+               if (attr.type.equals(WeaverVersionInfo.AttributeName)) {
+                       WeaverVersionInfo wv = (WeaverVersionInfo)((AjASMAttribute)attr).unpack(relatedDelegate);
+                       relatedDelegate.weaverVersion = wv;
+               } else {
+                       attributes.add(attr);
+               }
+       }
+
+       public void visitInnerClass(String name, String outer, String inner, int access) {
+               if (name.equals(this.name)) {
+                       relatedDelegate.isNested=true;
+                       relatedDelegate.isAnonymous = (inner==null);
+               }
+       }
+
+       public FieldVisitor visitField(int modifiers, String name, String descType, String signature, Object value) {
+               AsmField rm = new AsmField(ResolvedMember.FIELD,this.relatedDelegate.getResolvedTypeX(),modifiers,name,descType);
+               rm.setGenericSignature(signature);
+               rm.setClassDelegate(relatedDelegate);
+               fieldsList.add(rm);
+               if (AsmDelegate.careAboutMemberAnnotationsAndAttributes) {
+                       return new FdVisitor(rm);
+               } else {
+                       return null;
+               }
+       }
+
+       public MethodVisitor visitMethod(int modifiers, String name, String desc, String signature, String[] exceptions) {
+               if (Modifier.isInterface(relatedDelegate.getModifiers()) && Modifier.isAbstract(modifiers))  // wtf? (see testIterator in WorldTestCase)
+                               modifiers = modifiers | Modifier.INTERFACE;
+               AsmMethod rm = new AsmMethod(ResolvedMember.METHOD,this.relatedDelegate.getResolvedTypeX(),modifiers,name,desc);
+               rm.setGenericSignature(signature);
+               rm.setClassDelegate(relatedDelegate);
+               if (exceptions!=null && exceptions.length!=0) {
+                       UnresolvedType[] excs = new UnresolvedType[exceptions.length];
+                       for (int i = 0; i < exceptions.length; i++) {
+                               excs[i]=UnresolvedType.forSignature("L"+exceptions[i]+";");
+                       }
+                       rm.setCheckedExceptions(excs);
+               }
+               methodsList.add(rm);
+               if (AsmDelegate.careAboutMemberAnnotationsAndAttributes) {
+                       return new MethVisitor(rm);
+               } else {
+                       return null;
+               }
+       }
+
+       public void visitSource(String sourcefilename, String debug) {
+               relatedDelegate.setSourcefilename(sourcefilename); 
+    }
+
+       public void visitOuterClass(String arg0, String arg1, String arg2) {/*DeliberatelyBlank*/}
+
+       // --- 
+
+       /**
+        * Pick through what we learned whilst visiting the type - and set what we need to on the 
+        * related delegate.  Discard what we can now.
+        */
+       public void visitEnd() {
+               relatedDelegate.methods = (ResolvedMember[])methodsList.toArray(new ResolvedMember[]{});
+               methodsList.clear();
+               relatedDelegate.fields  = (ResolvedMember[])fieldsList.toArray(new ResolvedMember[]{});
+               fieldsList.clear();
+               // Fast pass of the attributes, unpacking lightweight ones.  Fast ones are:
+               // Aspect
+               if (attributes.size()>0) {
+                       relatedDelegate.attributes = new ArrayList();
+                       for (Iterator iter = attributes.iterator(); iter.hasNext();) {
+                               Attribute element = (Attribute) iter.next();
+                               //System.err.println("Processing:"+element);
+                               if (element instanceof AjASMAttribute) {
+                                       // Aspect
+                                       if (element.type.equals(Aspect.AttributeName)) {
+                                               Aspect aspectAttribute = (Aspect)((AjASMAttribute)element).unpack(relatedDelegate);
+                                               relatedDelegate.perClause = aspectAttribute.reify(null); // param not used
+                                               relatedDelegate.isAspect  = true;
+                                               continue;
+                                       }
+                               }
+                           relatedDelegate.attributes.add(element);
+                       }
+               }
+               
+               // Similar thing for annotations, unpacking lightweight/common ones.  These are:
+               // Retention
+               // For annotations, retention policy should default to CLASS if not set.
+               boolean retentionPolicySet = false;
+               if (annotations.size()>0) relatedDelegate.annotations = new ArrayList();
+               for (Iterator iter = annotations.iterator(); iter.hasNext();) {
+                       AnnotationAJ element = (AnnotationAJ) iter.next();
+                       
+                       // Retention
+                       if (element.getTypeSignature().equals(AnnotationRetention)) {
+                               relatedDelegate.retentionPolicy = element.getStringValueOf("value");
+                               relatedDelegate.isRuntimeRetention = relatedDelegate.retentionPolicy.equals("RUNTIME");
+                               retentionPolicySet=true;
+//                             continue; // possible optimization - dont store them, we've pulled out all the relevant stuff
+                       }
+                       
+                       // Target
+                       if (element.getTypeSignature().equals(AnnotationTarget)) {
+                               setDelegateFieldsForAnnotationTarget(element.getNameValuePairs());
+//                             continue; // possible optimization - dont store them, we've pulled out all the relevant stuff
+                       }
+                       
+                   relatedDelegate.annotations.add(element);
+               }
+               if (relatedDelegate.isAnnotation() && !retentionPolicySet) { relatedDelegate.retentionPolicy="CLASS"; relatedDelegate.isRuntimeRetention=false;}
+       }
+       
+       private void setDelegateFieldsForAnnotationTarget(List/*AnnotationNameValuePair*/ nvpairs) {
+               // Should only be one nvpair, thats the value
+               if (nvpairs.size()>0) {
+                       boolean canTargetType = false;
+                       ArrayAnnotationValue targetsArray = (ArrayAnnotationValue)((AnnotationNameValuePair)nvpairs.get(0)).getValue();
+                       AnnotationValue[] targets = targetsArray.getValues();
+                       List targetKinds = new ArrayList();
+                       for (int i = 0; i < targets.length; i++) {
+                               String targetKind = targets[i].stringify();
+                               if (targetKind.equals("ANNOTATION_TYPE")) {
+                                       targetKinds.add(AnnotationTargetKind.ANNOTATION_TYPE);
+                } else if (targetKind.equals("CONSTRUCTOR")) {
+                                       targetKinds.add(AnnotationTargetKind.CONSTRUCTOR);
+                               } else if (targetKind.equals("FIELD")) {
+                                       targetKinds.add(AnnotationTargetKind.FIELD);
+                               } else if (targetKind.equals("LOCAL_VARIABLE")) {
+                                       targetKinds.add(AnnotationTargetKind.LOCAL_VARIABLE);
+                               } else if (targetKind.equals("METHOD")) {
+                                       targetKinds.add(AnnotationTargetKind.METHOD);
+                               } else if (targetKind.equals("PACKAGE")) {
+                                       targetKinds.add(AnnotationTargetKind.PACKAGE);
+                               } else if (targetKind.equals("PARAMETER")) {
+                                       targetKinds.add(AnnotationTargetKind.PARAMETER);
+                               } else if (targetKind.equals("TYPE")) {
+                                       targetKinds.add(AnnotationTargetKind.TYPE); canTargetType = true;
+                               } 
+                       }
+                       relatedDelegate.targetKinds = (AnnotationTargetKind[])targetKinds.toArray(new AnnotationTargetKind[]{});
+                       relatedDelegate.canAnnotationTargetType = canTargetType;
+               }
+       }
+       
+       // ---
+       private static final String AnnotationRetention = "Ljava/lang/annotation/Retention;";
+       private static final String AnnotationTarget = "Ljava/lang/annotation/Target;";
+       
+}
\ No newline at end of file