Question 1.1: ==================================================== aspect traversal1 { void A. t() { b.t(); c.t(); } void B.t() { d.t(); e.t(); } void C.t() {} void D.t() { System.out.println(" in D-object direct "); } void E.t() { System.out.println(" in E-object direct "); } } aspect visitor { // advising traversal traversal1 before() : execution(void D.t()) { // before() : call(void D.t()) { // does not work in general, // e.g., in A.c is a D System.out.println(" in D-object "); } before() : execution(void E.t()) { // before() : call(void E.t()) { System.out.println(" in E-object "); } } class A { B b; C c; A(B b, C c){ this.b = b; this.c = c;} } class B { D d; E e; B(D d, E e) {this.d = d; this.e = e;} } class C { } class D extends C { } class E extends C { } class Main { static public void main(String args[]) { A a_in = new A(new B(new D(), new E()), new D()); a_in.t(); } } in D-object in D-object direct in E-object in E-object direct in D-object in D-object direct Question 1.2 ============================================ // Plan: // to capture crossings from one object to another, // we rewrite the traversal so that a pointcut // call(void *.crossing*(..)) && this(s) && args(t) // captures edge crossings. If t is a D, we print s. aspect traversal1 { void A. t() { crossing_t_b(b); crossing_t_c(c) ; } void A.crossing_t_b(B b){b.t();} void A.crossing_t_c(C c){c.t();} void B.t() { crossing_t_d(d); crossing_t_e(e); } void B.crossing_t_d(D d){d.t();} void B.crossing_t_e(E e){e.t();} // void B.t() { // d.t(); e.t(); // } void C.t() {} void D.t() { System.out.println(" in D-object direct "); } void E.t() { System.out.println(" in E-object direct "); } } aspect visitor { // advising traversal traversal1 before() : execution(void D.t()) { // before() : call(void D.t()) { System.out.println(" in D-object "); } before() : execution(void E.t()) { // before() : call(void E.t()) { System.out.println(" in E-object "); } before() : call(void D.t()) { Object thiz = thisJoinPoint.getThis(); Object target = thisJoinPoint.getTarget(); System.out.println("target = " + target + "this =" + thiz); } pointcut crossing(Object s, Object t): call(void *.crossing*(..)) && this(s) && args(t); before(Object s, Object t) : crossing(s,t) { if (t instanceof D) { System.out.println("target = " + t + "source =" + s); } } } class A { B b; C c; A(B b, C c){ this.b = b; this.c = c;} } class B { D d; E e; B(D d, E e) {this.d = d; this.e = e;} } class C { } class D extends C { } class E extends C { } class Main { static public void main(String args[]) { A a_in = new A(new B(new D(), new E()), new D()); a_in.t(); } } output: target = D@31f71asource =B@5601ea target = D@31f71athis =B@5601ea in D-object in D-object direct in E-object in E-object direct target = D@7259dasource =A@6930e2 in D-object in D-object direct Ryan Culpepper's solution: aspect FoundD{ Object caller; void around():call(void *.t()) { caller = thisJoinPoint.getThis(); proceed(); } void around() : execution(void D.t()) { System.out.println(" ryan " + thisJoinPoint.getThis()); System.out.println(" ryan " + caller); } } Question 2: ====================================== aspect AddMain { after():call(static void main(..)){ System.out.println(" done "); } } Question 3: essay question Question 4: ==================================================== 1: Execution 2: Execution 3: thisJoinPoint.getArgs 4: argument 5: thisJoinPoint.getThis 6: receiver 7: NOTHING 8: Execution 9: ConstructorCall 10: NOTHING 11: NOTHING 12: newLocalObj 13: local 14: Execution 15: MethodCall 16: NOTHING 17: if(returnVal != null){ if(thisJoinPoint.getThis() == thisJoinPoint.getTarget()){ add(returnVal, local + JPUtil.at(thisJoinPoint)); } 18: remove // in: // suppliers.add( ArgumentBin.aspectOf() ); // suppliers.add( LocallyConstructedBin.aspectOf() ); // suppliers.add( ReturnValueBin.aspectOf() );