import java.util.Set;
import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.World;
/**
* @author colyer
void setClassLoader(ClassLoader annotationLoader);
+ void setWorld(World aWorld);
+
Object getAnnotation(ResolvedType annotationType, Object onObject);
Object getAnnotationFromMember(ResolvedType annotationType, Member aMember);
Object getAnnotationFromClass(ResolvedType annotationType, Class aClass);
- Set/*UnresolvedType*/ getAnnotations(Member onMember);
+ Set/*ResolvedType*/ getAnnotations(Member onMember);
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.reflect;
+
+import org.aspectj.weaver.UnresolvedType;
+
+/**
+ * This interface exists to support two different strategies for answering
+ * generic signature related questions on Java 5 and pre-Java 5.
+ */
+public interface GenericSignatureInformationProvider {
+
+ UnresolvedType[] getGenericParameterTypes(ReflectionBasedResolvedMemberImpl resolvedMember);
+
+ UnresolvedType getGenericReturnType(ReflectionBasedResolvedMemberImpl resolvedMember);
+
+ boolean isBridge(ReflectionBasedResolvedMemberImpl resolvedMember);
+
+ boolean isVarArgs(ReflectionBasedResolvedMemberImpl resolvedMember);
+
+ boolean isSynthetic(ReflectionBasedResolvedMemberImpl resolvedMember);
+}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.reflect;
+
+import org.aspectj.weaver.UnresolvedType;
+
+/**
+ * Under JDK 1.4 or lower, we can't give generic signature info...
+ */
+public class Java14GenericSignatureInformationProvider implements
+ GenericSignatureInformationProvider {
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#getGenericParameterTypes(org.aspectj.weaver.reflect.ReflectionBasedResolvedMemberImpl)
+ */
+ public UnresolvedType[] getGenericParameterTypes(
+ ReflectionBasedResolvedMemberImpl resolvedMember) {
+ return resolvedMember.getParameterTypes();
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#getGenericReturnType(org.aspectj.weaver.reflect.ReflectionBasedResolvedMemberImpl)
+ */
+ public UnresolvedType getGenericReturnType(
+ ReflectionBasedResolvedMemberImpl resolvedMember) {
+ return resolvedMember.getReturnType();
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isBridge()
+ */
+ public boolean isBridge(ReflectionBasedResolvedMemberImpl resolvedMember) {
+ return false;
+ }
+
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isVarArgs()
+ */
+ public boolean isVarArgs(ReflectionBasedResolvedMemberImpl resolvedMember) {
+ return false;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isSynthetic()
+ */
+ public boolean isSynthetic(ReflectionBasedResolvedMemberImpl resolvedMember) {
+ return false;
+ }
+
+}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
+import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.Collections;
public void ensureDelegateConsistent() {
// Nothing to do - a reflection based delegate can't become inconsistent...
}
+
+ public ReflectionBasedResolvedMemberImpl createResolvedMemberFor(Member aMember) {
+ return null;
+ }
}
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
}
}
+ private static GenericSignatureInformationProvider createGenericSignatureProvider(World inWorld) {
+ if (LangUtil.is15VMOrGreater()) {
+ try {
+ Class providerClass = Class.forName("org.aspectj.weaver.reflect.Java15GenericSignatureInformationProvider");
+ Constructor cons = providerClass.getConstructor(new Class[] {World.class});
+ GenericSignatureInformationProvider ret = (GenericSignatureInformationProvider) cons.newInstance(new Object[] {inWorld});
+ return ret;
+ } catch (ClassNotFoundException cnfEx) {
+ throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but org.aspectj.weaver.reflect.Java15GenericSignatureInformationProvider was not found on classpath");
+ } catch (NoSuchMethodException nsmEx) {
+ throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but: " + nsmEx + " occured");
+ } catch (InstantiationException insEx) {
+ throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but: " + insEx + " occured");
+ } catch (InvocationTargetException invEx) {
+ throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but: " + invEx + " occured");
+ } catch (IllegalAccessException illAcc) {
+ throw new IllegalStateException("Attempted to create Java 1.5 generic signature provider but: " + illAcc + " occured");
+ }
+ } else {
+ return new Java14GenericSignatureInformationProvider();
+ }
+ }
+
/**
* convert a java.lang.reflect.Member into a resolved member in the world
* @param reflectMember
if (inWorld instanceof ReflectionWorld) {
ret.setAnnotationFinder(((ReflectionWorld)inWorld).getAnnotationFinder());
}
+ ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld));
return ret;
}
if (inWorld instanceof ReflectionWorld) {
ret.setAnnotationFinder(((ReflectionWorld)inWorld).getAnnotationFinder());
}
+ ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld));
return ret;
}
if (inWorld instanceof ReflectionWorld) {
ret.setAnnotationFinder(((ReflectionWorld)inWorld).getAnnotationFinder());
}
+ ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld));
return ret;
}
if (inWorld instanceof ReflectionWorld) {
ret.setAnnotationFinder(((ReflectionWorld)inWorld).getAnnotationFinder());
}
+ ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld));
return ret;
}
// classes that represent arrays return a class name that is the signature of the array type, ho-hum...
String className = aClass.getName();
if (aClass.isArray()) {
- return aWorld.resolve(UnresolvedType.forSignature(className));
+ return aWorld.resolve(UnresolvedType.forSignature(className.replace('.','/')));
}
else{
return aWorld.resolve(className);
public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl {
private AnnotationFinder annotationFinder = null;
+ private GenericSignatureInformationProvider gsigInfoProvider =
+ new Java14GenericSignatureInformationProvider();
private Member reflectMember;
this.reflectMember = reflectMember;
}
+ public Member getMember() {
+ return this.reflectMember;
+ }
+
+ // generic signature support
+
+ public void setGenericSignatureInformationProvider(GenericSignatureInformationProvider gsigProvider) {
+ this.gsigInfoProvider = gsigProvider;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.ResolvedMemberImpl#getGenericParameterTypes()
+ */
+ public UnresolvedType[] getGenericParameterTypes() {
+ return this.gsigInfoProvider.getGenericParameterTypes(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.ResolvedMemberImpl#getGenericReturnType()
+ */
+ public UnresolvedType getGenericReturnType() {
+ return this.gsigInfoProvider.getGenericReturnType(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.ResolvedMemberImpl#isSynthetic()
+ */
+ public boolean isSynthetic() {
+ return this.gsigInfoProvider.isSynthetic(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.ResolvedMemberImpl#isVarargsMethod()
+ */
+ public boolean isVarargsMethod() {
+ return this.gsigInfoProvider.isVarArgs(this);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.ResolvedMemberImpl#isBridgeMethod()
+ */
+ public boolean isBridgeMethod() {
+ return this.gsigInfoProvider.isBridge(this);
+ }
+
+ // annotation support
+
public void setAnnotationFinder(AnnotationFinder finder) {
this.annotationFinder = finder;
}
Class java15AnnotationFinder = Class.forName("org.aspectj.weaver.reflect.Java15AnnotationFinder");
this.annotationFinder = (AnnotationFinder) java15AnnotationFinder.newInstance();
this.annotationFinder.setClassLoader(loader);
+ this.annotationFinder.setWorld(this);
} catch(ClassNotFoundException ex) {
// must be on 1.4 or earlier
} catch(IllegalAccessException ex) {
private Repository bcelRepository;
private ClassLoader classLoader;
+ private World world;
// must have no-arg constructor for reflective construction
public Java15AnnotationFinder() {
this.classLoader = aLoader;
}
+ public void setWorld(World aWorld) {
+ this.world = aWorld;
+ }
+
/* (non-Javadoc)
* @see org.aspectj.weaver.reflect.AnnotationFinder#getAnnotation(org.aspectj.weaver.ResolvedType, java.lang.Object)
*/
bcelRepository.clear();
if (anns == null) anns = new org.aspectj.apache.bcel.classfile.annotation.Annotation[0];
// convert to our Annotation type
- Set<UnresolvedType> annSet = new HashSet<UnresolvedType>();
+ Set<ResolvedType> annSet = new HashSet<ResolvedType>();
for (int i = 0; i < anns.length; i++) {
- annSet.add(UnresolvedType.forName(anns[i].getTypeName()));
+ annSet.add(UnresolvedType.forName(anns[i].getTypeName()).resolve(world));
}
return annSet;
} catch (ClassNotFoundException cnfEx) {
Annotation[] anns = ao.getDeclaredAnnotations();
Set<UnresolvedType> annSet = new HashSet<UnresolvedType>();
for (int i = 0; i < anns.length; i++) {
- annSet.add(UnresolvedType.forName(anns[i].annotationType().getName()));
+ annSet.add(UnresolvedType.forName(anns[i].annotationType().getName()).resolve(world));
}
return annSet;
}
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.reflect;
+
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Field;
+import java.lang.reflect.Member;
+import java.lang.reflect.Method;
+import java.lang.reflect.Type;
+
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+
+/**
+ * Uses Java 1.5 reflection APIs to determine generic signatures
+ */
+public class Java15GenericSignatureInformationProvider implements
+ GenericSignatureInformationProvider {
+
+ private final World world;
+
+ public Java15GenericSignatureInformationProvider(World forWorld) {
+ this.world = forWorld;
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#getGenericParameterTypes(org.aspectj.weaver.reflect.ReflectionBasedResolvedMemberImpl)
+ */
+ public UnresolvedType[] getGenericParameterTypes(
+ ReflectionBasedResolvedMemberImpl resolvedMember) {
+ JavaLangTypeToResolvedTypeConverter typeConverter = new JavaLangTypeToResolvedTypeConverter(world);
+ Type[] pTypes = new Type[0];
+ Member member = resolvedMember.getMember();
+ if (member instanceof Method) {
+ pTypes = ((Method)member).getGenericParameterTypes();
+ } else if (member instanceof Constructor) {
+ pTypes = ((Constructor)member).getGenericParameterTypes();
+ }
+ return typeConverter.fromTypes(pTypes);
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#getGenericReturnType(org.aspectj.weaver.reflect.ReflectionBasedResolvedMemberImpl)
+ */
+ public UnresolvedType getGenericReturnType(
+ ReflectionBasedResolvedMemberImpl resolvedMember) {
+ JavaLangTypeToResolvedTypeConverter typeConverter = new JavaLangTypeToResolvedTypeConverter(world);
+ Member member = resolvedMember.getMember();
+ if (member instanceof Field) {
+ return typeConverter.fromType(((Field)member).getGenericType());
+ } else if (member instanceof Method) {
+ return typeConverter.fromType(((Method)member).getGenericReturnType());
+ } else if (member instanceof Constructor) {
+ return typeConverter.fromType(((Constructor)member).getDeclaringClass());
+ } else {
+ throw new IllegalStateException("unexpected member type: " + member);
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isBridge()
+ */
+ public boolean isBridge(ReflectionBasedResolvedMemberImpl resolvedMember) {
+ Member member = resolvedMember.getMember();
+ if (member instanceof Method) {
+ return ((Method)member).isBridge();
+ } else {
+ return false;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isVarArgs()
+ */
+ public boolean isVarArgs(ReflectionBasedResolvedMemberImpl resolvedMember) {
+ Member member = resolvedMember.getMember();
+ if (member instanceof Method) {
+ return ((Method)member).isVarArgs();
+ } else if (member instanceof Constructor) {
+ return ((Constructor)member).isVarArgs();
+ } else {
+ return false;
+ }
+ }
+
+ /* (non-Javadoc)
+ * @see org.aspectj.weaver.reflect.GenericSignatureInformationProvider#isSynthetic()
+ */
+ public boolean isSynthetic(ReflectionBasedResolvedMemberImpl resolvedMember) {
+ Member member = resolvedMember.getMember();
+ return member.isSynthetic();
+ }
+
+}
private ResolvedType superclass;
private ResolvedType[] superInterfaces;
private String genericSignature = null;
+ private JavaLangTypeToResolvedTypeConverter typeConverter;
private Java15AnnotationFinder annotationFinder = null;
myType = AjTypeSystem.getAjType(aClass);
annotationFinder = new Java15AnnotationFinder();
annotationFinder.setClassLoader(classLoader);
+ this.typeConverter = new JavaLangTypeToResolvedTypeConverter(aWorld);
}
public ResolvedType[] getDeclaredInterfaces() {
if (superInterfaces == null) {
Type[] genericInterfaces = getBaseClass().getGenericInterfaces();
- this.superInterfaces = fromTypes(genericInterfaces);
+ this.superInterfaces = typeConverter.fromTypes(genericInterfaces);
}
return superInterfaces;
}
public ResolvedType getSuperclass() {
if (superclass == null && getBaseClass()!=Object.class) {// superclass of Object is null
Type t = this.getBaseClass().getGenericSuperclass();
- if (t!=null) superclass = fromType(t);
+ if (t!=null) superclass = typeConverter.fromType(t);
if (t==null) superclass = getWorld().resolve(UnresolvedType.OBJECT);
}
return superclass;
this.getResolvedTypeX().getWorld().recordTypeVariablesCurrentlyBeingProcessed(getBaseClass(),typeVariables);
// now fill in the details...
for (int i = 0; i < tVars.length; i++) {
- TypeVariableReferenceType tvrt = ((TypeVariableReferenceType) fromType(tVars[i]));
+ TypeVariableReferenceType tvrt = ((TypeVariableReferenceType) typeConverter.fromType(tVars[i]));
TypeVariable tv = tvrt.getTypeVariable();
typeVariables[i].setUpperBound(tv.getUpperBound());
typeVariables[i].setAdditionalInterfaceBounds(tv.getAdditionalInterfaceBounds());
new ReflectionBasedResolvedMemberImpl(org.aspectj.weaver.Member.METHOD,
getGenericResolvedType(),
forMethod.getModifiers(),
- fromType(forMethod.getGenericReturnType()),
+ typeConverter.fromType(forMethod.getReturnType()),
forMethod.getName(),
- fromTypes(forMethod.getGenericParameterTypes()),
- fromTypes(forMethod.getGenericExceptionTypes()),
+ typeConverter.fromTypes(forMethod.getParameterTypes()),
+ typeConverter.fromTypes(forMethod.getExceptionTypes()),
forMethod
);
ret.setAnnotationFinder(this.annotationFinder);
+ ret.setGenericSignatureInformationProvider(new Java15GenericSignatureInformationProvider(this.getWorld()));
return ret;
}
forConstructor.getModifiers(),
getGenericResolvedType(),
"init",
- fromTypes(forConstructor.getGenericParameterTypes()),
- fromTypes(forConstructor.getGenericExceptionTypes()),
+ typeConverter.fromTypes(forConstructor.getParameterTypes()),
+ typeConverter.fromTypes(forConstructor.getExceptionTypes()),
forConstructor
);
ret.setAnnotationFinder(this.annotationFinder);
+ ret.setGenericSignatureInformationProvider(new Java15GenericSignatureInformationProvider(this.getWorld()));
return ret;
}
org.aspectj.weaver.Member.FIELD,
getGenericResolvedType(),
forField.getModifiers(),
- fromType(forField.getGenericType()),
+ typeConverter.fromType(forField.getType()),
forField.getName(),
new UnresolvedType[0],
forField);
ret.setAnnotationFinder(this.annotationFinder);
+ ret.setGenericSignatureInformationProvider(new Java15GenericSignatureInformationProvider(this.getWorld()));
return ret;
}
//return false; // for now
return getBaseClass().getTypeParameters().length > 0;
}
-
- // Used to prevent recursion - we record what we are working on and return it if asked again *whilst* working on it
- private Map /*java.lang.reflect.TypeVariable > TypeVariableReferenceType */typeVariablesInProgress = new HashMap();
-
- private ResolvedType fromType(Type aType) {
- if (aType instanceof Class) {
- Class clazz = (Class)aType;
- String name = clazz.getName();
- /**
- * getName() can return:
- *
- * 1. If this class object represents a reference type that is not an array type
- * then the binary name of the class is returned
- * 2. If this class object represents a primitive type or void, then the
- * name returned is a String equal to the Java language keyword corresponding to the primitive type or void.
- * 3. If this class object represents a class of arrays, then the internal form
- * of the name consists of the name of the element type preceded by one or more '[' characters representing the depth of the array nesting.
- */
- if (clazz.isArray()) {
- UnresolvedType ut = UnresolvedType.forSignature(name);
- return getWorld().resolve(ut);
- } else {
- return getWorld().resolve(name);
- }
- } else if (aType instanceof ParameterizedType) {
- ParameterizedType pt = (ParameterizedType) aType;
- ResolvedType baseType = fromType(pt.getRawType());
- Type[] args = pt.getActualTypeArguments();
- ResolvedType[] resolvedArgs = fromTypes(args);
- return TypeFactory.createParameterizedType(baseType, resolvedArgs, getWorld());
- } else if (aType instanceof java.lang.reflect.TypeVariable) {
- if (typeVariablesInProgress.get(aType)!=null) // check if we are already working on this type
- return (TypeVariableReferenceType)typeVariablesInProgress.get(aType);
-
- java.lang.reflect.TypeVariable tv = (java.lang.reflect.TypeVariable) aType;
- TypeVariable rt_tv = new TypeVariable(tv.getName());
- TypeVariableReferenceType tvrt = new TypeVariableReferenceType(rt_tv,getWorld());
-
- typeVariablesInProgress.put(aType,tvrt); // record what we are working on, for recursion case
-
- Type[] bounds = tv.getBounds();
- ResolvedType[] resBounds = fromTypes(bounds);
- ResolvedType upperBound = resBounds[0];
- ResolvedType[] additionalBounds = new ResolvedType[0];
- if (resBounds.length > 1) {
- additionalBounds = new ResolvedType[resBounds.length - 1];
- System.arraycopy(resBounds,1,additionalBounds,0,additionalBounds.length);
- }
- rt_tv.setUpperBound(upperBound);
- rt_tv.setAdditionalInterfaceBounds(additionalBounds);
-
- typeVariablesInProgress.remove(aType); // we have finished working on it
-
- return tvrt;
- } else if (aType instanceof WildcardType) {
- WildcardType wildType = (WildcardType) aType;
- Type[] lowerBounds = wildType.getLowerBounds();
- Type[] upperBounds = wildType.getUpperBounds();
- ResolvedType bound = null;
- boolean isExtends = lowerBounds.length == 0;
- if (isExtends) {
- bound = fromType(upperBounds[0]);
- } else {
- bound = fromType(lowerBounds[0]);
- }
- return new BoundedReferenceType((ReferenceType)bound,isExtends,getWorld());
- } else if (aType instanceof GenericArrayType) {
- GenericArrayType gt = (GenericArrayType) aType;
- Type componentType = gt.getGenericComponentType();
- return UnresolvedType.makeArray(fromType(componentType),1).resolve(getWorld());
- }
- return ResolvedType.MISSING;
- }
-
- private ResolvedType[] fromTypes(Type[] types) {
- ResolvedType[] ret = new ResolvedType[types.length];
- for (int i = 0; i < ret.length; i++) {
- ret[i] = fromType(types[i]);
- }
- return ret;
- }
@Override
public boolean isAnonymous() {
--- /dev/null
+/* *******************************************************************
+ * Copyright (c) 2005 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://eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Adrian Colyer Initial implementation
+ * ******************************************************************/
+package org.aspectj.weaver.reflect;
+
+import java.lang.reflect.GenericArrayType;
+import java.lang.reflect.ParameterizedType;
+import java.lang.reflect.Type;
+import java.lang.reflect.WildcardType;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.aspectj.weaver.BoundedReferenceType;
+import org.aspectj.weaver.ReferenceType;
+import org.aspectj.weaver.ResolvedType;
+import org.aspectj.weaver.TypeFactory;
+import org.aspectj.weaver.TypeVariable;
+import org.aspectj.weaver.TypeVariableReferenceType;
+import org.aspectj.weaver.UnresolvedType;
+import org.aspectj.weaver.World;
+
+/**
+ * Handles the translation of java.lang.reflect.Type objects into
+ * AspectJ UnresolvedTypes.
+ *
+ */
+public class JavaLangTypeToResolvedTypeConverter {
+
+ // Used to prevent recursion - we record what we are working on and return it if asked again *whilst* working on it
+ private Map<Type,TypeVariableReferenceType> typeVariablesInProgress
+ = new HashMap<Type,TypeVariableReferenceType>();
+ private final World world;
+
+ public JavaLangTypeToResolvedTypeConverter(World aWorld) {
+ this.world = aWorld;
+ }
+
+ private World getWorld() {
+ return this.world;
+ }
+
+ public ResolvedType fromType(Type aType) {
+ if (aType instanceof Class) {
+ Class clazz = (Class)aType;
+ String name = clazz.getName();
+ /**
+ * getName() can return:
+ *
+ * 1. If this class object represents a reference type that is not an array type
+ * then the binary name of the class is returned
+ * 2. If this class object represents a primitive type or void, then the
+ * name returned is a String equal to the Java language keyword corresponding to the primitive type or void.
+ * 3. If this class object represents a class of arrays, then the internal form
+ * of the name consists of the name of the element type preceded by one or more '[' characters representing the depth of the array nesting.
+ */
+ if (clazz.isArray()) {
+ UnresolvedType ut = UnresolvedType.forSignature(name.replace('.','/'));
+ return getWorld().resolve(ut);
+ } else {
+ return getWorld().resolve(name);
+ }
+ } else if (aType instanceof ParameterizedType) {
+ ParameterizedType pt = (ParameterizedType) aType;
+ ResolvedType baseType = fromType(pt.getRawType());
+ Type[] args = pt.getActualTypeArguments();
+ ResolvedType[] resolvedArgs = fromTypes(args);
+ return TypeFactory.createParameterizedType(baseType, resolvedArgs, getWorld());
+ } else if (aType instanceof java.lang.reflect.TypeVariable) {
+ if (typeVariablesInProgress.get(aType)!=null) // check if we are already working on this type
+ return typeVariablesInProgress.get(aType);
+
+ java.lang.reflect.TypeVariable tv = (java.lang.reflect.TypeVariable) aType;
+ TypeVariable rt_tv = new TypeVariable(tv.getName());
+ TypeVariableReferenceType tvrt = new TypeVariableReferenceType(rt_tv,getWorld());
+
+ typeVariablesInProgress.put(aType,tvrt); // record what we are working on, for recursion case
+
+ Type[] bounds = tv.getBounds();
+ ResolvedType[] resBounds = fromTypes(bounds);
+ ResolvedType upperBound = resBounds[0];
+ ResolvedType[] additionalBounds = new ResolvedType[0];
+ if (resBounds.length > 1) {
+ additionalBounds = new ResolvedType[resBounds.length - 1];
+ System.arraycopy(resBounds,1,additionalBounds,0,additionalBounds.length);
+ }
+ rt_tv.setUpperBound(upperBound);
+ rt_tv.setAdditionalInterfaceBounds(additionalBounds);
+
+ typeVariablesInProgress.remove(aType); // we have finished working on it
+
+ return tvrt;
+ } else if (aType instanceof WildcardType) {
+ WildcardType wildType = (WildcardType) aType;
+ Type[] lowerBounds = wildType.getLowerBounds();
+ Type[] upperBounds = wildType.getUpperBounds();
+ ResolvedType bound = null;
+ boolean isExtends = lowerBounds.length == 0;
+ if (isExtends) {
+ bound = fromType(upperBounds[0]);
+ } else {
+ bound = fromType(lowerBounds[0]);
+ }
+ return new BoundedReferenceType((ReferenceType)bound,isExtends,getWorld());
+ } else if (aType instanceof GenericArrayType) {
+ GenericArrayType gt = (GenericArrayType) aType;
+ Type componentType = gt.getGenericComponentType();
+ return UnresolvedType.makeArray(fromType(componentType),1).resolve(getWorld());
+ }
+ return ResolvedType.MISSING;
+ }
+
+ public ResolvedType[] fromTypes(Type[] types) {
+ ResolvedType[] ret = new ResolvedType[types.length];
+ for (int i = 0; i < ret.length; i++) {
+ ret[i] = fromType(types[i]);
+ }
+ return ret;
+ }
+
+
+}
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.reflect.Method;
+import java.util.List;
import org.aspectj.lang.annotation.Pointcut;
private Method a;
private Method b;
private Method c;
+ private Method d;
public void testAtThis() {
PointcutExpression atThis = parser.parsePointcutExpression("@this(org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
assertTrue("matches",jp2.matches());
}
+ public void testAtArgs2() {
+ PointcutExpression atArgs = parser.parsePointcutExpression("@args(*, org.aspectj.weaver.tools.Java15PointcutExpressionTest.MyAnnotation)");
+ ShadowMatch sMatch1 = atArgs.matchesMethodExecution(c);
+ ShadowMatch sMatch2 = atArgs.matchesMethodExecution(d);
+ assertTrue("maybe matches c",sMatch1.maybeMatches());
+ assertTrue("maybe matches d",sMatch2.maybeMatches());
+ JoinPointMatch jp1 = sMatch1.matchesJoinPoint(new B(), new B(), new Object[] {new A(), new B()});
+ assertTrue("matches",jp1.matches());
+ JoinPointMatch jp2 = sMatch2.matchesJoinPoint(new B(), new B(), new Object[] {new A(),new A()});
+ assertFalse("does not match",jp2.matches());
+ }
+
public void testAtArgsWithBinding() {
PointcutParameter p1 = parser.createPointcutParameter("a",MyAnnotation.class);
PointcutParameter p2 = parser.createPointcutParameter("b", MyAnnotation.class);
assertTrue("matches",sMatch.alwaysMatches());
}
+ public void testGenericMethodSignatures() throws Exception{
+ PointcutExpression ex = parser.parsePointcutExpression("execution(* set*(java.util.List<org.aspectj.weaver.tools.Java15PointcutExpressionTest.C>))");
+ Method m = TestBean.class.getMethod("setFriends",List.class);
+ ShadowMatch sm = ex.matchesMethodExecution(m);
+ assertTrue("should match",sm.alwaysMatches());
+ }
+
+ public void testAnnotationInExecution() throws Exception {
+ PointcutExpression ex = parser.parsePointcutExpression("execution(@(org.springframework..*) * *(..))");
+ }
+
+ public void testVarArgsMatching() throws Exception {
+ PointcutExpression ex = parser.parsePointcutExpression("execution(* *(String...))");
+ Method usesVarArgs = D.class.getMethod("varArgs",String[].class);
+ Method noVarArgs = D.class.getMethod("nonVarArgs", String[].class);
+ ShadowMatch sm1 = ex.matchesMethodExecution(usesVarArgs);
+ assertTrue("should match",sm1.alwaysMatches());
+ ShadowMatch sm2 = ex.matchesMethodExecution(noVarArgs);
+ assertFalse("should not match",sm2.alwaysMatches());
+ }
+
protected void setUp() throws Exception {
super.setUp();
parser = PointcutParser.getPointcutParserSupportingAllPrimitivesAndUsingSpecifiedClassloaderForResolution(this.getClass().getClassLoader());
a = A.class.getMethod("a");
b = B.class.getMethod("b");
c = B.class.getMethod("c",new Class[] {A.class,B.class});
+ d = B.class.getMethod("d",new Class[] {A.class,A.class});
}
@Retention(RetentionPolicy.RUNTIME)
private static class B {
@MyClassFileRetentionAnnotation public void b() {}
public void c(A anA, B aB) {}
+
+ public void d(A anA, A anotherA) {}
}
private static class C {
@Pointcut(value="execution(* *(..)) && this(x)", argNames="x")
public void goo(A x) {}
}
+
+ private static class D {
+
+ public void nonVarArgs(String[] strings) {};
+
+ public void varArgs(String... strings) {};
+
+ }
+
+ static class TestBean {
+ public void setFriends(List<C> friends) {}
+ }
}