]> source.dussan.org Git - aspectj.git/commitdiff
fix for Bugzilla Bug 53981
authoracolyer <acolyer>
Tue, 10 Aug 2004 13:22:08 +0000 (13:22 +0000)
committeracolyer <acolyer>
Tue, 10 Aug 2004 13:22:08 +0000 (13:22 +0000)
  proceed used as method name in around advice

docs/progGuideDB/semantics.xml
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java
tests/bugs/pr53981/Proceeding1.aj [new file with mode: 0644]
tests/bugs/pr53981/Proceeding2.aj [new file with mode: 0644]
tests/bugs/pr53981/Proceeding3.aj [new file with mode: 0644]
tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java
tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml

index b88e86c7efe198db12e3dd9e0dcb8cce87fe7a0a..ba16b849cf7bd789b612ee5e84a058e178655359 100644 (file)
   }
 </programlisting>
 
+       <para>
+               Any occurence of <literal>proceed(..)</literal> within the body of
+               around advice is treated as the special proceed form (even if the
+               aspect defines a method named <literal>proceed</literal>) unless a 
+               target other than the aspect instance is specified as the recipient of
+               the call.
+               For example, in the following program the first 
+               call to proceed will be treated as a method call to
+               the <literal>ICanProceed</literal> instance, whereas the second call to
+               proceed is treated as the special proceed form.
+       </para>
+
+<programlisting>
+  aspect A {
+     Object around(ICanProceed canProceed) : execution(* *(..)) <![CDATA[&&]]> this(canProceed) {
+        canProceed.proceed();         // a method call
+        return proceed(canProceed);   // the special proceed form
+     }
+     
+     private Object proceed(ICanProceed canProceed) {
+        // this method cannot be called from inside the body of around advice in
+        // the aspect
+     }
+  }    
+</programlisting>
+
     <para>
       In all kinds of advice, the parameters of the advice behave exactly like
       method parameters.  In particular, assigning to any parameter affects
index ae07cec8626217ba820a3b258f2dc74b96846012..82e96f1e8731c1284e5c337a92bb9e1ce0a8987e 100644 (file)
@@ -1,5 +1,6 @@
 /* *******************************************************************
  * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
+ *               2004 contributors
  * All rights reserved. 
  * This program and the accompanying materials are made available 
  * under the terms of the Common Public License v1.0 
@@ -7,7 +8,8 @@
  * http://www.eclipse.org/legal/cpl-v10.html 
  *  
  * Contributors: 
- *     PARC     initial implementation 
+ *     PARC     initial implementation
+ *     IBM      ongoing maintenance 
  * ******************************************************************/
 
 
@@ -26,7 +28,8 @@ import org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
 /**
  * Used to represent any method call to a method named <code>proceed</code>.  During
  * <code>resolvedType</code> it will be determined if this is actually in the body
- * of an <code>around</code> advice and if not this will be treated like any other
+ * of an <code>around</code> advice and has no receiver (must be a bare proceed call, 
+ * see pr 53981), and if not this will be treated like any other
  * MessageSend.
  * 
  * @author Jim Hugunin
@@ -111,13 +114,15 @@ public class Proceed extends MessageSend {
 
        private AdviceDeclaration findEnclosingAround(Scope scope) {
                if (scope == null) return null;
-               
+                               
                if (scope instanceof MethodScope) {
                        MethodScope methodScope = (MethodScope)scope;
                        ReferenceContext context = methodScope.referenceContext;
                        if (context instanceof AdviceDeclaration) {
                                AdviceDeclaration adviceDecl = (AdviceDeclaration)context;
                                if (adviceDecl.kind == AdviceKind.Around) {
+                                       // pr 53981 only match "bare" calls to proceed
+                                       if((receiver != null) && (!receiver.isThis())) { return null; }
                                        adviceDecl.proceedCalls.add(this);
                                        return adviceDecl;
                                } else {
diff --git a/tests/bugs/pr53981/Proceeding1.aj b/tests/bugs/pr53981/Proceeding1.aj
new file mode 100644 (file)
index 0000000..a64f282
--- /dev/null
@@ -0,0 +1,26 @@
+import org.aspectj.testing.Tester;
+
+public class Proceeding1 {
+    public static void main(String[] args) { 
+       Tester.checkAllEvents();
+    }
+    static aspect A {
+        interface IProceed {
+            void proceeds(Runnable next);
+        }
+        IProceed decorator = new IProceed() {
+            public void proceeds(Runnable next) {
+                Tester.event("IProceed.proceed()");
+                next.run();
+            }
+        };
+        void around() : execution(void main(String[])) {
+            Tester.expectEvent("IProceed.proceed()");
+            decorator.proceeds(new Runnable() {
+                public void run() {
+                    proceed();
+                }
+            });
+        }
+    }
+}
\ No newline at end of file
diff --git a/tests/bugs/pr53981/Proceeding2.aj b/tests/bugs/pr53981/Proceeding2.aj
new file mode 100644 (file)
index 0000000..f77854c
--- /dev/null
@@ -0,0 +1,13 @@
+import org.aspectj.testing.Tester;
+
+public class Proceeding2 {
+    public static void main(String[] args) {
+        Tester.checkFailed("Proceed with a receiver should be treated as a method call, not the special form");
+    }
+    static aspect A {
+        void around() : execution(void main(String[])) {
+            Proceeding2.proceed(null); // BUG: treated as proceed(Object);
+        }
+    }
+    static void proceed(Object o) {}
+}
\ No newline at end of file
diff --git a/tests/bugs/pr53981/Proceeding3.aj b/tests/bugs/pr53981/Proceeding3.aj
new file mode 100644 (file)
index 0000000..7033c39
--- /dev/null
@@ -0,0 +1,14 @@
+import org.aspectj.testing.Tester;
+
+public class Proceeding3 {
+    public static void main(String[] args) {
+    }
+    static aspect A {
+        void around() : execution(void main(String[])) {
+            proceed(); // special form or Proceeding.proceed()?
+        }
+    }
+    void proceed() {
+        Tester.checkFailed("A bare call to proceed inside around advice should never refer to a method");
+    }
+}
\ No newline at end of file
index 1c400a562710aa34b9bdbcacd715770819139814..5a3c6d496f97d478ccc005ae912a085286a5de49 100644 (file)
@@ -127,5 +127,17 @@ public class Ajc121Tests extends org.aspectj.testing.XMLBasedAjcTestCase {
 //  public void test022_BcelFailureWithVeryLargeClasses_Binary() {
 //      runTest("Weaver fails in BCEL for large classes (binary)");
 //  }
+  
+  public void test023_proceedInAround1() {
+      runTest("proceed used as method name in around advice (1)");
+  }
+
+  public void test024_proceedInAround2() {
+      runTest("proceed used as method name in around advice (2)");
+  }
+
+  public void test025_proceedInAround3() {
+      runTest("proceed used as method name in around advice (3)");
+  }
 }
 
index 4ea2144c84f35197b6de7d16fec38f947ba518d2..37ac4da2dbed8278524b98028905cc88649cdb14 100644 (file)
                <message kind="error" line="0" text="constant pool too big"></message>
            </compile>
        </ajc-test>
--->
\ No newline at end of file
+-->
+
+       <ajc-test dir="bugs/pr53981" pr="538981"
+       title="proceed used as method name in around advice (1)">
+       <compile files="Proceeding1.aj"/>
+       <run class="Proceeding1"/>
+       </ajc-test>
+
+       <ajc-test dir="bugs/pr53981" pr="538981"
+       title="proceed used as method name in around advice (2)">
+       <compile files="Proceeding2.aj"/>
+       <run class="Proceeding2"/>
+       </ajc-test>
+
+       <ajc-test dir="bugs/pr53981" pr="538981"
+       title="proceed used as method name in around advice (3)">
+       <compile files="Proceeding3.aj"/>
+       <run class="Proceeding3"/>
+       </ajc-test>
\ No newline at end of file