]> source.dussan.org Git - aspectj.git/commitdiff
double-dispatch example
authorwisberg <wisberg>
Wed, 6 Aug 2003 10:30:25 +0000 (10:30 +0000)
committerwisberg <wisberg>
Wed, 6 Aug 2003 10:30:25 +0000 (10:30 +0000)
docs/sandbox/common/language/DoubleDispatch.java [new file with mode: 0644]
docs/sandbox/sandbox-test.xml

diff --git a/docs/sandbox/common/language/DoubleDispatch.java b/docs/sandbox/common/language/DoubleDispatch.java
new file mode 100644 (file)
index 0000000..2d5a23f
--- /dev/null
@@ -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
index 494fa56722727ce12a3297fa56fbdc1f0efde68d..332a4a9d1dd17f04ac477e53b6576a9fcc1e3df4 100644 (file)
                <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