--- /dev/null
+/* *******************************************************************
+ * 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
--- /dev/null
+/* *******************************************************************
+ * 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
--- /dev/null
+/* *******************************************************************
+ * 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
--- /dev/null
+/* *******************************************************************
+ * 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")
+ };
+ }
+
+}
--- /dev/null
+/* *******************************************************************
+ * 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)
+ }
+
+}
--- /dev/null
+/* *******************************************************************
+ * 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);
+ }
+}
--- /dev/null
+/* *******************************************************************
+ * 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);
+ }
+ // ---
+
+}
--- /dev/null
+/* *******************************************************************
+ * 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
--- /dev/null
+/* *******************************************************************
+ * 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
--- /dev/null
+/* *******************************************************************
+ * 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
--- /dev/null
+/* *******************************************************************
+ * 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