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
|
import java.util.Vector;
import org.aspectj.testing.*;
public class Counting1 {
public static void main(String[] args) {
Point pt1 = new Point(0, 0);
Point pt2 = new Point(4, 4);
Line ln1 = new Line(pt1, pt2);
System.out.println(MoveTracking.testAndClear());
ln1.translate(3, 6);
System.out.println(MoveTracking.testAndClear());
System.out.println(pt1.getX());
Mobility.disableMoves();
ln1.translate(3, 6);
System.out.println(pt1.getX());
}
static class System {
static O out = new O();
static class O {
public void println(Object o) {}
public void println(int i) {}
public void println(boolean b) {}
}
}
}
class FigureEditor {
//...
}
class Figure {
Vector elements = new Vector();
//...
}
interface FigureElement {
public void translate(int dx, int dy);
//...
}
class Point implements FigureElement {
private int _x = 0, _y = 0;
Point(int x, int y) {
_x = x;
_y = y;
}
public void translate(int dx, int dy) {
setX(getX() + dx);
setY(getY() + dy);
}
int getX() { return _x; }
int getY() { return _y; }
void setX(int x) { _x = x; }
void setY(int y) { _y = y; }
//...
}
class Line implements FigureElement {
private Point _p1, _p2;
Line (Point p1, Point p2) {
_p1 = p1;
_p2 = p2;
}
public void translate(int dx, int dy) {
_p1.translate(dx, dy);
_p2.translate(dx, dy);
}
Point getP1() { return _p1; }
Point getP2() { return _p2; }
void setP1(Point p1) { _p1 = p1; }
void setP2(Point p2) { _p2 = p2; }
//...
}
aspect JoinPointCounting {
static int n = 0;
static boolean enable = true;
pointcut points():
/*
instanceof(*) &&
!(receptions(* *.new(..)) ||
executions(* *.new(..)));
*/
call(* *.*(..)) ||
//receptions(* *.*(..)) ||
execution(* *.*(..));/* ||
gets(* *.*) ||
sets(* *.*);
*/
before(): points() && !within(JoinPointCounting) {
if ( enable ) {
String s = thisJoinPoint + "";
Tester.check(s.indexOf("$") == -1, s + " contains a $");
}
}
}
aspect MoveTracking {
static boolean flag = false;
static boolean testAndClear() {
boolean result = flag;
flag = false;
return result;
}
pointcut moves():
call(void FigureElement.translate(int, int)) ||
call(void Line.setP1(Point)) ||
call(void Line.setP2(Point)) ||
call(void Point.setX(int)) ||
call(void Point.setY(int));
after(): moves() {
flag = true;
}
}
aspect Mobility { declare precedence: Mobility, MoveTracking;
private static boolean enableMoves = true;
static void enableMoves() { enableMoves = true; }
static void disableMoves() { enableMoves = false; }
private int getSomething() { return 10; }
void around(): MoveTracking.moves() {
int x = getSomething();
if ( enableMoves || enableMoves )
proceed(); //!!! in versions prior to 0.7b10 runNext is a
//!!! method on the join point object, so the
//!!! syntax of this call is slightly different
//!!! than in the paper
}
void around(int i): args(i) && call(void *gaoijbal()) {
if (enableMoves) throw new RuntimeException("bad things");
}
}
privileged aspect Foo {
public static boolean getEnableMoves() {
return Mobility.enableMoves;
}
}
|