Software Design and Development COM 1205 Winter 2002 Prof. Karl Lieberherr John Sung, Teaching Assistant MIDTERM YOUR NAME: ====================== Do the 14 UNKNOWN-PARSE at the very end! ====================== Open book and open notes. Points: 6 UNKNOWN-ABS: 2 points each: 12 points 14 UNKNOWN-AP: 5 points each: 70 points 14 UNKNOWN-PARSE: 3 points each: 42 points 7 UNKNOWN-PRINT: 2 points each: 14 points -- 41 UNKNOWNS 138 points total Consider the following class dictionary, behavior files, input and output. The class dictionary describes a simple notation to talk about Java programs. The program is written in the Java/XML-binding programming-style that we use in this course. A class dictionary plays the role of an XML schema. Find the UNKNOWNS: class dictionary: ===================================================================== import edu.neu.ccs.demeter.dj.*; import java.util.*; AspectJFragment = List(PointCut) EOF. PointCut = "pointcut" PCName PCList(ArgDecl) ":" PCExp ";". PCExp : Simple | Compound. Simple : This | Target | Call | Args | PCRef. Compound : AndOrExp | NotExp | CFlow. CFlow = "cflow" "(" PCExp ")". NotExp = "!" PCExp. Op : AndOp | OrOp. OpPCExp = Op PCExp. AndOrExp = "(" PCExp List(OpPCExp) ")". AndOp = "&&". OrOp = "||". PCRef = "*" PCName PCList(Variable). This = "this" PVariable. Target = "target" PVariable. PVariable = "(" Variable ")". Call = "call" "(" Type FName "(..)" ")". Args = "args" PCList(Variable). ArgDecl = Type Variable. Variable = Ident. PCName = Ident. FName = Ident. Type = Ident. PCList(S) ~ "(" S { "," S } ")". List(S) ~ {S}. Main = String. CommandVisitor = extends Visitor. Behavior files: ==================================================================== Main { {{ static ClassGraph cg; static String FIdent = " edu.neu.ccs.demeter.Ident "; public static void main(String args[]) throws Exception { AspectJFragment fr = AspectJFragment.parse(System.in); System.out.println(); fr.display(); System.out.println(); ClassGraph cgTemp = new ClassGraph(true, false); cg = new ClassGraph(cgTemp, "from AspectJFragment bypassing -> *,tail,* to *"); fr.process(); System.out.println(); System.out.println(" Used Variables"); HashSet used = fr.getUsedVars(); // iterator() // Returns an iterator over the elements in this set. Iterator it = used.iterator(); while (it.hasNext()){ Variable curvar = (Variable) it.next(); System.out.println(); curvar.print(); } System.out.println(); System.out.println(" Defined Variables"); HashSet defined = fr.getDefinedVars(); it = defined.iterator(); while (it.hasNext()){ Variable curvar = (Variable) it.next(); System.out.println(); curvar.print(); } System.out.println(); // the code in the above two paragraphs contains // significant duplication. To remove the duplication, // we need a method "show". show(UNKNOWN-ABS1); show(UNKNOWN-ABS2); System.out.println("done"); } // implement method show: static UNKNOWN-ABS3 show(UNKNOWN-ABS4) { UNKNOWN-ABS5 while (it.hasNext()){ UNKNOWN-ABS6 System.out.println(); curvar.print(); } System.out.println(); } }} } AspectJFragment { void print() to * (PrintVisitor); } Compound { void print() to * (PrintVisitor); } Variable { void print() to * (PrintVisitor); } AspectJFragment { {{ // method process finds all Compound-objects inside // an AspectJFragment-object and prints the message: // "This is a Compound expression: " for each Compound-object. // See output. void process() { UNKNOWN-AP1; Main.cg.UNKNOWN-AP2(UNKNOWN-AP3, UNKNOWN-AP4, cV); } }} } CommandVisitor { {{ void UNKNOWN-AP5(UNKNOWN-AP6){ System.out.println("This is a Compound expression: "); host.print(); System.out.println(); } }} } AspectJFragment { void display() to * (DisplayVisitor); } AspectJFragment { {{ // Find all Variable-objects on the right-hand-side // (after the colon) of PointCut-objects static String usedVarsSpec = "from AspectJFragment via PCExp to Variable"; // the following strategy is equivalent and more robust // "from AspectJFragment via -> *,rhs,* to Variable"; // This is even better: // "from AspectJFragment via PointCut via -> *,rhs,* to Variable"; // Find all Variable-objects on the left-hand-side // (before the colon) of PointCut-objects static String definedVarsSpec = UNKNOWN-AP7 // HashSet implements the Set interface which contains method: // add(Object o) // Adds the specified element to this set if // it is not already present. HashSet collectVars(String travspec){ // using an inlined visitor UNKNOWN-AP8 v = UNKNOWN-AP9 { // construct a new empty set HashSet return_val = new HashSet(); void UNKNOWN-AP10(Variable v1) {return_val.add(v1);} public Object getReturnValue(){return return_val;} }; return (HashSet) Main.cg.UNKNOWN-AP11(UNKNOWN-AP12, UNKNOWN-AP13, UNKNOWN-AP14); } HashSet getUsedVars() { return this.collectVars(usedVarsSpec); } HashSet getDefinedVars() { return this.collectVars(definedVarsSpec); } }} } output: (I have removed the indentation from the output to avoid wrapping of lines) =================================================================== : AspectJFragment ( : UNKNOWN-PARSE1 { : Nonempty_PointCut_List ( : UNKNOWN-PARSE2 ( : UNKNOWN-PARSE3 ( : Ident "UNKNOWN-PARSE4" ) : ArgDecl_PCList { : Nonempty_ArgDecl_PCList ( : UNKNOWN-PARSE5 ( : UNKNOWN-PARSE6 ( : Ident "UNKNOWN-PARSE7" ) : UNKNOWN-PARSE8 ( : Ident "UNKNOWN-PARSE9" ) ) ) } : UNKNOWN-PARSE11 ( : UNKNOWN-PARSE12 ( : UNKNOWN-PARSE13 ( : Ident "UNKNOWN-PARSE14" ) ) ) ) : Nonempty_PointCut_List ( : PointCut ( : PCName ( : Ident "X2" ) : ArgDecl_PCList { : Nonempty_ArgDecl_PCList ( : ArgDecl ( : Type ( : Ident "S" ) : Variable ( : Ident "s2" ) ) : Nonempty_ArgDecl_PCList ( : ArgDecl ( : Type ( : Ident "T" ) : Variable ( : Ident "t2" ) ) ) ) } : AndOrExp ( : Call ( : Type ( : Ident "void" ) : FName ( : Ident "crossing_x" ) ) : OpPCExp_List { : Nonempty_OpPCExp_List ( : OpPCExp ( : AndOp ( ) : This ( : PVariable ( : Variable ( : Ident "s" ) ) ) ) : Nonempty_OpPCExp_List ( : OpPCExp ( : AndOp ( ) : Target ( : PVariable ( : Variable ( : Ident "t" ) ) ) ) ) ) } ) ) : Nonempty_PointCut_List ( : PointCut ( : PCName ( : Ident "X3" ) : ArgDecl_PCList { : Nonempty_ArgDecl_PCList ( : ArgDecl ( : Type ( : Ident "A" ) : Variable ( : Ident "a1" ) ) : Nonempty_ArgDecl_PCList ( : ArgDecl ( : Type ( : Ident "B" ) : Variable ( : Ident "b2" ) ) : Nonempty_ArgDecl_PCList ( : ArgDecl ( : Type ( : Ident "C" ) : Variable ( : Ident "c3" ) ) ) ) ) } : CFlow ( : PCRef ( : PCName ( : Ident "visiting_A1" ) : Variable_PCList { : Nonempty_Variable_PCList ( : Variable ( : Ident "a" ) ) } ) ) ) ) ) ) } ) This is a Compound expression: (call(void crossing_x(..))&&this(s)&&target(t)) This is a Compound expression: cflow(*visiting_A1(a)) Used Variables t s a s Defined Variables s1 s2 t2 a1 c3 b2 t s a s s1 s2 t2 a1 c3 b2 done input: =================================================================== pointcut X1(S s1) : this(s); pointcut X2(S s2, T t2) : (call(void crossing_x(..)) && this(s) && target(t) ); pointcut UNKNOWN-PRINT1(A UNKNOWN-PRINT2, B UNKNOWN-PRINT3, C c3) : UNKNOWN-PRINT4( UNKNOWN-PRINT5 UNKNOWN-PRINT6(UNKNOWN-PRINT7));