diff options
author | acolyer <acolyer> | 2004-08-10 13:22:08 +0000 |
---|---|---|
committer | acolyer <acolyer> | 2004-08-10 13:22:08 +0000 |
commit | 05dabd1821fffd9f353d1e965a56658b962c82d7 (patch) | |
tree | ac21652c7b86d12a0deaf3f287e97b6f5d07f16b | |
parent | b3f5f6fe945ef35f8a3b97ec71bb5cc57e89a641 (diff) | |
download | aspectj-05dabd1821fffd9f353d1e965a56658b962c82d7.tar.gz aspectj-05dabd1821fffd9f353d1e965a56658b962c82d7.zip |
fix for Bugzilla Bug 53981
proceed used as method name in around advice
-rw-r--r-- | docs/progGuideDB/semantics.xml | 26 | ||||
-rw-r--r-- | org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java | 11 | ||||
-rw-r--r-- | tests/bugs/pr53981/Proceeding1.aj | 26 | ||||
-rw-r--r-- | tests/bugs/pr53981/Proceeding2.aj | 13 | ||||
-rw-r--r-- | tests/bugs/pr53981/Proceeding3.aj | 14 | ||||
-rw-r--r-- | tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java | 12 | ||||
-rw-r--r-- | tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml | 20 |
7 files changed, 118 insertions, 4 deletions
diff --git a/docs/progGuideDB/semantics.xml b/docs/progGuideDB/semantics.xml index b88e86c7e..ba16b849c 100644 --- a/docs/progGuideDB/semantics.xml +++ b/docs/progGuideDB/semantics.xml @@ -1560,6 +1560,32 @@ } </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 diff --git a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java index ae07cec86..82e96f1e8 100644 --- a/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java +++ b/org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java @@ -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 index 000000000..a64f28240 --- /dev/null +++ b/tests/bugs/pr53981/Proceeding1.aj @@ -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 index 000000000..f77854c83 --- /dev/null +++ b/tests/bugs/pr53981/Proceeding2.aj @@ -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 index 000000000..7033c393b --- /dev/null +++ b/tests/bugs/pr53981/Proceeding3.aj @@ -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 diff --git a/tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java b/tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java index 1c400a562..5a3c6d496 100644 --- a/tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java +++ b/tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java @@ -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)"); + } } diff --git a/tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml b/tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml index 4ea2144c8..37ac4da2d 100644 --- a/tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml +++ b/tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml @@ -183,4 +183,22 @@ <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 |