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.

PointcutRewriterTest.java 16KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366
  1. /* *******************************************************************
  2. * Copyright (c) 2004 IBM Corporation.
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Common Public License v1.0
  6. * which accompanies this distribution and is available at
  7. * http://www.eclipse.org/legal/cpl-v10.html
  8. *
  9. * ******************************************************************/
  10. package org.aspectj.weaver.patterns;
  11. import java.util.Iterator;
  12. import java.util.Set;
  13. import org.aspectj.weaver.Shadow;
  14. import junit.framework.TestCase;
  15. /**
  16. * @author colyer
  17. *
  18. * TODO To change the template for this generated type comment go to
  19. * Window - Preferences - Java - Code Style - Code Templates
  20. */
  21. public class PointcutRewriterTest extends TestCase {
  22. private PointcutRewriter prw;
  23. public void testDistributeNot() {
  24. Pointcut plain = getPointcut("this(Foo)");
  25. assertEquals("Unchanged",plain,prw.rewrite(plain));
  26. Pointcut not = getPointcut("!this(Foo)");
  27. assertEquals("Unchanged",not,prw.rewrite(not));
  28. Pointcut notNot = getPointcut("!!this(Foo)");
  29. assertEquals("this(Foo)",prw.rewrite(notNot).toString());
  30. Pointcut notNotNOT = getPointcut("!!!this(Foo)");
  31. assertEquals("!this(Foo)",prw.rewrite(notNotNOT).toString());
  32. Pointcut and = getPointcut("!(this(Foo) && this(Goo))");
  33. assertEquals("(!this(Foo) || !this(Goo))",prw.rewrite(and).toString());
  34. Pointcut or = getPointcut("!(this(Foo) || this(Goo))");
  35. assertEquals("(!this(Foo) && !this(Goo))",prw.rewrite(or).toString());
  36. Pointcut nestedNot = getPointcut("!(this(Foo) && !this(Goo))");
  37. assertEquals("(!this(Foo) || this(Goo))",prw.rewrite(nestedNot).toString());
  38. }
  39. public void testPullUpDisjunctions() {
  40. Pointcut aAndb = getPointcut("this(Foo) && this(Goo)");
  41. assertEquals("Unchanged",aAndb,prw.rewrite(aAndb));
  42. Pointcut aOrb = getPointcut("this(Foo) || this(Moo)");
  43. assertEquals("Unchanged",aOrb,prw.rewrite(aOrb));
  44. Pointcut leftOr = getPointcut("this(Foo) || (this(Goo) && this(Boo))");
  45. System.out.println(prw.rewrite(leftOr));
  46. assertEquals("(this(Foo) || (this(Boo) && this(Goo)))",prw.rewrite(leftOr).toString());
  47. Pointcut rightOr = getPointcut("(this(Goo) && this(Boo)) || this(Foo)");
  48. assertEquals("(this(Foo) || (this(Boo) && this(Goo)))",prw.rewrite(rightOr).toString());
  49. Pointcut leftAnd = getPointcut("this(Foo) && (this(Goo) || this(Boo))");
  50. assertEquals("((this(Boo) && this(Foo)) || (this(Foo) && this(Goo)))",prw.rewrite(leftAnd).toString());
  51. Pointcut rightAnd = getPointcut("(this(Goo) || this(Boo)) && this(Foo)");
  52. assertEquals("((this(Boo) && this(Foo)) || (this(Foo) && this(Goo)))",prw.rewrite(rightAnd).toString());
  53. Pointcut nestedOrs = getPointcut("this(Foo) || this(Goo) || this(Boo)");
  54. assertEquals("((this(Boo) || this(Foo)) || this(Goo))",prw.rewrite(nestedOrs).toString());
  55. Pointcut nestedAnds = getPointcut("(this(Foo) && (this(Boo) && (this(Goo) || this(Moo))))");
  56. // t(F) && (t(B) && (t(G) || t(M)))
  57. // ==> t(F) && ((t(B) && t(G)) || (t(B) && t(M)))
  58. // ==> (t(F) && (t(B) && t(G))) || (t(F) && (t(B) && t(M)))
  59. assertEquals("(((this(Boo) && this(Foo)) && this(Goo)) || ((this(Boo) && this(Foo)) && this(Moo)))",
  60. prw.rewrite(nestedAnds).toString());
  61. }
  62. // public void testSplitOutWithins() {
  63. // Pointcut simpleExecution = getPointcut("execution(* *.*(..))");
  64. // assertEquals("Unchanged",simpleExecution,prw.rewrite(simpleExecution));
  65. // Pointcut simpleWithinCode = getPointcut("withincode(* *.*(..))");
  66. // assertEquals("Unchanged",simpleWithinCode,prw.rewrite(simpleWithinCode));
  67. // Pointcut execution = getPointcut("execution(@Foo Foo (@Goo org.xyz..*).m*(Foo,Boo))");
  68. // assertEquals("(within((@(Goo) org.xyz..*)) && execution(@(Foo) Foo m*(Foo, Boo)))",
  69. // prw.rewrite(execution).toString());
  70. // Pointcut withincode = getPointcut("withincode(@Foo Foo (@Goo org.xyz..*).m*(Foo,Boo))");
  71. // assertEquals("(within((@(Goo) org.xyz..*)) && withincode(@(Foo) Foo m*(Foo, Boo)))",
  72. // prw.rewrite(withincode).toString());
  73. // Pointcut notExecution = getPointcut("!execution(Foo BankAccount+.*(..))");
  74. // assertEquals("(!within(BankAccount+) || !execution(Foo *(..)))",
  75. // prw.rewrite(notExecution).toString());
  76. // Pointcut andWithincode = getPointcut("withincode(Foo.new(..)) && this(Foo)");
  77. // assertEquals("((within(Foo) && withincode(new(..))) && this(Foo))",
  78. // prw.rewrite(andWithincode).toString());
  79. // Pointcut orExecution = getPointcut("this(Foo) || execution(Goo Foo.moo(Baa))");
  80. // assertEquals("((within(Foo) && execution(Goo moo(Baa))) || this(Foo))",
  81. // prw.rewrite(orExecution).toString());
  82. // }
  83. public void testRemoveDuplicatesInAnd() {
  84. Pointcut dupAnd = getPointcut("this(Foo) && this(Foo)");
  85. assertEquals("this(Foo)",prw.rewrite(dupAnd).toString());
  86. Pointcut splitdupAnd = getPointcut("(this(Foo) && target(Boo)) && this(Foo)");
  87. assertEquals("(target(Boo) && this(Foo))",prw.rewrite(splitdupAnd).toString());
  88. }
  89. public void testNotRemoveNearlyDuplicatesInAnd() {
  90. Pointcut toAndto = getPointcut("this(Object+) && this(Object)");
  91. Pointcut rewritten = prw.rewrite(toAndto);
  92. }
  93. public void testAAndNotAinAnd() {
  94. Pointcut aAndNota = getPointcut("this(Foo)&& !this(Foo)");
  95. assertEquals("Matches nothing","",prw.rewrite(aAndNota).toString());
  96. Pointcut aAndBAndNota = getPointcut("this(Foo) && execution(* *.*(..)) && !this(Foo)");
  97. assertEquals("Matches nothing","",prw.rewrite(aAndBAndNota).toString());
  98. }
  99. public void testIfFalseInAnd() {
  100. Pointcut ifFalse = IfPointcut.makeIfFalsePointcut(Pointcut.CONCRETE);
  101. Pointcut p = getPointcut("this(A)");
  102. assertEquals("Matches nothing","",prw.rewrite(new AndPointcut(ifFalse,p)).toString());
  103. }
  104. public void testMatchesNothinginAnd() {
  105. Pointcut nothing = Pointcut.makeMatchesNothing(Pointcut.CONCRETE);
  106. Pointcut p = getPointcut("this(A)");
  107. assertEquals("Matches nothing","",prw.rewrite(new AndPointcut(nothing,p)).toString());
  108. }
  109. public void testMixedKindsInAnd() {
  110. Pointcut mixedKinds = getPointcut("call(* *(..)) && execution(* *(..))");
  111. assertEquals("Matches nothing","",prw.rewrite(mixedKinds).toString());
  112. Pointcut ok = getPointcut("call(* *(..)) && this(Foo)");
  113. assertEquals(ok,prw.rewrite(ok));
  114. }
  115. public void testDetermineKindSetOfAnd() {
  116. Pointcut oneKind = getPointcut("execution(* foo(..)) && this(Boo)");
  117. AndPointcut rewritten = (AndPointcut) prw.rewrite(oneKind);
  118. assertEquals("Only one kind",1,rewritten.couldMatchKinds().size());
  119. assertTrue("It's Shadow.MethodExecution",rewritten.couldMatchKinds().contains(Shadow.MethodExecution));
  120. }
  121. public void testKindSetOfExecution() {
  122. Pointcut p = getPointcut("execution(* foo(..))");
  123. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  124. assertTrue("It's Shadow.MethodExecution",p.couldMatchKinds().contains(Shadow.MethodExecution));
  125. p = getPointcut("execution(new(..))");
  126. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  127. assertTrue("It's Shadow.ConstructorExecution",p.couldMatchKinds().contains(Shadow.ConstructorExecution));
  128. }
  129. public void testKindSetOfCall() {
  130. Pointcut p = getPointcut("call(* foo(..))");
  131. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  132. assertTrue("It's Shadow.MethodCall",p.couldMatchKinds().contains(Shadow.MethodCall));
  133. p = getPointcut("call(new(..))");
  134. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  135. assertTrue("It's Shadow.ConstructorCall",p.couldMatchKinds().contains(Shadow.ConstructorCall));
  136. }
  137. public void testKindSetOfAdviceExecution() {
  138. Pointcut p = getPointcut("adviceexecution()");
  139. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  140. assertTrue("It's Shadow.AdviceExecution",p.couldMatchKinds().contains(Shadow.AdviceExecution));
  141. }
  142. public void testKindSetOfGet() {
  143. Pointcut p = getPointcut("get(* *)");
  144. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  145. assertTrue("It's Shadow.FieldGet",p.couldMatchKinds().contains(Shadow.FieldGet));
  146. }
  147. public void testKindSetOfSet() {
  148. Pointcut p = getPointcut("set(* *)");
  149. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  150. assertTrue("It's Shadow.FieldSet",p.couldMatchKinds().contains(Shadow.FieldSet));
  151. }
  152. public void testKindSetOfHandler() {
  153. Pointcut p = getPointcut("handler(*)");
  154. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  155. assertTrue("It's Shadow.ExceptionHandler",p.couldMatchKinds().contains(Shadow.ExceptionHandler));
  156. }
  157. public void testKindSetOfInitialization() {
  158. Pointcut p = getPointcut("initialization(new (..))");
  159. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  160. assertTrue("It's Shadow.Initialization",p.couldMatchKinds().contains(Shadow.Initialization));
  161. }
  162. public void testKindSetOfPreInitialization() {
  163. Pointcut p = getPointcut("preinitialization(new (..))");
  164. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  165. assertTrue("It's Shadow.PreInitialization",p.couldMatchKinds().contains(Shadow.PreInitialization));
  166. }
  167. public void testKindSetOfStaticInitialization() {
  168. Pointcut p = getPointcut("staticinitialization(*)");
  169. assertEquals("Only one kind",1,p.couldMatchKinds().size());
  170. assertTrue("It's Shadow.StaticInitialization",p.couldMatchKinds().contains(Shadow.StaticInitialization));
  171. }
  172. public void testKindSetOfThis() {
  173. Pointcut p = getPointcut("this(Foo)");
  174. Set matches = p.couldMatchKinds();
  175. for (Iterator iter = matches.iterator(); iter.hasNext();) {
  176. Shadow.Kind kind = (Shadow.Kind) iter.next();
  177. assertFalse("No kinds that don't have a this",kind.neverHasThis());
  178. }
  179. for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
  180. if (!Shadow.SHADOW_KINDS[i].neverHasThis()) {
  181. assertTrue("All kinds that do have this",matches.contains(Shadow.SHADOW_KINDS[i]));
  182. }
  183. }
  184. // + @
  185. p = getPointcut("@this(@Foo)");
  186. matches = p.couldMatchKinds();
  187. for (Iterator iter = matches.iterator(); iter.hasNext();) {
  188. Shadow.Kind kind = (Shadow.Kind) iter.next();
  189. assertFalse("No kinds that don't have a this",kind.neverHasThis());
  190. }
  191. for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
  192. if (!Shadow.SHADOW_KINDS[i].neverHasThis()) {
  193. assertTrue("All kinds that do have this",matches.contains(Shadow.SHADOW_KINDS[i]));
  194. }
  195. }
  196. }
  197. public void testKindSetOfTarget() {
  198. Pointcut p = getPointcut("target(Foo)");
  199. Set matches = p.couldMatchKinds();
  200. for (Iterator iter = matches.iterator(); iter.hasNext();) {
  201. Shadow.Kind kind = (Shadow.Kind) iter.next();
  202. assertFalse("No kinds that don't have a target",kind.neverHasTarget());
  203. }
  204. for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
  205. if (!Shadow.SHADOW_KINDS[i].neverHasTarget()) {
  206. assertTrue("All kinds that do have target",matches.contains(Shadow.SHADOW_KINDS[i]));
  207. }
  208. }
  209. // + @
  210. p = getPointcut("@target(@Foo)");
  211. matches = p.couldMatchKinds();
  212. for (Iterator iter = matches.iterator(); iter.hasNext();) {
  213. Shadow.Kind kind = (Shadow.Kind) iter.next();
  214. assertFalse("No kinds that don't have a target",kind.neverHasTarget());
  215. }
  216. for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
  217. if (!Shadow.SHADOW_KINDS[i].neverHasTarget()) {
  218. assertTrue("All kinds that do have target",matches.contains(Shadow.SHADOW_KINDS[i]));
  219. }
  220. }
  221. }
  222. public void testKindSetOfArgs() {
  223. Pointcut p = getPointcut("args(..)");
  224. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  225. // + @
  226. p = getPointcut("@args(..)");
  227. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  228. }
  229. public void testKindSetOfAnnotation() {
  230. Pointcut p = getPointcut("@annotation(@Foo)");
  231. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  232. }
  233. public void testKindSetOfWithin() {
  234. Pointcut p = getPointcut("within(*)");
  235. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  236. // + @
  237. p = getPointcut("@within(@Foo)");
  238. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  239. }
  240. public void testKindSetOfWithinCode() {
  241. Pointcut p = getPointcut("withincode(* foo(..))");
  242. Set matches = p.couldMatchKinds();
  243. for (Iterator iter = matches.iterator(); iter.hasNext();) {
  244. Shadow.Kind kind = (Shadow.Kind) iter.next();
  245. assertFalse("No kinds that are themselves enclosing",
  246. (kind.isEnclosingKind() && kind != Shadow.ConstructorExecution && kind != Shadow.Initialization));
  247. }
  248. for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
  249. if (!Shadow.SHADOW_KINDS[i].isEnclosingKind()) {
  250. assertTrue("All kinds that are not enclosing",matches.contains(Shadow.SHADOW_KINDS[i]));
  251. }
  252. }
  253. assertTrue("Need cons-exe for inlined field inits",matches.contains(Shadow.ConstructorExecution));
  254. assertTrue("Need init for inlined field inits",matches.contains(Shadow.Initialization));
  255. // + @
  256. p = getPointcut("@withincode(@Foo)");
  257. matches = p.couldMatchKinds();
  258. for (Iterator iter = matches.iterator(); iter.hasNext();) {
  259. Shadow.Kind kind = (Shadow.Kind) iter.next();
  260. assertFalse("No kinds that are themselves enclosing",kind.isEnclosingKind());
  261. }
  262. for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) {
  263. if (!Shadow.SHADOW_KINDS[i].isEnclosingKind()) {
  264. assertTrue("All kinds that are not enclosing",matches.contains(Shadow.SHADOW_KINDS[i]));
  265. }
  266. }
  267. }
  268. public void testKindSetOfIf() {
  269. Pointcut p = new IfPointcut(null,0);
  270. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  271. p = IfPointcut.makeIfTruePointcut(Pointcut.CONCRETE);
  272. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  273. p = IfPointcut.makeIfFalsePointcut(Pointcut.CONCRETE);
  274. assertTrue("Nothing",p.couldMatchKinds().isEmpty());
  275. }
  276. public void testKindSetOfCflow() {
  277. Pointcut p = getPointcut("cflow(this(Foo))");
  278. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  279. // [below]
  280. p = getPointcut("cflowbelow(this(Foo))");
  281. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  282. }
  283. public void testKindSetInNegation() {
  284. Pointcut p = getPointcut("!execution(new(..))");
  285. assertTrue("All kinds",p.couldMatchKinds().containsAll(Shadow.ALL_SHADOW_KINDS));
  286. }
  287. public void testKindSetOfOr() {
  288. Pointcut p = getPointcut("execution(new(..)) || get(* *)");
  289. Set matches = p.couldMatchKinds();
  290. assertEquals("2 kinds",2,matches.size());
  291. assertTrue("ConstructorExecution",matches.contains(Shadow.ConstructorExecution));
  292. assertTrue("FieldGet",matches.contains(Shadow.FieldGet));
  293. }
  294. public void testOrderingInAnd() {
  295. Pointcut bigLongPC = getPointcut("cflow(this(Foo)) && @args(@X) && args(X) && @this(@Foo) && @target(@Boo) && this(Moo) && target(Boo) && @annotation(@Moo) && @withincode(@Boo) && withincode(new(..)) && set(* *)&& @within(@Foo) && within(Foo)");
  296. Pointcut rewritten = prw.rewrite(bigLongPC);
  297. assertEquals("((((((((((((within(Foo) && @within(@Foo)) && set(* *)) && withincode(new(..))) && @withincode(@Boo)) && @annotation(@Moo)) && target(Boo)) && this(Moo)) && @target(@Boo)) && @this(@Foo)) && args(X)) && @args(@X)) && cflow(this(Foo)))",rewritten.toString());
  298. }
  299. public void testOrderingInSimpleOr() {
  300. OrPointcut opc = (OrPointcut) getPointcut("execution(new(..)) || get(* *)");
  301. assertEquals("reordered","(get(* *) || execution(new(..)))",prw.rewrite(opc).toString());
  302. }
  303. public void testOrderingInNestedOrs() {
  304. OrPointcut opc = (OrPointcut) getPointcut("(execution(new(..)) || get(* *)) || within(abc)");
  305. assertEquals("reordered","((within(abc) || get(* *)) || execution(new(..)))",
  306. prw.rewrite(opc).toString());
  307. }
  308. public void testOrderingInOrsWithNestedAnds() {
  309. OrPointcut opc = (OrPointcut) getPointcut("get(* *) || (execution(new(..)) && within(abc))");
  310. assertEquals("reordered","((within(abc) && execution(new(..))) || get(* *))",
  311. prw.rewrite(opc).toString());
  312. }
  313. private Pointcut getPointcut(String s) {
  314. return new PatternParser(s).parsePointcut();
  315. }
  316. /*
  317. * @see TestCase#setUp()
  318. */
  319. protected void setUp() throws Exception {
  320. super.setUp();
  321. prw = new PointcutRewriter();
  322. }
  323. }