aboutsummaryrefslogtreecommitdiffstats
path: root/tests/new/IfPCDAdviceMethods.java
blob: 26367d990141bef055cb326d98cfd117d45735bc (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
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
import org.aspectj.testing.Tester; 
import org.aspectj.testing.Tester;

class TestContext {
	public static void signal(String event) {
		Tester.event(event);
	}
	public static void expectSignal(String event) {
		Tester.expectEvent(event);
	}
	public static void startTest() {
	}
	public static void endTest() {
        Tester.checkAllEventsIgnoreDups();
	}
	public static void testFailed(String failureMessage) {
        Tester.check(false,failureMessage);
	}
}

class BaseApp {
	int i;
    int get()  { return i; }
    void set(int i)  {  this.i = i; }
    void uncountedCall()  { }
	// permits call to be restricted to within(BaseApp)
    void callFromOutside(int i)  { 
		call(i);
	} 
    private void call(int i)  { TestContext.signal("call(int)"); } 
}

/**
 * Test touching pcd if() variants: 
 * <table>
 * <tr><td>pcd if(expr)</td><td>anonymous, named</td></tr>
 * <tr><td>pcd combination</td><td>execution, call, callTyped,initialization,set,get</td></tr>
 * <tr><td>advice</td><td></td>before, after, around</tr>
 * </table>
 * (callTyped is probably not a relevant difference).
 * Currently passing.
 * @author wes
 * History
 *   8/20/01  initial draft
 *   8/21/01  fixed namedIf call, added initializations
 * Todo
 *       
 */
public class IfPCDAdviceMethods {
    public static void main(String[] args) {
        TestContext.startTest();
        BaseApp target = new BaseApp();
		target.callFromOutside(0);
		target.uncountedCall();
		target.set(1);
		if (!(1 == target.get())) {
			TestContext.testFailed("1 != target.get()");
		}
        TestContext.endTest();
    }
    static {
		// variants of advice defined below
        String[] cuts = { "call_pc", "callType_pc", "execution_pc",
						  "get_pc", "set_pc", "initialization_pc" } ; 
        String[] kinds = { "before", "after", "around" };
        String[] ifs = { "if(true)", "namedIf()", "anonymous" };
        for (int i = 0; i < cuts.length; i++) {
            for (int j = 0; j < kinds.length; j++) {
				for (int k = 0; k < ifs.length; k++) {
					//XXX no around on initialization yet
					if (kinds[j].equals("around") && cuts[i].equals("initialization_pc")) continue;
					TestContext.expectSignal(kinds[j] + "." + cuts[i] + "." + ifs[k]);
				}
            }
        }
		// ensure BaseApp method was called
		TestContext.expectSignal("call(int)");

		// Aspect namedIf delegate should have been called this many times
        // (todo: only checks for at-least, not for extra calls)
         // -1 for anonymous, 2* for two calls, -1 for around initialization
		final int namedIfCalls = 2*cuts.length * (ifs.length-1) - 1;
        for (int i = 0; i < namedIfCalls; i++) {
			TestContext.expectSignal("executedNamedIf:"+i);
		}
    }
}

/** Catch test failures using aspects - mainly to surface caller/join point easily */
aspect TestSignals {
	/** identify methods that should never be called */
	pointcut errorIfCalled () : call(boolean *..executedNamedIfNever(..));
	/** signal failure if method that wasn't supposed to be called is in fact invoked */
	after () : errorIfCalled() {
		// todo: will StaticPart will always have null for source ?
		StringBuffer sb = new StringBuffer();
		sb.append("TestSignals.after() : errorIfCalled()");
		org.aspectj.lang.JoinPoint.StaticPart sp = thisJoinPointStaticPart;
		if (null == sp) {
			sb.append("null thisJoinPointStaticPart");
		} else {
			sb.append(" kind=" + sp.getKind());
			sb.append(" signature=" + sp.getSignature());
			sb.append(" source=" + sp.getSourceLocation());
		}
		TestContext.testFailed(sb.toString());
	}
}

/** named pointcuts including if(expr) - call, execution only */
aspect Aspect {
	static int namedIfCounter;
	static int namedIfNeverCounter;
	static int i;
	static boolean executedNamedIf() {
		//System.err.println("named if + " + namedIfCounter);
		a("executedNamedIf:"+namedIfCounter++);
		return true;
	}
	static boolean executedNamedIfNever() {
		a("executedNamedIfNever:"+namedIfNeverCounter++);
		return true;
	}

	/**
	 * should not short-circuit, but instead call executedNamedIf
	 * @testTarget ifpcd.run.expr.java.group no short-circuit of false "or"
	 * @testTarget ifpcd.run.expr.java.group method invocation in if-expression
	 */
	pointcut namedIf () 
		: !within(Aspect) && if( ((1 == 0) || executedNamedIf()) ) ; 

	/**
	 * should short-circuit, never calling executedNamedIfNever
	 * @testTarget ifpcd.run.expr.java.group short-circuit of false "and"
	 * @testTarget ifpcd.run.expr.java.group assignment in if-expression
	 */
	pointcut namedIfNever () // should short-circuit, never calling executedNamedIfNever
		: if( ((1 == 1) && executedNamedIfNever()) ) ;

	/**
	 * @testTarget ifpcd.run.expr.literal literal operations not optimized away fyi
	 */
    pointcut ifTrue () : if(true);

	/**
	 * @testTarget ifpcd.run.expr.literal literal operations not optimized away fyi
	 */
    pointcut ifFalse () : if(false);

	// ------------------------------------- pointcuts
	/** @testTarget ifpcd.compile.pcds.named.set */
    pointcut set_pc     (): if (true) && set(int BaseApp.i) ; 
	/** @testTarget ifpcd.compile.pcds.named.get */
    pointcut get_pc     (): if (true) && get(int BaseApp.i) ; 
	/** @testTarget ifpcd.compile.pcds.named.call */
    pointcut call_pc     (): if (true) && call(void *.call(int)) && within(BaseApp);
	/** @testTarget ifpcd.compile.pcds.named.call with Type */
    pointcut callType_pc(): if(true) && call(void BaseApp.call(int));
	/** @testTarget ifpcd.compile.pcds.named.execution */
    pointcut execution_pc(): if(true) && within(BaseApp) && execution(void *(int));
	/** @testTarget ifpcd.compile.pcds.named.initialization */
    pointcut initialization_pc(): if(true) && initialization(BaseApp.new(..));
	// currently broken
	/** @testTarget ifpcd.compile.pcds.named.initialization */
    //pointcut staticinitialization_pc(): if(true) && staticinitialization(BaseApp);

	/** @testTarget ifpcd.compile.pcds.namedIf.set */
    pointcut named_set_pc     (): namedIf() && set(int BaseApp.i) ; 
	/** @testTarget ifpcd.compile.pcds.namedIf.get */
    pointcut named_get_pc     (): namedIf() && get(int BaseApp.i) ; 
	/** @testTarget ifpcd.compile.pcds.namedIf.call if pcd by name composition */
    pointcut named_call_pc()     : namedIf() && call(void *.call(int)) && within(BaseApp);
	/** @testTarget ifpcd.compile.pcds.namedIf.call with Type, if pcd by name composition */
    pointcut named_callType_pc() : namedIf() && call(void BaseApp.call(int)) && within(BaseApp);;
	/** @testTarget ifpcd.compile.pcds.namedIf.execution if pcd by name composition */
    pointcut named_execution_pc(): namedIf() && execution(void *(int));
	/** @testTarget ifpcd.compile.pcds.namedIf.initialization */
    pointcut named_initialization_pc(): namedIf() && initialization(BaseApp.new(..));

    before(): set_pc     () { a("before.set_pc.if(true)");      }
    before(): get_pc     () { a("before.get_pc.if(true)");      }
    before(): call_pc     () { a("before.call_pc.if(true)");      }
    before(): callType_pc() { a("before.callType_pc.if(true)"); }
    before(): execution_pc() { a("before.execution_pc.if(true)"); }
    before(): initialization_pc() { a("before.initialization_pc.if(true)"); }
    //before(): staticinitialization_pc() { a("before.staticinitialization_pc.if(true)"); }

    before(): named_set_pc     () { a("before.set_pc.namedIf()");      }
    before(): named_get_pc     () { a("before.get_pc.namedIf()");      }
    before(): named_call_pc     () { a("before.call_pc.namedIf()");      }
    before(): named_callType_pc() { a("before.callType_pc.namedIf()"); }
    before(): named_execution_pc() { a("before.execution_pc.namedIf()"); }
    before(): named_initialization_pc() { a("before.initialization_pc.namedIf()"); }

    Object around() : set_pc     () { a("around.set_pc.if(true)");  return proceed(); }
    int around() : get_pc     () { a("around.get_pc.if(true)");  return proceed(); }
    void around() : call_pc     () { a("around.call_pc.if(true)");      proceed(); }
    void around() : callType_pc() { a("around.callType_pc.if(true)"); proceed(); }
    void around() : execution_pc() { a("around.execution_pc.if(true)"); proceed(); }
    //XXXvoid around() : initialization_pc() { a("around.initialization_pc.if(true)"); proceed(); }

    Object around() : named_set_pc     () { a("around.set_pc.namedIf()"); return proceed(); }
    int around() : named_get_pc     () { a("around.get_pc.namedIf()"); return proceed(); }
    void around() : named_call_pc     () { a("around.call_pc.namedIf()");      proceed(); }
    void around() : named_callType_pc() { a("around.callType_pc.namedIf()"); proceed(); }
    void around() : named_execution_pc() { a("around.execution_pc.namedIf()"); proceed(); }
    //XXXvoid around() : named_initialization_pc() { a("around.initialization_pc.namedIf()"); proceed(); }

	// ------------------------------------- after 
    after(): set_pc     () { a("after.set_pc.if(true)");      }
    after(): get_pc     () { a("after.get_pc.if(true)");      }
    after(): call_pc     () { a("after.call_pc.if(true)");      }
    after(): callType_pc() { a("after.callType_pc.if(true)"); }
    after(): execution_pc() { a("after.execution_pc.if(true)"); }
    after(): initialization_pc() { a("after.initialization_pc.if(true)"); }
    //after(): staticinitialization_pc() { a("after.staticinitialization_pc.if(true)"); }

    after(): named_set_pc     () { a("after.set_pc.namedIf()");      }
    after(): named_get_pc     () { a("after.get_pc.namedIf()");      }
    after(): named_call_pc     () { a("after.call_pc.namedIf()");      }
    after(): named_callType_pc() { a("after.callType_pc.namedIf()"); }
    after(): named_execution_pc() { a("after.execution_pc.namedIf()"); }
    after(): named_initialization_pc() { a("after.initialization_pc.namedIf()"); }

    static void a(String msg) {
        TestContext.signal(msg);
    }
}

/** anonymous pointcuts including if(expr) - call, execution only */
aspect Aspect2 {

	/** @testTarget ifpcd.compile.pcds.unnamed.set.before */
    before() : if(true) && set(int BaseApp.i) {
		a("before.set_pc.anonymous");
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.get.before */
    before() : if(true) && get(int BaseApp.i) {
		a("before.get_pc.anonymous");
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.call.before */
    before() : if(true) && call(void *.uncountedCall()) {
		a("before.call_pc.anonymous");
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.call.before with Type */
    before() : if(true) && call(void BaseApp.uncountedCall()) {
		a("before.callType_pc.anonymous");
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.execution.before */
    before() : if(true) && execution(void BaseApp.uncountedCall()) {
		a("before.execution_pc.anonymous");
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.initialization.before */
    before() : if(true) && initialization(BaseApp.new(..)) {
		a("before.initialization_pc.anonymous");
	}

	/** @testTarget ifpcd.compile.pcds.unnamed.set.around */
    Object around() : if(true) && set(int BaseApp.i) {
		a("around.set_pc.anonymous");
		return proceed();
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.get.around */
    int around() : if(true) && get(int BaseApp.i) {
		a("around.get_pc.anonymous");
		return proceed();
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.call.around */
    void around() : if(true) && call(void *.uncountedCall()) {
		a("around.call_pc.anonymous");
		proceed();
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.call.around with Type */
    void around() : if(true) && call(void BaseApp.uncountedCall()) {
		a("around.callType_pc.anonymous");
		proceed();
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.execution.around */
    void around() : if(true) && execution(void BaseApp.uncountedCall()) {
		a("around.execution_pc.anonymous");
		proceed();
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.initialization.around */
	//XXX
//    void around() : if(true) && initialization(BaseApp.new(..)) {
//		a("around.initialization_pc.anonymous");
//		proceed();
//	}

	/** @testTarget ifpcd.compile.pcds.unnamed.set.after */
    after() : if(true) && set(int BaseApp.i) {
		a("after.set_pc.anonymous");
	}

	/** @testTarget ifpcd.compile.pcds.unnamed.get.after */
    after() : if(true) && get(int BaseApp.i) {
		a("after.get_pc.anonymous");
	}

	/** @testTarget ifpcd.compile.pcds.unnamed.call.after */
    after() : if(true) && call(void *.uncountedCall()) {
		a("after.call_pc.anonymous");
	}

	/** @testTarget ifpcd.compile.pcds.unnamed.call.after with Type */
    after() : if(true) && call(void BaseApp.uncountedCall()) {
		a("after.callType_pc.anonymous");
	}

	/** @testTarget ifpcd.compile.pcds.unnamed.execution.after */
    after() : if(true) && execution(void BaseApp.uncountedCall()) {
		a("after.execution_pc.anonymous");
	}
	/** @testTarget ifpcd.compile.pcds.unnamed.initialization.after */
    after() : if(true) && initialization(BaseApp.new(..)) {
		a("after.initialization_pc.anonymous");
	}


    static void a(String msg) {
        TestContext.signal(msg);
    }
}