diff options
author | avasseur <avasseur> | 2005-05-02 08:17:36 +0000 |
---|---|---|
committer | avasseur <avasseur> | 2005-05-02 08:17:36 +0000 |
commit | cdddd38d261f0ae75bf95f0859e7a440be1bb3d5 (patch) | |
tree | fa61448ab8b0d848cd65930fc5e9a44a71433ea8 | |
parent | 0b7744f560fb4ff70b70884a4932c8ebeb603fd2 (diff) | |
download | aspectj-cdddd38d261f0ae75bf95f0859e7a440be1bb3d5.tar.gz aspectj-cdddd38d261f0ae75bf95f0859e7a440be1bb3d5.zip |
PTW perClause for @AJ + perClause test
10 files changed, 531 insertions, 279 deletions
diff --git a/runtime/src/org/aspectj/lang/Aspects.java b/runtime/src/org/aspectj/lang/Aspects.java index 0d8cb5ccb..dd1286365 100644 --- a/runtime/src/org/aspectj/lang/Aspects.java +++ b/runtime/src/org/aspectj/lang/Aspects.java @@ -13,13 +13,14 @@ package org.aspectj.lang; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.InvocationTargetException; /** * Handles generic aspectOf method when those are not available in the aspects but added later on * thru load time weaving. * <p/> * Aspects.aspectOf(..) is doing reflective calls to the aspect aspectOf, so for better performance - * consider using preparation of the aspects. + * consider using ajc compilation of the aspects and using them as a binary dependancies in your project. * * @author <a href="mailto:alex AT gnilux DOT com">Alexandre Vasseur</a> */ @@ -27,11 +28,13 @@ public class Aspects { private final static Class[] EMPTY_CLASS_ARRAY = new Class[0]; private final static Class[] PEROBJECT_CLASS_ARRAY = new Class[]{Object.class}; + private final static Class[] PERTYPEWITHIN_CLASS_ARRAY = new Class[]{Class.class}; private final static Object[] EMPTY_OBJECT_ARRAY = new Object[0]; private final static String ASPECTOF = "aspectOf"; + private final static String HASASPECT = "hasAspect"; /** - * Returns the singleton aspect + * Returns the singleton aspect or the percflow / percflowbelow associated with the current thread * * @param aspectClass * @return @@ -39,7 +42,9 @@ public class Aspects { */ public static Object aspectOf(Class aspectClass) throws NoAspectBoundException { try { - return getSingletonAspectOf(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY); + return getSingletonOrThreadAspectOf(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY); + } catch (InvocationTargetException e) { + throw new NoAspectBoundException(aspectClass.getName(), e.getCause()); } catch (Exception e) { throw new NoAspectBoundException(aspectClass.getName(), e); } @@ -55,22 +60,78 @@ public class Aspects { public static Object aspectOf(Class aspectClass, Object perObject) throws NoAspectBoundException { try { return getPerObjectAspectOf(aspectClass).invoke(null, new Object[]{perObject}); + } catch (InvocationTargetException e) { + throw new NoAspectBoundException(aspectClass.getName(), e.getCause()); } catch (Exception e) { throw new NoAspectBoundException(aspectClass.getName(), e); } } - public static Object aspectOf(Class aspectClass, Thread perThread) throws NoAspectBoundException { - //TODO - how to know it s a real per Thread ? - // if it is actually a singleton one, we will have it as well... + /** + * Returns the pertypewithin aspect + * @param aspectClass + * @param perTypeWithin class + * @return + * @throws NoAspectBoundException if no such aspect, or no aspect bound + */ + public static Object aspectOf(Class aspectClass, Class perTypeWithin) throws NoAspectBoundException { try { - return getSingletonAspectOf(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY); + return getPerTypeWithinAspectOf(aspectClass).invoke(null, new Object[]{perTypeWithin}); + } catch (InvocationTargetException e) { + throw new NoAspectBoundException(aspectClass.getName(), e.getCause()); } catch (Exception e) { throw new NoAspectBoundException(aspectClass.getName(), e); } } - private static Method getSingletonAspectOf(Class aspectClass) throws NoSuchMethodException { + /** + * Returns true if singleton aspect or percflow / percflowbelow aspect is bound + * + * @param aspectClass + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass) throws NoAspectBoundException { + try { + return ((Boolean)getSingletonOrThreadHasAspect(aspectClass).invoke(null, EMPTY_OBJECT_ARRAY)).booleanValue(); + } catch (Exception e) { + return false; + } + } + + /** + * Returns true if the perthis / pertarget aspect is bound + * @param aspectClass + * @param perObject + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass, Object perObject) throws NoAspectBoundException { + try { + return ((Boolean)getPerObjectHasAspect(aspectClass).invoke(null, new Object[]{perObject})).booleanValue(); + } catch (Exception e) { + return false; + } + } + + /** + * Returns true if the pertypewithin aspect is bound + * @param aspectClass + * @param perTypeWithin class + * @return + * @throws NoAspectBoundException if not bound + */ + public static boolean hasAspect(Class aspectClass, Class perTypeWithin) throws NoAspectBoundException { + try { + return ((Boolean)getPerTypeWithinHasAspect(aspectClass).invoke(null, new Object[]{perTypeWithin})).booleanValue(); + } catch (Exception e) { + return false; + } + } + + // -- aspectOf + + private static Method getSingletonOrThreadAspectOf(Class aspectClass) throws NoSuchMethodException { Method method = aspectClass.getDeclaredMethod(ASPECTOF, EMPTY_CLASS_ARRAY); return checkAspectOf(method, aspectClass); } @@ -80,8 +141,12 @@ public class Aspects { return checkAspectOf(method, aspectClass); } - private static Method checkAspectOf(Method method, Class aspectClass) - throws NoSuchMethodException { + private static Method getPerTypeWithinAspectOf(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(ASPECTOF, PERTYPEWITHIN_CLASS_ARRAY); + return checkAspectOf(method, aspectClass); + } + + private static Method checkAspectOf(Method method, Class aspectClass) throws NoSuchMethodException { method.setAccessible(true); if (!method.isAccessible() || !Modifier.isPublic(method.getModifiers()) @@ -90,4 +155,31 @@ public class Aspects { } return method; } + + // -- hasAspect + + private static Method getSingletonOrThreadHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, EMPTY_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method getPerObjectHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, PEROBJECT_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method getPerTypeWithinHasAspect(Class aspectClass) throws NoSuchMethodException { + Method method = aspectClass.getDeclaredMethod(HASASPECT, PERTYPEWITHIN_CLASS_ARRAY); + return checkHasAspect(method, aspectClass); + } + + private static Method checkHasAspect(Method method, Class aspectClass) throws NoSuchMethodException { + method.setAccessible(true); + if (!method.isAccessible() + || !Modifier.isPublic(method.getModifiers()) + || !Modifier.isStatic(method.getModifiers())) { + throw new NoSuchMethodException(aspectClass.getName() + ".hasAspect(..) is not accessible public static"); + } + return method; + } } diff --git a/tests/java5/ataspectj/ataspectj/BindingTest.java b/tests/java5/ataspectj/ataspectj/BindingTest.java index c4114f020..342b8ebf0 100644 --- a/tests/java5/ataspectj/ataspectj/BindingTest.java +++ b/tests/java5/ataspectj/ataspectj/BindingTest.java @@ -90,6 +90,10 @@ public class BindingTest extends TestCase { //assertEquals(2, aspect.m_count); } + public void testTryCatch() { + assertEquals(6, echo(3)); + } + private static void callWithinStatic() { int res = dup((3+1)); assertEquals(6, res); @@ -177,10 +181,18 @@ public class BindingTest extends TestCase { @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 ? + //m_count++;// what if inlined ?//FIXME return jp.proceed(); } + @Around("call(int echo(int)) && withincode(void ataspectj.BindingTest.testTryCatch()) && args(i)") + public Object aaround8(int i, final ProceedingJoinPoint jp) throws Throwable { + try { + return 2*((Integer)jp.proceed()).intValue(); + } catch (Throwable t) { + throw t; + } + } } } diff --git a/tests/java5/ataspectj/ataspectj/PerClauseTest.java b/tests/java5/ataspectj/ataspectj/PerClauseTest.java index 0773f627f..ff8a354d2 100644 --- a/tests/java5/ataspectj/ataspectj/PerClauseTest.java +++ b/tests/java5/ataspectj/ataspectj/PerClauseTest.java @@ -33,9 +33,46 @@ public class PerClauseTest extends TestCase { } public static junit.framework.Test suite() { - return new junit.framework.TestSuite(AfterXTest.class); + return new junit.framework.TestSuite(PerClauseTest.class); } + public void perSingleton() { + log("perSingleton"); + } + + public void testPerSingleton() { + s_log = new StringBuffer(); + + // singleton is bound as soon as clinit + try { + assertTrue(Aspects.hasAspect(TestAspectPerSingleton.class)); + Aspects.aspectOf(TestAspectPerSingleton.class); + } catch (NoAspectBoundException e) { + fail(e.toString()); + } + + perSingleton(); + assertEquals("AOP.perSingleton perSingleton ", s_log.toString()); + + perSingleton(); + assertEquals(1, TestAspectPerSingleton.s_count); + } + + @Aspect() + public static class TestAspectPerSingleton { + static int s_count = 0; + public TestAspectPerSingleton() { + s_count++; + } + + @Before("execution(* ataspectj.PerClauseTest.perSingleton()) && target(t)") + public void before(JoinPoint jp, Object t) { + log("AOP."+jp.getSignature().getName()); + assertTrue("perX match", this.equals(Aspects.aspectOf(getClass()))); + } + } + + public void perTarget() { log("perTarget"); } @@ -45,8 +82,9 @@ public class PerClauseTest extends TestCase { perTarget(); assertEquals("AOP.perTarget perTarget ", s_log.toString()); - // singleton + // calling singleton API will fail try { + assertFalse(Aspects.hasAspect(TestAspectPerTarget.class)); Aspects.aspectOf(TestAspectPerTarget.class); fail("should fail with NOABE"); } catch (NoAspectBoundException e) { @@ -55,6 +93,7 @@ public class PerClauseTest extends TestCase { // this per try { + assertTrue(Aspects.hasAspect(TestAspectPerTarget.class, this)); TestAspectPerTarget aspect = (TestAspectPerTarget) Aspects.aspectOf(TestAspectPerTarget.class, this); assertNotNull(aspect); } catch (NoAspectBoundException e) { @@ -64,6 +103,7 @@ public class PerClauseTest extends TestCase { // another per PerClauseTest me = new PerClauseTest(); try { + assertFalse(Aspects.hasAspect(TestAspectPerTarget.class, me)); Aspects.aspectOf(TestAspectPerTarget.class, me); fail("should fail"); } catch (NoAspectBoundException e) { @@ -71,18 +111,22 @@ public class PerClauseTest extends TestCase { } me.perTarget(); try { + assertTrue(Aspects.hasAspect(TestAspectPerTarget.class, me)); TestAspectPerTarget aspect = (TestAspectPerTarget) Aspects.aspectOf(TestAspectPerTarget.class, me); assertNotNull(aspect); } catch (NoAspectBoundException e) { fail(e.toString()); } + + assertEquals(2, TestAspectPerTarget.s_count); } @Aspect("pertarget(execution(* ataspectj.PerClauseTest.perTarget()))") public static class TestAspectPerTarget { + static int s_count; public TestAspectPerTarget() { - ; + s_count++; } @Before("execution(* ataspectj.PerClauseTest.perTarget()) && target(t)") @@ -93,6 +137,13 @@ public class PerClauseTest extends TestCase { } public void perCflowEntry() { + // the aspect is bound to the executing thread + try { + assertTrue(Aspects.hasAspect(TestAspectPerCflow.class)); + Aspects.aspectOf(TestAspectPerCflow.class); + } catch (NoAspectBoundException e) { + fail(e.toString()); + } perCflow(); } @@ -100,27 +151,126 @@ public class PerClauseTest extends TestCase { log("perCflow"); } - public void testPerCflow() { + public void testPerCflow() throws Throwable { s_log = new StringBuffer(); + + // no aspect bound yet + try { + assertFalse(Aspects.hasAspect(TestAspectPerCflow.class)); + Aspects.aspectOf(TestAspectPerCflow.class); + fail("No perCflow should be bound yet"); + } catch (NoAspectBoundException e) { + ;//ok + } + perCflow(); assertEquals("perCflow ", s_log.toString()); + // still no aspect bound yet + try { + assertFalse(Aspects.hasAspect(TestAspectPerCflow.class)); + Aspects.aspectOf(TestAspectPerCflow.class); + fail("No perCflow should be bound yet"); + } catch (NoAspectBoundException e) { + ;//ok + } s_log = new StringBuffer(); perCflowEntry(); assertEquals("AOP.perCflow perCflow ", s_log.toString()); + // no aspect bound anymore since went OUT of the per clause + try { + assertFalse(Aspects.hasAspect(TestAspectPerCflow.class)); + Aspects.aspectOf(TestAspectPerCflow.class); + fail("No perCflow should be bound anymore"); + } catch (NoAspectBoundException e) { + ;//ok + } + + Runnable rok = new Runnable() { + public void run() { + perCflowEntry(); + } + }; + Thread trok = new Thread(rok); + trok.start(); + trok.join(); + + Runnable rko = new Runnable() { + public void run() { + perCflow(); + } + }; + Thread trko = new Thread(rko); + trko.start(); + trko.join(); + + assertEquals(2, TestAspectPerCflow.s_count); } @Aspect("percflow(execution(* ataspectj.PerClauseTest.perCflowEntry()))") public static class TestAspectPerCflow { + static int s_count; public TestAspectPerCflow() { - ; + s_count++; } @Before("execution(* ataspectj.PerClauseTest.perCflow())") public void before(JoinPoint jp) { log("AOP."+jp.getSignature().getName()); - assertTrue("perX match", this.equals(Aspects.aspectOf(getClass(), Thread.currentThread()))); + assertTrue("perX match", this.equals(Aspects.aspectOf(getClass()))); + } + } + + public void testPerTypeWithin() { + assertTrue(Aspects.hasAspect(TestAspectPTW.class, PTW1.class)); + assertTrue(Aspects.hasAspect(TestAspectPTW.class, PTW2.class)); + assertFalse(Aspects.hasAspect(TestAspectPTW.class, PTWNoMatch.class)); + + PTW1.foo(); + PTW2.foo(); + PTWNoMatch.foo(); + + assertEquals(2, TestAspectPTW.s_count); + try { + assertTrue(Aspects.hasAspect(TestAspectPTW.class, PTW1.class)); + assertTrue(Aspects.hasAspect(TestAspectPTW.class, PTW2.class)); + Aspects.aspectOf(TestAspectPTW.class, PTW1.class); + Aspects.aspectOf(TestAspectPTW.class, PTW2.class); + } catch (NoAspectBoundException e) { + fail(e.toString()); + } + try { + assertFalse(Aspects.hasAspect(TestAspectPTW.class, PTWNoMatch.class)); + Aspects.aspectOf(TestAspectPTW.class, PTWNoMatch.class); + fail("should not have PTW aspect"); + } catch (NoAspectBoundException e) { + ;//ok } } + + static class PTW1 { + static void foo() {}; + } + static class PTW2 { + static void foo() {}; + } + static class PTWNoMatch { + static void foo() {}; + } + + @Aspect("pertypewithin(ataspectj.PerClauseTest.PTW* && !ataspectj.PerClauseTest.PTWNoMatch)") + public static class TestAspectPTW { + static int s_count; + + public TestAspectPTW() { + s_count++; + } + + @Before("execution(* ataspectj.PerClauseTest.PTW*.foo())") + public void before(JoinPoint jp) { + ; + } + + } } diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150-tests.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150-tests.xml deleted file mode 100644 index c426dbaa6..000000000 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150-tests.xml +++ /dev/null @@ -1,208 +0,0 @@ -<!-- @AspectJ v1.5.0 Tests --> - - <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> - - <ajc-test dir="java5/ataspectj" title="AfterXTest"> - <compile files="ataspectj/AfterXTest.java,ataspectj/TestHelper.java" options="-1.5"/> - <run class="ataspectj.AfterXTest"/> - </ajc-test> - - <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> - - <!-- ================================================================= --> - <!-- 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 "excution(* *.*(..))""/> - </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> - diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150.xml deleted file mode 100644 index fb3611111..000000000 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150.xml +++ /dev/null @@ -1,12 +0,0 @@ -<!DOCTYPE suite SYSTEM "../tests/ajcTestSuite.dtd"[ -<!ENTITY tests SYSTEM "../tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150-tests.xml"> -]> - -<!-- @AspectJ v1.5.0 Tests --> - -<suite> - -&tests; - -</suite> - diff --git a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml index 417d0be48..daeb4da84 100644 --- a/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml +++ b/tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml @@ -79,4 +79,12 @@ <compile files="ataspectj/BindingTest.java,ataspectj/TestHelper.java" options="-1.5 -XnoInline"/> <run class="ataspectj.BindingTest"/> </ajc-test> + + <ajc-test dir="java5/ataspectj" title="PerClause"> + <compile files="ataspectj/PerClauseTest.java,ataspectj/TestHelper.java" options="-1.5 -Xdev:NoAtAspectJProcessing"/> + <run class="ataspectj.PerClauseTest"/> + <compile files="ataspectj/PerClauseTest.java,ataspectj/TestHelper.java" options="-1.5"/> + <run class="ataspectj.PerClauseTest"/> + </ajc-test> + </suite>
\ No newline at end of file diff --git a/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java b/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java index a7005d6b4..f90ed90b3 100644 --- a/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java +++ b/tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java @@ -223,8 +223,14 @@ public class AjdeInteractionTestbed extends TestCase { // AMC - I did this rather than use the JDK default as I hate having to go look // in c:\documents and settings\......... for the results of a failed test. if (os.startsWith("Windows")) { - tempDir = new File("C:\\temp"); - if (!tempDir.exists()) {tempDir.mkdir();} + //Alex: try D first since NTFS on mine while FAT leads to failure.. + tempDir = new File("D:\\temp"); + if (!tempDir.exists()) { + tempDir = new File("C:\\temp"); + if (!tempDir.exists()) { + tempDir.mkdir(); + } + } } else { tempDir = new File("/tmp"); } diff --git a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java index d285a1574..428c0b4b8 100644 --- a/weaver/src/org/aspectj/weaver/AjcMemberMaker.java +++ b/weaver/src/org/aspectj/weaver/AjcMemberMaker.java @@ -160,7 +160,15 @@ public class AjcMemberMaker { TypeX.forSignature("Ljava/lang/String;"), NameMangler.PERTYPEWITHIN_WITHINTYPEFIELD, TypeX.NONE); } - + public static ResolvedMember perTypeWithinPerClassMapField(ResolvedTypeX aspectType) { + int modifiers = Modifier.PRIVATE; + if (!TypeX.SERIALIZABLE.isAssignableFrom(aspectType, aspectType.getWorld())) { + modifiers |= Modifier.TRANSIENT; + } + return new ResolvedMember(Member.FIELD, aspectType, modifiers, + TypeX.forSignature("Ljava/util/Map;"), "instances", TypeX.NONE); + } + public static ResolvedMember perObjectBind(TypeX declaringType) { return new ResolvedMember( Member.METHOD, @@ -184,7 +192,22 @@ public class AjcMemberMaker { ); return rm; } - + + // PTWIMPL ResolvedMember for "Set getInstances()" method, declared in aspect + public static ResolvedMember perTypeWithinGetInstancesSet(TypeX declaringType) { +// public Set getInstances() + ResolvedMember rm = new ResolvedMember( + Member.METHOD, + declaringType, + Modifier.PUBLIC, + TypeX.forSignature("Ljava/util/Set;"), + "getInstances", + TypeX.NONE, + TypeX.NONE + ); + return rm; + } + public static ResolvedMember perTypeWithinCreateAspectInstance(TypeX declaringType) { // public static a.X ajc$createAspectInstance(java.lang.String) ResolvedMember rm = new ResolvedMember( diff --git a/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java b/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java index 7f759c721..254f429fe 100644 --- a/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java +++ b/weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java @@ -27,6 +27,13 @@ import org.aspectj.apache.bcel.generic.POP; import org.aspectj.apache.bcel.generic.PUSH; import org.aspectj.apache.bcel.generic.ReferenceType; import org.aspectj.apache.bcel.generic.Type; +import org.aspectj.apache.bcel.generic.MethodGen; +import org.aspectj.apache.bcel.generic.RETURN; +import org.aspectj.apache.bcel.generic.NEW; +import org.aspectj.apache.bcel.generic.INVOKESPECIAL; +import org.aspectj.apache.bcel.generic.ASTORE; +import org.aspectj.apache.bcel.generic.ACONST_NULL; +import org.aspectj.apache.bcel.generic.IRETURN; import org.aspectj.weaver.AjcMemberMaker; import org.aspectj.weaver.Member; import org.aspectj.weaver.NameMangler; @@ -35,6 +42,8 @@ import org.aspectj.weaver.ResolvedTypeX; import org.aspectj.weaver.TypeX; import org.aspectj.weaver.patterns.PerClause; +import java.util.Iterator; + /** * Adds aspectOf, hasAspect etc to the annotation defined aspects * @@ -58,8 +67,12 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { public boolean munge(BcelClassWeaver weaver) { LazyClassGen gen = weaver.getLazyClassGen(); - // agressively generate the inner interface + // agressively generate the inner interface if any + // Note: we do so because of the bug that leads to have this interface implemented by all classes and not + // only those matched by the per clause, which fails under LTW since the very first class + // gets weaved and impl this interface that is still not defined. if (!hasGeneratedInner) { + //FIXME AV - restore test below or ?? + add test to detect such side effect //if (kind == PerClause.PEROBJECT || kind == PerClause.PERCFLOW) { //inner class TypeX interfaceTypeX = AjcMemberMaker.perObjectInterfaceType(aspectType); @@ -99,6 +112,12 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { generatePerCflowHasAspectMethod(gen); generatePerCflowPushMethod(gen); generatePerCflowAjcClinitMethod(gen); + } else if (kind == PerClause.PERTYPEWITHIN) { + generatePerTWGetInstancesMethod(gen); + generatePerTWAspectOfMethod(gen); + generatePerTWHasAspectMethod(gen); + generatePerTWGetInstanceMethod(gen); + generatePerTWCreateAspectInstanceMethod(gen); } else { throw new RuntimeException("TODO not yet implemented perClause " + kind.getName()); } @@ -135,31 +154,45 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { } else if (kind == PerClause.PEROBJECT) { ResolvedMember perObjectFieldInfo = AjcMemberMaker.perObjectField(aspectType, aspectType); classGen.addField(makeFieldGen(classGen, perObjectFieldInfo).getField(), null); - -// //inner class -// TypeX interfaceTypeX = AjcMemberMaker.perObjectInterfaceType(aspectType); -// LazyClassGen interfaceGen = new LazyClassGen( -// interfaceTypeX.getName(), -// "java.lang.Object", -// null, -// Constants.ACC_PRIVATE + Constants.ACC_ABSTRACT, -// new String[0] -// ); -// interfaceGen.addMethodGen(makeMethodGen(interfaceGen, AjcMemberMaker.perObjectInterfaceGet(aspectType))); -// interfaceGen.addMethodGen(makeMethodGen(interfaceGen, AjcMemberMaker.perObjectInterfaceSet(aspectType))); -// classGen.addGeneratedInner(interfaceGen); + // if lazy generation of the inner interface MayHaveAspect works on LTW (see previous note) + // it should be done here. } else if (kind == PerClause.PERCFLOW) { ResolvedMember perCflowFieldInfo = AjcMemberMaker.perCflowField(aspectType); classGen.addField(makeFieldGen(classGen, perCflowFieldInfo).getField(), null); + } else if (kind == PerClause.PERTYPEWITHIN) { + ResolvedMember perTypeWithinForField = AjcMemberMaker.perTypeWithinWithinTypeField(aspectType, aspectType); + classGen.addField(makeFieldGen(classGen, perTypeWithinForField).getField(), null); + ResolvedMember perTypeWithinPerClassMapField = AjcMemberMaker.perTypeWithinPerClassMapField(aspectType); + classGen.addField(makeFieldGen(classGen, perTypeWithinPerClassMapField).getField(), null); + // we need to initialize this map as a WeakHashMap in the aspect constructor(s) + InstructionFactory factory = classGen.getFactory(); + for (Iterator iterator = classGen.getMethodGens().iterator(); iterator.hasNext();) { + LazyMethodGen methodGen = (LazyMethodGen) iterator.next(); + if ("<init>".equals(methodGen.getName())) { + InstructionList il = new InstructionList(); + il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createGet(factory, perTypeWithinPerClassMapField)); + BranchInstruction ifNotNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); + il.append(ifNotNull); + il.append(InstructionConstants.ALOAD_0); + il.append(factory.createNew("java/util/WeakHashMap")); + il.append(new DUP()); + il.append(factory.createInvoke( + "java/util/WeakHashMap", + "<init>", + Type.VOID, + Type.NO_ARGS, + Constants.INVOKESPECIAL + )); + il.append(Utility.createSet(factory, perTypeWithinPerClassMapField)); + InstructionHandle currentEnd = methodGen.getBody().getEnd(); + ifNotNull.setTarget(currentEnd); + methodGen.getBody().insert(currentEnd, il); + } + } } else { - throw new RuntimeException("TODO not implemented yet"); + throw new Error("Should not happen - no such kind " + kind.toString()); } -// } else if (kind == PerClause.PERTYPEWITHIN) { -// //PTWIMPL Add field for storing typename in aspect for which the aspect instance exists -// binding.addField(factory.makeFieldBinding(AjcMemberMaker.perTypeWithinWithinTypeField(typeX,typeX))); -// } else { -// throw new RuntimeException("unimplemented"); -// } } private void generatePerSingletonAspectOfMethod(LazyClassGen classGen) { @@ -217,8 +250,8 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { InstructionHandle tryStart = il.append(factory.createInvoke(aspectType.getName(), NameMangler.AJC_POST_CLINIT_NAME, Type.VOID, Type.NO_ARGS, Constants.INVOKESTATIC)); BranchInstruction tryEnd = InstructionFactory.createBranchInstruction(Constants.GOTO, null); il.append(tryEnd); - InstructionHandle handler = il.append(InstructionFactory.createStore(Type.OBJECT, 0)); - il.append(InstructionFactory.createLoad(Type.OBJECT, 0)); + InstructionHandle handler = il.append(InstructionConstants.ASTORE_0); + il.append(InstructionConstants.ALOAD_0); il.append(Utility.createSet(factory, AjcMemberMaker.initFailureCauseField(aspectType))); il.append(InstructionFactory.createReturn(Type.VOID)); tryEnd.setTarget(il.getEnd()); @@ -239,14 +272,14 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(method); InstructionList il = method.getBody(); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createInstanceOf(interfaceType)); BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); il.append(ifEq); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createCheckCast(interfaceType)); il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); - il.append(new DUP()); + il.append(InstructionConstants.DUP); BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); il.append(ifNull); il.append(InstructionFactory.createReturn(BcelWorld.makeBcelType(aspectType))); @@ -254,7 +287,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { ifNull.setTarget(ifNullElse); InstructionHandle ifEqElse = il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); ifEq.setTarget(ifEqElse); - il.append(new DUP()); + il.append(InstructionConstants.DUP); il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); il.append(new ATHROW()); } @@ -266,20 +299,20 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(method); InstructionList il = method.getBody(); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createInstanceOf(interfaceType)); BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); il.append(ifEq); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createCheckCast(interfaceType)); il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); il.append(ifNull); - il.append(new ICONST(1));//TODO is ok ? else Push boolean + il.append(InstructionConstants.ICONST_1); il.append(InstructionFactory.createReturn(Type.INT)); - InstructionHandle ifEqElse = il.append(new ICONST(0)); + InstructionHandle ifEqElse = il.append(InstructionConstants.ICONST_0); ifEq.setTarget(ifEqElse); - ifNull.setTarget(ifEqElse);//?? + ifNull.setTarget(ifEqElse);//??//FIXME AV - ok or what ? il.append(InstructionFactory.createReturn(Type.INT)); } @@ -290,16 +323,16 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(method); InstructionList il = method.getBody(); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createInstanceOf(interfaceType)); BranchInstruction ifEq = InstructionFactory.createBranchInstruction(Constants.IFEQ, null); il.append(ifEq); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createCheckCast(interfaceType)); il.append(Utility.createInvoke(factory, Constants.INVOKEINTERFACE, AjcMemberMaker.perObjectInterfaceGet(aspectType))); BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); il.append(ifNonNull); - il.append(new ALOAD(0)); + il.append(InstructionConstants.ALOAD_0); il.append(factory.createCheckCast(interfaceType)); il.append(factory.createNew(aspectType.getName())); il.append(InstructionConstants.DUP); @@ -317,7 +350,7 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(methodGet); InstructionList ilGet = methodGet.getBody(); ilGet = new InstructionList(); - ilGet.append(new ALOAD(0)); + ilGet.append(InstructionConstants.ALOAD_0); ilGet.append(Utility.createGet(factory, AjcMemberMaker.perObjectField(aspectType, aspectType))); ilGet.append(InstructionFactory.createReturn(Type.OBJECT)); @@ -325,8 +358,8 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { classGen.addMethodGen(methodSet); InstructionList ilSet = methodSet.getBody(); ilSet = new InstructionList(); - ilSet.append(new ALOAD(0)); - ilSet.append(new ALOAD(1)); + ilSet.append(InstructionConstants.ALOAD_0); + ilSet.append(InstructionConstants.ALOAD_1); ilSet.append(Utility.createSet(factory, AjcMemberMaker.perObjectField(aspectType, aspectType))); ilSet.append(InstructionFactory.createReturn(Type.VOID)); } @@ -387,4 +420,144 @@ public class BcelPerClauseAspectAdder extends BcelTypeMunger { clinit.getBody().insert(il); } + private void generatePerTWGetInstancesMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinGetInstancesSet(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createGet(factory, AjcMemberMaker.perTypeWithinPerClassMapField(aspectType))); + il.append(factory.createInvoke( + "java/util/Map", "keySet", Type.getType("Ljava/util/Set;"), Type.NO_ARGS, Constants.INVOKEINTERFACE + )); + il.append(InstructionFactory.createReturn(Type.OBJECT)); + } + + private void generatePerTWAspectOfMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinAspectOfMethod(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + InstructionHandle tryStart = il.append(InstructionConstants.ALOAD_0); + + il.append(Utility.createInvoke( + factory, + Constants.INVOKESTATIC, + AjcMemberMaker.perTypeWithinGetInstance(aspectType) + )); + il.append(InstructionConstants.ASTORE_1); + il.append(InstructionConstants.ALOAD_1); + BranchInstruction ifNonNull = InstructionFactory.createBranchInstruction(Constants.IFNONNULL, null); + il.append(ifNonNull); + il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); + il.append(InstructionConstants.DUP); + il.append(new PUSH(classGen.getConstantPoolGen(), aspectType.getName())); + il.append(InstructionConstants.ACONST_NULL); + il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, new Type[] { Type.STRING, new ObjectType("java.lang.Throwable") }, Constants.INVOKESPECIAL)); + il.append(InstructionConstants.ATHROW); + InstructionHandle ifElse = il.append(InstructionConstants.ALOAD_1); + ifNonNull.setTarget(ifElse); + il.append(InstructionFactory.createReturn(Type.OBJECT)); + + InstructionHandle handler = il.append(InstructionConstants.ASTORE_1); + il.append(factory.createNew(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName())); + il.append(InstructionConstants.DUP); + il.append(factory.createInvoke(AjcMemberMaker.NO_ASPECT_BOUND_EXCEPTION.getName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL)); + il.append(InstructionConstants.ATHROW); + + method.addExceptionHandler( + tryStart, handler.getPrev(), handler, new ObjectType("java.lang.Exception"), false + ); + } + + private void generatePerTWHasAspectMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinHasAspectMethod(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + InstructionHandle tryStart = il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createInvoke( + factory, + Constants.INVOKESTATIC, + AjcMemberMaker.perTypeWithinGetInstance(aspectType) + )); + BranchInstruction ifNull = InstructionFactory.createBranchInstruction(Constants.IFNULL, null); + il.append(ifNull); + il.append(InstructionConstants.ICONST_1); + il.append(InstructionConstants.IRETURN); + InstructionHandle ifElse = il.append(InstructionConstants.ICONST_0); + ifNull.setTarget(ifElse); + il.append(InstructionConstants.IRETURN); + + InstructionHandle handler = il.append(InstructionConstants.ASTORE_1); + il.append(InstructionConstants.ICONST_0); + il.append(InstructionConstants.IRETURN); + + method.addExceptionHandler( + tryStart, handler.getPrev(), handler, new ObjectType("java.lang.Exception"), false + ); + } + + private void generatePerTWGetInstanceMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinGetInstance(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + InstructionHandle tryStart = il.append(InstructionConstants.ALOAD_0); + il.append(new PUSH(factory.getConstantPool(), NameMangler.perTypeWithinLocalAspectOf(aspectType))); + il.append(InstructionConstants.ACONST_NULL);//Class[] for "getDeclaredMethod" + il.append(factory.createInvoke( + "java/lang/Class", + "getDeclaredMethod", + Type.getType("Ljava/lang/reflect/Method;"), + new Type[]{Type.getType("Ljava/lang/String;"), Type.getType("[Ljava/lang/Class;")}, + Constants.INVOKEVIRTUAL + )); + il.append(InstructionConstants.ACONST_NULL);//Object for "invoke", static method + il.append(InstructionConstants.ACONST_NULL);//Object[] for "invoke", no arg + il.append(factory.createInvoke( + "java/lang/reflect/Method", + "invoke", + Type.OBJECT, + new Type[]{Type.getType("Ljava/lang/Object;"), Type.getType("[Ljava/lang/Object;")}, + Constants.INVOKEVIRTUAL + )); + il.append(factory.createCheckCast((ReferenceType) BcelWorld.makeBcelType(aspectType))); + il.append(InstructionConstants.ARETURN); + + InstructionHandle handler = il.append(InstructionConstants.ASTORE_1); + il.append(InstructionConstants.ALOAD_1); + il.append(InstructionConstants.ATHROW); + + method.addExceptionHandler( + tryStart, handler.getPrev(), handler, new ObjectType("java.lang.Exception"), false + ); + } + + private void generatePerTWCreateAspectInstanceMethod(LazyClassGen classGen) { + InstructionFactory factory = classGen.getFactory(); + LazyMethodGen method = makeMethodGen(classGen, AjcMemberMaker.perTypeWithinCreateAspectInstance(aspectType)); + classGen.addMethodGen(method); + + InstructionList il = method.getBody(); + il.append(factory.createNew(aspectType.getName())); + il.append(InstructionConstants.DUP); + il.append(factory.createInvoke( + aspectType.getName(), "<init>", Type.VOID, Type.NO_ARGS, Constants.INVOKESPECIAL + )); + il.append(InstructionConstants.ASTORE_1); + il.append(InstructionConstants.ALOAD_1); + il.append(InstructionConstants.ALOAD_0); + il.append(Utility.createSet( + factory, + AjcMemberMaker.perTypeWithinWithinTypeField(aspectType, aspectType) + )); + il.append(InstructionConstants.ALOAD_1); + il.append(InstructionConstants.ARETURN); + } + } diff --git a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java index 151e3f2d7..df2db0cbb 100644 --- a/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java +++ b/weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java @@ -145,6 +145,14 @@ public class PerTypeWithin extends PerClause { ResolvedTypeMunger munger = new PerTypeWithinTargetTypeMunger(inAspect, ret); inAspect.crosscuttingMembers.addTypeMunger(world.concreteTypeMunger(munger, inAspect)); + + //ATAJ: add a munger to add the aspectOf(..) to the @AJ aspects + if (inAspect.isAnnotationStyleAspect()) { + inAspect.crosscuttingMembers.addTypeMunger( + inAspect.getWorld().makePerClauseAspect(inAspect, getKind()) + ); + } + return ret; } |