You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

NegativeSourceLocation.java 13KB

21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
21 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. import org.aspectj.lang.*;
  2. import org.aspectj.lang.reflect.*;
  3. import org.aspectj.testing.*;
  4. /**
  5. * @testcase PR#525 validate presence/absence of thisEnclosingJoinPointStaticPart
  6. * @testcase PR#525 validate SourceLocation
  7. */
  8. public class NegativeSourceLocation {
  9. public static void main(String[] args) {
  10. Signal.expect(Const.EXPECTED);
  11. TargetClass target = new TargetClass();
  12. // run from outside code the compiler controls
  13. Thread t = new Thread(target, "NegativeSourceLocation");
  14. t.start();
  15. int i = 0;
  16. // todo: use Timer to add interrupt?
  17. while ((10 > i++) && t.isAlive()) {
  18. try { t.join(); }
  19. catch (InterruptedException e) {}
  20. }
  21. Signal.checkAll();
  22. }
  23. }
  24. /** indirection for test utility */
  25. class Signal {
  26. public static final void failed(String s) {
  27. //Thread.currentThread().dumpStack();
  28. Tester.checkFailed(s);
  29. }
  30. public static final void found(JoinPoint.StaticPart s) {
  31. Tester.event(s.toString());
  32. }
  33. public static final void found(String s) {
  34. Tester.event(s);
  35. }
  36. public static final void checkAll() {
  37. Tester.checkAllEvents();
  38. }
  39. public static final void expect(String[] sra) {
  40. Tester.expectEventsInString(sra);
  41. }
  42. } // class Signal
  43. /** TargetClass has most every join point, provoked by initializatin and run() */
  44. class TargetClass implements Runnable {
  45. TargetClass() {}
  46. static String staticString = "two"; // jp has -1 source location
  47. static {
  48. staticString = "one";
  49. String s = staticString + "asdf";
  50. }
  51. static {
  52. staticString = "three";
  53. }
  54. String string = "bar";
  55. public static void staticRun() { // execute
  56. staticString = "foo"; // set - static var
  57. String s = staticString; // get - static var
  58. s = s + "ss";
  59. staticString = s + "u"; // set - instance var
  60. TargetClass u = new TargetClass(); // initialization
  61. staticString = u.toString();
  62. }
  63. public void run() { // execute - no thisEnclosingJoinPoint when called from Thread.start()
  64. boolean doNotOptimize = (staticString != null);
  65. if (doNotOptimize) internalRun();
  66. }
  67. private void internalRun() { // execute
  68. staticString = "foo"; // set - static var
  69. staticRun(); // call static
  70. String s = staticString; // get - static var
  71. String t = string; // get - instance var
  72. s = s + t;
  73. string = s + t; // set - instance var
  74. final Error e = new Error("caught here");
  75. try {
  76. throw e;
  77. } catch (Error er) { // handler
  78. if (er != e) {
  79. Signal.failed("caught Error=" + er);
  80. } else {
  81. Signal.found("caught");
  82. }
  83. }
  84. }
  85. } // class TargetClass
  86. /**
  87. * This Aspect attempts to specify join points that have enclosing
  88. * join points and whether the source locations are valid.
  89. * It fails in using only pointcuts.
  90. * This is just a first cut. I (wes) have an AroundAll
  91. * which does this tracking...
  92. */
  93. aspect Aspect {
  94. // ------------------------------- pointcuts select logical sets of join points
  95. // 1.1 includes StringBuffer calls that weren't in 1.0
  96. pointcut allTargetJoinPoints()
  97. : within(TargetClass) &&
  98. !call(* StringBuffer.*(..)) && !call(StringBuffer.new(..))
  99. && !call(* String.valueOf(Object));
  100. /** these have no enclosing join point */
  101. pointcut noEnclosingJoinPoint()
  102. : ((call(public void TargetClass.run())) // called from Thread.start() (caller-side, but has callee-side?)
  103. //|| staticinitialization(TargetClass) // the enclosing jp here is itself
  104. );
  105. // || initialization(TargetClass.new())
  106. // || execution(TargetClass.new()) // todo: expect it to be self like in methods?
  107. /** these have enclosing join points */
  108. pointcut hasEnclosingJoinPoint()
  109. : allTargetJoinPoints()
  110. && !(noEnclosingJoinPoint())
  111. ;
  112. /** expecting an enclosing join point different from thisJoinPoint */
  113. pointcut enclosingDiffers()
  114. : get(* TargetClass.*)
  115. || set(* TargetClass.*)
  116. || call(* TargetClass.*(..))
  117. || handler(Error)
  118. ;
  119. pointcut hasDifferentEnclosingJoinPoint()
  120. : hasEnclosingJoinPoint()
  121. && enclosingDiffers()
  122. ;
  123. pointcut hasSameEnclosingJoinPoint()
  124. : hasEnclosingJoinPoint()
  125. && (!enclosingDiffers());
  126. /** synthetic join points have no source location */
  127. pointcut syntheticJoinPoints()
  128. : staticinitialization(TargetClass)
  129. || initialization(TargetClass.new(UnknownConstructor))
  130. ;
  131. pointcut joinPointHasValidSourceLocation()
  132. : allTargetJoinPoints()
  133. && (!syntheticJoinPoints())
  134. //&& if(expectSourceLocation(thisJoinPointStaticPart))
  135. ;
  136. pointcut enclosingJoinPointHasValidSourceLocation() // todo: cannot specify
  137. : hasEnclosingJoinPoint()
  138. && (!syntheticJoinPoints())
  139. //&& if(expectSourceLocation(thisEnclosingJoinPointStaticPart))
  140. ;
  141. // ---------------------- advice applies invariants to each logical set of join points
  142. /** @testcase all join points have non-null thisJoinPoint and thisJoinPointStaticPart */
  143. before(): allTargetJoinPoints() {
  144. Signal.found("before AllTargetJoinPoints " + thisJoinPointStaticPart);
  145. //System.err.println(thisJoinPointStaticPart + " at " + thisJoinPointStaticPart.getSourceLocation());
  146. String test = "all join points have non-null thisJoinPointStaticPart";
  147. if (null == thisJoinPoint) {
  148. Signal.failed(test + " failed with null thisJoinPoint: " + thisJoinPointStaticPart);
  149. }
  150. if (null == thisJoinPointStaticPart) {
  151. Signal.failed(test + " failed with null thisJoinPointStaticPart: " + thisJoinPoint);
  152. }
  153. }
  154. /** @testcase non-null thisEnclosingStaticJoinPoint at certain join points */
  155. before() : hasEnclosingJoinPoint() {
  156. String test = "failed (most join points have non-null thisEnclosingStaticJoinPoint) ";
  157. if (null == thisEnclosingJoinPointStaticPart) {
  158. String jpName = thisJoinPointStaticPart.toString();
  159. Signal.failed(test + render(thisJoinPointStaticPart, thisEnclosingJoinPointStaticPart));
  160. //if (!jpName.equals("execution(TargetClass.<init>)")) { // todo: unable to specify this...
  161. }
  162. }
  163. /** @testcase non-null thisEnclosingStaticJoinPoint at join points (except for tested exceptions) */
  164. before() : hasDifferentEnclosingJoinPoint() {
  165. String test = "join points with different thisEnclosingStaticJoinPoint";
  166. if (thisEnclosingJoinPointStaticPart != thisEnclosingJoinPointStaticPart) {
  167. Signal.failed(test + " different static part : " + thisJoinPointStaticPart);
  168. }
  169. }
  170. /** @testcase expecting valid source locations */
  171. before() : joinPointHasValidSourceLocation() {
  172. if (null == thisJoinPointStaticPart) {
  173. Signal.failed("null thisJoinPointStaticPart");
  174. } else {
  175. checkSourceLocation(thisJoinPointStaticPart);
  176. }
  177. }
  178. /** @testcase expecting valid source locations in enclosing join point */
  179. before() : enclosingJoinPointHasValidSourceLocation() {
  180. if (null == thisEnclosingJoinPointStaticPart) {
  181. Signal.failed("null thisEnclosingJoinPointStaticPart in " + thisJoinPointStaticPart);
  182. } else {
  183. checkSourceLocation(thisEnclosingJoinPointStaticPart);
  184. }
  185. }
  186. /** @testcase non-null thisEnclosingJoinPointStaticPart in static initializer if invoked within a join point? */
  187. before() : staticinitialization(AnotherTargetClass) {
  188. String test = "static initializer join points have non-null thisJoinPointStaticPart when invoked from CCC";
  189. if (null == thisJoinPoint) {
  190. Signal.failed(test + " failed with null thisJoinPoint: " + thisJoinPointStaticPart);
  191. }
  192. if (null == thisJoinPointStaticPart) {
  193. Signal.failed(test + " failed with null thisJoinPointStaticPart: " + thisJoinPoint);
  194. }
  195. Signal.found("staticinitialization(AnotherTargetClass))");
  196. //Signal.found(thisJoinPointStaticPart); // todo: relying on formatting of toString() - fix
  197. }
  198. /** @testcase no call from outside CCC has thisEnclosingJoinPointStaticPart (possible mistake) */
  199. before() : noEnclosingJoinPoint() {
  200. Signal.found("before noEnclosingJoinPoint " + thisJoinPointStaticPart);
  201. if (null != thisEnclosingJoinPointStaticPart) {
  202. Signal.failed("unexpected non-null thisEnclosingJoinPointStaticPart: "
  203. + thisEnclosingJoinPointStaticPart + " from " + thisJoinPointStaticPart);
  204. }
  205. }
  206. static String render(JoinPoint.StaticPart jp, JoinPoint.StaticPart ejp) {
  207. StringBuffer sb = new StringBuffer();
  208. sb.append("thisJoinPoint: ");
  209. sb.append(null == jp ? "null" : jp.toString());
  210. sb.append("thisEnclosingJoinPoint: ");
  211. sb.append(null == ejp ? "null" : ejp.toString());
  212. return sb.toString();
  213. }
  214. void checkSourceLocation(JoinPoint.StaticPart jp) { // todo: provide caller context?
  215. checkSourceLocation(jp.getSourceLocation(), jp.toString());
  216. }
  217. /** aborted attempt to check jp by name for jp without enclosing */
  218. private static boolean expectSourceLocation(JoinPoint.StaticPart jp) {
  219. if (null == jp) {
  220. return false;
  221. } else {
  222. String name = jp.toString();
  223. if (-1 != name.indexOf("TargetClass.<init>")) {
  224. return false;
  225. }
  226. }
  227. return true; // todo: overinclusive
  228. }
  229. private boolean inInitCode(JoinPoint.StaticPart jp) {
  230. return (-1 != jp.toString().indexOf("<init>"));
  231. }
  232. void checkSourceLocation(SourceLocation sl, String context) {
  233. if (sl == null) {
  234. Signal.failed(context + "null SourceLocation");
  235. } else {
  236. int i = sl.getLine();
  237. if (0 > i) {
  238. Signal.failed(context + " line<0: " + i);
  239. }
  240. // 1.1 doesn't provide column info
  241. // i = sl.getColumn();
  242. // if (0 > i) {
  243. // Signal.failed(context + " column<0: " + i);
  244. // }
  245. }
  246. }
  247. } // Aspect
  248. /** more readable to put expected messages at end of file */
  249. class Const {
  250. // todo: EXPECTED will break if JoinPoint.StaticPart.toString() changes
  251. public static final String[] EXPECTED = new String[]
  252. {
  253. "before AllTargetJoinPoints staticinitialization(TargetClass.<clinit>)"
  254. , "before AllTargetJoinPoints set(String TargetClass.staticString)"
  255. , "before AllTargetJoinPoints get(String TargetClass.staticString)"
  256. , "before AllTargetJoinPoints get(String TargetClass.staticString)"
  257. , "before AllTargetJoinPoints set(String TargetClass.staticString)"
  258. , "before AllTargetJoinPoints set(String TargetClass.staticString)"
  259. , "before AllTargetJoinPoints preinitialization(TargetClass())"
  260. , "before AllTargetJoinPoints initialization(java.lang.Runnable())"
  261. //, "before AllTargetJoinPoints execution(java.lang.Runnable())"
  262. , "before AllTargetJoinPoints initialization(TargetClass())"
  263. //, "before AllTargetJoinPoints execution(TargetClass.<init>)"
  264. , "before AllTargetJoinPoints set(String TargetClass.string)"
  265. , "before AllTargetJoinPoints execution(TargetClass())"
  266. , "before AllTargetJoinPoints execution(void TargetClass.run())"
  267. , "before AllTargetJoinPoints call(void TargetClass.internalRun())"
  268. , "before AllTargetJoinPoints execution(void TargetClass.internalRun())"
  269. , "before AllTargetJoinPoints set(String TargetClass.staticString)"
  270. , "before AllTargetJoinPoints call(void TargetClass.staticRun())"
  271. , "before AllTargetJoinPoints execution(void TargetClass.staticRun())"
  272. , "before AllTargetJoinPoints set(String TargetClass.staticString)"
  273. , "before AllTargetJoinPoints get(String TargetClass.staticString)"
  274. , "before AllTargetJoinPoints set(String TargetClass.staticString)"
  275. , "before AllTargetJoinPoints call(TargetClass())"
  276. , "before AllTargetJoinPoints preinitialization(TargetClass())"
  277. , "before AllTargetJoinPoints initialization(TargetClass())"
  278. , "before AllTargetJoinPoints initialization(java.lang.Runnable())"
  279. //, "before AllTargetJoinPoints execution(java.lang.Runnable())"
  280. //, "before AllTargetJoinPoints execution(TargetClass.<init>)"
  281. , "before AllTargetJoinPoints set(String TargetClass.string)"
  282. , "before AllTargetJoinPoints execution(TargetClass())"
  283. , "before AllTargetJoinPoints call(String java.lang.Object.toString())"
  284. , "before AllTargetJoinPoints set(String TargetClass.staticString)"
  285. , "before AllTargetJoinPoints get(String TargetClass.staticString)"
  286. , "before AllTargetJoinPoints get(String TargetClass.string)"
  287. , "before AllTargetJoinPoints set(String TargetClass.string)"
  288. , "before AllTargetJoinPoints call(java.lang.Error(String))"
  289. , "before AllTargetJoinPoints handler(catch(Error))"
  290. , "before AllTargetJoinPoints call(void Signal.found(String))"
  291. , "caught"
  292. };
  293. }