diff options
12 files changed, 271 insertions, 86 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java index 85810decc..5c803b132 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java @@ -206,8 +206,8 @@ public class EclipseFactory { // case let's set it correctly based on the one in the eclipse WildcardBinding if (eWB.bound instanceof TypeVariableBinding) { UnresolvedType tVar = fromTypeVariableBinding((TypeVariableBinding)eWB.bound); - if (ut.isGenericWildcardSuper()) ut.setLowerBound(tVar); - if (ut.isGenericWildcardExtends()) ut.setUpperBound(tVar); + if (ut.isGenericWildcard() && ut.isSuper()) ut.setLowerBound(tVar); + if (ut.isGenericWildcard() && ut.isExtends()) ut.setUpperBound(tVar); } return ut; } @@ -297,12 +297,13 @@ public class EclipseFactory { tv.setUpperBound(superclassType); tv.setAdditionalInterfaceBounds(superinterfaces); tv.setRank(aTypeVariableBinding.rank); -// dont need the declaring element yet... -// if (aTypeVariableBinding.declaringElement instanceof MethodBinding) { + if (aTypeVariableBinding.declaringElement instanceof MethodBinding) { + tv.setDeclaringElementKind(TypeVariable.METHOD); // tv.setDeclaringElement(fromBinding((MethodBinding)aTypeVariableBinding.declaringElement); -// } else { + } else { + tv.setDeclaringElementKind(TypeVariable.TYPE); // // tv.setDeclaringElement(fromBinding(aTypeVariableBinding.declaringElement)); -// } + } ret.setTypeVariable(tv); typeVariableBindingsInProgress.remove(aTypeVariableBinding); return ret; @@ -504,12 +505,14 @@ public class EclipseFactory { BoundedReferenceType brt = (BoundedReferenceType)typeX; // Work out 'kind' for the WildcardBinding int boundkind = Wildcard.UNBOUND; - if (brt.isExtends()) boundkind = Wildcard.EXTENDS; - if (brt.isSuper()) boundkind = Wildcard.SUPER; - // get the bound right TypeBinding bound = null; - if (brt.isGenericWildcardExtends()) bound = makeTypeBinding(brt.getUpperBound()); - if (brt.isGenericWildcardSuper()) bound = makeTypeBinding(brt.getLowerBound()); + if (brt.isExtends()) { + boundkind = Wildcard.EXTENDS; + bound = makeTypeBinding(brt.getUpperBound()); + } else if (brt.isSuper()) { + boundkind = Wildcard.SUPER; + bound = makeTypeBinding(brt.getLowerBound()); + } TypeBinding[] otherBounds = null; if (brt.getAdditionalBounds()!=null && brt.getAdditionalBounds().length!=0) otherBounds = makeTypeBindings(brt.getAdditionalBounds()); // FIXME asc rank should not always be 0 ... diff --git a/tests/java5/generics/itds/MethodITDOnGeneric.aj b/tests/java5/generics/itds/MethodITDOnGeneric.aj deleted file mode 100644 index ce024337d..000000000 --- a/tests/java5/generics/itds/MethodITDOnGeneric.aj +++ /dev/null @@ -1,5 +0,0 @@ -class C<A,B> { public B getB(A a) { return null; } } - -aspect X { - public List<C> C<D,C>.getBs(D ds) { return null; } -} diff --git a/tests/java5/generics/itds/ParameterizedMethodITD5.aj b/tests/java5/generics/itds/ParameterizedMethodITD5.aj new file mode 100644 index 000000000..d41667d23 --- /dev/null +++ b/tests/java5/generics/itds/ParameterizedMethodITD5.aj @@ -0,0 +1,18 @@ +class C<A,B> { public B getB(A a) { return null; } } + +aspect X { + public List<C> C<D,C>.getBs(D ds) { return null; } +} + +public class ParameterizedMethodITD5 { + + public static void main(String[]argv) { + C instance = new C<Integer,String>(); + + Integer i = instance.getB("hello"); + + List<String> ls = instance.getBs(3); + + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java index 53a7d5f36..593a66679 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java @@ -114,7 +114,6 @@ public class GenericsTests extends XMLBasedAjcTestCase { * - parameterized ITDs (methods/ctors/fields) * - ITD target: interface/class/aspect * - multiple type variables - * - generic ITDs (like generic methods) * - constructor ITDs, method ITDs * - ITDs sharing type variables with generic types * - relating to above point, this makes generic ITD fields possible @@ -126,8 +125,32 @@ public class GenericsTests extends XMLBasedAjcTestCase { * - do type variables assigned to members need to persist across serialization * - recursive type variable definitions eg. <R extends Comparable<? super R>> * - super/extends with parameterized types <? extends List<String>> - * - source/binary weaving * - multiple ITDs defined in one type that reuse type variable letters, specifying different bounds + * - generic aspects + * + * PASS parsing generic ITDs + * PASS generic methods + * PASS generic constructors + * PASS ITD visibility + * PASS static/nonstatic + * PASS parameterizedITDs + * PASS differing targets (interface/class/aspect) + * PASS multiple type variables in an ITD + * TODO using type variables from the target type in your ITD (no type vars of your own) + * TODO parsing ITDs that share type variables with target type + * TODO sharing type variables (methods) + * TODO sharing type variables (fields) + * TODO sharing type variables (constructors) + * TODO sharing type variables and having your own type variables (methods/constructors) + * TODO signature attributes for generic ITDs (public only?) + * TODO binary weaving with changing types (moving between generic and simple) + * TODO bridge method creation + * TODO reusing type variable letter but differing spec across multiple ITDs in one aspect + * PASS wildcards + * TODO exotic class/interface bounds ('? extends List<String>') + * PASS recursive type variable definitions + * TODO generic aspects + * TODO parameterizing ITDs with type variables */ public static Test suite() { @@ -171,44 +194,33 @@ public class GenericsTests extends XMLBasedAjcTestCase { } // generic aspects - public void testPR96220_GenericAspects1() { - runTest("generic aspects - 1"); - } - - public void testPR96220_GenericAspects2() { - runTest("generic aspects - 2"); - } + public void testPR96220_GenericAspects1() {runTest("generic aspects - 1");} + public void testPR96220_GenericAspects2() {runTest("generic aspects - 2");} + public void testPR96220_GenericAspects3() {runTest("generic aspects - 3");} +// public void testGenericAspects4() {runTest("generic aspects - 4");} +// public void testGenericAspects5() {runTest("generic aspects - 5 (ajdk)");} - public void testPR96220_GenericAspects3() { - runTest("generic aspects - 3"); - } + ////////////////////////////////////////////////////////////////////////////// + // Generic/Parameterized ITDs - includes scenarios from developers notebook // + ////////////////////////////////////////////////////////////////////////////// - // Developers notebook // parsing of generic ITD members - public void testParseItdNonStaticMethod() {runTest("Parsing generic ITDs - 1");} public void testParseItdStaticMethod() {runTest("Parsing generic ITDs - 2");} public void testParseItdCtor() {runTest("Parsing generic ITDs - 3");} public void testParseItdComplexMethod() {runTest("Parsing generic ITDs - 4");} // public void testParseItdSharingVars1() {runTest("Parsing generic ITDs - 5");} // public void testParseItdSharingVars2() {runTest("Parsing generic ITDs - 6");} - - public void testItdNonStaticMember() {runTest("itd of non static member");} - public void testItdStaticMember() {runTest("itd of static member");} - - public void testStaticGenericMethodITD() { - runTest("static generic method itd"); - } + // non static - - public void testGenericMethodITD1() {runTest("generic method itd - 1");} // <E> ... (List<? extends E>) - public void testGenericMethodITD2() {runTest("generic method itd - 2");} // <E extends Number> ... (List<? extends E>) called incorrectly - public void testGenericMethodITD3() {runTest("generic method itd - 3");} // <E> ... (List<E>,List<E>) - public void testGenericMethodITD4() {runTest("generic method itd - 4");} // <A,B> ... (List<A>,List<B>) - public void testGenericMethodITD5() {runTest("generic method itd - 5");} // <E> ... (List<E>,List<E>) called incorrectly - public void testGenericMethodITD6() {runTest("generic method itd - 6");} // <E extends Number> ... (List<? extends E>) + public void testGenericMethodITD1() {runTest("generic method itd - 1");} // <E> ... (List<? extends E>) + public void testGenericMethodITD2() {runTest("generic method itd - 2");} // <E extends Number> ... (List<? extends E>) called incorrectly + public void testGenericMethodITD3() {runTest("generic method itd - 3");} // <E> ... (List<E>,List<E>) + public void testGenericMethodITD4() {runTest("generic method itd - 4");} // <A,B> ... (List<A>,List<B>) + public void testGenericMethodITD5() {runTest("generic method itd - 5");} // <E> ... (List<E>,List<E>) called incorrectly + public void testGenericMethodITD6() {runTest("generic method itd - 6");} // <E extends Number> ... (List<? extends E>) public void testGenericMethodITD7() {runTest("generic method itd - 7"); } // <E> ... (List<E>,List<? extends E>) public void testGenericMethodITD8() {runTest("generic method itd - 8"); } // <E> ... (List<E>,List<? extends E>) called incorrectly public void testGenericMethodITD9() {runTest("generic method itd - 9"); } // <R extends Comparable<? super R>> ... (List<R>) @@ -220,30 +232,48 @@ public class GenericsTests extends XMLBasedAjcTestCase { public void testGenericMethodITD15() {runTest("generic method itd - 15");} // <R extends Comparable<? super R>> ... (List<R>) called correctly in a clever way - public void testParameterizedMethodITD1() {runTest("parameterized method itd - 1");} // (List<? extends Super>) - public void testParameterizedMethodITD2() {runTest("parameterized method itd - 2");} // (List<? extends Number>) called incorrectly - public void testParameterizedMethodITD3() {runTest("parameterized method itd - 3");} // (List<? super A>) called incorrectly - public void testParameterizedMethodITD4() {runTest("parameterized method itd - 4");} // (List<? super B>) - + // generic ctors public void testGenericCtorITD1() {runTest("generic ctor itd - 1");} // <T> new(List<T>) public void testGenericCtorITD2() {runTest("generic ctor itd - 2");} // <T> new(List<T>,List<? extends T>) public void testGenericCtorITD3() {runTest("generic ctor itd - 3");} // <T> new(List<T>,Comparator<? super T>) -/* - public void testMultipleGenericITDsInOneFile() { runTest("multiple generic itds in one file");} + // parameterized ITDs + public void testParameterizedMethodITD1() {runTest("parameterized method itd - 1");} // (List<? extends Super>) + public void testParameterizedMethodITD2() {runTest("parameterized method itd - 2");} // (List<? extends Number>) called incorrectly + public void testParameterizedMethodITD3() {runTest("parameterized method itd - 3");} // (List<? super A>) called incorrectly + public void testParameterizedMethodITD4() {runTest("parameterized method itd - 4");} // (List<? super B>) + - // ITDs of differing visibilities + // differing visibilities public void testPublicITDs() {runTest("public itds");} public void testPublicITDsErrors() {runTest("public itds with errors");} public void testPrivateITDs() {runTest("private itds");} public void testPackageITDs() {runTest("package itds");} - // ITDs that share a type variable with the target generic type - public void testMethodITDsSharingTvar() {runTest("method itd sharing type variable with generic type");} - public void testFieldITDsSharingTvar() {runTest("field itd sharing type variable with generic type");} -*/ + + // targetting different types (interface/class/aspect) + public void testTargettingInterface() {runTest("targetting interface");} + public void testTargettingAspect() {runTest("targetting aspect");} + public void testTargettingClass() {runTest("targetting class");} + + + + // sharing a type variable between the ITD and the target generic type +// public void testMethodITDsSharingTvar() {runTest("method itd sharing type variable with generic type");} +// public void testFieldITDsSharingTvar() {runTest("field itd sharing type variable with generic type");} + + + // general tests ... usually just more complex scenarios + public void testReusingTypeVariableLetters() {runTest("reusing type variable letters");} + public void testMultipleGenericITDsInOneFile() {runTest("multiple generic itds in one file");} + public void testItdNonStaticMember() {runTest("itd of non static member");} + public void testItdStaticMember() {runTest("itd of static member");} + public void testStaticGenericMethodITD() {runTest("static generic method itd");} + + + // public void testGenericITFSharingTypeVariable() { // runTest("generic intertype field declaration, sharing type variable"); // } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml index 08f164614..958df1395 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml @@ -2327,6 +2327,16 @@ </run> </ajc-test> + <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 4"> + <compile files="ParentChildRelationship.aj" options="-1.5"/> + </ajc-test> + + <!-- ajdk example --> + <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 5 (ajdk)"> + <compile files="Blob.java,BlobContainment.aj,ParentChildRelationship.aj" options="-1.5"/> + <run class="BlobContainment"/> + </ajc-test> + <!-- end of generic aspects --> <!-- generic ITDs --> diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index a8b942c94..185c1d9fe 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -18,7 +18,6 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Collections; -import java.util.HashMap; import java.util.HashSet; import java.util.Iterator; import java.util.List; @@ -29,6 +28,7 @@ import org.aspectj.bridge.IMessage; import org.aspectj.bridge.ISourceLocation; import org.aspectj.bridge.Message; import org.aspectj.bridge.MessageUtil; +import org.aspectj.util.FuzzyBoolean; import org.aspectj.weaver.patterns.Declare; import org.aspectj.weaver.patterns.PerClause; @@ -1609,6 +1609,69 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl public String getSignatureForAttribute() { throw new RuntimeException("Cannot ask this type "+this+" for a generic sig attribute"); } - + + private FuzzyBoolean parameterizedWithAMemberTypeVariable = FuzzyBoolean.MAYBE; + + /** + * return true if the parameterization of this type includes a member type variable. Member + * type variables occur in generic methods/ctors. + */ + public boolean isParameterizedWithAMemberTypeVariable() { + // MAYBE means we haven't worked it out yet... + if (parameterizedWithAMemberTypeVariable==FuzzyBoolean.MAYBE) { + + // if there are no type parameters then we cant be... + if (typeParameters==null || typeParameters.length==0) { + parameterizedWithAMemberTypeVariable = FuzzyBoolean.NO; + return false; + } + + for (int i = 0; i < typeParameters.length; i++) { + UnresolvedType aType = (ResolvedType)typeParameters[i]; + if (aType.isTypeVariableReference() && ((TypeVariableReference)aType).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) { + parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES; + return true; + } + if (aType.isParameterizedType()) { + boolean b = aType.isParameterizedWithAMemberTypeVariable(); + if (b) { + parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES; + return true; + } + } + if (aType.isGenericWildcard()) { + if (aType.isExtends()) { + boolean b = false; + UnresolvedType upperBound = aType.getUpperBound(); + if (upperBound.isParameterizedType()) { + b = upperBound.isParameterizedWithAMemberTypeVariable(); + } else if (upperBound.isTypeVariableReference() && ((TypeVariableReference)upperBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) { + b = true; + } + if (b) { + parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES; + return true; + } + // FIXME asc need to check additional interface bounds + } + if (aType.isSuper()) { + boolean b = false; + UnresolvedType lowerBound = aType.getLowerBound(); + if (lowerBound.isParameterizedType()) { + b = lowerBound.isParameterizedWithAMemberTypeVariable(); + } else if (lowerBound.isTypeVariableReference() && ((TypeVariableReference)lowerBound).getTypeVariable().getDeclaringElementKind()==TypeVariable.METHOD) { + b = true; + } + if (b) { + parameterizedWithAMemberTypeVariable = FuzzyBoolean.YES; + return true; + } + } + } + } + parameterizedWithAMemberTypeVariable=FuzzyBoolean.NO; + } + return parameterizedWithAMemberTypeVariable.alwaysTrue(); + } } diff --git a/weaver/src/org/aspectj/weaver/TypeVariable.java b/weaver/src/org/aspectj/weaver/TypeVariable.java index 35623d7bd..f450d8b76 100644 --- a/weaver/src/org/aspectj/weaver/TypeVariable.java +++ b/weaver/src/org/aspectj/weaver/TypeVariable.java @@ -34,7 +34,17 @@ public class TypeVariable { private String name; private int rank; - + + // It would be nice to push this field onto the TypeVariableDeclaringElement + // interface (a getKind()) but at the moment we don't always guarantee + // to set the declaring element (eclipse seems to utilise the knowledge of + // what declared the type variable, but we dont yet...) + /** + * What kind of element declared this type variable? + */ + private int declaringElementKind = TYPE; + public static final int METHOD = 1; + public static final int TYPE = 2; private TypeVariableDeclaringElement declaringElement; /** @@ -254,4 +264,13 @@ public class TypeVariable { return declaringElement; } + public void setDeclaringElementKind(int kind) { + this.declaringElementKind = kind; + } + + public int getDeclaringElementKind() { +// if (declaringElementKind==UNKNOWN) throw new RuntimeException("Dont know declarer of this tvar : "+this); + return declaringElementKind; + } + } diff --git a/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java b/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java index 9c47db1aa..17941318a 100644 --- a/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java +++ b/weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java @@ -56,7 +56,7 @@ public class TypeVariableReferenceType extends BoundedReferenceType implements T return true; } -// public ResolvedType resolve(World world) { + //public ResolvedType resolve(World world) { // return super.resolve(world); //} diff --git a/weaver/src/org/aspectj/weaver/UnresolvedType.java b/weaver/src/org/aspectj/weaver/UnresolvedType.java index 320d93e5c..5efa8c423 100644 --- a/weaver/src/org/aspectj/weaver/UnresolvedType.java +++ b/weaver/src/org/aspectj/weaver/UnresolvedType.java @@ -156,6 +156,12 @@ public class UnresolvedType implements TypeVariableDeclaringElement { */ private UnresolvedType lowerBound; + /** + * for wildcards '? extends' or for type variables 'T extends' + */ + private boolean isSuper = false; + private boolean isExtends = false; + /** * Determines if this represents a primitive type. A primitive type * is one of nine predefined resolved types. @@ -172,16 +178,16 @@ public class UnresolvedType implements TypeVariableDeclaringElement { * @see ResolvedType#Double * @see ResolvedType#Void */ - public boolean isPrimitiveType() { return typeKind == TypeKind.PRIMITIVE; } - public boolean isSimpleType() { return typeKind == TypeKind.SIMPLE; } - public boolean isRawType() { return typeKind == TypeKind.RAW; } - public boolean isGenericType() { return typeKind == TypeKind.GENERIC; } - public boolean isParameterizedType() { return typeKind == TypeKind.PARAMETERIZED; } - public boolean isTypeVariableReference() { return typeKind == TypeKind.TYPE_VARIABLE; } - public boolean isGenericWildcard() { return typeKind == TypeKind.WILDCARD; } - public boolean isGenericWildcardExtends() { return isGenericWildcard() && upperBound != null; } - public boolean isGenericWildcardSuper() { return isGenericWildcard() && lowerBound != null; } - + public boolean isPrimitiveType() { return typeKind == TypeKind.PRIMITIVE; } + public boolean isSimpleType() { return typeKind == TypeKind.SIMPLE; } + public boolean isRawType() { return typeKind == TypeKind.RAW; } + public boolean isGenericType() { return typeKind == TypeKind.GENERIC; } + public boolean isParameterizedType() { return typeKind == TypeKind.PARAMETERIZED; } + public boolean isTypeVariableReference() { return typeKind == TypeKind.TYPE_VARIABLE; } + public boolean isGenericWildcard() { return typeKind == TypeKind.WILDCARD; } + public boolean isExtends() { return isExtends;} + public boolean isSuper() { return isSuper; } + // for any reference type, we can get some extra information... public final boolean isArray() { return signature.startsWith("["); } @@ -241,14 +247,17 @@ public class UnresolvedType implements TypeVariableDeclaringElement { */ protected UnresolvedType(String signature) { super(); - // if (signature.indexOf('<') != -1) throw new IllegalStateException("Shouldn't be calling simple signature based type constructor with generic info in signature"); this.signature = signature; this.signatureErasure = signature; + if (signature.charAt(0)=='-') isSuper = true; + if (signature.charAt(0)=='+') isExtends = true; } protected UnresolvedType(String signature, String signatureErasure) { this.signature = signature; this.signatureErasure = signatureErasure; + if (signature.charAt(0)=='-') isSuper = true; + if (signature.charAt(0)=='+') isExtends = true; } // called from TypeFactory @@ -825,7 +834,7 @@ public class UnresolvedType implements TypeVariableDeclaringElement { public String toString() { return type; -} + } private TypeKind(String type) { this.type = type; @@ -834,5 +843,14 @@ public class UnresolvedType implements TypeVariableDeclaringElement { private final String type; } + /** + * Will return true if the type being represented is parameterized with a type variable + * from a generic method/ctor rather than a type variable from a generic type. + * Only subclasses know the answer... + */ + public boolean isParameterizedWithAMemberTypeVariable() { + throw new RuntimeException("I dont know - you should ask a resolved version of me: "+this); + } + } diff --git a/weaver/src/org/aspectj/weaver/World.java b/weaver/src/org/aspectj/weaver/World.java index 053a3c10d..c94090ebb 100644 --- a/weaver/src/org/aspectj/weaver/World.java +++ b/weaver/src/org/aspectj/weaver/World.java @@ -340,18 +340,16 @@ public abstract class World implements Dump.INode { */ private ReferenceType resolveGenericWildcardFor(UnresolvedType aType) { BoundedReferenceType ret = null; - // FIXME asc isExtends? isGenericWildcardExtends? I dont like having two // FIXME asc doesnt take account of additional interface bounds (e.g. ? super R & Serializable - can you do that?) - if (aType.isGenericWildcardExtends()) { + if (aType.isExtends()) { ReferenceType upperBound = (ReferenceType)resolve(aType.getUpperBound()); ret = new BoundedReferenceType(upperBound,true,this); - } else { + } else if (aType.isSuper()) { ReferenceType lowerBound = (ReferenceType) resolve(aType.getLowerBound()); ret = new BoundedReferenceType(lowerBound,false,this); + } else { + // must be ? on its own! } - // FIXME asc verify: I don't think these go in the typemap, it makes it potentially impossible to differentiate different uses of 'T', - // for example '? super T' where T is representing different things in two places would have the same sig (-TT;) - // typeMap.put(aType.getSignature(),ret); return ret; } @@ -593,9 +591,42 @@ public abstract class World implements Dump.INode { private Map tMap = new HashMap(); /** Map of types that may be ejected from the cache if we need space */ private Map expendableMap = new WeakHashMap(); - - /** Add a new type into the map, the key is the type signature */ + + private static final boolean debug = false; + /** + * Add a new type into the map, the key is the type signature. + * Some types do *not* go in the map, these are ones involving + * *member* type variables. The reason is that when all you have is the + * signature which gives you a type variable name, you cannot + * guarantee you are using the type variable in the same way + * as someone previously working with a similarly + * named type variable. So, these do not go into the map: + * - TypeVariableReferenceType. + * - ParameterizedType where a member type variable is involved. + * - BoundedReferenceType when one of the bounds is a type variable. + * + * definition: "member type variables" - a tvar declared on a generic + * method/ctor as opposed to those you see declared on a generic type. + */ public ResolvedType put(String key, ResolvedType type) { + if (type.isParameterizedType() && type.isParameterizedWithAMemberTypeVariable()) { + if (debug) + System.err.println("Not putting a parameterized type that utilises member declared type variables into the typemap: key="+key+" type="+type); + return type; + } + if (type.isTypeVariableReference()) { + if (debug) + System.err.println("Not putting a type variable reference type into the typemap: key="+key+" type="+type); + return type; + } + // this test should be improved - only avoid putting them in if one of the + // bounds is a member type variable + if (type instanceof BoundedReferenceType) { + if (debug) + System.err.println("Not putting a bounded reference type into the typemap: key="+key+" type="+type); + return type; + } + if (isExpendable(type)) { return (ResolvedType) expendableMap.put(key,type); } else { diff --git a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java index 834168bfb..01983f3f7 100644 --- a/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java +++ b/weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java @@ -253,13 +253,13 @@ public class WildTypePattern extends TypePattern { if (lowerBound == null && aType.getLowerBound() != null) return false; if (upperBound != null) { // match ? extends - if (aType.isGenericWildcardSuper()) return false; + if (aType.isGenericWildcard() && aType.isSuper()) return false; if (aType.getUpperBound() == null) return false; return upperBound.matches((ResolvedType)aType.getUpperBound(),staticOrDynamic).alwaysTrue(); } if (lowerBound != null) { // match ? super - if (!aType.isGenericWildcardSuper()) return false; + if (!(aType.isGenericWildcard() && aType.isSuper())) return false; return lowerBound.matches((ResolvedType)aType.getLowerBound(),staticOrDynamic).alwaysTrue(); } return true; diff --git a/weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java b/weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java index 35ea06360..a51ffdc2c 100644 --- a/weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java +++ b/weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java @@ -11,16 +11,14 @@ * ******************************************************************/ package org.aspectj.weaver.bcel; +import junit.framework.TestCase; + import org.aspectj.apache.bcel.Repository; import org.aspectj.apache.bcel.classfile.GenericSignatureParser; import org.aspectj.apache.bcel.classfile.JavaClass; import org.aspectj.apache.bcel.classfile.Signature; -import org.aspectj.weaver.ResolvedType; -import org.aspectj.weaver.TypeVariable; import org.aspectj.weaver.UnresolvedType; -import junit.framework.TestCase; - /** * @author colyer * |