aboutsummaryrefslogtreecommitdiffstats
path: root/docs/sandbox
diff options
context:
space:
mode:
Diffstat (limited to 'docs/sandbox')
-rw-r--r--docs/sandbox/common/language/DoubleDispatch.java81
-rw-r--r--docs/sandbox/sandbox-test.xml5
2 files changed, 86 insertions, 0 deletions
diff --git a/docs/sandbox/common/language/DoubleDispatch.java b/docs/sandbox/common/language/DoubleDispatch.java
new file mode 100644
index 000000000..2d5a23f0a
--- /dev/null
+++ b/docs/sandbox/common/language/DoubleDispatch.java
@@ -0,0 +1,81 @@
+
+
+package language;
+
+import org.aspectj.testing.Tester;
+
+/** @author Wes Isberg */
+public class DoubleDispatch {
+
+ public static void main(String[] a) {
+ Worker worker = new Worker();
+ worker.run((SuperType) new SubTypeOne());
+ worker.run((SuperType) new SubTypeTwo());
+ worker.run(new SuperType());
+ Tester.checkAllEvents();
+ }
+ static aspect A {
+ static int counter;
+ static {
+ Tester.expectEvent("language.SubTypeOne-1");
+ Tester.expectEvent("language.SubTypeTwo-2");
+ Tester.expectEvent("language.SuperType-3");
+ }
+ before(Object o) : execution(void Worker.run(..)) && args(o) {
+ Tester.event(o.getClass().getName() + "-" + ++counter);
+ }
+ }
+}
+
+// START-SAMPLE language-doubleDispatch Implementing double-dispatch
+
+/**
+ * By hypothesis, there is a working class with
+ * methods taking a supertype and subtypes.
+ * The goal of double-dispatch is to execute the
+ * subtype method rather than the supertype
+ * method selected when the compile-time
+ * reference is of the super's type.
+ */
+class Worker {
+ void run(SuperType t) {}
+ void run(SubTypeOne t) {}
+ void run(SubTypeTwo t) {}
+}
+
+class SuperType {}
+class SubTypeOne extends SuperType {}
+class SubTypeTwo extends SuperType {}
+
+/** Implement double-dispatch for Worker.run(..) */
+aspect DoubleDispatchWorker {
+
+ /**
+ * Replace a call to the Worker.run(SuperType)
+ * by delegating to a target method.
+ * Each target subtype in this method dispatches back
+ * to the subtype-specific Worker.run(SubType..) method,
+ * to implement double-dispatch.
+ */
+ void around (Worker worker, SuperType targ):
+ !withincode(void SuperType.doWorkerRun(Worker)) &&
+ target (worker) && call (void run(SuperType)) &&
+ args (targ) {
+ targ.doWorkerRun(worker);
+ }
+
+ void SuperType.doWorkerRun(Worker worker) {
+ worker.run(this);
+ }
+
+ // these could be in separate aspects
+ void SubTypeOne.doWorkerRun(Worker worker) {
+ worker.run(this);
+ }
+ void SubTypeTwo.doWorkerRun(Worker worker) {
+ worker.run(this);
+ }
+}
+
+// END-SAMPLE language-doubleDispatch
+ \ No newline at end of file
diff --git a/docs/sandbox/sandbox-test.xml b/docs/sandbox/sandbox-test.xml
index 494fa5672..332a4a9d1 100644
--- a/docs/sandbox/sandbox-test.xml
+++ b/docs/sandbox/sandbox-test.xml
@@ -62,6 +62,11 @@
<run class="language.ControlFlow"/>
</ajc-test>
+ <ajc-test dir="common" title="language-doubleDispatch">
+ <compile files="language/DoubleDispatch.java"/>
+ <run class="language.DoubleDispatch"/>
+ </ajc-test>
+
<ajc-test dir="common" title="tracing-simpleLogging">
<compile