From 5611db4f27a752ef5b65f61b614eb3d5ca30bb01 Mon Sep 17 00:00:00 2001 From: acolyer Date: Tue, 6 Dec 2005 01:11:13 +0000 Subject: [PATCH] fixes getGenericXXX methods in Reflection-based resolved member impl, GenericSignatureInformationProvider allows this to work across both 1.4 and 1.5 --- .../weaver/reflect/AnnotationFinder.java | 5 +- .../GenericSignatureInformationProvider.java | 31 +++++ ...14GenericSignatureInformationProvider.java | 60 ++++++++ .../ReflectionBasedReferenceTypeDelegate.java | 5 + ...tionBasedReferenceTypeDelegateFactory.java | 30 +++- .../ReflectionBasedResolvedMemberImpl.java | 49 +++++++ .../weaver/reflect/ReflectionWorld.java | 1 + .../reflect/Java15AnnotationFinder.java | 11 +- ...15GenericSignatureInformationProvider.java | 103 ++++++++++++++ ...5ReflectionBasedReferenceTypeDelegate.java | 104 ++------------ .../JavaLangTypeToResolvedTypeConverter.java | 129 ++++++++++++++++++ .../tools/Java15PointcutExpressionTest.java | 50 +++++++ .../weaver/tools/PointcutExpressionTest.java | 1 + 13 files changed, 484 insertions(+), 95 deletions(-) create mode 100644 weaver/src/org/aspectj/weaver/reflect/GenericSignatureInformationProvider.java create mode 100644 weaver/src/org/aspectj/weaver/reflect/Java14GenericSignatureInformationProvider.java create mode 100644 weaver5/java5-src/org/aspectj/weaver/reflect/Java15GenericSignatureInformationProvider.java create mode 100644 weaver5/java5-src/org/aspectj/weaver/reflect/JavaLangTypeToResolvedTypeConverter.java diff --git a/weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java b/weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java index 88b2c7450..07d7e7cac 100644 --- a/weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java +++ b/weaver/src/org/aspectj/weaver/reflect/AnnotationFinder.java @@ -15,6 +15,7 @@ import java.lang.reflect.Member; import java.util.Set; import org.aspectj.weaver.ResolvedType; +import org.aspectj.weaver.World; /** * @author colyer @@ -24,11 +25,13 @@ public interface AnnotationFinder { 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); } diff --git a/weaver/src/org/aspectj/weaver/reflect/GenericSignatureInformationProvider.java b/weaver/src/org/aspectj/weaver/reflect/GenericSignatureInformationProvider.java new file mode 100644 index 000000000..fce972348 --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/GenericSignatureInformationProvider.java @@ -0,0 +1,31 @@ +/* ******************************************************************* + * 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); +} diff --git a/weaver/src/org/aspectj/weaver/reflect/Java14GenericSignatureInformationProvider.java b/weaver/src/org/aspectj/weaver/reflect/Java14GenericSignatureInformationProvider.java new file mode 100644 index 000000000..91b32ff0e --- /dev/null +++ b/weaver/src/org/aspectj/weaver/reflect/Java14GenericSignatureInformationProvider.java @@ -0,0 +1,60 @@ +/* ******************************************************************* + * 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; + } + +} diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java index 300df73af..739e1bc6f 100644 --- a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegate.java @@ -13,6 +13,7 @@ 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.util.Collection; import java.util.Collections; @@ -346,5 +347,9 @@ public class ReflectionBasedReferenceTypeDelegate implements ReferenceTypeDelega public void ensureDelegateConsistent() { // Nothing to do - a reflection based delegate can't become inconsistent... } + + public ReflectionBasedResolvedMemberImpl createResolvedMemberFor(Member aMember) { + return null; + } } diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java index 1b5abc058..5063fb0a0 100644 --- a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedReferenceTypeDelegateFactory.java @@ -13,6 +13,7 @@ package org.aspectj.weaver.reflect; 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; @@ -62,6 +63,29 @@ public class ReflectionBasedReferenceTypeDelegateFactory { } } + 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 @@ -91,6 +115,7 @@ public class ReflectionBasedReferenceTypeDelegateFactory { if (inWorld instanceof ReflectionWorld) { ret.setAnnotationFinder(((ReflectionWorld)inWorld).getAnnotationFinder()); } + ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); return ret; } @@ -108,6 +133,7 @@ public class ReflectionBasedReferenceTypeDelegateFactory { if (inWorld instanceof ReflectionWorld) { ret.setAnnotationFinder(((ReflectionWorld)inWorld).getAnnotationFinder()); } + ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); return ret; } @@ -136,6 +162,7 @@ public class ReflectionBasedReferenceTypeDelegateFactory { if (inWorld instanceof ReflectionWorld) { ret.setAnnotationFinder(((ReflectionWorld)inWorld).getAnnotationFinder()); } + ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); return ret; } @@ -151,6 +178,7 @@ public class ReflectionBasedReferenceTypeDelegateFactory { if (inWorld instanceof ReflectionWorld) { ret.setAnnotationFinder(((ReflectionWorld)inWorld).getAnnotationFinder()); } + ret.setGenericSignatureInformationProvider(createGenericSignatureProvider(inWorld)); return ret; } @@ -167,7 +195,7 @@ public class ReflectionBasedReferenceTypeDelegateFactory { // 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); diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java index ecdd60d1f..86aab4599 100644 --- a/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionBasedResolvedMemberImpl.java @@ -26,6 +26,8 @@ import org.aspectj.weaver.UnresolvedType; public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { private AnnotationFinder annotationFinder = null; + private GenericSignatureInformationProvider gsigInfoProvider = + new Java14GenericSignatureInformationProvider(); private Member reflectMember; @@ -101,6 +103,53 @@ public class ReflectionBasedResolvedMemberImpl extends ResolvedMemberImpl { 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; } diff --git a/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java b/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java index 01b2c6e79..03aca9ac8 100644 --- a/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java +++ b/weaver/src/org/aspectj/weaver/reflect/ReflectionWorld.java @@ -66,6 +66,7 @@ public class ReflectionWorld extends World { 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) { diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java index 40985bd26..1453e05ff 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15AnnotationFinder.java @@ -36,6 +36,7 @@ public class Java15AnnotationFinder implements AnnotationFinder { private Repository bcelRepository; private ClassLoader classLoader; + private World world; // must have no-arg constructor for reflective construction public Java15AnnotationFinder() { @@ -46,6 +47,10 @@ public class Java15AnnotationFinder implements AnnotationFinder { 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) */ @@ -109,9 +114,9 @@ public class Java15AnnotationFinder implements AnnotationFinder { bcelRepository.clear(); if (anns == null) anns = new org.aspectj.apache.bcel.classfile.annotation.Annotation[0]; // convert to our Annotation type - Set annSet = new HashSet(); + Set annSet = new HashSet(); 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) { @@ -123,7 +128,7 @@ public class Java15AnnotationFinder implements AnnotationFinder { Annotation[] anns = ao.getDeclaredAnnotations(); Set annSet = new HashSet(); 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; } diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15GenericSignatureInformationProvider.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15GenericSignatureInformationProvider.java new file mode 100644 index 000000000..c9de9517e --- /dev/null +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15GenericSignatureInformationProvider.java @@ -0,0 +1,103 @@ +/* ******************************************************************* + * 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(); + } + +} diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java index 57909f6df..502dd80fb 100644 --- a/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/Java15ReflectionBasedReferenceTypeDelegate.java @@ -59,6 +59,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends private ResolvedType superclass; private ResolvedType[] superInterfaces; private String genericSignature = null; + private JavaLangTypeToResolvedTypeConverter typeConverter; private Java15AnnotationFinder annotationFinder = null; @@ -70,6 +71,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends myType = AjTypeSystem.getAjType(aClass); annotationFinder = new Java15AnnotationFinder(); annotationFinder.setClassLoader(classLoader); + this.typeConverter = new JavaLangTypeToResolvedTypeConverter(aWorld); } @@ -124,7 +126,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends public ResolvedType[] getDeclaredInterfaces() { if (superInterfaces == null) { Type[] genericInterfaces = getBaseClass().getGenericInterfaces(); - this.superInterfaces = fromTypes(genericInterfaces); + this.superInterfaces = typeConverter.fromTypes(genericInterfaces); } return superInterfaces; } @@ -133,7 +135,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends 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; @@ -156,7 +158,7 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends 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()); @@ -202,13 +204,14 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends 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; } @@ -219,11 +222,12 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends 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; } @@ -233,11 +237,12 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends 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; } @@ -300,87 +305,6 @@ public class Java15ReflectionBasedReferenceTypeDelegate extends //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() { diff --git a/weaver5/java5-src/org/aspectj/weaver/reflect/JavaLangTypeToResolvedTypeConverter.java b/weaver5/java5-src/org/aspectj/weaver/reflect/JavaLangTypeToResolvedTypeConverter.java new file mode 100644 index 000000000..d4f352d6a --- /dev/null +++ b/weaver5/java5-src/org/aspectj/weaver/reflect/JavaLangTypeToResolvedTypeConverter.java @@ -0,0 +1,129 @@ +/* ******************************************************************* + * 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 typeVariablesInProgress + = new HashMap(); + 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; + } + + +} diff --git a/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java b/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java index f7ded6117..b8363d040 100644 --- a/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java +++ b/weaver5/java5-testsrc/org/aspectj/weaver/tools/Java15PointcutExpressionTest.java @@ -14,6 +14,7 @@ package org.aspectj.weaver.tools; 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; @@ -37,6 +38,7 @@ public class Java15PointcutExpressionTest extends TestCase { 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)"); @@ -116,6 +118,18 @@ public class Java15PointcutExpressionTest extends TestCase { 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); @@ -241,12 +255,34 @@ public class Java15PointcutExpressionTest extends TestCase { assertTrue("matches",sMatch.alwaysMatches()); } + public void testGenericMethodSignatures() throws Exception{ + PointcutExpression ex = parser.parsePointcutExpression("execution(* set*(java.util.List))"); + 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) @@ -262,6 +298,8 @@ public class Java15PointcutExpressionTest extends TestCase { 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 { @@ -272,6 +310,18 @@ public class Java15PointcutExpressionTest extends TestCase { @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 friends) {} + } } diff --git a/weaver5/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java b/weaver5/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java index 53d1a6089..dba650e63 100644 --- a/weaver5/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java +++ b/weaver5/testsrc/org/aspectj/weaver/tools/PointcutExpressionTest.java @@ -555,4 +555,5 @@ public class PointcutExpressionTest extends TestCase { } static class X {} + } -- 2.39.5