COM 3360 Midterm Winter 2003 Karl Lieberherr Open books and open notes Question 1: =========== 26 UNKNOWNs 1 point per UNKNOWN = 26 points Consider the following files: program.cd program.java Display.trv A.java DVisitor.java program.input and the output produced with program.input as input file. Find the UNKNOWNs in the output. ========================================================================= program.cd // class dictionary Input = "JPT-Input" JPT "JPTrace-Input" JPTrace "JPTraceCF-Input" JPTraceCF EOF. JPT = "jp" JPN ID List(ID) List(JPT) ID. List(S) ~ "(" {S} ")". ID = Ident. // OF to JPT JPTrace = "jp" JPN Objekt List(Objekt) List(JPTrace) Objekt. Objekt = ID. // CF to JPT JPTraceCF = "jp" JPN Klass List(Klass) List(JPTraceCF) Klass. Klass = ID. JPN = Ident. ========================================================================= // program.java import java.io.File; class Main { public static void main(String args[]) throws Exception { Input input = Input.parse(new File(args[0])); input.display(); System.out.println("done"); } } ========================================================================= Display.trv aspect Display { declare strategy: everyWhere: "from Input to ID"; declare traversal: void display(): everyWhere(DVisitor); } ========================================================================= // A.java aspect A { pointcut c() : call(* *everyWhere*(..)) && (target(ID) || target(JPT)); before(): c() { System.out.println(thisJoinPoint); } } ========================================================================= // DVisitor.java // import edu.neu.ccs.demeter.Ident; class DVisitor { void before(Input host) { System.out.println(host); } void before(ID host) { System.out.println(host.ident.toString()); } } ========================================================================= // program.input JPT-Input jp bar_callt1_JPN ID (a1 a2) () r1 JPTrace-Input jp foo_call //jpn oid1 // target (oid2 oid3) // actualArgs // (foo2_call foo3_call) () oid4 // actualReturn JPTraceCF-Input jp foo_call //jpn Basket // target class (Integer Foo) // formalArgs // (foo2_call foo3_call) () Integer //returnType The output: ================================================================= UNKNOWN1@5d173 call(void UNKNOWN2.everyWhere(BitSet[])) call(void UNKNOWN3.everyWhere_crossing_target(BitSet[])) call(void UNKNOWN4.everyWhere(BitSet[])) UNKNOWN5 call(void UNKNOWN6.everyWhere_crossing_arguments(BitSet[])) call(void UNKNOWN7.everyWhere(BitSet[])) UNKNOWN8 call(void UNKNOWN9.everyWhere(BitSet[])) UNKNOWN10 call(void UNKNOWN11.everyWhere_crossing_body(BitSet[])) call(void UNKNOWN12.everyWhere_crossing_returns(BitSet[])) call(void UNKNOWN13.everyWhere(BitSet[])) UNKNOWN14 call(void UNKNOWN15.everyWhere(BitSet[])) UNKNOWN16 call(void UNKNOWN17.everyWhere(BitSet[])) UNKNOWN18 call(void UNKNOWN19.everyWhere(BitSet[])) UNKNOWN20 call(void UNKNOWN21.everyWhere(BitSet[])) UNKNOWN22 call(void ID.everyWhere(BitSet[])) UNKNOWN23 call(void ID.everyWhere(BitSet[])) UNKNOWN24 call(void ID.everyWhere(BitSet[])) UNKNOWN25 call(void ID.everyWhere(BitSet[])) UNKNOWN26 done Question 2: =========== 3 points per pointcut : 15 points 3 points per declare 3 points 18 points Describe in English the set of join points selected by each pointcut. Describe in English the first "declare parents" statement. package lawofDemeter; import test.*; aspect checkingLoD_test_AJ extends LawofDemeter_AJ{ public pointcut Check(Object thiz, Object target): call(* test..*.*(..)) && target(target) && this(thiz); public pointcut NonStaticMethod(Object target): call(* test..*.*(..)) && target(target); public pointcut StaticMethod(Object thiz): call(static * test..*.*(..)) && this(thiz); public pointcut Constructor(Object thiz, Object target): call(test..*.new(..)) && this(thiz) && target(target); public pointcut Set(Object target, Object value): set(* test..*.*) && args(value) && target(target); declare parents: test..* implements Checked; declare parents: test..* implements MethodSupplier; declare parents: test..* implements FieldSupplier; } Question 3: ====================================================== 25 points Consider the object tree a_in representing an object of class A in the Java program below. We want to traverse this object in depth-first order as shown in the implementation below. Consider the method t. It's code is spread across several classes. Write an aspect that prints the following for every D-object d1 that is found during traversal t: a) d1.toString() b) x2.toString() for the object x2 visited immediately before the D-object d1 is visited. Your program should be generic and work for any application that has a method t() that is called on D-objects. The program: class A { B b; C c; A(B b, C c){ this.b = b; this.c = c;} void t() { b.t(); c.t(); } } class B { D d; E e; B(D d, E e) {this.d = d; this.e = e;} void t() { d.t(); e.t(); } } class C { void t() {} } class D extends C { void t() { System.out.println(" in D-object "); } } class E extends C { void t() { System.out.println(" in E-object "); } } class Main { static public void main(String args[]) { A a_in = new A(new B(new D(), new E()), new D()); a_in.t(); } } Question 4: =========== 10 points Discuss how to simulate DJ in DAJ. How would you simulate this code in DAJ? cg = new ClassGraph(true, false); ClassGraph cgCommandsWithoutTail = new ClassGraph(Main.cg, "from Commands bypassing -> *,tail,* to *"); cs.process(new TraversalGraph ("from Commands to Simple",cgCommandsWithoutTail));