diff options
7 files changed, 171 insertions, 45 deletions
diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java index 58e650286..c3756aec0 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java @@ -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); diff --git a/tests/java5/generics/genericaspects/BlobContainment.aj b/tests/java5/generics/genericaspects/BlobContainment.aj index 923e12224..9ae21df0b 100644 --- a/tests/java5/generics/genericaspects/BlobContainment.aj +++ b/tests/java5/generics/genericaspects/BlobContainment.aj @@ -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()); +*/ } } diff --git a/tests/java5/generics/genericaspects/ParentChildRelationship.aj b/tests/java5/generics/genericaspects/ParentChildRelationship.aj index 6d9624d6d..b5fb093fb 100644 --- a/tests/java5/generics/genericaspects/ParentChildRelationship.aj +++ b/tests/java5/generics/genericaspects/ParentChildRelationship.aj @@ -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 index 000000000..42be102f1 --- /dev/null +++ b/tests/java5/generics/genericaspects/TheBigOne.java @@ -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; + } + } + +} diff --git a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java index b761d28e7..6348d6371 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java +++ b/tests/src/org/aspectj/systemtest/ajc150/GenericsTests.java @@ -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");} diff --git a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml index 5e907a2c8..4c43a907e 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ajc150.xml @@ -3081,6 +3081,12 @@ <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 --> diff --git a/weaver/src/org/aspectj/weaver/ResolvedType.java b/weaver/src/org/aspectj/weaver/ResolvedType.java index ba8271901..257cfb58c 100644 --- a/weaver/src/org/aspectj/weaver/ResolvedType.java +++ b/weaver/src/org/aspectj/weaver/ResolvedType.java @@ -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); } /** |