]> source.dussan.org Git - aspectj.git/commitdiff
PTW perClause for @AJ + perClause test
authoravasseur <avasseur>
Mon, 2 May 2005 08:17:36 +0000 (08:17 +0000)
committeravasseur <avasseur>
Mon, 2 May 2005 08:17:36 +0000 (08:17 +0000)
runtime/src/org/aspectj/lang/Aspects.java
tests/java5/ataspectj/ataspectj/BindingTest.java
tests/java5/ataspectj/ataspectj/PerClauseTest.java
tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150-tests.xml [deleted file]
tests/src/org/aspectj/systemtest/ajc150/ataspectj/atajc150.xml [deleted file]
tests/src/org/aspectj/systemtest/ajc150/ataspectj/syntax.xml
tests/src/org/aspectj/systemtest/incremental/tools/AjdeInteractionTestbed.java
weaver/src/org/aspectj/weaver/AjcMemberMaker.java
weaver/src/org/aspectj/weaver/bcel/BcelPerClauseAspectAdder.java
weaver/src/org/aspectj/weaver/patterns/PerTypeWithin.java

index 0d8cb5ccbea270a0bc39e4e25b06a963ec295326..dd128636551012a4d89dccb1bcaaace824a6b663 100644 (file)
@@ -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;
+    }
 }
index c4114f0205190d555c144800d1f4bcd9ab73f060..342b8ebf06d78d32d57cc36c45efd0a0d95a7b6f 100644 (file)
@@ -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;
+            }
+        }
     }
 
 }
index 0773f627f2b9a52b0c7794fe63f021adaa1add08..ff8a354d2229fee899d67e2d296f6d4c46656907 100644 (file)
@@ -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 (file)
index c426dba..0000000
+++ /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 (file)
index fb36111..0000000
+++ /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>
-
index 417d0be482710d5432eb4aa1b83003d2bf16301d..daeb4da84d8a5550b7917ac936fd6b1a75a44c47 100644 (file)
         <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
index a7005d6b40349eb757a0fa190c091dce073e4de2..f90ed90b3561a250a32bbb12e8b0b6c7d5929023 100644 (file)
@@ -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");
                }
index d285a1574eefee6b789715c3bbec437e73de80ff..428c0b4b81edf47bb07f4aca6e9130a674ff5e50 100644 (file)
@@ -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(
index 7f759c7217aefe65a13153f4632e50d26f022095..254f429feef1def67f265d28de62aebc06833cf5 100644 (file)
@@ -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);
+    }
+
 }
index 151e3f2d708e1450507209918f713938eb044b79..df2db0cbb82df59886f126e722b0cf4b2d59b015 100644 (file)
@@ -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;
                
        }