Pointcuts and Analysis Oege de Moor, Oxford on behalf of the  abc  team: Pavel Avgustinov, Eric Bodden, Torbj ő rn Ekman,  Elnar Hajiyev, Laurie Hendren, Ond ř ej Lhot á k,  Oege de Moor, Neil Ongkingco, Damien Sereni,  Ganesh Sittampalam, Julian Tibble
Swing thread safety (Ramnivas Laddad) Once a component is visible only the event-dispatching thread  can safely access or modify  the state of the realized component. (but some methods are exempt)
Doing it by hand… interface  Runnable { void  run(); } asynchronous invocation: EventQueue.invokeLater(Runnable run) synchronous invocation: EventQueue.invokeAndWait(Runnable run)
With an aspect… void   around () :  routedMethods() &&  voidReturnValueCalls() &&  !uiSyncMethodCalls()  { Runnable worker =  new  Runnable() { public   void  run() { proceed (); }}; EventQueue.invokeLater(worker); } only once instead of scattered over Swing client program
Some of the pointcuts pointcut  viewMethodCalls() :  call (* javax..JComponent+.*(..)); pointcut  modelMethodCalls() :  call (* javax..*Model+.*(..)) ||  call (* javax.swing.text.Document+.*(..)); pointcut  uiMethodCalls() : viewMethodCalls() || modelMethodCalls(); pointcut  uiSyncMethodCalls() : call (* javax..JOptionPane+.*(..));
Nice example of aspects: Clean solution to awkward problem Instead of polluting application code,  describe policy in one place Pointcut language is concise and intuitive
QUIZ: pointcuts are intuitive? Given types with fully qualified names a.b.c.SomeType a.b.c.SomeType.ANestedType In a.b.c.Aspect, which patterns have NO matches? SomeType *..SomeType  a.b.c.*  SomeType.ANestedType SomeType.*  ANestedType Some*.ANestedType a.b.c..ANestedType (first prize: free copy of abc; second prize: free copy of ajc)
Rules for matching type patterns The pattern is matched against the fully-qualified name of the candidate type, and matches only if that fully-qualified name is “lexically” matched by the type pattern. [imports  etc   are not taken into account] If the pattern contains no wildcards at all it matches only the type that would result from resolving the exact same string using normal Java scoping rules. Adrian Colyer : Bug 141133.
This talk Semantics of static pointcuts: Shadow labelling Pointcuts are relational queries Translating pointcuts to queries Queries beyond AspectJ Static call graph analysis Everything is a joinpoint Intercept  any  instruction Aspect interfaces Taming the (newly introduced) power POPL 2007 speculative
Semantics of static pointcuts Walker  et al. :  -  formalise shadow matching via explicit labels - operational semantics for explicit labels
From static pointcuts to label sets (0) public   class  X { void  f1(int n) { } void  f2(int n) { f1(n); } void  f3(int n) { f2(n); } public   static   void   main(String[] args) { X x = new X(); x.f3(0); x.f2(1); } } aspect  A { pointcut  a ( int  n) :  call (* f*(..))  &&  args (n) &&  cflowbelow ( execution (* f3(..))); before ( int  n) : a(n) { System.out.println( thisJoinPoint  + ": n="+n); } }
From static pointcuts to label sets (1) public   class  X { void  f1(int n) { L1:{} } void  f2(int n) {  L2: { L3:  { f1(n); } } } void  f3(int n) { L4 : {L5: { f2(n); } } } public   static   void   main(String[] args) {   L6 : {  X x = L7 : {new X()};   L8 : {x.f3(0)};   L9 : {x.f2(1)}; } } aspect  A { pointcut  a ( int  n) :  label (L3,L5,L8,L9)  // call (* f*(..))   &&  args (n) &&  cflowbelow ( label (L4)  // execution (* f3(..)) ); before ( int  n) : a(n) { System.out.println( thisJoinPoint  + ": n="+n); } }
Pointcuts are queries (0) Store program as a set of primitive relations,  e.g. methodDecl( MethodId , Name , Sig , DeclType , RetType ) callShadow( ShadowId , Method , ReceiverType ) executionShadow( ShadowId , Method ) (Naïve) query for  pointcut “ call (* f*(..))”  : p( S )  Ã   9   M  :  method ,  N  :  string  . callShadow( S ,  M , _), methodDecl( M ,  N , _, _, _), regexpmatch(’f.*’,  N ).
Pointcuts are queries (1) Store program as a set of primitive relations,  e.g. methodDecl( MethodId , Name , Sig , DeclType , RetType ) callShadow( ShadowId , Method , ReceiverType ) executionShadow( ShadowId , Method ) (Naïve) query for  pointcut “ execution (* f3(..))”  : p( S )  Ã   9   M  :  method ,  N  :  string  . executionShadow( S ,  M ), methodDecl( M ,  N , _, _, _), regexpmatch(’f3’,  N ).
Overview of semantics Find shadows, store in database relations Take pointcuts, rewrite to queries [set of 90 simple rewrite rules]  Run queries Results are instrumentation points
Query language: Datalog Series of backward implications p(X 1  : t 1 , X 2  : t 2 , … , X n  : t n )  Ã   q 1 (Y 1 , .., Y k ), … , q m (Z 1 , .., Z j ) . Conjunctions indicated by comma Disjunctions indicated by semi-colon Query itself is formula with free variables
Powered by Tarski (1902-1983) (subject to mild restrictions) “ least solution” of implications all queries terminate all queries have a finite result NO surprises  very deeply investigated in    theory of databases
Datalog has two kinds of relations Primitive: stored in database   relational representation of program Rules: implication rules written in program   e.g.  for testing transitive subtype relation
Example rule hasSubtype*( T  :  type ,  T  :  type ) . hasSubtype*( T  :  type ,  S  :  type )  Ã 9   U  :  type  .  hasSubtype( T ,  U ), hasSubtype*( U ,  S ) . hasSubtype is primitive (= stored in database)
Mapping pointcuts to queries Given pointcut  pc Define query pcq ( Context  :  type ,  S  :  shadow )  which is true precisely when shadow  S matches pointcut  pc  declared in type  Context [ Context  is needed for name resolution, Quiz 1]
Example: call  versus  execution class  A {  void  m() {} } class  B  extends  A {} class  C  extends  B {  void  m() {} } pointcut  c() :  call (* B.m(..)); pointcut  e() :  execution (* B.m(..)); (new A()).m(); (new B()).m(); (new C()).m(); QUIZ 2: Where does c() match? Where does e() match?
Query for  c() :  call (* B.m(..)) c( Context  :  type ,  Shadow  :  shadow )   9   M  :  method ,  Recv  :  type ,  N  :  method   . matchpat( Context ,  M ,  Recv ) , overrides( N ,  M ) , callShadow( Shadow ,  N ,  Recv )  . reflexive relation overrides(N,M)
Matching method patterns matchpat( Context  :  type ,  M  :  method ,  Recv  :  type )   T  :  type ,  MD  :  type  . simpleTypeLookup( Context ,  ‘B’  ,  T ), hasSubtype*( T ,  Recv ), methodDecl( M , ‘ m ’ , _,  MD , _), ( ( hasStrModifier( M ,  ‘static ’),  MD = T  ) ; (  not (hasStrModifier( M ,  ‘static’  )),  hasSubtype*( MD ,  T ) ) )  .
Query for  e() :  execution (* B.m(..)) e( Context   :  type ,  Shadow  :  shadow )      M  :  method ,  Recv  :  type ,  N  :  method  . matchpat( Context ,  M ,  Recv ), overrides( N ,  M ), hasChild( Recv ,  N ),  executionShadow( Shadow , N )  . difference with call
Semantics of static AspectJ pointcuts All static pointcuts covered Only 90 rewrite rules Concrete syntax implementation with Stratego
Flavour of rewrite rules (0) aj2dl (pc1 && pc2,  C ,  S )     aj2dl (pc1, C , S ),  aj2dl (pc2, C , S )  aj2dl (pc1 || pc2, C , S )    aj2dl (pc1, C , S )  ;  aj2dl (pc2, C , S ) aj2dl (not(pc), C , S )    not ( aj2dl (pc, C , S ))
Flavour of rewrite rules (1) fieldmembpat2dl (namepat..snamepat, C , R , X )  Y  :  packageOrType ,  Z  :  type ,  P  :  type  . wcnamepat2dl (namepat, Y ), hasChild+( Y ,  Z ),  hasSubtype*( P ,  Z ), hasChild( P ,  X ),  field( X ), snamepat2dl (snamepat,  X ),  hasSubtype*( Z ,  R ) . this is as complex as it gets
Implementation AspectJ program relational database (M$ SQL Server) pointcuts Datalog  program Shadow Grab (modified abc) Strip from source Stratego rewrites Matched shadows Procedural SQL CodeQuest compiler primitives
It works! 2.81 43.50 14.93 32.25 101 jigsaw 2.84 26.58 9.94 19.89 51 reweave 4.94 12.15 7.73 5.05 21 jhotdraw 4.09 9.15 7.79 5.49 10 weka Ratio = (PI + AQ + AJC) / AJC Aggregate Query (AQ) Populate + index (PI) ajc ksloc project
Should all AspectJ users learn Datalog? NO But power users will learn it…
Conclusions of pointcut semantics Datalog suitable for pinning down semantics Directly generating implementation from semantics is feasible Datalog at sweet spot between expressiveness and efficiency
Beyond AspectJ
No calls to UI methods from beans declare error  : call (* java.awt..*.*(..)) &&  within (Bean+) : “ do not call GUI methods from Bean” only catches direct calls
Catching all errors maycall+( M  :  method ,  N  :  method )  Ã maycall( M , N ) ; 9   K  :  method  . maycall( M , K ), maycall+( K , N ). declare warning   at   M  : 9   T  :  type  . bean( T ), methodDecl( M ,_,_, T ,_,_), 9   N  :  method  . maycall+( M , N ), guiMethod( N ): “ may be calling a GUI method from this method”
Other applications Advise methods that  “may change the state of class C” Find security flaws (PQL, Martin et al) Many more in LogicAJ papers BUT: we are limited by the joinpoint model of AspectJ
Everything is a joinpoint
The 11 joinpoint kinds of AspectJ Method call Method execution Constructor call Constructor execution Static initializer execution Object pre-initialization Object initialization Field read Field write Handler execution Advice execution Why are these the right choice?
Joinpoints = Jimple instructions int  foo(int x, int y) { if  (x<y)    return  (y-x); else   return  (x-y); } int  foo( int ,  int ) {   Example this; int x, y, $i0, $i1; this := @this:Example; x := @parameter0: int; y := @parameter1: int; if  x >= y  goto  label0; $i0 = y - x; return  $i0; label0: $i1 = x - y; return  $i1; } Java: Jimple: Jimple: a typed, 3-address, stack-less representation of bytecode
Advantages of Joinpoints = Jimple Points-to analysis in Datalog [ Whaley et al ], and based on that many more complex analyses (like precise  predicted cflow ) General dataflow pointcuts [ Masuhara et al ] Jimple has been designed to make static analyses easy
Disadvantage of Jimple = Joinpoints complete loss of encapsulation AspectJ does not have encapsulation, but now the problem is even worse…
Aspect Interfaces User control over visible joinpoints   e.g.  hide non-AspectJ joinpoints Datalog for semantics-based control   e.g.  only allow ‘pure’ aspects to advise
Open modules aspects aspects aspects aspects classes Open module: specifies what can be advised by which aspect
An example open module module  FigureModule { class  Point,Figure; advertise  : call(Figure Figure.translate(int,int)); expose to   MoveTrackAspect : call (* Point.translate(int,int)) &&  within (Figure); } classes that are affected only external calls are advised MoveTrackAspect may advise the specified joinpoints
Opening modules for debugging module  Debug { open  FigureModule; expose to  debug.* :  call (* *.*(..)); } another form of module inclusion  constrains  included module
Datalog for semantics-based control expose to  <aspect-query> : <event-query> Current abc: aspect-query =  classname pattern expression event-query =  pointcut Using datalog queries, can express: pureaspect(A)  =  A’s only side effect is writing to System.err then expose to  pureaspect(A) : call(* mysys..*(..))
Hiding non-AspectJ shadows (0) Predicate for each AspectJ shadow: callShadow( S , M , R ); setShadow( S , F , R ); … These are defined in terms of primitive relations  that store Jimple instructions Define new predicate aspectj(S)     (    M ,  R  : callShadow( S , M , R )) ; (    F ,  R  : setShadow( S , F , R )); …
Hiding non-AspectJ joinpoints (1) module  AspectJVisibility { constrain  existingModule; expose (S)  aspectjShadows(S) ; } only expose AspectJ joinpoints from an existing module:
Discussion points Expose Datalog to power users? via new syntax + rewrite rules better Datalog syntax Whole program accessible via pointcuts? via AST via IR such as Jimple How do we recover encapsulation? Open modules Datalog to give semantic hiding conditions

Pointcuts and Analysis

  • 1.
    Pointcuts and AnalysisOege de Moor, Oxford on behalf of the abc team: Pavel Avgustinov, Eric Bodden, Torbj ő rn Ekman, Elnar Hajiyev, Laurie Hendren, Ond ř ej Lhot á k, Oege de Moor, Neil Ongkingco, Damien Sereni, Ganesh Sittampalam, Julian Tibble
  • 2.
    Swing thread safety(Ramnivas Laddad) Once a component is visible only the event-dispatching thread can safely access or modify the state of the realized component. (but some methods are exempt)
  • 3.
    Doing it byhand… interface Runnable { void run(); } asynchronous invocation: EventQueue.invokeLater(Runnable run) synchronous invocation: EventQueue.invokeAndWait(Runnable run)
  • 4.
    With an aspect…void around () : routedMethods() && voidReturnValueCalls() && !uiSyncMethodCalls() { Runnable worker = new Runnable() { public void run() { proceed (); }}; EventQueue.invokeLater(worker); } only once instead of scattered over Swing client program
  • 5.
    Some of thepointcuts pointcut viewMethodCalls() : call (* javax..JComponent+.*(..)); pointcut modelMethodCalls() : call (* javax..*Model+.*(..)) || call (* javax.swing.text.Document+.*(..)); pointcut uiMethodCalls() : viewMethodCalls() || modelMethodCalls(); pointcut uiSyncMethodCalls() : call (* javax..JOptionPane+.*(..));
  • 6.
    Nice example ofaspects: Clean solution to awkward problem Instead of polluting application code, describe policy in one place Pointcut language is concise and intuitive
  • 7.
    QUIZ: pointcuts areintuitive? Given types with fully qualified names a.b.c.SomeType a.b.c.SomeType.ANestedType In a.b.c.Aspect, which patterns have NO matches? SomeType *..SomeType a.b.c.* SomeType.ANestedType SomeType.* ANestedType Some*.ANestedType a.b.c..ANestedType (first prize: free copy of abc; second prize: free copy of ajc)
  • 8.
    Rules for matchingtype patterns The pattern is matched against the fully-qualified name of the candidate type, and matches only if that fully-qualified name is “lexically” matched by the type pattern. [imports etc are not taken into account] If the pattern contains no wildcards at all it matches only the type that would result from resolving the exact same string using normal Java scoping rules. Adrian Colyer : Bug 141133.
  • 9.
    This talk Semanticsof static pointcuts: Shadow labelling Pointcuts are relational queries Translating pointcuts to queries Queries beyond AspectJ Static call graph analysis Everything is a joinpoint Intercept any instruction Aspect interfaces Taming the (newly introduced) power POPL 2007 speculative
  • 10.
    Semantics of staticpointcuts Walker et al. : - formalise shadow matching via explicit labels - operational semantics for explicit labels
  • 11.
    From static pointcutsto label sets (0) public class X { void f1(int n) { } void f2(int n) { f1(n); } void f3(int n) { f2(n); } public static void main(String[] args) { X x = new X(); x.f3(0); x.f2(1); } } aspect A { pointcut a ( int n) : call (* f*(..)) && args (n) && cflowbelow ( execution (* f3(..))); before ( int n) : a(n) { System.out.println( thisJoinPoint + &quot;: n=&quot;+n); } }
  • 12.
    From static pointcutsto label sets (1) public class X { void f1(int n) { L1:{} } void f2(int n) { L2: { L3: { f1(n); } } } void f3(int n) { L4 : {L5: { f2(n); } } } public static void main(String[] args) { L6 : { X x = L7 : {new X()}; L8 : {x.f3(0)}; L9 : {x.f2(1)}; } } aspect A { pointcut a ( int n) : label (L3,L5,L8,L9) // call (* f*(..)) && args (n) && cflowbelow ( label (L4) // execution (* f3(..)) ); before ( int n) : a(n) { System.out.println( thisJoinPoint + &quot;: n=&quot;+n); } }
  • 13.
    Pointcuts are queries(0) Store program as a set of primitive relations, e.g. methodDecl( MethodId , Name , Sig , DeclType , RetType ) callShadow( ShadowId , Method , ReceiverType ) executionShadow( ShadowId , Method ) (Naïve) query for pointcut “ call (* f*(..))” : p( S ) Ã 9 M : method , N : string . callShadow( S , M , _), methodDecl( M , N , _, _, _), regexpmatch(’f.*’, N ).
  • 14.
    Pointcuts are queries(1) Store program as a set of primitive relations, e.g. methodDecl( MethodId , Name , Sig , DeclType , RetType ) callShadow( ShadowId , Method , ReceiverType ) executionShadow( ShadowId , Method ) (Naïve) query for pointcut “ execution (* f3(..))” : p( S ) Ã 9 M : method , N : string . executionShadow( S , M ), methodDecl( M , N , _, _, _), regexpmatch(’f3’, N ).
  • 15.
    Overview of semanticsFind shadows, store in database relations Take pointcuts, rewrite to queries [set of 90 simple rewrite rules] Run queries Results are instrumentation points
  • 16.
    Query language: DatalogSeries of backward implications p(X 1 : t 1 , X 2 : t 2 , … , X n : t n ) Ã q 1 (Y 1 , .., Y k ), … , q m (Z 1 , .., Z j ) . Conjunctions indicated by comma Disjunctions indicated by semi-colon Query itself is formula with free variables
  • 17.
    Powered by Tarski(1902-1983) (subject to mild restrictions) “ least solution” of implications all queries terminate all queries have a finite result NO surprises very deeply investigated in theory of databases
  • 18.
    Datalog has twokinds of relations Primitive: stored in database relational representation of program Rules: implication rules written in program e.g. for testing transitive subtype relation
  • 19.
    Example rule hasSubtype*(T : type , T : type ) . hasSubtype*( T : type , S : type ) Ã 9 U : type . hasSubtype( T , U ), hasSubtype*( U , S ) . hasSubtype is primitive (= stored in database)
  • 20.
    Mapping pointcuts toqueries Given pointcut pc Define query pcq ( Context : type , S : shadow ) which is true precisely when shadow S matches pointcut pc declared in type Context [ Context is needed for name resolution, Quiz 1]
  • 21.
    Example: call versus execution class A { void m() {} } class B extends A {} class C extends B { void m() {} } pointcut c() : call (* B.m(..)); pointcut e() : execution (* B.m(..)); (new A()).m(); (new B()).m(); (new C()).m(); QUIZ 2: Where does c() match? Where does e() match?
  • 22.
    Query for c() : call (* B.m(..)) c( Context : type , Shadow : shadow )  9 M : method , Recv : type , N : method . matchpat( Context , M , Recv ) , overrides( N , M ) , callShadow( Shadow , N , Recv ) . reflexive relation overrides(N,M)
  • 23.
    Matching method patternsmatchpat( Context : type , M : method , Recv : type )   T : type , MD : type . simpleTypeLookup( Context , ‘B’ , T ), hasSubtype*( T , Recv ), methodDecl( M , ‘ m ’ , _, MD , _), ( ( hasStrModifier( M , ‘static ’), MD = T ) ; ( not (hasStrModifier( M , ‘static’ )), hasSubtype*( MD , T ) ) ) .
  • 24.
    Query for e() : execution (* B.m(..)) e( Context : type , Shadow : shadow )   M : method , Recv : type , N : method . matchpat( Context , M , Recv ), overrides( N , M ), hasChild( Recv , N ), executionShadow( Shadow , N ) . difference with call
  • 25.
    Semantics of staticAspectJ pointcuts All static pointcuts covered Only 90 rewrite rules Concrete syntax implementation with Stratego
  • 26.
    Flavour of rewriterules (0) aj2dl (pc1 && pc2, C , S )  aj2dl (pc1, C , S ), aj2dl (pc2, C , S ) aj2dl (pc1 || pc2, C , S )  aj2dl (pc1, C , S ) ; aj2dl (pc2, C , S ) aj2dl (not(pc), C , S )  not ( aj2dl (pc, C , S ))
  • 27.
    Flavour of rewriterules (1) fieldmembpat2dl (namepat..snamepat, C , R , X )  Y : packageOrType , Z : type , P : type . wcnamepat2dl (namepat, Y ), hasChild+( Y , Z ), hasSubtype*( P , Z ), hasChild( P , X ), field( X ), snamepat2dl (snamepat, X ), hasSubtype*( Z , R ) . this is as complex as it gets
  • 28.
    Implementation AspectJ programrelational database (M$ SQL Server) pointcuts Datalog program Shadow Grab (modified abc) Strip from source Stratego rewrites Matched shadows Procedural SQL CodeQuest compiler primitives
  • 29.
    It works! 2.8143.50 14.93 32.25 101 jigsaw 2.84 26.58 9.94 19.89 51 reweave 4.94 12.15 7.73 5.05 21 jhotdraw 4.09 9.15 7.79 5.49 10 weka Ratio = (PI + AQ + AJC) / AJC Aggregate Query (AQ) Populate + index (PI) ajc ksloc project
  • 30.
    Should all AspectJusers learn Datalog? NO But power users will learn it…
  • 31.
    Conclusions of pointcutsemantics Datalog suitable for pinning down semantics Directly generating implementation from semantics is feasible Datalog at sweet spot between expressiveness and efficiency
  • 32.
  • 33.
    No calls toUI methods from beans declare error : call (* java.awt..*.*(..)) && within (Bean+) : “ do not call GUI methods from Bean” only catches direct calls
  • 34.
    Catching all errorsmaycall+( M : method , N : method ) Ã maycall( M , N ) ; 9 K : method . maycall( M , K ), maycall+( K , N ). declare warning at M : 9 T : type . bean( T ), methodDecl( M ,_,_, T ,_,_), 9 N : method . maycall+( M , N ), guiMethod( N ): “ may be calling a GUI method from this method”
  • 35.
    Other applications Advisemethods that “may change the state of class C” Find security flaws (PQL, Martin et al) Many more in LogicAJ papers BUT: we are limited by the joinpoint model of AspectJ
  • 36.
    Everything is ajoinpoint
  • 37.
    The 11 joinpointkinds of AspectJ Method call Method execution Constructor call Constructor execution Static initializer execution Object pre-initialization Object initialization Field read Field write Handler execution Advice execution Why are these the right choice?
  • 38.
    Joinpoints = Jimpleinstructions int foo(int x, int y) { if (x<y) return (y-x); else return (x-y); } int foo( int , int ) { Example this; int x, y, $i0, $i1; this := @this:Example; x := @parameter0: int; y := @parameter1: int; if x >= y goto label0; $i0 = y - x; return $i0; label0: $i1 = x - y; return $i1; } Java: Jimple: Jimple: a typed, 3-address, stack-less representation of bytecode
  • 39.
    Advantages of Joinpoints= Jimple Points-to analysis in Datalog [ Whaley et al ], and based on that many more complex analyses (like precise predicted cflow ) General dataflow pointcuts [ Masuhara et al ] Jimple has been designed to make static analyses easy
  • 40.
    Disadvantage of Jimple= Joinpoints complete loss of encapsulation AspectJ does not have encapsulation, but now the problem is even worse…
  • 41.
    Aspect Interfaces Usercontrol over visible joinpoints e.g. hide non-AspectJ joinpoints Datalog for semantics-based control e.g. only allow ‘pure’ aspects to advise
  • 42.
    Open modules aspectsaspects aspects aspects classes Open module: specifies what can be advised by which aspect
  • 43.
    An example openmodule module FigureModule { class Point,Figure; advertise : call(Figure Figure.translate(int,int)); expose to MoveTrackAspect : call (* Point.translate(int,int)) && within (Figure); } classes that are affected only external calls are advised MoveTrackAspect may advise the specified joinpoints
  • 44.
    Opening modules fordebugging module Debug { open FigureModule; expose to debug.* : call (* *.*(..)); } another form of module inclusion constrains included module
  • 45.
    Datalog for semantics-basedcontrol expose to <aspect-query> : <event-query> Current abc: aspect-query = classname pattern expression event-query = pointcut Using datalog queries, can express: pureaspect(A) = A’s only side effect is writing to System.err then expose to pureaspect(A) : call(* mysys..*(..))
  • 46.
    Hiding non-AspectJ shadows(0) Predicate for each AspectJ shadow: callShadow( S , M , R ); setShadow( S , F , R ); … These are defined in terms of primitive relations that store Jimple instructions Define new predicate aspectj(S)  (  M , R : callShadow( S , M , R )) ; (  F , R : setShadow( S , F , R )); …
  • 47.
    Hiding non-AspectJ joinpoints(1) module AspectJVisibility { constrain existingModule; expose (S) aspectjShadows(S) ; } only expose AspectJ joinpoints from an existing module:
  • 48.
    Discussion points ExposeDatalog to power users? via new syntax + rewrite rules better Datalog syntax Whole program accessible via pointcuts? via AST via IR such as Jimple How do we recover encapsulation? Open modules Datalog to give semantic hiding conditions