]> source.dussan.org Git - aspectj.git/commitdiff
genericitds: 2 big changes here: I've modifed the super/extends stuff so its only...
authoraclement <aclement>
Tue, 9 Aug 2005 10:19:41 +0000 (10:19 +0000)
committeraclement <aclement>
Tue, 9 Aug 2005 10:19:41 +0000 (10:19 +0000)
12 files changed:
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/EclipseFactory.java
tests/java5/generics/itds/MethodITDOnGeneric.aj [deleted file]
tests/java5/generics/itds/ParameterizedMethodITD5.aj [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java
tests/src/org/aspectj/systemtest/ajc150/ajc150.xml
weaver/src/org/aspectj/weaver/ResolvedType.java
weaver/src/org/aspectj/weaver/TypeVariable.java
weaver/src/org/aspectj/weaver/TypeVariableReferenceType.java
weaver/src/org/aspectj/weaver/UnresolvedType.java
weaver/src/org/aspectj/weaver/World.java
weaver/src/org/aspectj/weaver/patterns/WildTypePattern.java
weaver/testsrc/org/aspectj/weaver/bcel/BcelGenericSignatureToTypeXTestCase.java

index 85810deccfd9c2da3cc5c7dca35b427f2fcd80d6..5c803b132f4654ca73108273b436b69fe980baef 100644 (file)
@@ -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 (file)
index ce02433..0000000
+++ /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 (file)
index 0000000..d41667d
--- /dev/null
@@ -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);
+    
+  }
+
+}
index 53a7d5f36e9524f6e16d338f89c1e837d09d550e..593a666797f50166eecf921050611d96d024c956 100644 (file)
@@ -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");
 //     }
index 08f1646149a157042e17de187b1a67162695b8fb..958df13950552e4eb41f5ef4eaff584753ce8625 100644 (file)
      </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 -->
index a8b942c946b8f2334e79a7f2eb03a1e47c9d3379..185c1d9febf00a251c6b8d14e3d05b32454f4783 100644 (file)
@@ -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();
+       }
            
 }
index 35623d7bd81fe6139b3b49d9c44eb4618e99a8be..f450d8b76a436039f8de5743b3505f19c0b248ba 100644 (file)
@@ -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;
+       }
+       
 }
index 9c47db1aab4f011f6c327e9ca608798853f3be3c..17941318a709b6027a8027c3178cb758695f8c81 100644 (file)
@@ -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);
        //}
        
index 320d93e5ccfb5299c12a0941782412ee17b00d9a..5efa8c423ed3b670e2266d89cb10ecd1eb34a6d1 100644 (file)
@@ -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);
+       }
+       
 }
 
index 053a3c10d4ea7e6edfe09a311634d774f486d5aa..c94090ebb30cce2abbf34a5cdc86790dab2158d2 100644 (file)
@@ -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 {
index 834168bfbd403763e35a29616ac18eb07050d47b..01983f3f7532c5228b7099501327e3d4a33f1f51 100644 (file)
@@ -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;
index 35ea06360b75ac7bd0ad78598ef3d84470636a19..a51ffdc2cce0281871c76964f1ec957a84cebe44 100644 (file)
  * ******************************************************************/
 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
  *