1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
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);
}
*/
|