]> source.dussan.org Git - aspectj.git/commitdiff
Fix for ordering problem when using generic abstract aspects. Fix for crappy code...
authoraclement <aclement>
Thu, 20 Oct 2005 10:32:20 +0000 (10:32 +0000)
committeraclement <aclement>
Thu, 20 Oct 2005 10:32:20 +0000 (10:32 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java
tests/java5/generics/genericaspects/BlobContainment.aj
tests/java5/generics/genericaspects/ParentChildRelationship.aj
tests/java5/generics/genericaspects/TheBigOne.java [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

index 58e650286b569670f871716f1e7e51093e0447c5..c3756aec0e9bcc9f5001a84ede48c98c03909064 100644 (file)
@@ -47,6 +47,7 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
+import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
@@ -251,8 +252,16 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC
                // Look at the supertype first
                ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.COLLECTING_ITDS_AND_DECLARES, sourceType.sourceName);
            ReferenceBinding superType = sourceType.superclass();
-           if (yetToProcess.contains(superType) && superType instanceof SourceTypeBinding) {
-               collectAllITDsAndDeclares((SourceTypeBinding)superType, yetToProcess);
+           if (superType instanceof SourceTypeBinding) {
+                   if (yetToProcess.contains(superType)) {
+                       collectAllITDsAndDeclares((SourceTypeBinding)superType, yetToProcess);
+                   }
+           } else if (superType instanceof ParameterizedTypeBinding) {
+               // If its a PTB we need to pull the SourceTypeBinding out of it.
+               ParameterizedTypeBinding ptb = (ParameterizedTypeBinding)superType;
+               if (ptb.type instanceof SourceTypeBinding && yetToProcess.contains(ptb.type)) {
+                       collectAllITDsAndDeclares((SourceTypeBinding)ptb.type, yetToProcess);
+               }
            }
         buildInterTypeAndPerClause(sourceType.scope);
         addCrosscuttingStructures(sourceType.scope);
index 923e12224ff2a1242438d4952b46eee4728c8cfd..9ae21df0bca15f714670c85fa4d7ccea139fcb68 100644 (file)
@@ -1,6 +1,5 @@
 public aspect BlobContainment extends ParentChildRelationship<Blob,Blob> {
 
-
   public static void main(String []argv) {
     Blob a = new Blob();
     Blob b = new Blob();
@@ -17,12 +16,14 @@ public aspect BlobContainment extends ParentChildRelationship<Blob,Blob> {
 
     // now query the layout
 
+/*
     if (!e.getParent().equals(b)) 
       throw new RuntimeException("why is E not parent of B? "+e.getParent());
     if (!d.getParent().equals(a)) 
       throw new RuntimeException("why is A not parent of D? "+d.getParent());
     if (a.getChildren().size()!=3)
       throw new RuntimeException("A should have 3 children, not:"+a.getChildren().size());
+*/
   }
 
 }
index 6d9624d6d0be26c0f7ae97c9642052ca6aa4f090..b5fb093fb43c7c8c4952238686daadcc41e18ace 100644 (file)
@@ -1,57 +1,99 @@
 import java.util.*;
 import org.aspectj.lang.annotation.*;
+
+abstract aspect ParentChildRelationship<Parent,Child> {
+
+  interface ParentHasChildren<C>{}
+  interface ChildHasParent<P>{}
+
+  declare parents: Parent implements ParentHasChildren<Child>;
+  declare parents: Child  implements ChildHasParent<Parent>;
+
+  public List<E> ParentHasChildren<E>.children = new ArrayList<E>();
+  public P ChildHasParent<P>.parent;
+
+  public List<D> ParentHasChildren<D>.getChildren() {
+    return Collections.unmodifiableList(children);
+  }
+
+  public P ChildHasParent<P>.getParent() {
+    return parent;
+  }
+
+  public void ChildHasParent<R>.setParent(R parent) {
+    this.parent = parent;
+    ParentHasChildren phc = (ParentHasChildren)parent;
+    if (phc.getChildren().contains(this))
+    phc.addChild(this);
+  }
+
+  public void ParentHasChildren<X>.addChild(X child) {
+    if (((ChildHasParent)child).parent != null) {
+      ((ParentHasChildren)((ChildHasParent)child).parent).removeChild(child);
+    } else {
+      ((ChildHasParent)child).setParent((ParentHasChildren)this);
+    }
+    children.add(child);
+  }
+
+  public void ParentHasChildren<Y>.removeChild(Y child) {
+    if (children.remove(child)) {
+      ((ChildHasParent)child).parent = null;
+    }
+  }
+
+}
+/*
 abstract aspect ParentChildRelationship<Parent,Child> {
 
-  /** interface implemented by parents */   
+  // interface implemented by parents    
   interface ParentHasChildren<C>{
-//    List<C> getChildren();
-//    void addChild(C child);
-//    void removeChild(C child);
+    List<C> getChildren();
+    void addChild(C child);
+    void removeChild(C child);
   }
 
-  /** interface implemented by children */
+  // interface implemented by children 
   interface ChildHasParent<P>{
-//    P getParent();
-//    void setParent(P parent);
+    P getParent();
+    void setParent(P parent);
   }
 
-  /** ensure the parent type implements ParentHasChildren<child type> */
+  // ensure the parent type implements ParentHasChildren<child type> 
   declare parents: Parent implements ParentHasChildren<Child>;
 
-  /** ensure the child type implements ChildHasParent<parent type> */
+  // ensure the child type implements ChildHasParent<parent type>
   declare parents: Child  implements ChildHasParent<Parent>;
 
   // Inter-type declarations made on the *generic* interface types to provide 
   // default implementations.
 
-  /** list of children maintained by parent */
+  // list of children maintained by parent 
   public List<E> ParentHasChildren<E>.children = new ArrayList<E>();
 
-  /** reference to parent maintained by child */        
+  // reference to parent maintained by child 
   public P ChildHasParent<P>.parent;
 
-  /** Default implementation of getChildren for the generic type ParentHasChildren */
+  // Default implementation of getChildren for the generic
+  //  type ParentHasChildren 
   public List<D> ParentHasChildren<D>.getChildren() {
     return Collections.unmodifiableList(children);  
   }
 
-  /** Default implementation of getParent for the generic type ChildHasParent */    
+  // Default implementation of getParent for the generic
+  //  type ChildHasParent 
   public P ChildHasParent<P>.getParent() {
     return parent;
   }
 
-    /**
-      * Default implementation of setParent for the generic type ChildHasParent.
-      * Ensures that this child is added to the children of the parent too.
-      */
+  // Default implementation of setParent for the generic type ChildHasParent.
+  // Ensures that this child is added to the children of the parent too.
   public void ChildHasParent<R>.setParent(R parent) {
     ((ParentHasChildren)parent).addChild(this);
   }
 
-  /** 
-    * Default implementation of addChild, ensures that parent of child is
-    * also updated.
-    */ 
+  // Default implementation of addChild, ensures that parent of child is
+  // also updated.
   public void ParentHasChildren<X>.addChild(X child) {
     if (((ChildHasParent)child).parent != null) {
       ((ParentHasChildren)((ChildHasParent)child).parent).removeChild(child);
@@ -60,27 +102,23 @@ abstract aspect ParentChildRelationship<Parent,Child> {
     ((ChildHasParent)child).parent = (ParentHasChildren)this;
   }
 
-   /**
-     * Default implementation of removeChild, ensures that parent of
-     * child is also updated.
-     */
+  // Default implementation of removeChild, ensures that parent of
+  //  child is also updated.
   public void ParentHasChildren<Y>.removeChild(Y child) {
     if (children.remove(child)) {
       ((ChildHasParent)child).parent = null;
     }
   }
-    /**
-      * Matches at an addChild join point for the parent type P and child type C
-      */    
+
+  // Matches at an addChild join point for the parent type P and child type C
     @SuppressAjWarnings
     public pointcut addingChild(Parent p, Child c) :
       execution(* Parent.addChild(Child)) && this(p) && args(c);
       
-    /**
-      * Matches at a removeChild join point for the parent type P and child type C
-      */    
-    @SuppressAjWarnings
-    public pointcut removingChild(Parent p, Child c) :
-      execution(* Parent.removeChild(Child)) && this(p) && args(c);
+  // Matches at a removeChild join point for the parent type P and child type C
+  @SuppressAjWarnings
+  public pointcut removingChild(Parent p, Child c) :
+    execution(* Parent.removeChild(Child)) && this(p) && args(c);
 
 }
+*/
diff --git a/tests/java5/generics/genericaspects/TheBigOne.java b/tests/java5/generics/genericaspects/TheBigOne.java
new file mode 100644 (file)
index 0000000..42be102
--- /dev/null
@@ -0,0 +1,76 @@
+import java.util.*;
+import org.aspectj.lang.annotation.*;
+
+class Blob {}
+
+public aspect TheBigOne extends ParentChildRelationship<Blob,Blob> {
+
+  public static void main(String []argv) {
+    Blob a = new Blob();
+    Blob b = new Blob();
+    Blob c = new Blob();
+    Blob d = new Blob();
+    Blob e = new Blob();
+
+    // arrange as follows: A contains B,C,D and B contains E
+
+    a.addChild(b);
+    a.addChild(c);
+    a.addChild(d);
+    b.addChild(e);
+
+    // now query the layout
+
+    if (!e.getParent().equals(b)) 
+      throw new RuntimeException("why is E not parent of B? "+e.getParent());
+    if (!d.getParent().equals(a)) 
+      throw new RuntimeException("why is A not parent of D? "+d.getParent());
+    if (a.getChildren().size()!=3)
+      throw new RuntimeException("A should have 3 children, not:"+a.getChildren().size());
+  }
+
+}
+
+
+abstract aspect ParentChildRelationship<Parent,Child> {
+
+  interface ParentHasChildren<C>{}
+  interface ChildHasParent<P>{}
+
+  declare parents: Parent implements ParentHasChildren<Child>;
+  declare parents: Child  implements ChildHasParent<Parent>;
+
+  public List<E> ParentHasChildren<E>.children = new ArrayList<E>();
+  public P ChildHasParent<P>.parent;
+
+  public List<D> ParentHasChildren<D>.getChildren() {
+    return Collections.unmodifiableList(children);
+  }
+
+  public P ChildHasParent<P>.getParent() {
+    return parent;
+  }
+
+  public void ChildHasParent<R>.setParent(R parent) {
+    this.parent = parent;
+    ParentHasChildren phc = (ParentHasChildren)parent;
+    if (phc.getChildren().contains(this))
+    phc.addChild(this);
+  }
+
+  public void ParentHasChildren<X>.addChild(X child) {
+    if (((ChildHasParent)child).parent != null) {
+      ((ParentHasChildren)((ChildHasParent)child).parent).removeChild(child);
+    } else {
+      ((ChildHasParent)child).setParent((ParentHasChildren)this);
+    }
+    children.add(child);
+  }
+
+  public void ParentHasChildren<Y>.removeChild(Y child) {
+    if (children.remove(child)) {
+      ((ChildHasParent)child).parent = null;
+    }
+  }
+
+}
index b761d28e74d4ce63f0a0fde953111b4322bfb9cf..6348d63714e98a6b989f9489addadffe4428ad16 100644 (file)
@@ -170,10 +170,6 @@ public class GenericsTests extends XMLBasedAjcTestCase {
         * TODO exotic class/interface bounds ('? extends List<String>','? super anything')
         * TODO signature attributes for generic ITDs (public only?)
         * 
-        * 
-        * strangeness:
-        * 
-        *   adding declare precedence into the itds/binaryweaving A2.aj, A3.aj causes a bizarre classfile inconsistent message
         */
        
        public static Test suite() {
@@ -221,8 +217,8 @@ public class GenericsTests extends XMLBasedAjcTestCase {
        public void testPR96220_GenericAspects2() {runTest("generic aspects - 2");}
        public void testPR96220_GenericAspects3() {runTest("generic aspects - 3");}
        public void testGenericAspects4()         {runTest("generic aspects - 4");} 
-    // TODO FREAKYGENERICASPECTPROBLEM why does everything have to be in one source file?
-       // public void testGenericAspects5()         {runTest("generic aspects - 5 (ajdk)");} 
+       public void testGenericAspects5()         {runTest("generic aspects - 5 (ajdk)");}  // in separate files
+       public void testGenericAspects6()         {runTest("generic aspects - 6 (ajdk)");}  // all in one file
        public void testTypeVariablesInDeclareWarning() { runTest("generic aspect with declare warning using type vars");}
        public void testTypeVariablesInExecutionAdvice() { runTest("generic aspect with execution advice using type vars");}
        public void testTypeVariablesInAnonymousPointcut() { runTest("generic aspect with anonymous pointcut");}
index 5e907a2c8d7c43722ddc0833ee71eb41788ed13b..4c43a907e37c0d85bc1007cb062165c3677886cc 100644 (file)
      <run class="BlobContainment"/>
    </ajc-test>
    
+   <!-- same as above but all types in one file -->
+   <ajc-test dir="java5/generics/genericaspects" title="generic aspects - 6 (ajdk)">
+     <compile files="TheBigOne.java" options="-1.5"/>
+     <run class="TheBigOne"/>
+   </ajc-test>
+   
    <!-- end of generic aspects -->
    
    <!-- generic ITDs -->
index ba8271901a4819376d7e9ff172ddf734bfa11592..257cfb58ca7645f7a13586116401fa7b387885fa 100644 (file)
@@ -1288,10 +1288,10 @@ public abstract class ResolvedType extends UnresolvedType implements AnnotatedEl
             for (int i = 0; i < superIs.length; i++) {
                     ResolvedType superI = superIs[i];
                     if (superI.genericTypeEquals(lookingFor)) return superI;
-                    ResolvedType checkTheSuperI = discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
+                    ResolvedType checkTheSuperI = superI.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
                     if (checkTheSuperI!=null) return checkTheSuperI;
             }
-            return discoverActualOccurrenceOfTypeInHierarchy(superT);
+            return superT.discoverActualOccurrenceOfTypeInHierarchy(lookingFor);
     }
 
     /**