diff options
Diffstat (limited to 'docs/sandbox')
-rw-r--r-- | docs/sandbox/common/language/DoubleDispatch.java | 81 | ||||
-rw-r--r-- | docs/sandbox/sandbox-test.xml | 5 |
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 |