diff options
author | aclement <aclement> | 2005-08-18 09:50:48 +0000 |
---|---|---|
committer | aclement <aclement> | 2005-08-18 09:50:48 +0000 |
commit | 04bebb62e80e2317cc19139dc71706db613d2d1f (patch) | |
tree | e8692737f133585fced47ef934be3f36c0019917 /tests | |
parent | 8eb191ad3ca2b5ea9365b9baf0db77c344c10a33 (diff) | |
download | aspectj-04bebb62e80e2317cc19139dc71706db613d2d1f.tar.gz aspectj-04bebb62e80e2317cc19139dc71706db613d2d1f.zip |
just a few tests for generic aspects...
Diffstat (limited to 'tests')
18 files changed, 773 insertions, 0 deletions
diff --git a/tests/java5/generics/genericaspects/GenericAspectA.aj b/tests/java5/generics/genericaspects/GenericAspectA.aj new file mode 100644 index 000000000..fcb3090ea --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectA.aj @@ -0,0 +1,19 @@ +// Simple - adding an interface to a type via a generic aspect and decp +abstract aspect GenericAspect<A> { + + declare parents: A implements SimpleI; + + interface SimpleI {} + +} + +aspect GenericAspectA extends GenericAspect<Base> { + public static void main(String []argv) { + Base b = new Base(); + if (!(b instanceof SimpleI)) + throw new RuntimeException("Base should implement SimpleI!"); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectB.aj b/tests/java5/generics/genericaspects/GenericAspectB.aj new file mode 100644 index 000000000..39d262223 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectB.aj @@ -0,0 +1,19 @@ +// Decp a generic interface +abstract aspect GenericAspect<A> { + + declare parents: A implements SimpleI; + + interface SimpleI<X> {} + +} + +aspect GenericAspectB extends GenericAspect<Base> { + public static void main(String []argv) { + Base b = new Base(); + if (!(b instanceof SimpleI)) + throw new RuntimeException("Base should implement SimpleI!"); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectC.aj b/tests/java5/generics/genericaspects/GenericAspectC.aj new file mode 100644 index 000000000..3e1d6c6ee --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectC.aj @@ -0,0 +1,24 @@ +// Decp an interface with an ITD method on it +abstract aspect GenericAspect<A> { + + interface SimpleI {} + + declare parents: A implements SimpleI; + + public int SimpleI.m() { return 4;} + +} + +aspect GenericAspectC extends GenericAspect<Base> { + public static void main(String []argv) { + Base b = new Base(); + + if (!(b instanceof SimpleI)) + throw new RuntimeException("Base should implement SimpleI!"); + + int i = b.m(); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectD.aj b/tests/java5/generics/genericaspects/GenericAspectD.aj new file mode 100644 index 000000000..30775a593 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectD.aj @@ -0,0 +1,24 @@ +// Decp an interface with an ITD field +abstract aspect GenericAspect<A> { + + interface SimpleI {} + + declare parents: A implements SimpleI; + + public int SimpleI.n; + +} + +aspect GenericAspectD extends GenericAspect<Base> { + public static void main(String []argv) { + Base b = new Base(); + + if (!(b instanceof SimpleI)) + throw new RuntimeException("Base should implement SimpleI!"); + + b.n=42; + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectE.aj b/tests/java5/generics/genericaspects/GenericAspectE.aj new file mode 100644 index 000000000..987f3d1a2 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectE.aj @@ -0,0 +1,21 @@ +import java.util.*; + +// Dumbed down to a normal aspect - as its generic form was failing... +public aspect GenericAspectE { + + public void IUtil<Z>.print1() {} + public void IUtil<Z>.print2(Z n) {} + public List<Z> IUtil<Z>.print3() {return null;} + + public static void main(String []argv) { + Base b = new Base(); + b.print1(); + b.print2("hello"); + List<String> s = b.print3(); + } +} + +interface IUtil<X> { } + +class Base implements IUtil<String> {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectF.aj b/tests/java5/generics/genericaspects/GenericAspectF.aj new file mode 100644 index 000000000..bf488eadc --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectF.aj @@ -0,0 +1,23 @@ +import java.util.*; +abstract aspect GenericAspect<A> { + + interface SimpleI<N extends Number> {} + + declare parents: A implements SimpleI<Integer>; + + public List<N> SimpleI<N>.ln; + public J SimpleI<J>.n; + +} + +aspect GenericAspectF extends GenericAspect<Base> { + public static void main(String []argv) { + Base b = new Base(); + + b.ln=new ArrayList<Integer>(); + b.n=new Integer(5); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectG.aj b/tests/java5/generics/genericaspects/GenericAspectG.aj new file mode 100644 index 000000000..4925f9315 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectG.aj @@ -0,0 +1,28 @@ +import java.util.*; + +abstract aspect GenericAspect<A> { + + interface SimpleI<N extends Number> {} + + declare parents: A implements SimpleI<Integer>; + + public void SimpleI<N>.m1() {}; + public List<N> SimpleI<N>.m2() {return null;}; + public void SimpleI<N>.m3(List<N> ln) {}; + public void SimpleI<N>.m4(N n) {}; + +} + +aspect GenericAspectG extends GenericAspect<Base> { + public static void main(String []argv) { + Base b = new Base(); + + b.m1(); + List<Integer> ln = b.m2(); + b.m3(new ArrayList<Integer>()); + b.m4(new Integer(5)); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectH.aj b/tests/java5/generics/genericaspects/GenericAspectH.aj new file mode 100644 index 000000000..9099ef424 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectH.aj @@ -0,0 +1,23 @@ +import java.util.*; + +abstract aspect GenericAspect<A> { + + interface SimpleI<N extends Number> {} + + declare parents: A implements SimpleI<String>; // error - String doesnt meet bounds + + public N SimpleI<N>.m4(N n) { System.err.println(n);return n;} + +} + +aspect GenericAspectH extends GenericAspect<Base> { + public static void main(String []argv) { + Base b = new Base(); + String s = b.m4("hello"); + if (!s.equals("hello")) + throw new RuntimeException("Not hello?? "+s); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectI.aj b/tests/java5/generics/genericaspects/GenericAspectI.aj new file mode 100644 index 000000000..6a9d03b61 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectI.aj @@ -0,0 +1,25 @@ +// here A is modified to implement SimpleI<B> where B is a type var reference +// passed to the generic aspect +import java.util.*; + +abstract aspect GenericAspect<A,B> { + + interface SimpleI<L> {} + + declare parents: A implements SimpleI<B>; + + public N SimpleI<N>.m4(N n) { System.err.println(n);return n;} + +} + +aspect GenericAspectI extends GenericAspect<Base,String> { + public static void main(String []argv) { + Base b = new Base(); + String s = b.m4("hello"); + if (!s.equals("hello")) + throw new RuntimeException("Not hello?? "+s); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectJ.aj b/tests/java5/generics/genericaspects/GenericAspectJ.aj new file mode 100644 index 000000000..e2c318c0a --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectJ.aj @@ -0,0 +1,24 @@ +// Here A is modified to implemen SimpleI<String> +import java.util.*; + +abstract aspect GenericAspect<A> { + + interface SimpleI<X> {} + + declare parents: A implements SimpleI<String>; + + public N SimpleI<N>.m4(N n) { System.err.println(n);return n;} + +} + +aspect GenericAspectJ extends GenericAspect<Base> { + public static void main(String []argv) { + Base b = new Base(); + String s = b.m4("hello"); + if (!s.equals("hello")) + throw new RuntimeException("Not hello?? "+s); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectK.aj b/tests/java5/generics/genericaspects/GenericAspectK.aj new file mode 100644 index 000000000..5c4b72f93 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectK.aj @@ -0,0 +1,23 @@ +import java.util.*; + +abstract aspect GenericAspect<A,B> { + + interface SimpleI<L extends Number> {} + + declare parents: A implements SimpleI<B>; + + public N SimpleI<N>.m4(N n) { System.err.println(n);return n;} + +} + +aspect GenericAspectI extends GenericAspect<Base,String> { // error, String doesnt meet bounds in SimpleI<> in the generic aspect + public static void main(String []argv) { + Base b = new Base(); + String s = b.m4("hello"); + if (!s.equals("hello")) + throw new RuntimeException("Not hello?? "+s); + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectL.aj b/tests/java5/generics/genericaspects/GenericAspectL.aj new file mode 100644 index 000000000..30e2df3a9 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectL.aj @@ -0,0 +1,29 @@ +import java.util.*; + +abstract aspect GenericAspect<A,B> { + + interface SimpleI<L> {} + + declare parents: A implements SimpleI<B>; + + public N SimpleI<N>.m0(N n) { System.err.println(n);return n;} + public List<N> SimpleI<N>.m1(List<N> ln) { System.err.println(ln);return ln;} + public N SimpleI<N>.f; + public List<N> SimpleI<N>.lf; + +} + +aspect GenericAspectL extends GenericAspect<Base,String> { + public static void main(String []argv) { + Base b = new Base(); + List<String> ls = new ArrayList<String>(); + String s = b.m0("hello"); + List<String> ls2 = b.m1(ls); + + b.f="hello"; + b.lf=ls; + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectM.aj b/tests/java5/generics/genericaspects/GenericAspectM.aj new file mode 100644 index 000000000..94abd653f --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectM.aj @@ -0,0 +1,31 @@ +// lots of errors +import java.util.*; + +abstract aspect GenericAspect<A,B> { + + interface SimpleI<L> {} + + declare parents: A implements SimpleI<B>; + + public N SimpleI<N>.m0(N n) { System.err.println(n);return n;} + public List<N> SimpleI<N>.m1(List<N> ln) { System.err.println(ln);return ln;} + public N SimpleI<N>.f; + public List<N> SimpleI<N>.lf; + +} + +// We are making the decp put SimpleI<Integer> on Base - so all these string +// things below should fail! +aspect GenericAspectM extends GenericAspect<Base,Integer> { + public static void main(String []argv) { + Base b = new Base(); + List<String> ls = new ArrayList<String>(); + String s = b.m0("hello"); // error + List<String> ls2 = b.m1(ls);// error + b.f="hello";// error + b.lf=ls;// error + } +} + +class Base {} + diff --git a/tests/java5/generics/genericaspects/GenericAspectN.aj b/tests/java5/generics/genericaspects/GenericAspectN.aj new file mode 100644 index 000000000..72ad8f1bf --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectN.aj @@ -0,0 +1,104 @@ +import java.util.*; +import java.lang.reflect.*; +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>; + +} + +aspect GenericAspectN extends ParentChildRelationship<Top,Bottom> { + + + public static void main(String []argv) { + + // Check the state of top + Top t = new Top(); + check(t instanceof ParentHasChildren,"Top should implement ParentHasChildren"); + Type[] intfs = Top.class.getGenericInterfaces(); + check(intfs[0] instanceof ParameterizedType, + "Expected Top to have parameterized interface but found "+intfs[0]); + ParameterizedType pt = (ParameterizedType) intfs[0]; + Type[] tArgs = pt.getActualTypeArguments(); + check(tArgs[0]==Bottom.class, + "Expecting Bottom parameter but found " + tArgs[0]); + + + // Check the state of top + Bottom b = new Bottom(); + check(b instanceof ChildHasParent,"Bottom should implement ChildHasParent"); + intfs = Bottom.class.getGenericInterfaces(); + check(intfs[0] instanceof ParameterizedType, + "Expected Bottom to have parameterized interface but found "+intfs[0]); + pt = (ParameterizedType) intfs[0]; + tArgs = pt.getActualTypeArguments(); + check(tArgs[0]==Top.class, + "Expecting Top parameter but found " + tArgs[0]); + + } + + public static void check(boolean b,String msg) { + if (!b) throw new RuntimeException(msg); + } +} + +class Top {} +class Bottom {} + +////////////////////////////////////////////////////////////////// + +/* End game for test Z, as bits work they are promoted up into the + testcase above :) + + TestN promoted the declare parents statements up + +public abstract aspect ParentChildRelationship<Parent,Child> { + + // Inter-type declarations made on the *generic* interface types to provide + // default implementations. + + public List<C> ParentHasChildren<C>.children; + + public P ChildHasParent<P>.parent; + + public List<C> ParentHasChildren<C>.getChildren() { + return Collections.unmodifiableList(children); + } + + public P ChildHasParent<P>.getParent() { + return parent; + } + + public void ParentHasChildren<C>.addChild(C child) { + if (child.parent != null) { + child.parent.removeChild(child); + } + children.add(child); + child.parent = this; + } + + public void ParentHasChildren<C>.removeChild(C child) { + if (children.remove(child)) { + child.parent = null; + } + } + + public void ChildHasParent<P>.setParent(P parent) { + parent.addChild(this); + } + + @SuppressAjWarnings + public pointcut addingChild(Parent p, Child c) : + execution(* Parent.addChild(Child)) && this(p) && args(c); + + @SuppressAjWarnings + public pointcut removingChild(Parent p, Child c) : + execution(* Parent.removeChild(Child)) && this(p) && args(c); +} +*/ + diff --git a/tests/java5/generics/genericaspects/GenericAspectO.aj b/tests/java5/generics/genericaspects/GenericAspectO.aj new file mode 100644 index 000000000..ee910f7ac --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectO.aj @@ -0,0 +1,86 @@ +import java.util.*; +import java.lang.reflect.*; +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<C> ParentHasChildren<C>.children; + public P ChildHasParent<P>.parent; + +} + +aspect GenericAspectO extends ParentChildRelationship<Top,Bottom> { + + + public static void main(String []argv) { + + // Field fiddling + Bottom.parent = t; // error - its not a static field + List<Bottom> kids = new ArrayList<Bottom>(); + kids.add(t); + Top.children = kids; // error - its not a static field + + + } + + public static void check(boolean b,String msg) { + if (!b) throw new RuntimeException(msg); + } +} + +class Top {} +class Bottom {} + +////////////////////////////////////////////////////////////////// + +/* End game for test Z, as bits work they are promoted up into the + testcase above :) + + TestN promoted the declare parents statements up + TestO promoted the fields up - a parent knows its children, a + child knows its parents - but then uses them incorrectly + +public abstract aspect ParentChildRelationship<Parent,Child> { + + public List<C> ParentHasChildren<C>.getChildren() { + return Collections.unmodifiableList(children); + } + + public P ChildHasParent<P>.getParent() { + return parent; + } + + public void ParentHasChildren<C>.addChild(C child) { + if (child.parent != null) { + child.parent.removeChild(child); + } + children.add(child); + child.parent = this; + } + + public void ParentHasChildren<C>.removeChild(C child) { + if (children.remove(child)) { + child.parent = null; + } + } + + public void ChildHasParent<P>.setParent(P parent) { + parent.addChild(this); + } + + @SuppressAjWarnings + public pointcut addingChild(Parent p, Child c) : + execution(* Parent.addChild(Child)) && this(p) && args(c); + + @SuppressAjWarnings + public pointcut removingChild(Parent p, Child c) : + execution(* Parent.removeChild(Child)) && this(p) && args(c); +} +*/ + diff --git a/tests/java5/generics/genericaspects/GenericAspectP.aj b/tests/java5/generics/genericaspects/GenericAspectP.aj new file mode 100644 index 000000000..1155d7776 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectP.aj @@ -0,0 +1,110 @@ +import java.util.*; +import java.lang.reflect.*; +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<C> ParentHasChildren<C>.children; + public P ChildHasParent<P>.parent; + +} + +aspect GenericAspectP extends ParentChildRelationship<Top,Bottom> { + + + public static void main(String []argv) { + + // Check the state of top + Top t = new Top(); + check(t instanceof ParentHasChildren,"Top should implement ParentHasChildren"); + Type[] intfs = Top.class.getGenericInterfaces(); + check(intfs[0] instanceof ParameterizedType, + "Expected Top to have parameterized interface but found "+intfs[0]); + ParameterizedType pt = (ParameterizedType) intfs[0]; + Type[] tArgs = pt.getActualTypeArguments(); + check(tArgs[0]==Bottom.class, + "Expecting Bottom parameter but found " + tArgs[0]); + + + // Check the state of top + Bottom b = new Bottom(); + check(b instanceof ChildHasParent,"Bottom should implement ChildHasParent"); + intfs = Bottom.class.getGenericInterfaces(); + check(intfs[0] instanceof ParameterizedType, + "Expected Bottom to have parameterized interface but found "+intfs[0]); + pt = (ParameterizedType) intfs[0]; + tArgs = pt.getActualTypeArguments(); + check(tArgs[0]==Top.class, + "Expecting Top parameter but found " + tArgs[0]); + + // Field fiddling + b.parent = t; + List<Bottom> kids = new ArrayList<Bottom>(); + kids.add(b); + t.children = kids; + + + } + + public static void check(boolean b,String msg) { + if (!b) throw new RuntimeException(msg); + } +} + +class Top {} +class Bottom {} + +////////////////////////////////////////////////////////////////// + +/* End game for test Z, as bits work they are promoted up into the + testcase above :) + + TestN promoted the declare parents statements up + TestO promoted the fields up - a parent knows its children, a + child knows its parents - but then used them incorrectly + TestP uses the fields correctly + +public abstract aspect ParentChildRelationship<Parent,Child> { + + public List<C> ParentHasChildren<C>.getChildren() { + return Collections.unmodifiableList(children); + } + + public P ChildHasParent<P>.getParent() { + return parent; + } + + public void ParentHasChildren<C>.addChild(C child) { + if (child.parent != null) { + child.parent.removeChild(child); + } + children.add(child); + child.parent = this; + } + + public void ParentHasChildren<C>.removeChild(C child) { + if (children.remove(child)) { + child.parent = null; + } + } + + public void ChildHasParent<P>.setParent(P parent) { + parent.addChild(this); + } + + @SuppressAjWarnings + public pointcut addingChild(Parent p, Child c) : + execution(* Parent.addChild(Child)) && this(p) && args(c); + + @SuppressAjWarnings + public pointcut removingChild(Parent p, Child c) : + execution(* Parent.removeChild(Child)) && this(p) && args(c); +} +*/ + diff --git a/tests/java5/generics/genericaspects/GenericAspectQ.aj b/tests/java5/generics/genericaspects/GenericAspectQ.aj new file mode 100644 index 000000000..bd73e6796 --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectQ.aj @@ -0,0 +1,34 @@ +import java.util.*; +import java.lang.reflect.*; +import org.aspectj.lang.annotation.*; + +class I<A> { + A a; +} + +aspect Foo { + +// B I<B>.b; + + C I<C>.m() { + return x; + } + + /* + In something like the above, although 'Z' is clearly a reference to + a member type variable, it is captured in the 'code' for the method as a + SingleTypeReference for Z. It doesnt cause a problem with a 'missing type' + because the compiler looks up the types in the set of type vars for a + member - in this case it will find Z and everything will be ok. + The problem above is that the type of x is 'A' and yet the return type + of the method is 'C' - they dont match => BANG + + */ +} + +public class GenericAspectQ extends I<String> { + + public static void main(String []argv) { + GenericAspectQ _instance = new GenericAspectQ(); + } +} diff --git a/tests/java5/generics/genericaspects/GenericAspectR.aj b/tests/java5/generics/genericaspects/GenericAspectR.aj new file mode 100644 index 000000000..73a81b91e --- /dev/null +++ b/tests/java5/generics/genericaspects/GenericAspectR.aj @@ -0,0 +1,126 @@ +import java.util.*; +import java.lang.reflect.*; +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; + public P ChildHasParent<P>.parent; + + public List<D> ParentHasChildren<D>.getChildren() { + return children;//Collections.unmodifiableList(children); + } + +// public List<Child> getChildren() { +// return Collections.unmodifiableList(new ArrayList<Child>()); +// } + +} + +aspect GenericAspectR extends ParentChildRelationship<Top,Bottom> { + + public static void main(String []argv) { + + // Check the state of top + Top t = new Top(); + check(t instanceof ParentHasChildren,"Top should implement ParentHasChildren"); + Type[] intfs = Top.class.getGenericInterfaces(); + check(intfs[0] instanceof ParameterizedType, + "Expected Top to have parameterized interface but found "+intfs[0]); + ParameterizedType pt = (ParameterizedType) intfs[0]; + Type[] tArgs = pt.getActualTypeArguments(); + check(tArgs[0]==Bottom.class, + "Expecting Bottom parameter but found " + tArgs[0]); + + + // Check the state of top + Bottom b = new Bottom(); + check(b instanceof ChildHasParent,"Bottom should implement ChildHasParent"); + intfs = Bottom.class.getGenericInterfaces(); + check(intfs[0] instanceof ParameterizedType, + "Expected Bottom to have parameterized interface but found "+intfs[0]); + pt = (ParameterizedType) intfs[0]; + tArgs = pt.getActualTypeArguments(); + check(tArgs[0]==Top.class, + "Expecting Top parameter but found " + tArgs[0]); + + + + + // Field fiddling + b.parent = t; + List<Bottom> kids = new ArrayList<Bottom>(); + kids.add(b); + t.children = kids; + + + // start using the methods + List<Bottom> kids2 = t.getChildren(); + check(kids2.size()==1, + "Expected one child of the Top but found "+kids2.size()); + check(kids2.get(0).equals(b), + "Expected one child of the Top which was what we put in there!"+kids2.get(0)); + + + } + + public static void check(boolean b,String msg) { + if (!b) throw new RuntimeException(msg); + } +} + +class Top {} +class Bottom {} + +////////////////////////////////////////////////////////////////// + +/* End game for test Z, as bits work they are promoted up into the + testcase above :) + + TestN promoted the declare parents statements up + TestO promoted the fields up - a parent knows its children, a + child knows its parents - but then used them incorrectly + TestP uses the fields correctly + TestQ promoted getChildren() method + +public abstract aspect ParentChildRelationship<Parent,Child> { + + + public P ChildHasParent<P>.getParent() { + return parent; + } + + public void ParentHasChildren<C>.addChild(C child) { + if (child.parent != null) { + child.parent.removeChild(child); + } + children.add(child); + child.parent = this; + } + + public void ParentHasChildren<C>.removeChild(C child) { + if (children.remove(child)) { + child.parent = null; + } + } + + public void ChildHasParent<P>.setParent(P parent) { + parent.addChild(this); + } + + @SuppressAjWarnings + public pointcut addingChild(Parent p, Child c) : + execution(* Parent.addChild(Child)) && this(p) && args(c); + + @SuppressAjWarnings + public pointcut removingChild(Parent p, Child c) : + execution(* Parent.removeChild(Child)) && this(p) && args(c); +} +*/ + |