Example: Object-based inheritance

We illustrate the use of pattern predicates with a simple example. Assume we want to select all method calls within the following Java program that invoke a method of their enclosing class C.

 1: class C{
 2:   void x ( ){
 3:     A.a(42, 43);
 4:     this.y();
 5:     y().y();
 6:   }
 7:   C y(){
 8:    return this ;
 9:   }
10: }

Listing 1: Simple Java class

Figure 6 shows a predicate to express this analysis. The use of the pattern predicate in Lines 2- 3 binds method calls to the variable ?call. The second one (Lines 6-10) matches public methods. Line 5 uses the unification operator ‘=’ to expresses that the method invoked by ?call must be the public one matched by the second concrete syntax pattern. If evaluated on the program from Figure 4 public self calls binds its argument tuple (?expr, ?name) to the result tuples (this, y), (y,y) and (this, y).

 1: public_self_calls(?call, ?method):−
 2:   ?call is [[
 3:   this.?name(??args)
 4:   ]],
 5:   ?method = ?call::decl
 6:   ?method is [[
 7:     public ?type ?name(??params){
 8:      ??stmts
 9:     }
10:   ]] .

Self-defined predicate using two pattern predicates

In this example we present the implementation of object-based inheritance in GenTL. The following listing shows the pattern predicate, the necessary two conditional transformations and the CT sequence combining them.

 1: ct add self parameter (?method, ?selfType) :
 2:   ?method is [[ public ?type ?name(??params){ ??statements } ]] ,
 3:   ?type = ?method::encl::type ,
 4:  replaceable ( ?type , ?sel fType ) ,
 5:  −>
 6:  add [[ ?selfType self ]] before ??params .
 7:
 8: ct redirect_self_calls_in(?calledMethod):
 9:   public_self_call(?call, ?calledMethod),
10:   ?call is [[ ?recv.?name(??params) ]]
11:   −>
12:   replace ?recv with [[ self ]] .
13:
14: ctseq use_self_param(?method, ?selfType):
15:   add self_parameter(?method, ?selfType) and
16:   redirect_self_calls_in(?method) .

GenTL transformation

Last modified: 2017/08/29 21:57
*