Managing Software Development CSG 110 Spring 2005 Karl Lieberherr Due date: April 7, 2005 Homework 8: ERE Controllable Law of Demeter (LoD) Checker (second version) ========================================================================== Our initial requirement "ERE for LoD" was to use regular expressions to control the scope of the Law of Demeter Checker. In hw 7 we implemented one version of this. Based on the technical report: http://abc.comlab.ox.ac.uk/techreports#abc-2005-1 we implement a second version of this "ERE for LoD" requirement. This shows again how important it is to dig for requirements. An informal requirement can have many different interpretations and it is the responsibility of the software developers to interact with the users and find out which interpretation was meant. This hw is also showing the importance of product family design. In this hw we implement a second member of our family of Law of Demeter checkers. A second interpretation of the requirement to use regular expressions to control the scope where the Law of Demeter Checker should check is described here. So far our regular expressions have selected paths from the root (call to main) to nodes in the execution tree through forward edges only. Now we generalize this path concept by using "history paths": Those are paths selected by the depth-first traversal of the execution tree. This involves forward and backward edges. We give a new interpretation to a regular expressions: Define a set of events of interest and naming them with a symbol name. Define a regular expression over those symbols. Not all declared symbols need to be used in the regular expression. If a "history path" matches: all events on the path need to be checked. Concretely, we use the following syntax to express tracematches that define where the LoD should be checked. TraceMatch = "tracematch" "(" [ CList(VariableDeclaration)] ")" List(Symbol) RegEx. VariableDeclaration = ClassName VariableName. Symbol = "sym" Name Kind ":" PointcutExp ";". Kind : Before | After. Before = "before". After = "after". PointcutExp : Simple | Compound. Simple : Call | Target | This. Call = "call" "(" "*" ClassName "." MethodName "(..)" ")". Target = "target" "(" VariableName ")". This = "this" "(" VariableName ")". Compound = "(" Op List(PointcutExp) ")". Op : Union | Intersection. Union = "|". Intersection = "&". RegEx = "regex". Name = Ident . ClassName = Ident. MethodName = Ident. VariableName = Ident. List(S) ~ {S}. CList(S) ~ S {"," S}. You will have to execute the program twice as in hw 7. The symbol definitions only use a limited set of pointcuts: call, target and this. Tracematches in abc implement the full AspectJ pointcut language. Again, it is important to implement this final part of the project in small incremental steps. The basic architecture from hw 7 should be reused in this project. All that changes here is that we apply the regular expressions to an extended notion of path. Simplifications you should make to start: 1. TraceMatch.decls is the empty list. 2. Only allow call pointcuts to define symbols (i.e., no This and Target). ================================== An example: Execution tree: the nodes are calls: (p1 (p2 (p3) (p4)) (p5 (p6) (p3))) The depth-first execution trace is: before p1 before p2 before p3 after p3 before p4 after p4 after p2 before p5 before p6 after p6 before p3 after p3 after p5 after p1 If we define the symbols: sym bp1 before p1 sym bp5 before p5 the filtered trace is: before p1 before p5 If the regular expression is: (# bp1 bp5) we have a match: before p1 before p2 before p3 after p3 before p4 after p4 after p2 before p5 and we call the LoD checker on the calls: p1 p2 p3 p4 p5 If we define the symbols: sym bp2 before p2 sym bp3 before p3 the filtered trace is before p2 before p3 before p3 If the regular expression is: (# bp2 bp3) we have a match: before p1 before p2 before p3 and we call the LoD checker on the calls: p1 p2 p3 If the regular expression is: (# bp2 (* bp3)) we have a match: before p1 before p2 before p3 after p3 before p4 after p4 after p2 before p5 before p6 after p6 before p3 after p3 and we call the LoD checker on all calls.