/* ******************************************************************* * Copyright (c) 2004 IBM Corporation. * All rights reserved. * This program and the accompanying materials are made available * under the terms of the Eclipse Public License v1.0 * which accompanies this distribution and is available at * http://www.eclipse.org/legal/epl-v10.html * * ******************************************************************/ package org.aspectj.weaver.patterns; import java.util.Iterator; import java.util.Set; import java.util.StringTokenizer; import junit.framework.TestCase; import org.aspectj.weaver.Shadow; /** * Testing the pointcut rewriter. * * @author Adrian Colyer * @author Andy Clement */ public class PointcutRewriterTest extends TestCase { private PointcutRewriter prw; public void testComplexRewrite1() { Pointcut p = getPointcut("(persingleton(org.eclipse.ajdt.internal.ui.ras.UIFFDC) && ((handler(java.lang.Throwable+) && args(arg1)) && ((within(org.eclipse.ajdt..*) && (!within(org.eclipse.ajdt.internal.ui.lazystart..*) && (!within(org.eclipse.ajdt.internal.ui.dialogs.OpenTypeSelectionDialog2) && !(within(org.eclipse.ajdt.internal.ui.editor.AspectJBreakpointRulerAction) && handler(org.eclipse.jface.text.BadLocationException))))) && (!(within(org.eclipse.ajdt.core.ras.FFDC+) || handler(org.eclipse.core.runtime.OperationCanceledException)) && !this(java.lang.Object)))))"); checkMultipleRewrite(p); p = getPointcut("((((((((((!within(org.eclipse.ajdt.internal.ui.lazystart..*) && !within(org.eclipse.ajdt.internal.ui.dialogs.OpenTypeSelectionDialog2)) && !within(org.eclipse.ajdt.core.ras.FFDC+)) && within(org.eclipse.ajdt..*)) && !within(org.eclipse.ajdt.internal.ui.editor.AspectJBreakpointRulerAction)) && handler(java.lang.Throwable+)) && !handler(org.eclipse.core.runtime.OperationCanceledException)) && !this(java.lang.Object)) && args(arg1)) && persingleton(org.eclipse.ajdt.internal.ui.ras.UIFFDC)) || (((((((((!within(org.eclipse.ajdt.internal.ui.lazystart..*) && !within(org.eclipse.ajdt.internal.ui.dialogs.OpenTypeSelectionDialog2)) && !within(org.eclipse.ajdt.core.ras.FFDC+)) && within(org.eclipse.ajdt..*)) && !handler(org.eclipse.jface.text.BadLocationException)) && handler(java.lang.Throwable+)) && !handler(org.eclipse.core.runtime.OperationCanceledException)) && !this(java.lang.Object)) && args(arg1)) && persingleton(org.eclipse.ajdt.internal.ui.ras.UIFFDC)))"); checkMultipleRewrite(p); p = getPointcut("(persingleton(Oranges) && ((handler(Apples+) && args(arg1)) && ((within(foo..*) && (!within(org.eclipse.ajdt.internal.ui.lazystart..*) && (!within(org.eclipse.ajdt.internal.ui.dialogs.OpenTypeSelectionDialog2) && !(within(org.eclipse.ajdt.internal.ui.editor.AspectJBreakpointRulerAction) && handler(org.eclipse.jface.text.BadLocationException))))) && (!(within(org.eclipse.ajdt.core.ras.FFDC+) || handler(org.eclipse.core.runtime.OperationCanceledException)) && !this(java.lang.Object)))))"); checkMultipleRewrite(p); p = getPointcut("(((handler(Apples+)) && ((within(foo..*) && (!within(org.eclipse.ajdt.internal.ui.lazystart..*) && (!within(org.eclipse.ajdt.internal.ui.dialogs.OpenTypeSelectionDialog2) && !(within(org.eclipse.ajdt.internal.ui.editor.AspectJBreakpointRulerAction) && handler(org.eclipse.jface.text.BadLocationException))))) && (!(within(org.eclipse.ajdt.core.ras.FFDC+) || handler(org.eclipse.core.runtime.OperationCanceledException)) && !this(java.lang.Object)))))"); checkMultipleRewrite(p); p = getPointcut("within(xxx..*) && within(XXY) && within(org.eclipse.AspectJBreakpoint)"); checkMultipleRewrite(p); } /** * Rewrites a pointcut twice and checks the format is stable */ private void checkMultipleRewrite(Pointcut p) { Pointcut rewrittenPointcut = prw.rewrite(p, false); String rewrite = rewrittenPointcut.toString(); Pointcut rewriteOfRewrittenPointcut = prw.rewrite(rewrittenPointcut, false); String rewriteOfRewritten = rewriteOfRewrittenPointcut.toString(); assertEquals(rewrite, rewriteOfRewritten); } public void testDistributeNot() { Pointcut plain = getPointcut("this(Foo)"); assertEquals("Unchanged", plain, prw.rewrite(plain)); Pointcut not = getPointcut("!this(Foo)"); assertEquals("Unchanged", not, prw.rewrite(not)); Pointcut notNot = getPointcut("!!this(Foo)"); assertEquals("this(Foo)", prw.rewrite(notNot).toString()); Pointcut notNotNOT = getPointcut("!!!this(Foo)"); assertEquals("!this(Foo)", prw.rewrite(notNotNOT).toString()); Pointcut and = getPointcut("!(this(Foo) && this(Goo))"); assertEquals("(!this(Foo) || !this(Goo))", prw.rewrite(and, true).toString()); Pointcut or = getPointcut("!(this(Foo) || this(Goo))"); assertEquals("(!this(Foo) && !this(Goo))", prw.rewrite(or, true).toString()); Pointcut nestedNot = getPointcut("!(this(Foo) && !this(Goo))"); assertEquals("(!this(Foo) || this(Goo))", prw.rewrite(nestedNot, true).toString()); } public void testPullUpDisjunctions() { Pointcut aAndb = getPointcut("this(Foo) && this(Goo)"); assertEquals("Unchanged", aAndb, prw.rewrite(aAndb)); Pointcut aOrb = getPointcut("this(Foo) || this(Moo)"); assertEquals("Unchanged", aOrb, prw.rewrite(aOrb)); Pointcut leftOr = getPointcut("this(Foo) || (this(Goo) && this(Boo))"); assertEquals("or%anyorder%this(Foo)%and%anyorder%this(Boo)%this(Goo)", prw.rewrite(leftOr)); // assertEquals("(this(Foo) || (this(Boo) && this(Goo)))",prw.rewrite(leftOr).toString()); Pointcut rightOr = getPointcut("(this(Goo) && this(Boo)) || this(Foo)"); // assertEquals("(this(Foo) || (this(Boo) && this(Goo)))",prw.rewrite(rightOr).toString()); assertEquals("or%anyorder%this(Foo)%and%anyorder%this(Goo)%this(Boo)", prw.rewrite(rightOr)); Pointcut leftAnd = getPointcut("this(Foo) && (this(Goo) || this(Boo))"); // assertEquals("((this(Boo) && this(Foo)) || (this(Foo) && this(Goo)))",prw.rewrite(leftAnd).toString()); assertEquals("or%anyorder%and%anyorder%this(Boo)%this(Foo)%and%anyorder%this(Foo)%this(Goo)", prw.rewrite(leftAnd)); Pointcut rightAnd = getPointcut("(this(Goo) || this(Boo)) && this(Foo)"); // assertEquals("((this(Boo) && this(Foo)) || (this(Foo) && this(Goo)))",prw.rewrite(rightAnd).toString()); assertEquals("or%anyorder%and%anyorder%this(Boo)%this(Foo)%and%anyorder%this(Foo)%this(Goo)", prw.rewrite(rightAnd)); Pointcut nestedOrs = getPointcut("this(Foo) || this(Goo) || this(Boo)"); // assertEquals("((this(Boo) || this(Foo)) || this(Goo))",prw.rewrite(nestedOrs).toString()); assertEquals("or%anyorder%this(Goo)%or%anyorder%this(Boo)%this(Foo)", prw.rewrite(nestedOrs)); Pointcut nestedAnds = getPointcut("(this(Foo) && (this(Boo) && (this(Goo) || this(Moo))))"); // t(F) && (t(B) && (t(G) || t(M))) // ==> t(F) && ((t(B) && t(G)) || (t(B) && t(M))) // ==> (t(F) && (t(B) && t(G))) || (t(F) && (t(B) && t(M))) // assertEquals("(((this(Boo) && this(Foo)) && this(Goo)) || ((this(Boo) && this(Foo)) && this(Moo)))", // prw.rewrite(nestedAnds).toString()); assertEquals( "or%anyorder%and%anyorder%and%anyorder%this(Boo)%this(Foo)%this(Goo)%and%anyorder%and%anyorder%this(Boo)%this(Foo)%this(Moo)", prw.rewrite(nestedAnds)); } /** * spec is reverse polish notation with operators and, or , not, anyorder, delimiter is "%" (not whitespace). * * @param spec * @param pc */ private void assertEquals(String spec, Pointcut pc) { StringTokenizer strTok = new StringTokenizer(spec, "%"); String[] tokens = new String[strTok.countTokens()]; for (int i = 0; i < tokens.length; i++) { tokens[i] = strTok.nextToken(); } tokenIndex = 0; assertTrue(spec, equals(pc, tokens)); } private int tokenIndex = 0; private boolean equals(Pointcut pc, String[] tokens) { if (tokens[tokenIndex].equals("and")) { tokenIndex++; if (!(pc instanceof AndPointcut)) { return false; } AndPointcut apc = (AndPointcut) pc; Pointcut left = apc.getLeft(); Pointcut right = apc.getRight(); if (tokens[tokenIndex].equals("anyorder")) { tokenIndex++; int restorePoint = tokenIndex; boolean leftMatchFirst = equals(left, tokens) && equals(right, tokens); if (leftMatchFirst) { return true; } tokenIndex = restorePoint; boolean rightMatchFirst = equals(right, tokens) && equals(left, tokens); return rightMatchFirst; } else { return equals(left, tokens) && equals(right, tokens); } } else if (tokens[tokenIndex].equals("or")) { tokenIndex++; if (!(pc instanceof OrPointcut)) { return false; } OrPointcut opc = (OrPointcut) pc; Pointcut left = opc.getLeft(); Pointcut right = opc.getRight(); if (tokens[tokenIndex].equals("anyorder")) { tokenIndex++; int restorePoint = tokenIndex; boolean leftMatchFirst = equals(left, tokens) && equals(right, tokens); if (leftMatchFirst) { return true; } tokenIndex = restorePoint; boolean rightMatchFirst = equals(right, tokens) && equals(left, tokens); return rightMatchFirst; } else { return equals(left, tokens) && equals(right, tokens); } } else if (tokens[tokenIndex].equals("not")) { if (!(pc instanceof NotPointcut)) { return false; } tokenIndex++; NotPointcut np = (NotPointcut) pc; return equals(np.getNegatedPointcut(), tokens); } else { return tokens[tokenIndex++].equals(pc.toString()); } } // public void testSplitOutWithins() { // Pointcut simpleExecution = getPointcut("execution(* *.*(..))"); // assertEquals("Unchanged",simpleExecution,prw.rewrite(simpleExecution)); // Pointcut simpleWithinCode = getPointcut("withincode(* *.*(..))"); // assertEquals("Unchanged",simpleWithinCode,prw.rewrite(simpleWithinCode)); // Pointcut execution = getPointcut("execution(@Foo Foo (@Goo org.xyz..*).m*(Foo,Boo))"); // assertEquals("(within((@(Goo) org.xyz..*)) && execution(@(Foo) Foo m*(Foo, Boo)))", // prw.rewrite(execution).toString()); // Pointcut withincode = getPointcut("withincode(@Foo Foo (@Goo org.xyz..*).m*(Foo,Boo))"); // assertEquals("(within((@(Goo) org.xyz..*)) && withincode(@(Foo) Foo m*(Foo, Boo)))", // prw.rewrite(withincode).toString()); // Pointcut notExecution = getPointcut("!execution(Foo BankAccount+.*(..))"); // assertEquals("(!within(BankAccount+) || !execution(Foo *(..)))", // prw.rewrite(notExecution).toString()); // Pointcut andWithincode = getPointcut("withincode(Foo.new(..)) && this(Foo)"); // assertEquals("((within(Foo) && withincode(new(..))) && this(Foo))", // prw.rewrite(andWithincode).toString()); // Pointcut orExecution = getPointcut("this(Foo) || execution(Goo Foo.moo(Baa))"); // assertEquals("((within(Foo) && execution(Goo moo(Baa))) || this(Foo))", // prw.rewrite(orExecution).toString()); // } public void testRemoveDuplicatesInAnd() { Pointcut dupAnd = getPointcut("this(Foo) && this(Foo)"); assertEquals("this(Foo)", prw.rewrite(dupAnd).toString()); Pointcut splitdupAnd = getPointcut("(this(Foo) && target(Boo)) && this(Foo)"); assertEquals("(target(Boo) && this(Foo))", prw.rewrite(splitdupAnd).toString()); } public void testNotRemoveNearlyDuplicatesInAnd() { Pointcut toAndto = getPointcut("this(Object+) && this(Object)"); // Pointcut rewritten = prw.rewrite(toAndto); } public void testAAndNotAinAnd() { Pointcut aAndNota = getPointcut("this(Foo)&& !this(Foo)"); assertEquals("Matches nothing", "", prw.rewrite(aAndNota).toString()); Pointcut aAndBAndNota = getPointcut("this(Foo) && execution(* *.*(..)) && !this(Foo)"); assertEquals("Matches nothing", "", prw.rewrite(aAndBAndNota).toString()); } public void testIfFalseInAnd() { Pointcut ifFalse = IfPointcut.makeIfFalsePointcut(Pointcut.CONCRETE); Pointcut p = getPointcut("this(A)"); assertEquals("Matches nothing", "", prw.rewrite(new AndPointcut(ifFalse, p)).toString()); } public void testMatchesNothinginAnd() { Pointcut nothing = Pointcut.makeMatchesNothing(Pointcut.CONCRETE); Pointcut p = getPointcut("this(A)"); assertEquals("Matches nothing", "", prw.rewrite(new AndPointcut(nothing, p)).toString()); } public void testMixedKindsInAnd() { Pointcut mixedKinds = getPointcut("call(* *(..)) && execution(* *(..))"); assertEquals("Matches nothing", "", prw.rewrite(mixedKinds).toString()); Pointcut ok = getPointcut("this(Foo) && call(* *(..))"); assertEquals(ok, prw.rewrite(ok)); } public void testDetermineKindSetOfAnd() { Pointcut oneKind = getPointcut("execution(* foo(..)) && this(Boo)"); AndPointcut rewritten = (AndPointcut) prw.rewrite(oneKind); assertEquals("Only one kind", 1, Shadow.howMany(rewritten.couldMatchKinds())); assertTrue("It's Shadow.MethodExecution", Shadow.MethodExecution.isSet(rewritten.couldMatchKinds())); } public void testKindSetOfExecution() { Pointcut p = getPointcut("execution(* foo(..))"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.MethodExecution", Shadow.MethodExecution.isSet(p.couldMatchKinds())); p = getPointcut("execution(new(..))"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.ConstructorExecution", Shadow.ConstructorExecution.isSet(p.couldMatchKinds())); } public void testKindSetOfCall() { Pointcut p = getPointcut("call(* foo(..))"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.MethodCall", Shadow.MethodCall.isSet(p.couldMatchKinds())); p = getPointcut("call(new(..))"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.ConstructorCall", Shadow.ConstructorCall.isSet(p.couldMatchKinds())); } public void testKindSetOfAdviceExecution() { Pointcut p = getPointcut("adviceexecution()"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.AdviceExecution", Shadow.AdviceExecution.isSet(p.couldMatchKinds())); } public void testKindSetOfGet() { Pointcut p = getPointcut("get(* *)"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.FieldGet", Shadow.FieldGet.isSet(p.couldMatchKinds())); } public void testKindSetOfSet() { Pointcut p = getPointcut("set(* *)"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.FieldSet", Shadow.FieldSet.isSet(p.couldMatchKinds())); } public void testKindSetOfHandler() { Pointcut p = getPointcut("handler(*)"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.ExceptionHandler", Shadow.ExceptionHandler.isSet(p.couldMatchKinds())); } public void testKindSetOfInitialization() { Pointcut p = getPointcut("initialization(new (..))"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.Initialization", Shadow.Initialization.isSet(p.couldMatchKinds())); } public void testKindSetOfPreInitialization() { Pointcut p = getPointcut("preinitialization(new (..))"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.PreInitialization", Shadow.PreInitialization.isSet(p.couldMatchKinds())); } public void testKindSetOfStaticInitialization() { Pointcut p = getPointcut("staticinitialization(*)"); assertEquals("Only one kind", 1, Shadow.howMany(p.couldMatchKinds())); assertTrue("It's Shadow.StaticInitialization", Shadow.StaticInitialization.isSet(p.couldMatchKinds())); } public void testKindSetOfThis() { Pointcut p = getPointcut("this(Foo)"); Set matches = Shadow.toSet(p.couldMatchKinds()); for (Iterator iter = matches.iterator(); iter.hasNext();) { Shadow.Kind kind = (Shadow.Kind) iter.next(); assertFalse("No kinds that don't have a this", kind.neverHasThis()); } for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { if (!Shadow.SHADOW_KINDS[i].neverHasThis()) { assertTrue("All kinds that do have this", matches.contains(Shadow.SHADOW_KINDS[i])); } } // + @ p = getPointcut("@this(Foo)"); matches = Shadow.toSet(p.couldMatchKinds()); for (Iterator iter = matches.iterator(); iter.hasNext();) { Shadow.Kind kind = (Shadow.Kind) iter.next(); assertFalse("No kinds that don't have a this", kind.neverHasThis()); } for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { if (!Shadow.SHADOW_KINDS[i].neverHasThis()) { assertTrue("All kinds that do have this", matches.contains(Shadow.SHADOW_KINDS[i])); } } } public void testKindSetOfTarget() { Pointcut p = getPointcut("target(Foo)"); Set matches = Shadow.toSet(p.couldMatchKinds()); for (Iterator iter = matches.iterator(); iter.hasNext();) { Shadow.Kind kind = (Shadow.Kind) iter.next(); assertFalse("No kinds that don't have a target", kind.neverHasTarget()); } for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { if (!Shadow.SHADOW_KINDS[i].neverHasTarget()) { assertTrue("All kinds that do have target", matches.contains(Shadow.SHADOW_KINDS[i])); } } // + @ p = getPointcut("@target(Foo)"); matches = Shadow.toSet(p.couldMatchKinds()); for (Iterator iter = matches.iterator(); iter.hasNext();) { Shadow.Kind kind = (Shadow.Kind) iter.next(); assertFalse("No kinds that don't have a target", kind.neverHasTarget()); } for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { if (!Shadow.SHADOW_KINDS[i].neverHasTarget()) { assertTrue("All kinds that do have target", matches.contains(Shadow.SHADOW_KINDS[i])); } } } public void testKindSetOfArgs() { Pointcut p = getPointcut("args(..)"); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); // + @ p = getPointcut("@args(..)"); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); } public void testKindSetOfAnnotation() { Pointcut p = getPointcut("@annotation(Foo)"); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); } public void testKindSetOfWithin() { Pointcut p = getPointcut("within(*)"); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); // + @ p = getPointcut("@within(Foo)"); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); } public void testKindSetOfWithinCode() { Pointcut p = getPointcut("withincode(* foo(..))"); Set matches = Shadow.toSet(p.couldMatchKinds()); for (Iterator iter = matches.iterator(); iter.hasNext();) { Shadow.Kind kind = (Shadow.Kind) iter.next(); assertFalse("No kinds that are themselves enclosing", (kind.isEnclosingKind() && kind != Shadow.ConstructorExecution && kind != Shadow.Initialization)); } for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { if (!Shadow.SHADOW_KINDS[i].isEnclosingKind()) { assertTrue("All kinds that are not enclosing", matches.contains(Shadow.SHADOW_KINDS[i])); } } assertTrue("Need cons-exe for inlined field inits", matches.contains(Shadow.ConstructorExecution)); assertTrue("Need init for inlined field inits", matches.contains(Shadow.Initialization)); // + @ p = getPointcut("@withincode(Foo)"); matches = Shadow.toSet(p.couldMatchKinds()); for (Iterator iter = matches.iterator(); iter.hasNext();) { Shadow.Kind kind = (Shadow.Kind) iter.next(); assertFalse("No kinds that are themselves enclosing", kind.isEnclosingKind()); } for (int i = 0; i < Shadow.SHADOW_KINDS.length; i++) { if (!Shadow.SHADOW_KINDS[i].isEnclosingKind()) { assertTrue("All kinds that are not enclosing", matches.contains(Shadow.SHADOW_KINDS[i])); } } } public void testKindSetOfIf() { Pointcut p = new IfPointcut(null, 0); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); p = IfPointcut.makeIfTruePointcut(Pointcut.CONCRETE); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); p = IfPointcut.makeIfFalsePointcut(Pointcut.CONCRETE); assertTrue("Nothing", p.couldMatchKinds() == Shadow.NO_SHADOW_KINDS_BITS); } public void testKindSetOfCflow() { Pointcut p = getPointcut("cflow(this(Foo))"); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); // [below] p = getPointcut("cflowbelow(this(Foo))"); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); } public void testKindSetInNegation() { Pointcut p = getPointcut("!execution(new(..))"); assertTrue("All kinds", p.couldMatchKinds() == Shadow.ALL_SHADOW_KINDS_BITS); } public void testKindSetOfOr() { Pointcut p = getPointcut("execution(new(..)) || get(* *)"); Set matches = Shadow.toSet(p.couldMatchKinds()); assertEquals("2 kinds", 2, matches.size()); assertTrue("ConstructorExecution", matches.contains(Shadow.ConstructorExecution)); assertTrue("FieldGet", matches.contains(Shadow.FieldGet)); } public void testOrderingInAnd() { 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)"); checkMultipleRewrite(bigLongPC); Pointcut rewritten = prw.rewrite(bigLongPC); assertEquals( "((((((((((((within(Foo) && @within(Foo)) && set(* *)) && withincode(new(..))) && @withincode(Boo)) && target(Boo)) && this(Moo)) && @annotation(Moo)) && @this(Foo)) && @target(Boo)) && args(X)) && @args(X)) && cflow(this(Foo)))", rewritten.toString()); } public void testOrderingInSimpleOr() { OrPointcut opc = (OrPointcut) getPointcut("execution(new(..)) || get(* *)"); assertEquals("reordered", "(get(* *) || execution(new(..)))", prw.rewrite(opc).toString()); } public void testOrderingInNestedOrs() { OrPointcut opc = (OrPointcut) getPointcut("(execution(new(..)) || get(* *)) || within(abc)"); assertEquals("reordered", "((within(abc) || get(* *)) || execution(new(..)))", prw.rewrite(opc).toString()); } public void testOrderingInOrsWithNestedAnds() { OrPointcut opc = (OrPointcut) getPointcut("get(* *) || (execution(new(..)) && within(abc))"); assertEquals("reordered", "((within(abc) && execution(new(..))) || get(* *))", prw.rewrite(opc).toString()); } private Pointcut getPointcut(String s) { return new PatternParser(s).parsePointcut(); } /* * @see TestCase#setUp() */ protected void setUp() throws Exception { super.setUp(); prw = new PointcutRewriter(); } }