From f139242382c8ba330d13a93bd75bbef5c06824e3 Mon Sep 17 00:00:00 2001 From: acolyer Date: Thu, 24 Nov 2005 11:05:03 +0000 Subject: [PATCH] fix for parameterizing reference pointcuts with bindings --- .../generics/genericaspects/GenericAspectY.aj | 2 +- .../aspectj/weaver/ResolvedMemberImpl.java | 6 +-- .../weaver/ResolvedPointcutDefinition.java | 35 ++++++++++++++++ .../weaver/patterns/ReferencePointcut.java | 42 ++++++++++--------- 4 files changed, 61 insertions(+), 24 deletions(-) diff --git a/tests/java5/generics/genericaspects/GenericAspectY.aj b/tests/java5/generics/genericaspects/GenericAspectY.aj index b677c3f10..c863fcf41 100644 --- a/tests/java5/generics/genericaspects/GenericAspectY.aj +++ b/tests/java5/generics/genericaspects/GenericAspectY.aj @@ -98,7 +98,7 @@ import org.aspectj.lang.annotation.*; aspect GenericAspectX extends ParentChildRelationship { // Advice to trigger weave infos - before(Top p): ParentChildRelationship.addingChildSimple(p) {} + before(Top p): /*ParentChildRelationship.*/addingChildSimple(p) {} // before(Top p,Bottom c): ParentChildRelationship.addingChild(p,c) {} // before(Top p,Bottom c): ParentChildRelationship.removingChild(p,c) {} diff --git a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java index 7bf91ef84..4a3d6ebc8 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java @@ -661,9 +661,9 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return typeVariables; } - private UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) { - if (aType instanceof TypeVariableReferenceType) { - String variableName = ((TypeVariableReferenceType)aType).getTypeVariable().getName(); + protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) { + if (aType instanceof TypeVariableReference) { + String variableName = ((TypeVariableReference)aType).getTypeVariable().getName(); if (!typeVariableMap.containsKey(variableName)) { return aType; // if the type variable comes from the method (and not the type) thats OK } diff --git a/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java b/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java index 8183ceb24..cf3d5967d 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java +++ b/weaver/src/org/aspectj/weaver/ResolvedPointcutDefinition.java @@ -15,6 +15,8 @@ package org.aspectj.weaver; import java.io.DataOutputStream; import java.io.IOException; +import java.util.HashMap; +import java.util.Map; import org.aspectj.weaver.patterns.Pointcut; @@ -113,6 +115,39 @@ public class ResolvedPointcutDefinition extends ResolvedMemberImpl { * Called when asking a parameterized super-aspect for its pointcuts. */ public ResolvedMemberImpl parameterizedWith(UnresolvedType[] typeParameters, ResolvedType newDeclaringType, boolean isParameterized) { + TypeVariable[] typeVariables = getDeclaringType().getTypeVariables(); + if (isParameterized && (typeVariables.length != typeParameters.length)) { + throw new IllegalStateException("Wrong number of type parameters supplied"); + } + Map typeMap = new HashMap(); + boolean typeParametersSupplied = typeParameters!=null && typeParameters.length>0; + if (typeVariables!=null) { + // If no 'replacements' were supplied in the typeParameters array then collapse + // type variables to their first bound. + for (int i = 0; i < typeVariables.length; i++) { + UnresolvedType ut = (!typeParametersSupplied?typeVariables[i].getFirstBound():typeParameters[i]); + typeMap.put(typeVariables[i].getName(),ut); + } + } + UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),typeMap,isParameterized); + UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length]; + for (int i = 0; i < parameterizedParameterTypes.length; i++) { + parameterizedParameterTypes[i] = + parameterize(getGenericParameterTypes()[i], typeMap,isParameterized); + } + ResolvedPointcutDefinition ret = new ResolvedPointcutDefinition( + newDeclaringType, + getModifiers(), + getName(), + parameterizedParameterTypes, + parameterizedReturnType, + pointcut.parameterizeWith(typeMap) + ); + ret.setTypeVariables(getTypeVariables()); + ret.setSourceContext(getSourceContext()); + ret.setPosition(getStart(),getEnd()); + ret.setParameterNames(getParameterNames()); + //return ret; return this; } diff --git a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java index 6d99ae261..2f2c965a4 100644 --- a/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java +++ b/weaver/src/org/aspectj/weaver/patterns/ReferencePointcut.java @@ -164,7 +164,7 @@ public class ReferencePointcut extends Pointcut { if (pointcutDef == null) { scope.message(IMessage.ERROR, this, "can't find referenced pointcut " + name); return; - } + } // check visibility if (!pointcutDef.isVisible(scope.getEnclosingType())) { @@ -193,12 +193,30 @@ public class ReferencePointcut extends Pointcut { parameterTypes.length + " found " + arguments.size()); return; } - - + + if (onType != null) { + if (onType.isParameterizedType()) { + // build a type map mapping type variable names in the generic type to + // the type parameters presented + typeVariableMap = new HashMap(); + ResolvedType underlyingGenericType = ((ResolvedType) onType).getGenericType(); + TypeVariable[] tVars = underlyingGenericType.getTypeVariables(); + ResolvedType[] typeParams = ((ResolvedType)onType).getResolvedTypeParameters(); + for (int i = 0; i < tVars.length; i++) { + typeVariableMap.put(tVars[i].getName(),typeParams[i]); + } + } else if (onType.isGenericType()) { + scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_REFERENCE_POINTCUT_IN_RAW_TYPE), + getSourceLocation())); + } + } for (int i=0,len=arguments.size(); i < len; i++) { TypePattern p = arguments.get(i); //we are allowed to bind to pointcuts which use subtypes as this is type safe + if (typeVariableMap != null) { + p = p.parameterizeWith(typeVariableMap); + } if (p == TypePattern.NO) { scope.message(IMessage.ERROR, this, "bad parameter to pointcut reference"); @@ -212,23 +230,7 @@ public class ReferencePointcut extends Pointcut { return; } } - - if (onType != null) { - if (onType.isParameterizedType()) { - // build a type map mapping type variable names in the generic type to - // the type parameters presented - typeVariableMap = new HashMap(); - ResolvedType underlyingGenericType = ((ResolvedType) onType).getGenericType(); - TypeVariable[] tVars = underlyingGenericType.getTypeVariables(); - ResolvedType[] typeParams = ((ResolvedType)onType).getResolvedTypeParameters(); - for (int i = 0; i < tVars.length; i++) { - typeVariableMap.put(tVars[i].getName(),typeParams[i]); - } - } else if (onType.isGenericType()) { - scope.message(MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_REFERENCE_POINTCUT_IN_RAW_TYPE), - getSourceLocation())); - } - } + } public void postRead(ResolvedType enclosingType) { -- 2.39.5