aboutsummaryrefslogtreecommitdiffstats
path: root/tests/new/PR559.java
blob: c8da6e4ae46e5779d342e53cc740af4ee356ce46 (plain)
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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import org.aspectj.testing.Tester; 

/**
   * This test case shows:
   * - no difference whether extending a class or aspect or interface
   * - underlying "within"-based pointcut works
   * - containing cflow-based pointcut does not
   * - true only of inherited pointcuts - member pointcuts work fine
   *
   * Note that to avoid pointcut cycles, 
   * pointcuts exclude code within a common superinterface.
   * It is not enough (now) to exclude code in the advice's super-most class subclasses.
   *
   * @testcase PR#559 subclass advice not run for join points selected by superclass cflow-based pointcuts
 */
public class PR559 {
  public static void main( String args[] ) {
        Tester.expectEvent("target aspect");
        Tester.expectEvent("inTarget class");
        Tester.expectEvent("inTarget aspect");
        Tester.expectEvent("inTargetFlow class");
        Tester.expectEvent("inTargetFlow aspect");
        Tester.expectEvent("TargetRun aspect");
        Tester.expectEvent("TargetRun class");
        Tester.expectEvent("TargetRunFlow aspect");
        Tester.expectEvent("TargetRunFlow class");
        Tester.expectEvent("TargetSubRunFlow aspect");
        Tester.expectEvent("TargetSubRunFlow class");
        new Target().run();
        Tester.checkAllEvents();
  }
}

interface AspectMarker {
    pointcut notInAspect()   : ! within(AspectMarker+) && 
    				!preinitialization(new(..)) && !initialization(new(..));
    pointcut allTarget()     : execution(* Target.*(..)) ;
    pointcut allTargetFlow() : cflow(allTarget()); 
    pointcut inTarget()      : notInAspect() && allTarget();
    pointcut inTargetFlow()  : notInAspect() && allTargetFlow();
}

class Target {
    public void run(){ }
}

class Base implements AspectMarker {
    pointcut TargetRun () 
        : within(Target) && execution(* *(..)) && notInAspect() ;
        ;
    pointcut TargetRunFlow () 
        : cflow(within(Target) && execution(* *(..))) && notInAspect() 
        ;
}

/** @testcase PR#559 subaspect advice not run for superclass cflow-based pointcut */
aspect Derived extends Base {
    pointcut TargetSubRunFlow () 
        : cflow(within(Target) && execution(* *(..))) && notInAspect() 
        ;
    Object around () : inTarget() {
        Tester.event("inTarget class");
        return proceed();
    }
    Object around () : inTargetFlow() {
        Tester.event("inTargetFlow class");
        return proceed();
    }
    Object around () : TargetRun() {
        Tester.event("TargetRun class");
        return proceed();
    }
    Object around () : TargetRunFlow() {
        Tester.event("TargetRunFlow class");
        return proceed();
    }
    Object around () : TargetSubRunFlow() {
        Tester.event("TargetSubRunFlow class");
        return proceed();
    }
}

abstract aspect BaseAspect implements AspectMarker {
    pointcut TargetRun () 
        : within(Target) && execution(* *(..)) && notInAspect() ;
        ;
    pointcut TargetRunFlow () 
        : cflow(within(Target) && execution(* *(..))) && notInAspect() 
        ;
}

/** @testcase PR#559 subaspect advice not run for superaspect cflow-based pointcut */
aspect DerivedAspect extends BaseAspect implements AspectMarker {
    pointcut TargetSubRunFlow () 
        : cflow(within(Target) && execution(* *(..))) && notInAspect() 
        ;
    Object around () : TargetRun() {
        Tester.event("target aspect");
        return proceed();
    }
    Object around () : inTarget() { // TargetRun() {
        Tester.event("inTarget aspect");
        return proceed();
    }
    Object around () : inTargetFlow() { // TargetRun() {
        Tester.event("inTargetFlow aspect");
        return proceed();
    }
    Object around () : TargetRun() {
        Tester.event("TargetRun aspect");
        return proceed();
    }
    Object around () : TargetRunFlow() {
        Tester.event("TargetRunFlow aspect");
        return proceed();
    }
    Object around () : TargetSubRunFlow() {
        Tester.event("TargetSubRunFlow aspect");
        return proceed();
    }
}