diff options
author | aclement <aclement> | 2008-01-17 00:24:51 +0000 |
---|---|---|
committer | aclement <aclement> | 2008-01-17 00:24:51 +0000 |
commit | c67a173f7f05d9725446e59fa491bd29b4150378 (patch) | |
tree | 32ebd00974d5a65f3d05bd3b27448630e2c91f2c | |
parent | c3a96ab7368037ebd2bd1a4b176d6767560f39ac (diff) | |
download | aspectj-c67a173f7f05d9725446e59fa491bd29b4150378.tar.gz aspectj-c67a173f7f05d9725446e59fa491bd29b4150378.zip |
AspectJ6: beginnings of fix for proper parameterization of generic ITDs
10 files changed, 208 insertions, 5 deletions
diff --git a/weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java b/weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java index abb85f65a..65a485e00 100644 --- a/weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/ConcreteTypeMunger.java @@ -13,6 +13,8 @@ package org.aspectj.weaver; +import java.util.Map; + import org.aspectj.bridge.ISourceLocation; import org.aspectj.util.PartialOrder; @@ -123,4 +125,6 @@ public abstract class ConcreteTypeMunger implements PartialOrder.PartialComparab if (munger==null) return false; return munger.isLateMunger(); } + + public abstract ConcreteTypeMunger parameterizeWith(Map parameterizationMap, World world); } diff --git a/weaver/src/org/aspectj/weaver/JoinPointSignature.java b/weaver/src/org/aspectj/weaver/JoinPointSignature.java index 246de45f3..57752d232 100644 --- a/weaver/src/org/aspectj/weaver/JoinPointSignature.java +++ b/weaver/src/org/aspectj/weaver/JoinPointSignature.java @@ -16,6 +16,7 @@ import java.io.IOException; import java.util.Collection; import java.util.Iterator; import java.util.List; +import java.util.Map; import org.aspectj.bridge.ISourceLocation; import org.aspectj.weaver.AjAttribute.EffectiveSignatureAttribute; @@ -406,4 +407,8 @@ public class JoinPointSignature implements ResolvedMember { } public void evictWeavingState() { realMember.evictWeavingState(); } + + public ResolvedMember parameterizedWith(Map m, World w) { + return realMember.parameterizedWith(m,w); + } } diff --git a/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java b/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java index 6a0974965..19ed670ab 100644 --- a/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/NewFieldTypeMunger.java @@ -16,6 +16,7 @@ package org.aspectj.weaver; import java.io.DataOutputStream; import java.io.IOException; import java.util.List; +import java.util.Map; import java.util.Set; import org.aspectj.bridge.ISourceLocation; @@ -94,6 +95,14 @@ public class NewFieldTypeMunger extends ResolvedTypeMunger { return nftm; } + public ResolvedTypeMunger parameterizeWith(Map m, World w) { + ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m,w); + NewFieldTypeMunger nftm = new NewFieldTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases); + nftm.setDeclaredSignature(getSignature()); + nftm.setSourceLocation(getSourceLocation()); + return nftm; + } + public boolean equals(Object other) { if (! (other instanceof NewFieldTypeMunger)) return false; NewFieldTypeMunger o = (NewFieldTypeMunger) other; diff --git a/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java b/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java index 05b6112ce..7ce5e1e8a 100644 --- a/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/NewMethodTypeMunger.java @@ -16,11 +16,15 @@ package org.aspectj.weaver; import java.io.DataOutputStream; import java.io.IOException; import java.util.List; +import java.util.Map; import java.util.Set; import org.aspectj.bridge.ISourceLocation; +import org.aspectj.weaver.patterns.DeclareParents; public class NewMethodTypeMunger extends ResolvedTypeMunger { + + public NewMethodTypeMunger( ResolvedMember signature, Set superMethodsCalled, @@ -128,5 +132,13 @@ public class NewMethodTypeMunger extends ResolvedTypeMunger { result = 37*result + ((typeVariableAliases == null) ? 0 : typeVariableAliases.hashCode()); return result; } - + + public ResolvedTypeMunger parameterizeWith(Map m, World w) { + ResolvedMember parameterizedSignature = getSignature().parameterizedWith(m,w); + NewMethodTypeMunger nmtm = new NewMethodTypeMunger(parameterizedSignature,getSuperMethodsCalled(),typeVariableAliases); + nmtm.setDeclaredSignature(getSignature()); + nmtm.setSourceLocation(getSourceLocation()); + return nmtm; + } + } diff --git a/weaver/src/org/aspectj/weaver/ReferenceType.java b/weaver/src/org/aspectj/weaver/ReferenceType.java index 31313cad8..8ffac153b 100644 --- a/weaver/src/org/aspectj/weaver/ReferenceType.java +++ b/weaver/src/org/aspectj/weaver/ReferenceType.java @@ -65,6 +65,7 @@ public class ReferenceType extends ResolvedType { ResolvedMember[] parameterizedPointcuts = null; ResolvedType[] parameterizedInterfaces = null; Collection parameterizedDeclares = null; + Collection parameterizedTypeMungers = null; //??? should set delegate before any use public ReferenceType(String signature, World world) { @@ -596,7 +597,28 @@ public class ReferenceType extends ResolvedType { return declares; } - protected Collection getTypeMungers() { return delegate.getTypeMungers(); } + protected Collection getTypeMungers() { + return delegate.getTypeMungers(); + } + // GENERICITDFIX +//// Map parameterizationMap = getAjMemberParameterizationMap(); +// +// // if (parameterizedTypeMungers != null) return parameterizedTypeMungers; +// Collection ret = null; +// if (ajMembersNeedParameterization()) { +// Collection genericDeclares = delegate.getTypeMungers(); +// parameterizedTypeMungers = new ArrayList(); +// Map parameterizationMap = getAjMemberParameterizationMap(); +// for (Iterator iter = genericDeclares.iterator(); iter.hasNext();) { +// ConcreteTypeMunger munger = (ConcreteTypeMunger)iter.next(); +// parameterizedTypeMungers.add(munger.parameterizeWith(parameterizationMap,world)); +// } +// ret = parameterizedTypeMungers; +// } else { +// ret = delegate.getTypeMungers(); +// } +// return ret; +// } protected Collection getPrivilegedAccesses() { return delegate.getPrivilegedAccesses(); } diff --git a/weaver/src/org/aspectj/weaver/ResolvedMember.java b/weaver/src/org/aspectj/weaver/ResolvedMember.java index 1664f1a18..61008578f 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMember.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMember.java @@ -16,6 +16,7 @@ package org.aspectj.weaver; import java.io.DataOutputStream; import java.io.IOException; import java.util.List; +import java.util.Map; import org.aspectj.bridge.ISourceLocation; @@ -159,4 +160,6 @@ public interface ResolvedMember extends Member, AnnotatedElement, TypeVariableDe public void resetReturnTypeToObjectArray(); public void evictWeavingState(); + + public ResolvedMember parameterizedWith(Map m, World w); }
\ No newline at end of file diff --git a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java index d1bff9816..8401fa4c8 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java +++ b/weaver/src/org/aspectj/weaver/ResolvedMemberImpl.java @@ -660,6 +660,68 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno ret.setParameterNames(getParameterNames()); return ret; } + + + /** + * Replace occurrences of type variables in the signature with values contained in the map. The map is of the form A=String,B=Integer and + * so a signature List<A> Foo.m(B i) {} would become List<String> Foo.m(Integer i) {} + */ + public ResolvedMember parameterizedWith(Map m, World w) { +// if (//isParameterized && <-- might need this bit... +// !getDeclaringType().isGenericType()) { +// throw new IllegalStateException("Can't ask to parameterize a member of non-generic type: "+getDeclaringType()+" kind("+getDeclaringType().typeKind+")"); +// } + declaringType = declaringType.resolve(w); + if (declaringType.isRawType()) declaringType = ((ResolvedType)declaringType).getGenericType(); + 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); +// } +// } +// // For ITDs on generic types that use type variables from the target type, the aliases +// // record the alternative names used throughout the ITD expression that must map to +// // the same value as the type variables real name. +// if (aliases!=null) { +// int posn = 0; +// for (Iterator iter = aliases.iterator(); iter.hasNext();) { +// String typeVariableAlias = (String) iter.next(); +// typeMap.put(typeVariableAlias,(!typeParametersSupplied?typeVariables[posn].getFirstBound():typeParameters[posn])); +// posn++; +// } +// } + + UnresolvedType parameterizedReturnType = parameterize(getGenericReturnType(),m,true,w); + UnresolvedType[] parameterizedParameterTypes = new UnresolvedType[getGenericParameterTypes().length]; + UnresolvedType[] genericParameterTypes = getGenericParameterTypes(); + for (int i = 0; i < parameterizedParameterTypes.length; i++) { + parameterizedParameterTypes[i] = + parameterize(genericParameterTypes[i], m,true,w); + } + ResolvedMemberImpl ret = new ResolvedMemberImpl( + getKind(), + declaringType, + getModifiers(), + parameterizedReturnType, + getName(), + parameterizedParameterTypes, + getExceptions(), + this + ); + ret.setTypeVariables(getTypeVariables()); + ret.setSourceContext(getSourceContext()); + ret.setPosition(getStart(),getEnd()); + ret.setParameterNames(getParameterNames()); + return ret; + } public void setTypeVariables(TypeVariable[] tvars) { typeVariables = tvars; @@ -668,8 +730,12 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno public TypeVariable[] getTypeVariables() { return typeVariables; } - + protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType) { + return parameterize(aType,typeVariableMap,inParameterizedType,null); + } + + protected UnresolvedType parameterize(UnresolvedType aType, Map typeVariableMap, boolean inParameterizedType,World w) { if (aType instanceof TypeVariableReference) { String variableName = ((TypeVariableReference)aType).getTypeVariable().getName(); if (!typeVariableMap.containsKey(variableName)) { @@ -678,7 +744,15 @@ public class ResolvedMemberImpl extends MemberImpl implements IHasPosition, Anno return (UnresolvedType) typeVariableMap.get(variableName); } else if (aType.isParameterizedType()) { if (inParameterizedType) { - if (aType instanceof UnresolvedType) aType= aType.resolve(((ResolvedType)getDeclaringType()).getWorld()); +// if (!(getDeclaringType() instanceof ResolvedType)) { +// int stop = 1; +// } + if (aType instanceof UnresolvedType) { + if (w!=null) aType = aType.resolve(w); + else { + aType= aType.resolve(((ResolvedType)getDeclaringType()).getWorld()); + } + } return aType.parameterize(typeVariableMap); } else { return aType.getRawType(); diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index 7d0bf1faf..65fa61ac9 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -508,7 +508,9 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl crosscuttingMembers = new CrosscuttingMembers(this,shouldConcretizeIfNeeded); crosscuttingMembers.setPerClause(getPerClause()); crosscuttingMembers.addShadowMungers(collectShadowMungers()); - crosscuttingMembers.addTypeMungers(getTypeMungers()); + // GENERICITDFIX +// crosscuttingMembers.addTypeMungers(collectTypeMungers()); + crosscuttingMembers.addTypeMungers(getTypeMungers()); //FIXME AV - skip but needed ?? or ?? crosscuttingMembers.addLateTypeMungers(getLateTypeMungers()); crosscuttingMembers.addDeclares(collectDeclares(!this.doesNotExposeShadowMungers())); crosscuttingMembers.addPrivilegedAccesses(getPrivilegedAccesses()); @@ -518,6 +520,41 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl return crosscuttingMembers; } + public final Collection collectTypeMungers() { + if (! this.isAspect() ) return Collections.EMPTY_LIST; + + ArrayList ret = new ArrayList(); + //if (this.isAbstract()) { +// for (Iterator i = getDeclares().iterator(); i.hasNext();) { +// Declare dec = (Declare) i.next(); +// if (!dec.isAdviceLike()) ret.add(dec); +// } +// +// if (!includeAdviceLike) return ret; + + if (!this.isAbstract()) { + final Iterators.Filter dupFilter = Iterators.dupFilter(); + Iterators.Getter typeGetter = new Iterators.Getter() { + public Iterator get(Object o) { + return + dupFilter.filter( + ((ResolvedType)o).getDirectSupertypes()); + } + }; + Iterator typeIterator = Iterators.recur(this, typeGetter); + + while (typeIterator.hasNext()) { + ResolvedType ty = (ResolvedType) typeIterator.next(); + for (Iterator i = ty.getTypeMungers().iterator(); i.hasNext();) { + ConcreteTypeMunger dec = (ConcreteTypeMunger) i.next(); + ret.add(dec); + } + } + } + + return ret; + } + public final Collection collectDeclares(boolean includeAdviceLike) { if (! this.isAspect() ) return Collections.EMPTY_LIST; @@ -1480,6 +1517,22 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl //??? returning too soon private boolean compareToExistingMembers(ConcreteTypeMunger munger, Iterator existingMembers) { ResolvedMember sig = munger.getSignature(); + + ResolvedType declaringAspectType = munger.getAspectType(); +// if (declaringAspectType.isRawType()) declaringAspectType = declaringAspectType.getGenericType(); +// if (declaringAspectType.isGenericType()) { +// +// ResolvedType genericOnType = getWorld().resolve(sig.getDeclaringType()).getGenericType(); +// ConcreteTypeMunger ctm = munger.parameterizedFor(discoverActualOccurrenceOfTypeInHierarchy(genericOnType)); +// sig = ctm.getSignature(); // possible sig change when type +// } +// if (munger.getMunger().hasTypeVariableAliases()) { +// ResolvedType genericOnType = +// getWorld().resolve(sig.getDeclaringType()).getGenericType(); +// ConcreteTypeMunger ctm = +// munger.parameterizedFor(discoverActualOccurrenceOfTypeInHierarchy(genericOnType)); +// sig = ctm.getSignature(); // possible sig change when type parameters filled in +// } while (existingMembers.hasNext()) { ResolvedMember existingMember = (ResolvedMember)existingMembers.next(); diff --git a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java index 594e31030..f3c631399 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/ResolvedTypeMunger.java @@ -26,6 +26,7 @@ import java.util.Collections; import java.util.HashSet; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.aspectj.bridge.ISourceLocation; @@ -68,6 +69,17 @@ public abstract class ResolvedTypeMunger { if (declaringType.isRawType()) throw new IllegalStateException("Use generic type, not raw type"); if (declaringType.isParameterizedType()) throw new IllegalStateException("Use generic type, not parameterized type"); } +// boolean aChangeOccurred = false; +// +// UnresolvedType rt = signature.getReturnType(); +// if (rt.isParameterizedType() || rt.isGenericType()) {rt = rt.getRawType();aChangeOccurred=true;} +// UnresolvedType[] pt = signature.getParameterTypes(); +// for (int i = 0; i < pt.length; i++) { +// if (pt[i].isParameterizedType() || pt[i].isGenericType()) { pt[i] = pt[i].getRawType();aChangeOccurred=true;} +// } +// if (aChangeOccurred) { +// this.signature = new ResolvedMemberImpl(signature.getKind(),signature.getDeclaringType(),signature.getModifiers(),rt,signature.getName(),pt,signature.getExceptions()); +// } } public void setSourceLocation(ISourceLocation isl) { @@ -424,5 +436,9 @@ public abstract class ResolvedTypeMunger { public boolean existsToSupportShadowMunging() { return false; } + + public ResolvedTypeMunger parameterizeWith(Map m, World w) { + throw new BCException("Dont call parameterizeWith() on a type munger of this kind: "+this.getClass()); + } } diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java index fec373f0c..143fa1f3b 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelTypeMunger.java @@ -17,6 +17,7 @@ package org.aspectj.weaver.bcel; import java.lang.reflect.Modifier; import java.util.Iterator; import java.util.List; +import java.util.Map; import java.util.Set; import org.aspectj.apache.bcel.Constants; @@ -1713,6 +1714,10 @@ public class BcelTypeMunger extends ConcreteTypeMunger { public ConcreteTypeMunger parameterizedFor(ResolvedType target) { return new BcelTypeMunger(munger.parameterizedFor(target),aspectType); } + + public ConcreteTypeMunger parameterizeWith(Map m, World w) { + return new BcelTypeMunger(munger.parameterizeWith(m,w),aspectType); + } /** * Returns a list of type variable aliases used in this munger. For example, if the |