author    = {Pengcheng Wu and Karl Lieberherr},
title     = {Shadow Programming: Reasoning about Programs using Lexical Join Point Information},
booktitle = {Proceedings of the 4th International Conference on Generative Programming and Component Engineering},
year      = {2005},
location  = {Tallinn, Estonia}

Paper from Springer Verlag . | Paper for personal use .

Notes by Karl:

This paper introduces an adapted lexical join point model (shadow model) for AspectJ and makes it available to the AspectJ programmer. The paper shows two use cases of the shadow model.

The statically executable advice use case shows how to do visitor-style programming on abstract syntax trees of Java programs using AspectJ. The traversal is universal and will visit the entire abstract syntax tree. The statically evaluable pointcut designators are used to define the events we are interested in. Visitors correspond to implementations of an interface IStaticallyExecutableAdvice. Instead of programming against the detailed abstract syntax trees, we program against an abstract version of the Java abstract syntax: the lexical join point class graph described in Fig. 1.

The shadow model organizes the structure of a Java program differently than a typical Java grammar. A Java grammar would define a meta programming structure to analyze Java programs, e.g., to check style rules.

The second use case, called Pointcut Evaluator, supports the use of arbitrary Java programs to process the shadow information.

For example, to check the class form of the Law of Demeter, we traverse the entire abstract syntax tree. We use an AspectJ pointcut designator to define the calls we want to check and the events that produce permissible types. We use a "visitor" that keeps track of the permissible types for each method body. The "visitor" is expressed as an implementation of the IStaticallyExecutableAdvice interface.

This approach works well as long as we only need information about the Java programs that is exposed by the join point model.

This is an interesting example of a traversal with filter. The outermost traversal visits the entire abstract syntax tree and the filter selects a subset of the traversal events that the visitor has code for. This calls for a DJ method: cg.traverse(object, whereToGo, filter, whereAndWhatToDo), where filter eliminates some of the nodes and edges where otherwise visitor code would be executed. Are there enough use cases to add this to DJ?