aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--testing/newsrc/org/aspectj/testing/AutowiredXMLBasedAjcTestCase.java15
-rw-r--r--tests/java5/ataspectj/ataspectj/BindingTest.java103
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java2
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java50
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml140
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml108
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml82
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelShadow.java268
8 files changed, 592 insertions, 176 deletions
diff --git a/testing/newsrc/org/aspectj/testing/AutowiredXMLBasedAjcTestCase.java b/testing/newsrc/org/aspectj/testing/AutowiredXMLBasedAjcTestCase.java
index f77e289d7..02adcd515 100644
--- a/testing/newsrc/org/aspectj/testing/AutowiredXMLBasedAjcTestCase.java
+++ b/testing/newsrc/org/aspectj/testing/AutowiredXMLBasedAjcTestCase.java
@@ -135,5 +135,20 @@ public abstract class AutowiredXMLBasedAjcTestCase extends XMLBasedAjcTestCase {
super.setUp();
}
+ /**
+ * This helper method runs the test with the given title in the
+ * suite spec file. All tests steps in given ajc-test execute
+ * in the same sandbox.
+ */
+ protected void runTest(String title) {
+ AjcTest currentTest = (AjcTest) testMap.get(title);
+ if (currentTest == null) {
+ fail("No test '" + title + "' in suite.");
+ }
+ ajc.setShouldEmptySandbox(true);
+ currentTest.runTest(this);
+ }
+
+
}
diff --git a/tests/java5/ataspectj/ataspectj/BindingTest.java b/tests/java5/ataspectj/ataspectj/BindingTest.java
index e88bead39..c4114f020 100644
--- a/tests/java5/ataspectj/ataspectj/BindingTest.java
+++ b/tests/java5/ataspectj/ataspectj/BindingTest.java
@@ -17,10 +17,13 @@ import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
+import org.aspectj.lang.Aspects;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
+import java.security.PrivilegedAction;
+
/**
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
@@ -43,6 +46,10 @@ public class BindingTest extends TestCase {
return i*3;//see x3 here
}
+ public int echo(int i) {
+ return i;
+ }
+
public void testAroundArgs() {
int res = substract(3, 2);// should be 2 without around advice
assertEquals(1, res);
@@ -54,6 +61,35 @@ public class BindingTest extends TestCase {
callWithinStatic();
}
+ public void testProceedInInner() {
+ int res = echo(3);//advice will x2 using an inner
+ assertEquals(6, res);
+ }
+
+ public void testNoProceed() {
+ int res = echo(3);//advice will return 0 and not proceed
+ assertEquals(0, res);
+ }
+
+ public void testDoubleProceed() {
+ int res = echo(3);//advice will proceed twice and add the returned values
+ assertEquals(6, res);
+ }
+
+ public void testDoubleProceedOneInner() {
+ int res = echo(3);//advice will proceed twice with one in inner and add the returned values
+ assertEquals(6, res);
+ }
+
+ public void testAccessAspectState() {
+ //TestAspect_1 aspect = (TestAspect_1) Aspects.aspectOf(TestAspect_1.class);
+ //aspect.m_count = 0;
+ int res = echo(3);
+ res += echo(3);
+ assertEquals(6, res);
+ //assertEquals(2, aspect.m_count);
+ }
+
private static void callWithinStatic() {
int res = dup((3+1));
assertEquals(6, res);
@@ -62,9 +98,12 @@ public class BindingTest extends TestCase {
@Aspect
public static class TestAspect_1 {
+ private int m_count = 0;
+
@Pointcut("call(int substract(int, int)) && within(ataspectj.BindingTest) && args(arg1, arg2)")
void pc(int arg2, int arg1) {}// see rather fancy ordering here..
+ // see return int here.
@Around("pc(argAdvice2, argAdvice1) && target(t)")//see here ordering remade consistent
public int aaround(ProceedingJoinPoint jp, BindingTest t, int argAdvice1, int argAdvice2) throws Throwable {
int res = ((Integer)jp.proceed()).intValue();
@@ -79,5 +118,69 @@ public class BindingTest extends TestCase {
int res = ((Integer)jp.proceed(new Object[]{new Integer(argAdvice1-1)})).intValue();
return new Integer(res/3*2);
}
+
+ @Around("call(int echo(int)) && withincode(void ataspectj.BindingTest.testProceedInInner()) && args(i)")
+ public int aaround3(int i, final ProceedingJoinPoint jp) throws Throwable {
+ final StringBuffer sb = new StringBuffer();
+ Runnable r = new Runnable() {
+ public void run() {
+ try {
+ int res = ((Integer)jp.proceed()).intValue();
+ sb.append(res);
+ } catch (Throwable t) {
+ fail(t.toString());
+ }
+ }
+ };
+ Thread t = new Thread(r);
+ t.start();
+ t.join();
+ assertEquals(i, Integer.parseInt(sb.toString()));
+ return Integer.parseInt(sb.toString())*2;
+ }
+
+ @Around("call(int echo(int)) && withincode(void ataspectj.BindingTest.testNoProceed()) && args(i)")
+ public int aaround4(int i, final ProceedingJoinPoint jp) throws Throwable {
+ // since no proceed() is call, this advice won't be inlined
+ return 0;
+ }
+
+ @Around("call(int echo(int)) && withincode(void ataspectj.BindingTest.testDoubleProceed()) && args(i)")
+ public int aaround5(int i, final ProceedingJoinPoint jp) throws Throwable {
+ int i1 = ((Integer)jp.proceed()).intValue();
+ int i2 = ((Integer)jp.proceed()).intValue();
+ return i1 + i2;
+ }
+
+ @Around("call(int echo(int)) && withincode(void ataspectj.BindingTest.testDoubleProceedOneInner()) && args(i)")
+ public int aaround6(int i, final ProceedingJoinPoint jp) throws Throwable {
+ int i1 = ((Integer)jp.proceed()).intValue();
+ Object io2 = new PrivilegedAction() {
+ public Object run() {
+ try {
+ return jp.proceed();
+ } catch (Throwable t) {
+ fail(t.toString());
+ return null;
+ }
+ }
+ }.run();
+ if (io2 == null) {
+ // since inlining occured, proceed was never called
+ fail("should not happen - advice was probably inlined while it must not be");
+ return i1 * 2;
+ } else {
+ int i2 = ((Integer)io2).intValue();
+ return i1 + i2;
+ }
+ }
+
+ @Around("call(int echo(int)) && withincode(void ataspectj.BindingTest.testAccessAspectState()) && args(i)")
+ public Object aaround7(int i, final ProceedingJoinPoint jp) throws Throwable {
+ //m_count++;// what if inlined ?
+ return jp.proceed();
+ }
+
}
+
}
diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java
index 0a2edb2ca..9004bf9bf 100644
--- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java
+++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjAnnotationGenTests.java
@@ -28,7 +28,7 @@ public class AtAjAnnotationGenTests extends XMLBasedAjcTestCase {
}
protected File getSpecFile() {
- return new File("../tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150.xml");
+ return new File("../tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml");
}
public void testSimpleAspect() {
diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java
index f1255b6aa..0ff079345 100644
--- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java
+++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/AtAjSyntaxTests.java
@@ -16,63 +16,21 @@ import java.io.File;
import junit.framework.Test;
import org.aspectj.testing.XMLBasedAjcTestCase;
+import org.aspectj.testing.AutowiredXMLBasedAjcTestCase;
/**
* A suite for @AspectJ aspects located in java5/ataspectj
*
* @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a>
*/
-public class AtAjSyntaxTests extends XMLBasedAjcTestCase {
+public class AtAjSyntaxTests extends AutowiredXMLBasedAjcTestCase {
public static Test suite() {
- return XMLBasedAjcTestCase.loadSuite(AtAjSyntaxTests.class);
+ return AutowiredXMLBasedAjcTestCase.loadSuite(AtAjSyntaxTests.class);
}
protected File getSpecFile() {
- return new File("../tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150.xml");
+ return new File("../tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml");
}
-
- public void testSimpleBefore() {
- runTest("SimpleBefore");
- }
-
- public void testSimpleAfter() {
- runTest("SimpleAfter");
- }
-
- public void testSingletonAspectBinding() {
- runTest("singletonAspectBindings");
- }
-
- public void testCflow() {
- runTest("CflowTest");
- }
-
- public void testPointcutReference() {
- runTest("PointcutReferenceTest");
- }
-
- public void testXXJoinPoint() {
- runTest("XXJoinPointTest");
- }
-
- public void testPrecedence() {
- runTest("PrecedenceTest");
- }
-
-// FIXME alex restore when AJC can compile it... #86452
-// public void testAfterX() {
-// runTest("AfterXTest");
-// }
-
- //FIXME AV uncomment when IfPointcutTest.TestAspect can be compiled ie if() pcd can be parsed.
- // right now the aspect is commented out.
-// public void testIfPointcut() {
-// runTest("IfPointcutTest");
-// }
-// FIXME alex java.lang.VerifyError: (class: ataspectj/BindingTest, method: dup_aroundBody5$advice signature: (ILorg/aspectj/lang/JoinPoint;Lataspectj/BindingTest$TestAspect_1;ILorg/aspectj/lang/ProceedingJoinPoint;)Ljava/lang/Object;) Register 0 contains wrong type
-// public void testBindings() {
-// runTest("BindingTest");
-// }
} \ No newline at end of file
diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml
new file mode 100644
index 000000000..c975b0d5e
--- /dev/null
+++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/annotationgen.xml
@@ -0,0 +1,140 @@
+<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>
+
+<suite>
+<!-- @AspectJ v1.5.0 Tests -->
+
+ <!-- ================================================================= -->
+ <!-- Adrian's tests for generation of @AspectJ annotations from ajc -->
+ <!-- ================================================================= -->
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for simple aspect">
+ <compile files="SimpleAspect.aj" options="-1.5"/>
+ <run class="SimpleAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for simple annotated aspect">
+ <compile files="SimpleAnnotatedAspect.aj" options="-1.5"/>
+ <run class="SimpleAnnotatedAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for simple aspect pre 1.5">
+ <compile files="Simple14Aspect.aj" options="-1.4"/>
+ <compile files="Simple14AspectTest.java" options="-1.5"/>
+ <run class="Simple14AspectTest"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for privileged aspect">
+ <compile files="PrivilegedAspect.aj" options="-1.5"/>
+ <run class="PrivilegedAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for perthis aspect">
+ <compile files="PerThisAspect.aj" options="-1.5"/>
+ <run class="PerThisAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for pertarget aspect">
+ <compile files="PerTargetAspect.aj" options="-1.5"/>
+ <run class="PerTargetAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for percflow aspect">
+ <compile files="PerCflowAspect.aj" options="-1.5"/>
+ <run class="PerCflowAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for percflowbelow aspect">
+ <compile files="PerCflowbelowAspect.aj" options="-1.5"/>
+ <run class="PerCflowbelowAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for pertypewithin aspect">
+ <compile files="PerTypeWithinAspect.aj" options="-1.5"/>
+ <run class="PerTypeWithinAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for inner aspect of aspect">
+ <compile files="InnerAspectAspect.aj" options="-1.5"/>
+ <run class="InnerAspectAspect"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for inner aspect of class">
+ <compile files="InnerAspectClass.aj" options="-1.5"/>
+ <run class="InnerAspectClass"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for advice declarations">
+ <compile files="BasicAdvice.aj" options="-1.5"/>
+ <run class="BasicAdvice"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for simple pointcut">
+ <compile files="SimplePointcut.aj" options="-1.5"/>
+ <run class="SimplePointcut"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for pointcut modifiers">
+ <compile files="PointcutModifiers.aj" options="-1.5"/>
+ <run class="PointcutModifiers"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for pointcut params">
+ <compile files="PointcutsWithParams.aj" options="-1.5"/>
+ <run class="PointcutsWithParams"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="annotation gen for pointcut refs">
+ <compile files="ReferencePointcuts.aj" options="-1.5"/>
+ <run class="ReferencePointcuts"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="before ann with non-void return">
+ <compile files="BeforeWithBadReturn.java" options="-1.5">
+ <message kind="error" line="7" text="This advice must return void"/>
+ <message kind="error" line="7" text="This method must return a result of type String"/>
+ </compile>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="two anns on same element">
+ <compile files="TwoForThePriceOfOne.java" options="-1.5">
+ <message kind="error" line="7" text="The annotation @Pointcut is disallowed for this location"/>
+ </compile>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="bad pcut in after advice">
+ <compile files="AfterReturningWithBadPCut.java" options="-1.5">
+ <message kind="error" line="6" text="Syntax error on token &quot;excution(* *.*(..))&quot;"/>
+ </compile>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="bad parameter binding in advice">
+ <compile files="BadParameterBinding.java" options="-1.5">
+ <message kind="warning" line="11" text="no match for this type name: bpb"/>
+ <message kind="warning" line="15" text="no match for this type name: TheUnknownType"/>
+ </compile>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="simple pointcut no params">
+ <compile files="APointcut.java" options="-1.5"/>
+ <run class="APointcut"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="pointcut medley">
+ <compile files="PointcutAssortment.java" options="-1.5">
+ <message kind="error" line="9" text="Methods annotated with @Pointcut must return void"/>
+ <message kind="error" line="9" text="This method must return a result of type String"/>
+ <message kind="error" line="15" text="Pointcuts should have an empty method body"/>
+ <message kind="error" line="28" text="Duplicate annotation @Pointcut"/>
+ <message kind="error" line="29" text="Duplicate annotation @Pointcut"/>
+ <message kind="error" line="11" text="can't find referenced pointcut foo"/>
+ <message kind="warning" line="32" text="no match for this type name: foo [Xlint:invalidAbsoluteTypeName]"/>
+ </compile>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj/annotationGen" title="advice in a class">
+ <compile files="AdviceInAClass.java" options="-1.5">
+ <message kind="error" line="6" text="Advice must be declared inside an aspect type"/>
+ </compile>
+ </ajc-test>
+
+</suite> \ No newline at end of file
diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml
index 1717bf9e0..d56357c80 100644
--- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml
+++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/misuse.xml
@@ -4,20 +4,20 @@
<suite>
- <comment>this one is ok - too simple - could be removed..</comment>
- <ajc-test dir="java5/ataspectj"
- pr="" title="@Aspect class extending @Aspect class">
- <compile files="ataspectj/misuse/Test005.java" options="-1.5 -Xdev:NoAtAspectJProcessing">
- </compile>
- </ajc-test>
-
- <comment>just a warning - might be skept if further optimized in Aj5Attributes..</comment>
- <ajc-test dir="java5/ataspectj"
- pr="" title="class with @Before extending @Aspect class">
- <compile files="ataspectj/misuse/Test006.java" options="-1.5 -Xdev:NoAtAspectJProcessing">
- <message kind="warning" line="11" text="Found @AspectJ annotations in a non @Aspect type 'ataspectj.misuse.Test006B'"/>
- </compile>
- </ajc-test>
+<!-- <comment>this one is ok - too simple - could be removed..</comment>-->
+<!-- <ajc-test dir="java5/ataspectj"-->
+<!-- pr="" title="@Aspect class extending @Aspect class">-->
+<!-- <compile files="ataspectj/misuse/Test005.java" options="-1.5 -Xdev:NoAtAspectJProcessing">-->
+<!-- </compile>-->
+<!-- </ajc-test>-->
+<!---->
+<!-- <comment>just a warning - might be skept if further optimized in Aj5Attributes..</comment>-->
+<!-- <ajc-test dir="java5/ataspectj"-->
+<!-- pr="" title="class with @Before extending @Aspect class">-->
+<!-- <compile files="ataspectj/misuse/Test006.java" options="-1.5 -Xdev:NoAtAspectJProcessing">-->
+<!-- <message kind="warning" line="11" text="Found @AspectJ annotations in a non @Aspect type 'ataspectj.misuse.Test006B'"/>-->
+<!-- </compile>-->
+<!-- </ajc-test>-->
<comment>a warning. We ignore the pointcut (TBD) - line is enclosing class (TBD Andy do better ?)</comment>
<ajc-test dir="java5/ataspectj"
@@ -35,46 +35,46 @@
<!-- </compile>-->
<!-- </ajc-test>-->
- <comment>line is enclosing class - TBD</comment>
- <ajc-test dir="java5/ataspectj"
- pr="" title="@Pointcut with garbage string">
- <compile files="ataspectj/misuse/Test014.java" options="-1.5 -Xdev:NoAtAspectJProcessing">
- <message kind="error" line="7" text="Cannot parse @Pointcut 'call%dddd"/>
- </compile>
- </ajc-test>
-
- <comment>line is enclosing class - TBD</comment>
- <ajc-test dir="java5/ataspectj"
- pr="" title="@Pointcut with throws clause">
- <compile files="ataspectj/misuse/Test016.java" options="-1.5 -Xdev:NoAtAspectJProcessing">
- <message kind="warning" line="7" text="Found @Pointcut on a method throwing exception 'someCall()V'"/>
- </compile>
- </ajc-test>
-
- <comment>very dirty hack - can't get this location to work properly so added match all error..</comment>
- <ajc-test dir="java5/ataspectj"
- pr="" title="@AfterReturning with wrong number of args">
- <compile files="ataspectj/misuse/Test019.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore">
- <message kind="error" line="1" text="the parameter x is not bound"/>
- <message kind="error"/>
- </compile>
- </ajc-test>
-
- <comment>line number is enclosing type</comment>
- <ajc-test dir="java5/ataspectj"
- pr="" title="@Before on non-public method">
- <compile files="ataspectj/misuse/Test020.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore">
- <message kind="error" line="7" text="Found @AspectJ annotation on a non public advice 'someCall()V'"/>
- </compile>
- </ajc-test>
-
- <comment>line number is enclosing type</comment>
- <ajc-test dir="java5/ataspectj"
- pr="" title="@Before on method not returning void">
- <compile files="ataspectj/misuse/Test021.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore">
- <message kind="error" line="7" text="Found @AspectJ annotation on a non around advice not returning void 'someCall()I'"/>
- </compile>
- </ajc-test>
+<!-- <comment>line is enclosing class - TBD</comment>-->
+<!-- <ajc-test dir="java5/ataspectj"-->
+<!-- pr="" title="@Pointcut with garbage string">-->
+<!-- <compile files="ataspectj/misuse/Test014.java" options="-1.5 -Xdev:NoAtAspectJProcessing">-->
+<!-- <message kind="error" line="7" text="Cannot parse @Pointcut 'call%dddd"/>-->
+<!-- </compile>-->
+<!-- </ajc-test>-->
+<!---->
+<!-- <comment>line is enclosing class - TBD</comment>-->
+<!-- <ajc-test dir="java5/ataspectj"-->
+<!-- pr="" title="@Pointcut with throws clause">-->
+<!-- <compile files="ataspectj/misuse/Test016.java" options="-1.5 -Xdev:NoAtAspectJProcessing">-->
+<!-- <message kind="warning" line="7" text="Found @Pointcut on a method throwing exception 'someCall()V'"/>-->
+<!-- </compile>-->
+<!-- </ajc-test>-->
+<!---->
+<!-- <comment>very dirty hack - can't get this location to work properly so added match all error..</comment>-->
+<!-- <ajc-test dir="java5/ataspectj"-->
+<!-- pr="" title="@AfterReturning with wrong number of args">-->
+<!-- <compile files="ataspectj/misuse/Test019.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore">-->
+<!-- <message kind="error" line="1" text="the parameter x is not bound"/>-->
+<!-- <message kind="error"/>-->
+<!-- </compile>-->
+<!-- </ajc-test>-->
+<!---->
+<!-- <comment>line number is enclosing type</comment>-->
+<!-- <ajc-test dir="java5/ataspectj"-->
+<!-- pr="" title="@Before on non-public method">-->
+<!-- <compile files="ataspectj/misuse/Test020.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore">-->
+<!-- <message kind="error" line="7" text="Found @AspectJ annotation on a non public advice 'someCall()V'"/>-->
+<!-- </compile>-->
+<!-- </ajc-test>-->
+<!---->
+<!-- <comment>line number is enclosing type</comment>-->
+<!-- <ajc-test dir="java5/ataspectj"-->
+<!-- pr="" title="@Before on method not returning void">-->
+<!-- <compile files="ataspectj/misuse/Test021.java" options="-1.5 -Xdev:NoAtAspectJProcessing -Xlint:ignore">-->
+<!-- <message kind="error" line="7" text="Found @AspectJ annotation on a non around advice not returning void 'someCall()I'"/>-->
+<!-- </compile>-->
+<!-- </ajc-test>-->
<!--
ALEX: todo
diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml
new file mode 100644
index 000000000..417d0be48
--- /dev/null
+++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml
@@ -0,0 +1,82 @@
+<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[]>
+<suite>
+
+ <ajc-test dir="java5/ataspectj" title="SimpleBefore">
+ <compile files="SimpleBefore.java" options="-1.5 -showWeaveInfo -XnoInline">
+ <message kind="weave" text="(SimpleBefore.java:23) advised by before advice from 'SimpleBefore$X' (SimpleBefore.java:1)"/>
+ </compile>
+ <run class="SimpleBefore"/>
+ <compile files="SimpleBefore.java" options="-1.5 -showWeaveInfo -XnoInline -Xdev:NoAtAspectJProcessing">
+ <message kind="weave" text="(SimpleBefore.java:23) advised by before advice from 'SimpleBefore$X' (SimpleBefore.java:1)"/>
+ </compile>
+ <run class="SimpleBefore"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="SimpleAfter">
+ <compile files="SimpleAfter.java" options="-1.5 -showWeaveInfo -XnoInline">
+ <message kind="weave" text="(SimpleAfter.java:13) advised by after advice from 'SimpleAfter$X'"/>
+ </compile>
+ <run class="SimpleAfter"/>
+ <compile files="SimpleAfter.java" options="-1.5 -showWeaveInfo -XnoInline -Xdev:NoAtAspectJProcessing">
+ <message kind="weave" text="(SimpleAfter.java:13) advised by after advice from 'SimpleAfter$X'"/>
+ </compile>
+ <run class="SimpleAfter"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="singletonAspectBindings">
+ <compile files="ataspectj/SingletonAspectBindingsTest.java,ataspectj/TestHelper.java" options="-1.5 -XnoInline"/>
+ <run class="ataspectj.SingletonAspectBindingsTest"/>
+ <compile files="ataspectj/SingletonAspectBindingsTest.java,ataspectj/TestHelper.java" options="-1.5 -XnoInline -Xdev:NoAtAspectJProcessing"/>
+ <run class="ataspectj.SingletonAspectBindingsTest"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="CflowTest">
+ <compile files="ataspectj/CflowTest.java,ataspectj/TestHelper.java" options="-1.5"/>
+ <run class="ataspectj.CflowTest"/>
+ <compile files="ataspectj/CflowTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing"/>
+ <run class="ataspectj.CflowTest"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="PointcutReferenceTest">
+ <compile files="ataspectj/PointcutReferenceTest.java,ataspectj/TestHelper.java" options="-1.5"/>
+ <run class="ataspectj.PointcutReferenceTest"/>
+ <compile files="ataspectj/PointcutReferenceTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing"/>
+ <run class="ataspectj.PointcutReferenceTest"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="XXJoinPointTest">
+ <compile files="ataspectj/XXJoinPointTest.java,ataspectj/TestHelper.java" options="-1.5"/>
+ <run class="ataspectj.XXJoinPointTest"/>
+ <compile files="ataspectj/XXJoinPointTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing"/>
+ <run class="ataspectj.XXJoinPointTest"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="PrecedenceTest">
+ <compile files="ataspectj/PrecedenceTest.java,ataspectj/TestHelper.java" options="-1.5"/>
+ <run class="ataspectj.PrecedenceTest"/>
+ <compile files="ataspectj/PrecedenceTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing"/>
+ <run class="ataspectj.PrecedenceTest"/>
+ </ajc-test>
+
+<!-- <comment>FIXME AV when JDT of M6 is in</comment>-->
+<!-- <ajc-test dir="java5/ataspectj" title="AfterXTest">-->
+<!-- <compile files="ataspectj/AfterXTest.java,ataspectj/TestHelper.java" options="-1.5"/>-->
+<!-- <run class="ataspectj.AfterXTest"/>-->
+<!-- </ajc-test>-->
+
+<!-- <comment>FIXME AV when we impl if support in pointcut parser and weaver</comment>-->
+<!-- <ajc-test dir="java5/ataspectj" title="IfPointcutTest">-->
+<!-- <compile files="ataspectj/IfPointcutTest.java,ataspectj/TestHelper.java" options="-1.5"/>-->
+<!-- <run class="ataspectj.IfPointcutTest"/>-->
+<!-- </ajc-test>-->
+
+ <ajc-test dir="java5/ataspectj" title="BindingTest">
+ <compile files="ataspectj/BindingTest.java,ataspectj/TestHelper.java" options="-1.5"/>
+ <run class="ataspectj.BindingTest"/>
+ </ajc-test>
+
+ <ajc-test dir="java5/ataspectj" title="BindingTest no inline">
+ <compile files="ataspectj/BindingTest.java,ataspectj/TestHelper.java" options="-1.5 -XnoInline"/>
+ <run class="ataspectj.BindingTest"/>
+ </ajc-test>
+</suite> \ No newline at end of file
diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
index 17f766f28..0442d8c68 100644
--- a/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
+++ b/weaver/src/org/aspectj/weaver/bcel/BcelShadow.java
@@ -1939,7 +1939,47 @@ public class BcelShadow extends Shadow {
weaveAroundClosure(munger, hasDynamicTest);
return;
}
-
+
+ // specific test for @AJ proceedInInners
+ if (munger.getConcreteAspect().isAnnotationStyleAspect()) {
+ //FIXME
+ // if we can't find one proceed()
+ // we suspect that the call is happening in an inner class
+ // so we don't inline it.
+ // Note: for code style, this is done at Aspect compilation time.
+ // Limitation: if there is two calls and one is done in an inner class, inlining will happen
+ // since we will see the non proceed in inner one as if it was the sole one.
+ // The one made in the inner class will never be madeXXX. Should be documented.
+ boolean canSeeProceedPassedToOther = false;
+ InstructionHandle curr = adviceMethod.getBody().getStart();
+ InstructionHandle end = adviceMethod.getBody().getEnd();
+ ConstantPoolGen cpg = adviceMethod.getEnclosingClass().getConstantPoolGen();
+ while (curr != end) {
+ InstructionHandle next = curr.getNext();
+ Instruction inst = curr.getInstruction();
+ /*if ((inst instanceof INVOKEINTERFACE)
+ && "proceed".equals(((INVOKEINTERFACE) inst).getMethodName(cpg))) {
+ canSeeProceed = true;
+ //continue since we may have a proceed in inner or pjp as arg
+ } else*/ if ((inst instanceof InvokeInstruction)
+ && ((InvokeInstruction)inst).getSignature(cpg).indexOf("Lorg/aspectj/lang/ProceedingJoinPoint;") > 0) {
+ // we may want to refine to exclude stuff returning jp ?
+ // does code style skip inline if i write dump(thisJoinPoint) ?
+ canSeeProceedPassedToOther = true;// we see one pjp passed around - dangerous
+ break;
+ }
+ curr = next;
+ }
+ if (canSeeProceedPassedToOther) {
+ // remember this decision to avoid re-analysis
+ adviceMethod.setCanInline(false);
+ weaveAroundClosure(munger, hasDynamicTest);
+ return;
+ }
+ }
+
+
+
// We can't inline around methods if they have around advice on them, this
// is because the weaving will extract the body and hence the proceed call.
//??? should consider optimizations to recognize simple cases that don't require body extraction
@@ -1954,8 +1994,9 @@ public class BcelShadow extends Shadow {
NameMangler.aroundCallbackMethodName(
getSignature(),
getEnclosingClass()),
- Modifier.PRIVATE,
- munger);
+ Modifier.PRIVATE,
+ munger
+ );
// now extract the advice into its own method
@@ -2164,18 +2205,22 @@ public class BcelShadow extends Shadow {
Instruction inst = curr.getInstruction();
if ((inst instanceof INVOKEINTERFACE)
&& "proceed".equals(((INVOKEINTERFACE) inst).getMethodName(cpg))) {
- //TODO proceed(...varargs) will need some stuff there
- InstructionList insteadProceedIl =
- getRedoneProceedCallForAnnotationStyle(
+ final boolean isProceedWithArgs;
+ if (((INVOKEINTERFACE) inst).getArgumentTypes(cpg).length == 1) {
+ // proceed with args as a boxed Object[]
+ isProceedWithArgs = true;
+ } else {
+ isProceedWithArgs = false;
+ }
+ InstructionList insteadProceedIl = getRedoneProceedCallForAnnotationStyle(
fact,
extractedMethod,
munger,
localAdviceMethod,
- proceedVarList);
- //TODO optimize, a POP is added somewhere, what for non void ?
- localAdviceMethod.getBody().append(
- curr, insteadProceedIl);
-
+ proceedVarList,
+ isProceedWithArgs
+ );
+ localAdviceMethod.getBody().append(curr, insteadProceedIl);
Utility.deleteInstruction(curr, localAdviceMethod);
}
curr = next;
@@ -2242,6 +2287,7 @@ public class BcelShadow extends Shadow {
* @param munger
* @param localAdviceMethod
* @param argVarList
+ * @param isProceedWithArgs
* @return
*/
private InstructionList getRedoneProceedCallForAnnotationStyle(
@@ -2249,57 +2295,129 @@ public class BcelShadow extends Shadow {
LazyMethodGen callbackMethod,
BcelAdvice munger,
LazyMethodGen localAdviceMethod,
- List argVarList)
+ List argVarList,
+ boolean isProceedWithArgs)
{
- //if (true) return new InstructionList();
+ // Notes:
+ // proceedingjp is on stack (since user was calling pjp.proceed(...)
+ // the boxed args to proceed() are on stack as well (Object[]) unless
+ // the call is to pjp.proceed(<noarg>)
- //TODO I think we just don't care about the proceed map
- // since that one must be the exact same of the advice sig.
- // perhaps with custom jp ?
+ // new Object[]{new Integer(argAdvice1-1)};// arg of proceed
+ // call to proceed(..) is NOT made
+ // instead we do
+ // itar callback args i
+ // get from array i, convert it to the callback arg i
+ // if ask for JP, push the one we got on the stack
+ // invoke callback, create conversion back to Object/Integer
- // we have on stack all the arguments for the ADVICE call.
- // we have in frame somewhere all the arguments for the non-advice call.
- BcelVar[] adviceVars = munger.getExposedStateAsBcelVars();
- IntMap proceedMap = makeProceedArgumentMap(adviceVars);
+ // rest of method -- (hence all those conversions)
+ // intValue() from original code
+ // int res = .. from original code
- //System.out.println(proceedMap + " for " + this);
- //System.out.println(argVarList);
-
- ResolvedTypeX[] proceedParamTypes =
- world.resolve(munger.getSignature().getParameterTypes());
- //System.out.println(proceedParamTypes);
+ //Note: we just don't care about the proceed map etc
InstructionList ret = new InstructionList();
- ret.append(new POP());//the joinpoint instance is there
- for (int i=0, len=callbackMethod.getArgumentTypes().length; i < len; i++) {
- Type stateType = callbackMethod.getArgumentTypes()[i];
- ResolvedTypeX stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
- if (proceedMap.hasKey(i)) {
- ret.append(new ALOAD(i));
- //throw new RuntimeException("unimplemented");
- //proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
- } else {
- //FIXME Alex: odd code there
- //((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
- //ret.append(new ALOAD(i));
+ // store the Object[] array on stack if proceed with args
+ if (isProceedWithArgs) {
+ Type objectArrayType = Type.getType("[Ljava/lang/Object;");
+ int localProceedArgArray = localAdviceMethod.allocateLocal(objectArrayType);
+ ret.append(InstructionFactory.createStore(objectArrayType, localProceedArgArray));
+
+ Type proceedingJpType = Type.getType("Lorg/aspectj/lang/ProceedingJoinPoint;");
+ int localJp = localAdviceMethod.allocateLocal(proceedingJpType);
+ ret.append(InstructionFactory.createStore(proceedingJpType, localJp));
+
+ // push on stack each element of the object array
+ // that is assumed to be consistent with the callback argument (ie munger args)
+ // TODO do we want to try catch ClassCast and AOOBE exception ?
+
+ // special logic when withincode is static or not
+ int startIndex = 0;
+ if (thisVar != null) {
+ startIndex = 1;
+ //TODO this logic is actually depending on target as well - test me
+ ret.append(new ALOAD(0));//thisVar
+ }
+ for (int i = startIndex, len=callbackMethod.getArgumentTypes().length; i < len; i++) {
+ Type stateType = callbackMethod.getArgumentTypes()[i];
+ ResolvedTypeX stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
- ret.append(new ALOAD(i));
+ ret.append(new ALOAD(localJp));// from localAdvice signature
} else {
- ret.append(new ALOAD(i));
+ ret.append(InstructionFactory.createLoad(objectArrayType, localProceedArgArray));
+ ret.append(Utility.createConstant(fact, i-startIndex));
+ ret.append(InstructionFactory.createArrayLoad(Type.OBJECT));
+ ret.append(Utility.createConversion(
+ fact,
+ Type.OBJECT,
+ stateType
+ ));
+ }
+ }
+ } else {
+ Type proceedingJpType = Type.getType("Lorg/aspectj/lang/ProceedingJoinPoint;");
+ int localJp = localAdviceMethod.allocateLocal(proceedingJpType);
+ ret.append(InstructionFactory.createStore(proceedingJpType, localJp));
+
+ for (int i = 0, len=callbackMethod.getArgumentTypes().length; i < len; i++) {
+ Type stateType = callbackMethod.getArgumentTypes()[i];
+ ResolvedTypeX stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
+ if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
+ ret.append(new ALOAD(localJp));// from localAdvice signature
+ } else {
+ ret.append(InstructionFactory.createLoad(stateType, i));
}
}
}
+ // do the callback invoke
ret.append(Utility.createInvoke(fact, callbackMethod));
- ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
- BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
-
- ret.append(new ACONST_NULL());//will be POPed //FIXME Alex: if so clean up
- if (true) return ret;
+ // box it again. Handles cases where around advice does return something else than Object
+ if (!TypeX.OBJECT.equals(munger.getSignature().getReturnType())) {
+ ret.append(Utility.createConversion(
+ fact,
+ callbackMethod.getReturnType(),
+ Type.OBJECT
+ ));
+ }
+ ret.append(Utility.createConversion(
+ fact,
+ callbackMethod.getReturnType(),
+ BcelWorld.makeBcelType(munger.getSignature().getReturnType())
+ ));
+ return ret;
+//
+//
+//
+// if (proceedMap.hasKey(i)) {
+// ret.append(new ALOAD(i));
+// //throw new RuntimeException("unimplemented");
+// //proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
+// } else {
+// //((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
+// //ret.append(new ALOAD(i));
+// if ("Lorg/aspectj/lang/JoinPoint;".equals(stateType.getSignature())) {
+// ret.append(new ALOAD(i));
+// } else {
+// ret.append(new ALOAD(i));
+// }
+// }
+// }
+//
+// ret.append(Utility.createInvoke(fact, callbackMethod));
+// ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
+// BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
+//
+// //ret.append(new ACONST_NULL());//will be POPed
+// if (true) return ret;
+//
+//
+//
// // we have on stack all the arguments for the ADVICE call.
// // we have in frame somewhere all the arguments for the non-advice call.
//
@@ -2311,36 +2429,36 @@ public class BcelShadow extends Shadow {
//
// ResolvedTypeX[] proceedParamTypes =
// world.resolve(munger.getSignature().getParameterTypes());
- // remove this*JoinPoint* as arguments to proceed
- if (munger.getBaseParameterCount()+1 < proceedParamTypes.length) {
- int len = munger.getBaseParameterCount()+1;
- ResolvedTypeX[] newTypes = new ResolvedTypeX[len];
- System.arraycopy(proceedParamTypes, 0, newTypes, 0, len);
- proceedParamTypes = newTypes;
- }
-
- //System.out.println("stateTypes: " + Arrays.asList(stateTypes));
- BcelVar[] proceedVars =
- Utility.pushAndReturnArrayOfVars(proceedParamTypes, ret, fact, localAdviceMethod);
-
- Type[] stateTypes = callbackMethod.getArgumentTypes();
-// System.out.println("stateTypes: " + Arrays.asList(stateTypes));
-
- for (int i=0, len=stateTypes.length; i < len; i++) {
- Type stateType = stateTypes[i];
- ResolvedTypeX stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
- if (proceedMap.hasKey(i)) {
- //throw new RuntimeException("unimplemented");
- proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
- } else {
- ((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
- }
- }
-
- ret.append(Utility.createInvoke(fact, callbackMethod));
- ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
- BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
- return ret;
+// // remove this*JoinPoint* as arguments to proceed
+// if (munger.getBaseParameterCount()+1 < proceedParamTypes.length) {
+// int len = munger.getBaseParameterCount()+1;
+// ResolvedTypeX[] newTypes = new ResolvedTypeX[len];
+// System.arraycopy(proceedParamTypes, 0, newTypes, 0, len);
+// proceedParamTypes = newTypes;
+// }
+//
+// //System.out.println("stateTypes: " + Arrays.asList(stateTypes));
+// BcelVar[] proceedVars =
+// Utility.pushAndReturnArrayOfVars(proceedParamTypes, ret, fact, localAdviceMethod);
+//
+// Type[] stateTypes = callbackMethod.getArgumentTypes();
+//// System.out.println("stateTypes: " + Arrays.asList(stateTypes));
+//
+// for (int i=0, len=stateTypes.length; i < len; i++) {
+// Type stateType = stateTypes[i];
+// ResolvedTypeX stateTypeX = BcelWorld.fromBcel(stateType).resolve(world);
+// if (proceedMap.hasKey(i)) {
+// //throw new RuntimeException("unimplemented");
+// proceedVars[proceedMap.get(i)].appendLoadAndConvert(ret, fact, stateTypeX);
+// } else {
+// ((BcelVar) argVarList.get(i)).appendLoad(ret, fact);
+// }
+// }
+//
+// ret.append(Utility.createInvoke(fact, callbackMethod));
+// ret.append(Utility.createConversion(fact, callbackMethod.getReturnType(),
+// BcelWorld.makeBcelType(munger.getSignature().getReturnType())));
+// return ret;
}
public void weaveAroundClosure(