summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoracolyer <acolyer>2004-08-10 13:22:08 +0000
committeracolyer <acolyer>2004-08-10 13:22:08 +0000
commit05dabd1821fffd9f353d1e965a56658b962c82d7 (patch)
treeac21652c7b86d12a0deaf3f287e97b6f5d07f16b
parentb3f5f6fe945ef35f8a3b97ec71bb5cc57e89a641 (diff)
downloadaspectj-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.xml26
-rw-r--r--org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/Proceed.java11
-rw-r--r--tests/bugs/pr53981/Proceeding1.aj26
-rw-r--r--tests/bugs/pr53981/Proceeding2.aj13
-rw-r--r--tests/bugs/pr53981/Proceeding3.aj14
-rw-r--r--tests/src/org/aspectj/systemtest/ajc121/Ajc121Tests.java12
-rw-r--r--tests/src/org/aspectj/systemtest/ajc121/ajc121-tests.xml20
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