world = new BcelWorld( | world = new BcelWorld( | ||||
getSandboxDirectory()+File.pathSeparator+ | getSandboxDirectory()+File.pathSeparator+ | ||||
System.getProperty("java.class.path")); | System.getProperty("java.class.path")); | ||||
world.setFastDelegateSupport(false); | |||||
} | } | ||||
} | } | ||||
<classpathentry kind="src" path="/bridge"/> | <classpathentry kind="src" path="/bridge"/> | ||||
<classpathentry kind="src" path="/asm"/> | <classpathentry kind="src" path="/asm"/> | ||||
<classpathentry combineaccessrules="false" kind="src" path="/aspectj5rt"/> | <classpathentry combineaccessrules="false" kind="src" path="/aspectj5rt"/> | ||||
<classpathentry kind="lib" path="/lib/asm/asm-aj.jar"/> | |||||
<classpathentry sourcepath="/lib/bcel/bcel-src.zip" kind="lib" path="/lib/bcel/bcel.jar"/> | <classpathentry sourcepath="/lib/bcel/bcel-src.zip" kind="lib" path="/lib/bcel/bcel.jar"/> | ||||
<classpathentry sourcepath="/lib/commons/commons-src.zip" kind="lib" path="/lib/commons/commons.jar"/> | <classpathentry sourcepath="/lib/commons/commons-src.zip" kind="lib" path="/lib/commons/commons.jar"/> | ||||
<classpathentry kind="output" path="bin"/> | <classpathentry kind="output" path="bin"/> |
private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.class); | private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.class); | ||||
// Records whether ASM is around ... so we might use it for delegates | // Records whether ASM is around ... so we might use it for delegates | ||||
protected static boolean isASMAround; | |||||
protected static boolean isASMAround = false; | |||||
private long errorThreshold; | private long errorThreshold; | ||||
private long warningThreshold; | private long warningThreshold; | ||||
static { | |||||
try { | |||||
Class c = Class.forName("org.aspectj.org.objectweb.asm.ClassVisitor"); | |||||
isASMAround = true; | |||||
} catch (ClassNotFoundException cnfe) { | |||||
isASMAround = false; | |||||
} | |||||
} | |||||
// static { | |||||
// try { | |||||
// Class c = Class.forName("org.aspectj.org.objectweb.asm.ClassVisitor"); | |||||
// isASMAround = true; | |||||
// } catch (ClassNotFoundException cnfe) { | |||||
// isASMAround = false; | |||||
// } | |||||
// } | |||||
/** | /** | ||||
* A list of RuntimeExceptions containing full stack information for every | * A list of RuntimeExceptions containing full stack information for every | ||||
} | } | ||||
public boolean isFastDelegateSupportEnabled() { | public boolean isFastDelegateSupportEnabled() { | ||||
ensureAdvancedConfigurationProcessed(); | |||||
return fastDelegateSupportEnabled; | |||||
return false; // ASM not currently being used | |||||
// ensureAdvancedConfigurationProcessed(); | |||||
// return fastDelegateSupportEnabled; | |||||
} | } | ||||
public void setIncrementalCompileCouldFollow(boolean b) {incrementalCompileCouldFollow = b;} | public void setIncrementalCompileCouldFollow(boolean b) {incrementalCompileCouldFollow = b;} |
/* ******************************************************************* | |||||
* 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; | |||||
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 BCException("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()); | |||||
unpacked=true; | |||||
return attr; | |||||
} | |||||
} |
/* ******************************************************************* | |||||
* 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.BCException; | |||||
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; | |||||
/** | |||||
* 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 { | |||||
throw new BCException("Annotation visitor choked on "+name+" = "+value); | |||||
} | |||||
} | |||||
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() {} | |||||
} |
/* ******************************************************************* | |||||
* 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.BCException; | |||||
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; | |||||
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 { | |||||
throw new BCException("ArrayAnnotationVisitor choking on "+name+" = "+value); | |||||
} | |||||
} | |||||
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[]{})); | |||||
} | |||||
} |
/* ******************************************************************* | |||||
* 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") | |||||
}; | |||||
} | |||||
} |
/* ******************************************************************* | |||||
* 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.org.objectweb.asm.Attribute; | |||||
import org.aspectj.org.objectweb.asm.ClassReader; | |||||
import org.aspectj.org.objectweb.asm.Opcodes; | |||||
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.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; | |||||
/** | |||||
* 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; | |||||
} | |||||
public ResolvedType 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()); | |||||
} | |||||
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) | |||||
} | |||||
} |
/* ******************************************************************* | |||||
* 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); | |||||
} | |||||
} |
/* ******************************************************************* | |||||
* 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); | |||||
} | |||||
// --- | |||||
} |
/* ******************************************************************* | |||||
* 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() {} | |||||
} |
/* ******************************************************************* | |||||
* 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() {} | |||||
} |
/* ******************************************************************* | |||||
* 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() {} | |||||
} |
/* ******************************************************************* | |||||
* 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;"; | |||||
} |
import org.aspectj.weaver.UnresolvedType; | import org.aspectj.weaver.UnresolvedType; | ||||
import org.aspectj.weaver.World; | import org.aspectj.weaver.World; | ||||
import org.aspectj.weaver.AjAttribute.Aspect; | import org.aspectj.weaver.AjAttribute.Aspect; | ||||
import org.aspectj.weaver.asm.AsmDelegate; | |||||
import org.aspectj.weaver.patterns.DeclareAnnotation; | import org.aspectj.weaver.patterns.DeclareAnnotation; | ||||
import org.aspectj.weaver.patterns.DeclareParents; | import org.aspectj.weaver.patterns.DeclareParents; | ||||
import org.aspectj.weaver.patterns.FormalBinding; | import org.aspectj.weaver.patterns.FormalBinding; | ||||
ensureAdvancedConfigurationProcessed(); | ensureAdvancedConfigurationProcessed(); | ||||
//UnwovenClassFile classFile = (UnwovenClassFile)sourceJavaClasses.get(name); | //UnwovenClassFile classFile = (UnwovenClassFile)sourceJavaClasses.get(name); | ||||
//if (classFile != null) jc = classFile.getJavaClass(); | //if (classFile != null) jc = classFile.getJavaClass(); | ||||
if (isFastDelegateSupportEnabled() && classPath!=null && !ty.needsModifiableDelegate() && isNotOnPackageRestrictedList(name)) { | |||||
ClassPathManager.ClassFile cf = classPath.find(ty); | |||||
if (cf==null) { | |||||
return null; | |||||
} else { | |||||
ReferenceTypeDelegate delegate = buildAsmDelegate(ty,cf); | |||||
if (fallbackToLoadingBcelDelegatesForAspects && delegate.isAspect()) { | |||||
// bugger - pr135001 - we can't inline around advice from an aspect because we don't load the instructions. | |||||
// fixing this quick to get AJDT upgraded with a good 1.5.2dev build. | |||||
// other fixes would be: | |||||
// 1. record that we are loading the superclass for an aspect, so we know to make it a BCEL delegate | |||||
// | |||||
// the 'fix' here is only reasonable because there are many less aspects than classes! | |||||
// Create a BCEL delegate | |||||
if (jc == null) jc = lookupJavaClass(classPath, name); | |||||
if (jc == null) return delegate; // worrying situation ?!? | |||||
else return buildBcelDelegate(ty, jc, false); | |||||
} else { | |||||
return delegate; | |||||
} | |||||
} | |||||
} else { | |||||
// if (isFastDelegateSupportEnabled() && classPath!=null && !ty.needsModifiableDelegate() && isNotOnPackageRestrictedList(name)) { | |||||
// ClassPathManager.ClassFile cf = classPath.find(ty); | |||||
// if (cf==null) { | |||||
// return null; | |||||
// } else { | |||||
// ReferenceTypeDelegate delegate = buildAsmDelegate(ty,cf); | |||||
// if (fallbackToLoadingBcelDelegatesForAspects && delegate.isAspect()) { | |||||
// // bugger - pr135001 - we can't inline around advice from an aspect because we don't load the instructions. | |||||
// // fixing this quick to get AJDT upgraded with a good 1.5.2dev build. | |||||
// // other fixes would be: | |||||
// // 1. record that we are loading the superclass for an aspect, so we know to make it a BCEL delegate | |||||
// // | |||||
// // the 'fix' here is only reasonable because there are many less aspects than classes! | |||||
// | |||||
// // Create a BCEL delegate | |||||
// if (jc == null) jc = lookupJavaClass(classPath, name); | |||||
// if (jc == null) return delegate; // worrying situation ?!? | |||||
// else return buildBcelDelegate(ty, jc, false); | |||||
// } else { | |||||
// return delegate; | |||||
// } | |||||
// } | |||||
// } else { | |||||
if (jc == null) { | if (jc == null) { | ||||
jc = lookupJavaClass(classPath, name); | jc = lookupJavaClass(classPath, name); | ||||
} | } | ||||
} else { | } else { | ||||
return buildBcelDelegate(ty, jc, false); | return buildBcelDelegate(ty, jc, false); | ||||
} | } | ||||
} | |||||
// } | |||||
} | } | ||||
private ReferenceTypeDelegate buildAsmDelegate(ReferenceType type,ClassPathManager.ClassFile t) { | |||||
AsmDelegate asmDelegate; | |||||
try { | |||||
asmDelegate = new AsmDelegate(type,t.getInputStream()); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
return null; | |||||
} | |||||
return asmDelegate; | |||||
} | |||||
// private ReferenceTypeDelegate buildAsmDelegate(ReferenceType type,ClassPathManager.ClassFile t) { | |||||
// AsmDelegate asmDelegate; | |||||
// try { | |||||
// asmDelegate = new AsmDelegate(type,t.getInputStream()); | |||||
// } catch (IOException e) { | |||||
// e.printStackTrace(); | |||||
// return null; | |||||
// } | |||||
// return asmDelegate; | |||||
// } | |||||
public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX, JavaClass jc, boolean exposedToWeaver) { | public BcelObjectType buildBcelDelegate(ReferenceType resolvedTypeX, JavaClass jc, boolean exposedToWeaver) { | ||||
BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, exposedToWeaver); | BcelObjectType ret = new BcelObjectType(resolvedTypeX, jc, exposedToWeaver); |
/* ******************************************************************* | |||||
* 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: | |||||
* Eugene Kuleshov, Ron Bodkin initial implementation | |||||
* ******************************************************************/ | |||||
package org.aspectj.weaver.tools; | |||||
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.Label; | |||||
import org.aspectj.org.objectweb.asm.MethodVisitor; | |||||
// should extend EmptyVisitor but it's not currently included with AspectJ's ASM... | |||||
public class IsAtAspectAnnotationVisitor implements ClassVisitor, FieldVisitor, | |||||
MethodVisitor, AnnotationVisitor { | |||||
private boolean isAspect = false; | |||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible) { | |||||
if ("Lorg/aspectj/lang/annotation/Aspect;".equals(desc)) { | |||||
isAspect = true; | |||||
} | |||||
return this; | |||||
} | |||||
public FieldVisitor visitField(int access, String name, String desc, | |||||
String signature, Object value) { | |||||
return null; | |||||
} | |||||
public MethodVisitor visitMethod(int access, String name, String desc, | |||||
String signature, String[] exceptions) { | |||||
return null; | |||||
} | |||||
public boolean isAspect() { | |||||
return isAspect; | |||||
} | |||||
public void visit(int version, int access, String name, String signature, | |||||
String superName, String[] interfaces) { | |||||
} | |||||
public void visitSource(String source, String debug) { | |||||
} | |||||
public void visitOuterClass(String owner, String name, String desc) { | |||||
} | |||||
public void visitAttribute(Attribute attr) { | |||||
} | |||||
public void visitInnerClass(String name, String outerName, | |||||
String innerName, int access) { | |||||
} | |||||
public void visitEnd() { | |||||
} | |||||
public AnnotationVisitor visitAnnotationDefault() { | |||||
return this; | |||||
} | |||||
public AnnotationVisitor visitParameterAnnotation(int parameter, | |||||
String desc, boolean visible) { | |||||
return this; | |||||
} | |||||
public void visitCode() { | |||||
} | |||||
public void visitInsn(int opcode) { | |||||
} | |||||
public void visitIntInsn(int opcode, int operand) { | |||||
} | |||||
public void visitVarInsn(int opcode, int var) { | |||||
} | |||||
public void visitTypeInsn(int opcode, String desc) { | |||||
} | |||||
public void visitFieldInsn(int opcode, String owner, String name, | |||||
String desc) { | |||||
} | |||||
public void visitMethodInsn(int opcode, String owner, String name, | |||||
String desc) { | |||||
} | |||||
public void visitJumpInsn(int opcode, Label label) { | |||||
} | |||||
public void visitLabel(Label label) { | |||||
} | |||||
public void visitLdcInsn(Object cst) { | |||||
} | |||||
public void visitIincInsn(int var, int increment) { | |||||
} | |||||
public void visitTableSwitchInsn(int min, int max, Label dflt, | |||||
Label labels[]) { | |||||
} | |||||
public void visitLookupSwitchInsn(Label dflt, int keys[], Label labels[]) { | |||||
} | |||||
public void visitMultiANewArrayInsn(String desc, int dims) { | |||||
} | |||||
public void visitTryCatchBlock(Label start, Label end, Label handler, | |||||
String type) { | |||||
} | |||||
public void visitLocalVariable(String name, String desc, String signature, | |||||
Label start, Label end, int index) { | |||||
} | |||||
public void visitLineNumber(int line, Label start) { | |||||
} | |||||
public void visitMaxs(int maxStack, int maxLocals) { | |||||
} | |||||
public void visit(String name, Object value) { | |||||
} | |||||
public void visitEnum(String name, String desc, String value) { | |||||
} | |||||
public AnnotationVisitor visitAnnotation(String name, String desc) { | |||||
return this; | |||||
} | |||||
public AnnotationVisitor visitArray(String name) { | |||||
return this; | |||||
} | |||||
} |
import org.aspectj.bridge.Version; | import org.aspectj.bridge.Version; | ||||
import org.aspectj.bridge.WeaveMessage; | import org.aspectj.bridge.WeaveMessage; | ||||
import org.aspectj.bridge.IMessage.Kind; | import org.aspectj.bridge.IMessage.Kind; | ||||
import org.aspectj.org.objectweb.asm.ClassReader; | |||||
import org.aspectj.util.FileUtil; | import org.aspectj.util.FileUtil; | ||||
import org.aspectj.util.LangUtil; | import org.aspectj.util.LangUtil; | ||||
import org.aspectj.weaver.IClassFileProvider; | import org.aspectj.weaver.IClassFileProvider; | ||||
*/ | */ | ||||
private boolean shouldWeaveAnnotationStyleAspect(String name, byte[] bytes) { | private boolean shouldWeaveAnnotationStyleAspect(String name, byte[] bytes) { | ||||
if (delegateForCurrentClass==null) { | if (delegateForCurrentClass==null) { | ||||
if (weaver.getWorld().isASMAround()) return asmCheckAnnotationStyleAspect(bytes); | |||||
else ensureDelegateInitialized(name, bytes); | |||||
// if (weaver.getWorld().isASMAround()) return asmCheckAnnotationStyleAspect(bytes); | |||||
// else | |||||
ensureDelegateInitialized(name, bytes); | |||||
} | } | ||||
return (delegateForCurrentClass.isAnnotationStyleAspect()); | return (delegateForCurrentClass.isAnnotationStyleAspect()); | ||||
} | } | ||||
private boolean asmCheckAnnotationStyleAspect(byte[] bytes) { | |||||
IsAtAspectAnnotationVisitor detector = new IsAtAspectAnnotationVisitor(); | |||||
ClassReader cr = new ClassReader(bytes); | |||||
try { | |||||
cr.accept(detector, true);//, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES); | |||||
} catch (Exception spe) { | |||||
// if anything goes wrong, e.g., an NPE, then assume it's NOT an @AspectJ aspect... | |||||
System.err.println("Unexpected problem parsing bytes to discover @Aspect annotation"); | |||||
spe.printStackTrace(); | |||||
return false; | |||||
} | |||||
return detector.isAspect(); | |||||
} | |||||
// private boolean asmCheckAnnotationStyleAspect(byte[] bytes) { | |||||
// IsAtAspectAnnotationVisitor detector = new IsAtAspectAnnotationVisitor(); | |||||
// | |||||
// ClassReader cr = new ClassReader(bytes); | |||||
// try { | |||||
// cr.accept(detector, true);//, ClassReader.SKIP_DEBUG | ClassReader.SKIP_CODE | ClassReader.SKIP_FRAMES); | |||||
// } catch (Exception spe) { | |||||
// // if anything goes wrong, e.g., an NPE, then assume it's NOT an @AspectJ aspect... | |||||
// System.err.println("Unexpected problem parsing bytes to discover @Aspect annotation"); | |||||
// spe.printStackTrace(); | |||||
// return false; | |||||
// } | |||||
// | |||||
// return detector.isAspect(); | |||||
// } | |||||
protected void ensureDelegateInitialized(String name,byte[] bytes) { | protected void ensureDelegateInitialized(String name,byte[] bytes) { | ||||
if (delegateForCurrentClass==null) | if (delegateForCurrentClass==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 initial implementation | |||||
* ******************************************************************/ | |||||
package org.aspectj.weaver.bcel; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.util.Enumeration; | |||||
import java.util.zip.ZipEntry; | |||||
import java.util.zip.ZipFile; | |||||
import org.aspectj.weaver.AbstractReferenceTypeDelegate; | |||||
import org.aspectj.weaver.AbstractWorldTestCase; | |||||
import org.aspectj.weaver.AjAttribute; | |||||
import org.aspectj.weaver.AnnotationX; | |||||
import org.aspectj.weaver.BcweaverTests; | |||||
import org.aspectj.weaver.ReferenceType; | |||||
import org.aspectj.weaver.ReferenceTypeDelegate; | |||||
import org.aspectj.weaver.ResolvedMember; | |||||
import org.aspectj.weaver.ResolvedMemberImpl; | |||||
import org.aspectj.weaver.ResolvedType; | |||||
import org.aspectj.weaver.ShadowMunger; | |||||
import org.aspectj.weaver.TypeVariable; | |||||
import org.aspectj.weaver.World; | |||||
import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute; | |||||
import org.aspectj.weaver.asm.AsmDelegate; | |||||
import org.aspectj.weaver.asm.AsmField; | |||||
import org.aspectj.weaver.asm.AsmMethod; | |||||
/** | |||||
* This is a test case for the nameType parts of worlds. | |||||
*/ | |||||
public class AsmDelegateTests extends AbstractWorldTestCase { | |||||
private final BcelWorld world = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
public AsmDelegateTests(String name) { | |||||
super(name); | |||||
} | |||||
protected World getWorld() { | |||||
return world; | |||||
} | |||||
// --- testcode | |||||
public void testWeDontGoBang() { | |||||
world.fallbackToLoadingBcelDelegatesForAspects = false; | |||||
ResolvedType rt = world.resolve("SimpleAspect"); | |||||
ReferenceTypeDelegate delegate = ((ReferenceType)rt).getDelegate(); | |||||
assertTrue("Should be an ASM delegate but is "+delegate.getClass(), | |||||
delegate.getClass().toString().equals("class org.aspectj.weaver.asm.AsmDelegate")); | |||||
} | |||||
public void testDifferentiatingBetweenAspectAndClass() { | |||||
ReferenceType rtAspect = (ReferenceType)world.resolve("SimpleAspect"); | |||||
ReferenceType rtString = (ReferenceType)world.resolve("java.lang.String"); | |||||
assertTrue("SimpleAspect should be an aspect",rtAspect.isAspect()); | |||||
assertTrue("String should not be an aspect",!rtString.isAspect()); | |||||
assertTrue("Should be a persingleton "+rtAspect.getPerClause(),rtAspect.getPerClause().toString().startsWith("persingleton")); | |||||
} | |||||
public void testRecognizingDifferentTypes() { | |||||
ResolvedType rtAnnotation = world.resolve("SimpleAnnotation"); | |||||
ResolvedType rtEnum = world.resolve("SimpleEnum"); | |||||
ResolvedType rtString = world.resolve("java.lang.String"); | |||||
assertTrue("Should be an annotation type",rtAnnotation.isAnnotation()); | |||||
assertTrue("Should be an enum type",rtEnum.isEnum()); | |||||
assertTrue("Should not be an annotation or enum type",!(rtString.isAnnotation() || rtString.isEnum())); | |||||
} | |||||
public void testAnnotationsBehaving() { | |||||
ReferenceType rtAnnotation = (ReferenceType)world.resolve("SimpleAnnotation"); | |||||
assertTrue("Should be SOURCE but is "+rtAnnotation.getRetentionPolicy(),rtAnnotation.getRetentionPolicy().equals("SOURCE")); | |||||
ReferenceType rtAnnotation2 = (ReferenceType)world.resolve("SimpleAnnotation2"); | |||||
assertTrue("Should be CLASS but is "+rtAnnotation2.getRetentionPolicy(),rtAnnotation2.getRetentionPolicy().equals("CLASS")); | |||||
ReferenceType rtAnnotation3 = (ReferenceType)world.resolve("SimpleAnnotation3"); | |||||
assertTrue("Should be RUNTIME but is "+rtAnnotation3.getRetentionPolicy(),rtAnnotation3.getRetentionPolicy().equals("RUNTIME")); | |||||
ReferenceType rtAnnotation4 = (ReferenceType)world.resolve("SimpleAnnotation4"); | |||||
assertTrue("Should be CLASS but is "+rtAnnotation4.getRetentionPolicy(),rtAnnotation4.getRetentionPolicy().equals("CLASS")); | |||||
} | |||||
public void testInterfaceflag() { | |||||
ReferenceType rtString = (ReferenceType)world.resolve("java.lang.String"); | |||||
assertTrue("String should not be an interface",!rtString.isInterface()); | |||||
ReferenceType rtSerializable = (ReferenceType)world.resolve("java.io.Serializable"); | |||||
assertTrue("Serializable should be an interface",rtSerializable.isInterface()); | |||||
} | |||||
public void testCompareDelegates() { | |||||
BcelWorld slowWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
ReferenceType bcelList = (ReferenceType)slowWorld.resolve("java.util.List"); | |||||
ReferenceType asmList = (ReferenceType)fastWorld.resolve("java.util.List"); | |||||
assertTrue("Should be a bcel delegate? "+bcelList.getDelegate().getClass(), | |||||
bcelList.getDelegate().getClass().toString().equals("class org.aspectj.weaver.bcel.BcelObjectType")); | |||||
assertTrue("Should be an asm delegate? "+asmList.getDelegate().getClass(), | |||||
asmList.getDelegate().getClass().toString().equals("class org.aspectj.weaver.asm.AsmDelegate")); | |||||
TypeVariable[] bcelTVars = bcelList.getTypeVariables(); | |||||
TypeVariable[] asmTVars = asmList.getTypeVariables(); | |||||
for (int i = 0; i < asmTVars.length; i++) { | |||||
TypeVariable variable = asmTVars[i]; | |||||
} | |||||
String bcelsig = bcelList.getSignature(); | |||||
String asmsig = asmList.getSignature(); | |||||
assertTrue("Signatures should be the same but "+bcelsig+"!="+asmsig,bcelsig.equals(asmsig)); | |||||
String bcelerasuresig = bcelList.getErasureSignature(); | |||||
String asmerasuresig = asmList.getErasureSignature(); | |||||
assertTrue("Erasure Signatures should be the same but "+bcelerasuresig+"!="+asmerasuresig,bcelerasuresig.equals(asmerasuresig)); | |||||
ResolvedMember[] bcelfields = bcelList.getDeclaredFields(); | |||||
ResolvedMember[] asmfields = asmList.getDeclaredFields(); | |||||
if (bcelfields.length!=asmfields.length) { | |||||
fail("Dont have the same number of fields? bcel="+bcelfields.length+" asm="+asmfields.length); | |||||
} | |||||
for (int i = 0; i < asmfields.length; i++) { | |||||
ResolvedMember member = asmfields[i]; | |||||
if (!bcelfields[i].equals(asmfields[i])) { | |||||
fail("Differing fields: "+bcelfields[i]+" and "+asmfields[i]); | |||||
} | |||||
} | |||||
} | |||||
public void testCompareDelegatesComplex() { | |||||
BcelWorld slowWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
ReferenceType bComplex = (ReferenceType)slowWorld.resolve("Complex"); | |||||
ReferenceType aComplex = (ReferenceType)fastWorld.resolve("Complex"); | |||||
checkEquivalent("",(AbstractReferenceTypeDelegate)aComplex.getDelegate(),(AbstractReferenceTypeDelegate)bComplex.getDelegate()); | |||||
} | |||||
public void testCompareDelegatesMonster() { | |||||
BcelWorld slowWorld = new BcelWorld("../lib/aspectj/lib/aspectjtools.jar");slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld("../lib/aspectj/lib/aspectjtools.jar"); | |||||
ResolvedMemberImpl.showParameterNames=false; | |||||
try { | |||||
File f = new File("../lib/aspectj/lib/aspectjtools.jar"); | |||||
assertTrue("Couldnt find aspectjtools to test. Tried: "+f.getAbsolutePath(),f.exists()); | |||||
ZipFile zf = new ZipFile(f); | |||||
int i = 0; | |||||
Enumeration entries = zf.entries(); | |||||
while (entries.hasMoreElements()) { | |||||
ZipEntry zfe = (ZipEntry)entries.nextElement(); | |||||
String classfileName = zfe.getName(); | |||||
if (classfileName.endsWith(".class")) { | |||||
String clazzname = classfileName.substring(0,classfileName.length()-6).replace('/','.'); | |||||
ReferenceType b = (ReferenceType)slowWorld.resolve(clazzname); | |||||
ReferenceType a = (ReferenceType)fastWorld.resolve(clazzname); | |||||
checkEquivalent("Comparison number #"+(i++)+" ",(AbstractReferenceTypeDelegate)a.getDelegate(),(AbstractReferenceTypeDelegate)b.getDelegate()); | |||||
} | |||||
} | |||||
//System.err.println();("Successfully compared "+i+" entries!!"); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
fail(e.getMessage()); | |||||
} | |||||
} | |||||
public void testCompareDelegatesLoadingPerformance() { | |||||
BcelWorld slowWorld = new BcelWorld("../lib/aspectj/lib/aspectjtools.jar");slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld("../lib/aspectj/lib/aspectjtools.jar"); | |||||
ResolvedMemberImpl.showParameterNames=false; | |||||
try { | |||||
File f = new File("../lib/aspectj/lib/aspectjtools.jar"); | |||||
assertTrue("Couldnt find aspectjtools to test. Tried: "+f.getAbsolutePath(),f.exists()); | |||||
ZipFile zf = new ZipFile(f); | |||||
int i = 0; | |||||
long stime = System.currentTimeMillis(); | |||||
Enumeration entries = zf.entries(); | |||||
while (entries.hasMoreElements()) { | |||||
ZipEntry zfe = (ZipEntry)entries.nextElement(); | |||||
String classfileName = zfe.getName(); | |||||
if (classfileName.endsWith(".class")) { | |||||
String clazzname = classfileName.substring(0,classfileName.length()-6).replace('/','.'); | |||||
ReferenceType b = (ReferenceType)slowWorld.resolve(clazzname); | |||||
i++; | |||||
} | |||||
} | |||||
long etime = System.currentTimeMillis(); | |||||
System.err.println("Time taken to load "+i+" entries with BCEL="+(etime-stime)+"ms"); | |||||
//System.err.println();("Successfully compared "+i+" entries!!"); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
fail(e.getMessage()); | |||||
} | |||||
try { | |||||
File f = new File("../lib/aspectj/lib/aspectjtools.jar"); | |||||
assertTrue("Couldnt find aspectjtools to test. Tried: "+f.getAbsolutePath(),f.exists()); | |||||
ZipFile zf = new ZipFile(f); | |||||
int i = 0; | |||||
long stime = System.currentTimeMillis(); | |||||
Enumeration entries = zf.entries(); | |||||
while (entries.hasMoreElements()) { | |||||
ZipEntry zfe = (ZipEntry)entries.nextElement(); | |||||
String classfileName = zfe.getName(); | |||||
if (classfileName.endsWith(".class")) { | |||||
String clazzname = classfileName.substring(0,classfileName.length()-6).replace('/','.'); | |||||
ReferenceType b = (ReferenceType)fastWorld.resolve(clazzname); | |||||
i++; | |||||
} | |||||
} | |||||
long etime = System.currentTimeMillis(); | |||||
System.err.println("Time taken to load "+i+" entries with ASM="+(etime-stime)+"ms"); | |||||
//System.err.println();("Successfully compared "+i+" entries!!"); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
fail(e.getMessage()); | |||||
} | |||||
} | |||||
private void checkEquivalent(String prefix,AbstractReferenceTypeDelegate asmType,AbstractReferenceTypeDelegate bcelType) { | |||||
assertTrue("Should be a bcel delegate? "+bcelType.getClass(), | |||||
bcelType.getClass().toString().equals("class org.aspectj.weaver.bcel.BcelObjectType")); | |||||
assertTrue("Should be an asm delegate? "+asmType.getClass(), | |||||
asmType.getClass().toString().equals("class org.aspectj.weaver.asm.AsmDelegate")); | |||||
String asmString = asmType.stringifyDelegate(); | |||||
String bcelString= bcelType.stringifyDelegate(); | |||||
if (!asmString.equals(bcelString)) { | |||||
fail(prefix+"Delegates don't match for "+bcelType.getResolvedTypeX()+"\n ASM=\n"+asmString+"\n BCEL=\n"+bcelString); | |||||
} | |||||
} | |||||
private void compareAnnotations(String n,World bcelWorld,World asmWorld) { | |||||
ReferenceType bcelT = (ReferenceType)bcelWorld.resolve(n); | |||||
ReferenceType asmT = (ReferenceType)asmWorld.resolve(n); | |||||
ensureTheSame(bcelT.getAnnotations(),asmT.getAnnotations()); | |||||
} | |||||
private void ensureTheSame(AnnotationX[] bcelSet,AnnotationX[] asmSet) { | |||||
String bcelString = stringify(bcelSet); | |||||
String asmString = stringify(asmSet); | |||||
if (bcelSet.length!=asmSet.length) { | |||||
fail("Lengths are different!!! Not a good start. \nBcel reports: \n"+bcelString+" Asm reports: \n"+asmString); | |||||
} | |||||
assertTrue("Different answers. \nBcel reports: \n"+bcelString+" Asm reports: \n"+asmString,bcelString.equals(asmString)); | |||||
} | |||||
public String stringify(AnnotationX[] annotations) { | |||||
if (annotations==null) return ""; | |||||
StringBuffer sb = new StringBuffer(); | |||||
for (int i = 0; i < annotations.length; i++) { | |||||
AnnotationX annotationX = annotations[i]; | |||||
sb.append(i+") "+annotationX.toString()); | |||||
sb.append("\n"); | |||||
} | |||||
return sb.toString(); | |||||
} | |||||
public void testDifferentAnnotationKinds() { | |||||
BcelWorld slowWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar");slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
compareAnnotations("AnnotatedClass",slowWorld,fastWorld); | |||||
compareAnnotations("AnnotatedFields",slowWorld,fastWorld); | |||||
compareAnnotations("AnnotatedMethods",slowWorld,fastWorld); | |||||
compareAnnotations("AnnotatedWithClassClass",slowWorld,fastWorld); | |||||
compareAnnotations("AnnotatedWithCombinedAnnotation",slowWorld,fastWorld); | |||||
compareAnnotations("AnnotatedWithEnumClass",slowWorld,fastWorld); | |||||
compareAnnotations("AnnotationClassElement",slowWorld,fastWorld); | |||||
compareAnnotations("AnnotationEnumElement",slowWorld,fastWorld); | |||||
compareAnnotations("ComplexAnnotation",slowWorld,fastWorld); | |||||
compareAnnotations("CombinedAnnotation",slowWorld,fastWorld); | |||||
compareAnnotations("ComplexAnnotatedClass",slowWorld,fastWorld); | |||||
} | |||||
/** | |||||
* Load up the AspectFromHell and take it apart... | |||||
*/ | |||||
public void testLoadingAttributesForTypes() { | |||||
BcelWorld slowWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
fastWorld.fallbackToLoadingBcelDelegatesForAspects = false; | |||||
ReferenceType bcelT = (ReferenceType)slowWorld.resolve("AspectFromHell"); | |||||
ReferenceType asmT = (ReferenceType)fastWorld.resolve("AspectFromHell"); | |||||
AsmDelegate asmD = (AsmDelegate)asmT.getDelegate(); | |||||
String [] asmAttributeNames = asmD.getAttributeNames(); | |||||
BcelObjectType bcelD = (BcelObjectType)bcelT.getDelegate(); | |||||
String [] bcelAttributeNames = bcelD.getAttributeNames(); | |||||
// Won't be exactly the same number as ASM currently processes some and then discards them - effectively those stored in the delegate | |||||
// are the 'not yet processed' ones | |||||
// should be 6 type mungers | |||||
AjAttribute[] asmTypeMungers = asmD.getAttributes("org.aspectj.weaver.TypeMunger"); | |||||
AjAttribute[] bcelTypeMungers = bcelD.getAttributes("org.aspectj.weaver.TypeMunger"); | |||||
assertTrue("Should be 6 type mungers but asm="+asmTypeMungers.length+" bcel="+bcelTypeMungers.length,asmTypeMungers.length==6 && bcelTypeMungers.length==6); | |||||
} | |||||
public void testLoadingAttributesForMethods() { | |||||
boolean debug = false; | |||||
BcelWorld slowWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar");slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
fastWorld.fallbackToLoadingBcelDelegatesForAspects = false; | |||||
ReferenceType bcelT = (ReferenceType)slowWorld.resolve("AspectFromHell"); | |||||
ReferenceType asmT = (ReferenceType)fastWorld.resolve("AspectFromHell"); | |||||
ResolvedMember[] bcelMethods = bcelT.getDeclaredMethods(); | |||||
ResolvedMember[] asmMethods = asmT.getDeclaredMethods(); | |||||
for (int i = 0; i < bcelMethods.length; i++) { | |||||
BcelMethod bmember = (BcelMethod)bcelMethods[i]; | |||||
AsmMethod amember = (AsmMethod)asmMethods[i]; | |||||
assertTrue("Seem to be in a muddle. a="+amember.getName()+" b="+bmember.getName(), | |||||
amember.getName().equals(bmember.getName())); | |||||
if (debug) System.err.println("Looking at "+bmember); | |||||
String[] bcelMemberAttributes = bmember.getAttributeNames(true); | |||||
String[] asmMemberAttributes = amember.getAttributeNames(true); | |||||
// System.err.println("BCEL=>\n"+stringifyStringArray(bcelMemberAttributes)); | |||||
// System.err.println(" ASM=>\n"+stringifyStringArray(asmMemberAttributes)); | |||||
compareAttributeNames(bcelMemberAttributes,asmMemberAttributes); | |||||
// Let's check the member ones of interest: | |||||
// org.aspectj.weaver.AjSynthetic | |||||
if (bmember.isAjSynthetic()) { | |||||
assertTrue("Why isnt the ASM method ajsynthetic? "+amember.toDebugString(),amember.isAjSynthetic()); | |||||
} else { | |||||
assertTrue("Why is the ASM method ajsynthetic? "+amember.toDebugString(),!amember.isAjSynthetic()); | |||||
} | |||||
// org.aspectj.weaver.EffectiveSignature | |||||
EffectiveSignatureAttribute bcelEsa = bmember.getEffectiveSignature(); | |||||
EffectiveSignatureAttribute asmEsa = amember.getEffectiveSignature(); | |||||
if (bcelEsa==null) { | |||||
assertTrue("Why isnt the ASM effective signature null? "+asmEsa,asmEsa==null); | |||||
} else { | |||||
if (asmEsa==null) fail("ASM effective signature is null, when BCEL effective signature is "+bcelEsa.toString()); | |||||
assertTrue("Should be the same?? b="+bcelEsa.toString()+" a="+asmEsa.toString(),bcelEsa.toString().equals(asmEsa.toString())); | |||||
} | |||||
// org.aspectj.weaver.MethodDeclarationLineNumber | |||||
int bLine = bmember.getDeclarationLineNumber(); | |||||
int aLine = amember.getDeclarationLineNumber(); | |||||
assertTrue("Should be the same number: "+bLine+" "+aLine,bLine==aLine); | |||||
// org.aspectj.weaver.Advice | |||||
ShadowMunger bcelSM = bmember.getAssociatedShadowMunger(); | |||||
ShadowMunger asmSM = amember.getAssociatedShadowMunger(); | |||||
if (bcelSM==null) { | |||||
assertTrue("Why isnt the ASM effective signature null? "+asmSM,asmSM==null); | |||||
} else { | |||||
if (asmSM==null) fail("ASM effective signature is null, when BCEL effective signature is "+bcelSM.toString()); | |||||
assertTrue("Should be the same?? b="+bcelSM.toString()+" a="+asmSM.toString(),bcelSM.toString().equals(asmSM.toString())); | |||||
} | |||||
// new AjASMAttribute("org.aspectj.weaver.SourceContext"), | |||||
} | |||||
} | |||||
// @SimpleAnnotation(id=1) int i; | |||||
// @SimpleAnnotation(id=2) String s; | |||||
public void testLoadingAnnotationsForFields() { | |||||
boolean debug = false; | |||||
BcelWorld slowWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar");slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
ReferenceType bcelT = (ReferenceType)slowWorld.resolve("AnnotatedFields"); | |||||
ReferenceType asmT = (ReferenceType)fastWorld.resolve("AnnotatedFields"); | |||||
ResolvedMember[] bcelFields = bcelT.getDeclaredFields(); | |||||
ResolvedMember[] asmFields = asmT.getDeclaredFields(); | |||||
for (int i = 0; i < bcelFields.length; i++) { | |||||
BcelField bmember = (BcelField)bcelFields[i]; | |||||
AsmField amember = (AsmField)asmFields[i]; | |||||
assertTrue("Seem to be in a muddle. a="+amember.getName()+" b="+bmember.getName(), | |||||
amember.getName().equals(bmember.getName())); | |||||
if (debug) System.err.println("Looking at "+bmember); | |||||
ResolvedType[] bAnns = bmember.getAnnotationTypes(); | |||||
ResolvedType[] aAnns = amember.getAnnotationTypes(); | |||||
assertTrue("Should have found an annotation on the bcel field?",bAnns!=null && bAnns.length==1); | |||||
assertTrue("Should have found an annotation on the asm field?",aAnns!=null && aAnns.length==1); | |||||
assertTrue("BCEL annotation should be 'SimpleAnnotation3' but is "+bAnns[0].toString(),bAnns[0].toString().equals("SimpleAnnotation3")); | |||||
assertTrue("ASM annotation should be 'SimpleAnnotation3' but is "+aAnns[0].toString(),aAnns[0].toString().equals("SimpleAnnotation3")); | |||||
AnnotationX[] bXs = bmember.getAnnotations(); | |||||
AnnotationX[] aXs = amember.getAnnotations(); | |||||
assertTrue("Should have found an annotation on the bcel field?",bXs!=null && bXs.length==1); | |||||
assertTrue("Should have found an annotation on the asm field?",aXs!=null && aXs.length==1); | |||||
String exp = null; | |||||
if (i==0) exp = "ANNOTATION [LSimpleAnnotation3;] [runtimeVisible] [id=1]"; | |||||
else if (i==1) exp="ANNOTATION [LSimpleAnnotation3;] [runtimeVisible] [id=2]"; | |||||
assertTrue("BCEL annotation should be '"+exp+"' but is "+bXs[0].toString(),bXs[0].toString().equals(exp)); | |||||
assertTrue("ASM annotation should be '"+exp+"' but is "+aXs[0].toString(),aXs[0].toString().equals(exp)); | |||||
} | |||||
} | |||||
// @SimpleAnnotation(id=1) | |||||
// public void method1() { } | |||||
// | |||||
// @SimpleAnnotation(id=2) | |||||
// public void method2() { } | |||||
public void testLoadingAnnotationsForMethods() { | |||||
boolean debug = false; | |||||
BcelWorld slowWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar");slowWorld.setFastDelegateSupport(false); | |||||
BcelWorld fastWorld = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
ReferenceType bcelT = (ReferenceType)slowWorld.resolve("AnnotatedMethods"); | |||||
ReferenceType asmT = (ReferenceType)fastWorld.resolve("AnnotatedMethods"); | |||||
ResolvedMember[] bcelMethods = bcelT.getDeclaredMethods(); | |||||
ResolvedMember[] asmMethods = asmT.getDeclaredMethods(); | |||||
for (int i = 0; i < bcelMethods.length; i++) { | |||||
BcelMethod bmember = (BcelMethod)bcelMethods[i]; | |||||
AsmMethod amember = (AsmMethod)asmMethods[i]; | |||||
if (!bmember.getName().startsWith("method")) continue; | |||||
assertTrue("Seem to be in a muddle. a="+amember.getName()+" b="+bmember.getName(), | |||||
amember.getName().equals(bmember.getName())); | |||||
if (debug) System.err.println("Looking at "+bmember); | |||||
ResolvedType[] bAnns = bmember.getAnnotationTypes(); | |||||
ResolvedType[] aAnns = amember.getAnnotationTypes(); | |||||
assertTrue("Should have found an annotation on the bcel method?",bAnns!=null && bAnns.length==1); | |||||
assertTrue("Should have found an annotation on the asm method?",aAnns!=null && aAnns.length==1); | |||||
assertTrue("BCEL annotation should be 'SimpleAnnotation3' but is "+bAnns[0].toString(),bAnns[0].toString().equals("SimpleAnnotation3")); | |||||
assertTrue("ASM annotation should be 'SimpleAnnotation3' but is "+aAnns[0].toString(),aAnns[0].toString().equals("SimpleAnnotation3")); | |||||
AnnotationX[] bXs = bmember.getAnnotations(); | |||||
AnnotationX[] aXs = amember.getAnnotations(); | |||||
assertTrue("Should have found an annotation on the bcel method?",bXs!=null && bXs.length==1); | |||||
assertTrue("Should have found an annotation on the asm method?",aXs!=null && aXs.length==1); | |||||
String exp = null; | |||||
if (i==1) exp = "ANNOTATION [LSimpleAnnotation3;] [runtimeVisible] [id=1]"; | |||||
else if (i==2) exp="ANNOTATION [LSimpleAnnotation3;] [runtimeVisible] [id=2]"; | |||||
assertTrue("BCEL annotation should be '"+exp+"' but is "+bXs[0].toString(),bXs[0].toString().equals(exp)); | |||||
assertTrue("ASM annotation should be '"+exp+"' but is "+aXs[0].toString(),aXs[0].toString().equals(exp)); | |||||
} | |||||
} | |||||
private void compareAttributeNames(String[] asmlist,String[] bcellist) { | |||||
String astring = stringifyStringArray(asmlist); | |||||
String bstring = stringifyStringArray(bcellist); | |||||
if (asmlist.length!=bcellist.length) { | |||||
fail("Differing lengths.\nBCEL=>\n"+bstring+" ASM=>\n"+astring); | |||||
} | |||||
} | |||||
private String stringifyStringArray(String[] s) { | |||||
StringBuffer r = new StringBuffer(); | |||||
for (int i = 0; i < s.length; i++) { | |||||
r.append(s[i]).append("\n"); | |||||
} | |||||
return r.toString(); | |||||
} | |||||
} |
suite.addTestSuite(TjpWeaveTestCase.class); | suite.addTestSuite(TjpWeaveTestCase.class); | ||||
suite.addTestSuite(UtilityTestCase.class); | suite.addTestSuite(UtilityTestCase.class); | ||||
suite.addTestSuite(WeaveOrderTestCase.class); | suite.addTestSuite(WeaveOrderTestCase.class); | ||||
suite.addTestSuite(WorldTestCase.class); | |||||
suite.addTestSuite(AsmDelegateTests.class); | |||||
suite.addTestSuite(WorldTestCase.class); | |||||
suite.addTestSuite(ZipTestCase.class); | suite.addTestSuite(ZipTestCase.class); | ||||
//$JUnit-END$ | //$JUnit-END$ | ||||
return suite; | return suite; |
/* ******************************************************************* | |||||
* 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.bcel; | |||||
import java.io.File; | |||||
import java.io.IOException; | |||||
import java.util.Enumeration; | |||||
import java.util.zip.ZipEntry; | |||||
import java.util.zip.ZipFile; | |||||
import org.aspectj.weaver.ReferenceType; | |||||
import org.aspectj.weaver.ResolvedMemberImpl; | |||||
/** | |||||
* Compares loading times for bcel and asm - NOT currently pointed at from the suite. | |||||
*/ | |||||
public class Perf { | |||||
public static void main(String[] n) { | |||||
// Two warm up runs, then 3 real runs then print average | |||||
//if (n[0].equals("BCEL")) { | |||||
long t = timeBcel(); | |||||
t = timeBcel(); | |||||
t = timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
t+= timeBcel(); | |||||
System.err.println("Average for BCEL (across 16 runs):"+(t/16)+"ms"); | |||||
//} else { | |||||
t = timeASM(); | |||||
t = timeASM(); | |||||
t = timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
t+= timeASM(); | |||||
System.err.println("Average for ASM (across 16 runs):"+(t/16)+"ms"); | |||||
//} | |||||
} | |||||
private static long timeASM() { | |||||
BcelWorld fastWorld = new BcelWorld( | |||||
"../lib/aspectj/lib/aspectjtools.jar"); | |||||
fastWorld.setBehaveInJava5Way(true); | |||||
try { | |||||
File f = new File("../lib/aspectj/lib/aspectjtools.jar"); | |||||
ZipFile zf = new ZipFile(f); | |||||
int i = 0; | |||||
long stime = System.currentTimeMillis(); | |||||
Enumeration entries = zf.entries(); | |||||
while (entries.hasMoreElements()) { | |||||
ZipEntry zfe = (ZipEntry) entries.nextElement(); | |||||
String classfileName = zfe.getName(); | |||||
if (classfileName.endsWith(".class")) { | |||||
String clazzname = classfileName.substring(0, | |||||
classfileName.length() - 6).replace('/', '.'); | |||||
ReferenceType b = (ReferenceType) fastWorld | |||||
.resolve(clazzname); | |||||
i++; | |||||
} | |||||
} | |||||
long etime = System.currentTimeMillis(); | |||||
System.err.println("asm (" + (etime - stime) + ")"); | |||||
// System.err.println();("Successfully compared "+i+" | |||||
// entries!!"); | |||||
fastWorld.flush(); | |||||
return (etime-stime); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return -1; | |||||
} | |||||
private static long timeBcel() { | |||||
BcelWorld slowWorld = new BcelWorld( | |||||
"../lib/aspectj/lib/aspectjtools.jar"); | |||||
slowWorld.setFastDelegateSupport(false); | |||||
slowWorld.setBehaveInJava5Way(true); | |||||
ResolvedMemberImpl.showParameterNames = false; | |||||
try { | |||||
File f = new File("../lib/aspectj/lib/aspectjtools.jar"); | |||||
// assertTrue("Couldnt find aspectjtools to test. Tried: | |||||
// "+f.getAbsolutePath(),f.exists()); | |||||
ZipFile zf = new ZipFile(f); | |||||
int i = 0; | |||||
long stime = System.currentTimeMillis(); | |||||
Enumeration entries = zf.entries(); | |||||
while (entries.hasMoreElements()) { | |||||
ZipEntry zfe = (ZipEntry) entries.nextElement(); | |||||
String classfileName = zfe.getName(); | |||||
if (classfileName.endsWith(".class")) { | |||||
String clazzname = classfileName.substring(0, | |||||
classfileName.length() - 6).replace('/', '.'); | |||||
ReferenceType b = (ReferenceType) slowWorld | |||||
.resolve(clazzname); | |||||
i++; | |||||
} | |||||
} | |||||
long etime = System.currentTimeMillis(); | |||||
System.err.println("bcel (" + (etime - stime) + ")"); | |||||
slowWorld.flush(); | |||||
return (etime-stime); | |||||
} catch (IOException e) { | |||||
e.printStackTrace(); | |||||
} | |||||
return -1; | |||||
} | |||||
} |
public void disassembleTest(String name) throws IOException { | public void disassembleTest(String name) throws IOException { | ||||
BcelWorld world = new BcelWorld("../weaver/bin"); | BcelWorld world = new BcelWorld("../weaver/bin"); | ||||
world.setFastDelegateSupport(false); | |||||
// world.setFastDelegateSupport(false); | |||||
world.addPath(WeaveTestCase.classDir); | world.addPath(WeaveTestCase.classDir); | ||||
LazyClassGen clazz = new LazyClassGen(BcelWorld.getBcelObjectType(world.resolve(name))); | LazyClassGen clazz = new LazyClassGen(BcelWorld.getBcelObjectType(world.resolve(name))); |
// we are using ASM delegates we don't know the names of parameters (they are irrelevant...) | // we are using ASM delegates we don't know the names of parameters (they are irrelevant...) | ||||
// and are missing from the dumping of asm delegates. This switch ensures we | // and are missing from the dumping of asm delegates. This switch ensures we | ||||
// continue to use BCEL for these tests. | // continue to use BCEL for these tests. | ||||
world.setFastDelegateSupport(false); | |||||
// world.setFastDelegateSupport(false); | |||||
} | } | ||||
public WeaveTestCase(String name) { | public WeaveTestCase(String name) { |
import junit.framework.Test; | import junit.framework.Test; | ||||
import junit.framework.TestSuite; | import junit.framework.TestSuite; | ||||
import org.aspectj.weaver.bcel.AsmDelegateTests5; | |||||
import org.aspectj.weaver.reflect.ReflectionWorldTest; | import org.aspectj.weaver.reflect.ReflectionWorldTest; | ||||
import org.aspectj.weaver.tools.PointcutExpressionTest; | import org.aspectj.weaver.tools.PointcutExpressionTest; | ||||
TestSuite suite = new TestSuite(AllWeaver5Tests.class.getName()); | TestSuite suite = new TestSuite(AllWeaver5Tests.class.getName()); | ||||
//$JUnit-BEGIN$ | //$JUnit-BEGIN$ | ||||
suite.addTest(AllTracing5Tests.suite()); | suite.addTest(AllTracing5Tests.suite()); | ||||
suite.addTest(AsmDelegateTests5.suite()); | |||||
suite.addTest(BcweaverModuleTests15.suite()); | suite.addTest(BcweaverModuleTests15.suite()); | ||||
suite.addTestSuite(PointcutExpressionTest.class); | suite.addTestSuite(PointcutExpressionTest.class); | ||||
suite.addTestSuite(ReflectionWorldTest.class); | suite.addTestSuite(ReflectionWorldTest.class); |
/* ******************************************************************* | |||||
* 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 initial implementation | |||||
* Matthew Webster move Java 5 tests | |||||
* ******************************************************************/ | |||||
package org.aspectj.weaver.bcel; | |||||
import junit.framework.Test; | |||||
import junit.framework.TestSuite; | |||||
import org.aspectj.weaver.AbstractWorldTestCase; | |||||
import org.aspectj.weaver.BcweaverTests; | |||||
import org.aspectj.weaver.ResolvedMember; | |||||
import org.aspectj.weaver.ResolvedType; | |||||
import org.aspectj.weaver.TypeVariable; | |||||
import org.aspectj.weaver.UnresolvedType; | |||||
import org.aspectj.weaver.World; | |||||
/** | |||||
* This is a test case for the nameType parts of worlds. | |||||
*/ | |||||
public class AsmDelegateTests5 extends AbstractWorldTestCase { | |||||
public static Test suite() { | |||||
TestSuite suite = new TestSuite(AsmDelegateTests5.class.getName()); | |||||
suite.addTestSuite(AsmDelegateTests5.class); | |||||
return suite; | |||||
} | |||||
private final BcelWorld world = new BcelWorld(BcweaverTests.TESTDATA_PATH+"/forAsmDelegateTesting/stuff.jar"); | |||||
public AsmDelegateTests5(String name) { | |||||
super(name); | |||||
} | |||||
protected World getWorld() { | |||||
return world; | |||||
} | |||||
// --- testcode | |||||
/** | |||||
* Methods are transformed according to generic signatures - this checks | |||||
* that some of the generic methods in java.lang.Class appear the same | |||||
* whether viewed through an ASM or a BCEL delegate. | |||||
*/ | |||||
public void testCompareGenericMethods() { | |||||
BcelWorld slowWorld = new BcelWorld(); | |||||
slowWorld.setFastDelegateSupport(false); | |||||
slowWorld.setBehaveInJava5Way(true); | |||||
BcelWorld fastWorld = new BcelWorld(); | |||||
fastWorld.setBehaveInJava5Way(true); | |||||
ResolvedType bcelJavaLangClass = slowWorld.resolve(UnresolvedType.forName("java.lang.Class")); | |||||
ResolvedType asmJavaLangClass = fastWorld.resolve(UnresolvedType.forName("java.lang.Class")); | |||||
bcelJavaLangClass = bcelJavaLangClass.getGenericType(); | |||||
asmJavaLangClass = asmJavaLangClass.getGenericType(); | |||||
ResolvedMember[] bcelMethods = bcelJavaLangClass.getDeclaredMethods(); | |||||
ResolvedMember[] asmMethods = asmJavaLangClass.getDeclaredMethods(); | |||||
for (int i = 0; i < bcelMethods.length; i++) { | |||||
bcelMethods[i].setParameterNames(null); // forget them, asm delegates dont currently know them | |||||
String one = bcelMethods[i].toDebugString(); | |||||
String two = asmMethods[i].toDebugString(); | |||||
if (!one.equals(two)) { | |||||
fail("These methods look different when viewed through ASM or BCEL\nBCEL='"+bcelMethods[i].toDebugString()+ | |||||
"'\n ASM='"+asmMethods[i].toDebugString()+"'"); | |||||
} | |||||
// If one is parameterized, check the other is... | |||||
if (bcelMethods[i].canBeParameterized()) { | |||||
assertTrue("ASM method '"+asmMethods[i].toDebugString()+"' can't be parameterized whereas its' BCEL variant could", | |||||
asmMethods[i].canBeParameterized()); | |||||
} | |||||
} | |||||
// Let's take a special look at: | |||||
// public <U> Class<? extends U> asSubclass(Class<U> clazz) | |||||
ResolvedMember bcelSubclassMethod = null; | |||||
for (int i = 0; i < bcelMethods.length; i++) { | |||||
if (bcelMethods[i].getName().equals("asSubclass")) { bcelSubclassMethod = bcelMethods[i]; break; } | |||||
} | |||||
ResolvedMember asmSubclassMethod = null; | |||||
for (int i = 0; i < asmMethods.length; i++) { | |||||
if (asmMethods[i].getName().equals("asSubclass")) { asmSubclassMethod = asmMethods[i];break; } | |||||
} | |||||
TypeVariable[] tvs = bcelSubclassMethod.getTypeVariables(); | |||||
assertTrue("should have one type variable on the bcel version but found: "+format(tvs),tvs!=null && tvs.length==1); | |||||
tvs = asmSubclassMethod.getTypeVariables(); | |||||
assertTrue("should have one type variable on the asm version but found: "+format(tvs),tvs!=null && tvs.length==1); | |||||
} | |||||
private String format(TypeVariable[] tvs) { | |||||
if (tvs==null) return "null"; | |||||
StringBuffer s = new StringBuffer(); | |||||
s.append("["); | |||||
for (int i = 0; i < tvs.length; i++) { | |||||
s.append(tvs[i]); | |||||
if ((i+1)<tvs.length) s.append(","); | |||||
} | |||||
s.append("]"); | |||||
return s.toString(); | |||||
} | |||||
public void testCompareGenericFields() { | |||||
BcelWorld slowWorld = new BcelWorld(); | |||||
slowWorld.setFastDelegateSupport(false); | |||||
slowWorld.setBehaveInJava5Way(true); | |||||
BcelWorld fastWorld = new BcelWorld(); | |||||
fastWorld.setBehaveInJava5Way(true); | |||||
ResolvedType bcelJavaLangClass = slowWorld.resolve(UnresolvedType.forName("java.lang.Class")); | |||||
ResolvedType asmJavaLangClass = fastWorld.resolve(UnresolvedType.forName("java.lang.Class")); | |||||
bcelJavaLangClass = bcelJavaLangClass.getGenericType(); | |||||
asmJavaLangClass = asmJavaLangClass.getGenericType(); | |||||
ResolvedMember[] bcelFields = bcelJavaLangClass.getDeclaredFields(); | |||||
ResolvedMember[] asmFields = asmJavaLangClass.getDeclaredFields(); | |||||
for (int i = 0; i < bcelFields.length; i++) { | |||||
UnresolvedType bcelFieldType = bcelFields[i].getGenericReturnType(); | |||||
UnresolvedType asmFieldType = asmFields[i].getGenericReturnType(); | |||||
if (!bcelFields[i].getGenericReturnType().toDebugString().equals(asmFields[i].getGenericReturnType().toDebugString())) { | |||||
fail("These fields look different when viewed through ASM or BCEL\nBCEL='"+bcelFieldType.toDebugString()+ | |||||
"'\n ASM='"+asmFieldType.toDebugString()+"'"); | |||||
} | |||||
} | |||||
} | |||||
} |