aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoravasseur <avasseur>2005-05-02 08:17:36 +0000
committeravasseur <avasseur>2005-05-02 08:17:36 +0000
commitcdddd38d261f0ae75bf95f0859e7a440be1bb3d5 (patch)
treefa61448ab8b0d848cd65930fc5e9a44a71433ea8
parent0b7744f560fb4ff70b70884a4932c8ebeb603fd2 (diff)
downloadaspectj-cdddd38d261f0ae75bf95f0859e7a440be1bb3d5.tar.gz
aspectj-cdddd38d261f0ae75bf95f0859e7a440be1bb3d5.zip
PTW perClause for @AJ + perClause test
-rw-r--r--runtime/src/org/aspectj/lang/Aspects.java112
-rw-r--r--tests/java5/ataspectj/ataspectj/BindingTest.java14
-rw-r--r--tests/java5/ataspectj/ataspectj/PerClauseTest.java162
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150-tests.xml208
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150.xml12
-rw-r--r--tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml8
-rw-r--r--tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java10
-rw-r--r--weaver/src/org/aspectj/weaver/AjcMemberMaker.java27
-rw-r--r--weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java249
-rw-r--r--weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java8
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 &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>
-
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;
}