New things!
shared library (potential exhibit) + “wide” quantification (dynamic-analysis-like)
xpi Jps { joinpointtype Object Creations(Class c); // pointcut library of "meaningful pointcuts for the JPT" pointcut creations(Class c) : call(* *.new(..)) && target(c); // other alternative joinpointtype Object Creations(Class c) defaults: call(* *.new(..)) && target(c); } module Collections { contains java.util.*; potentially-exhibits Object Jps.Creations(Class c) : creations(c); //alternative using the default potentially-exhibits Jps.Creations; } module M1 { contains C; } class C { void foo() { m = new HashMap(); m.add(x); // creates objects within Collections ... } } module M2 { contains C; exhibits Object Jps.Creations(Class c) : creations(c); //alternative using the default exhibits Jps.Creations; } module Aspect { contains Asp; } aspect Asp { around Object Jps.Creations(Class c) { if (shouldBeCached(c)) ...pool... else return proceed(c); } } RESULT: Asp does not see HashEntry creations caused by C@M1. Asp sees HashEntry creations caused by C@M2, as well as the HashMap creation in C.
symmetric case, beyond levels (topological scoping a la membranes)
module Prof { contains prof.*; advises Base, Racer; } module Base { contains ...; exhibits Jps.Creations(..) : ... exhibits Jps.FieldAccesses(..) : ... } module Racer { contains racer.*; advises Base; exhibits Jps.Creations(..) : ... } RESULT: Prof sees creations in both base and racer (not feasible with levels without reintroducing loops)
now with transitive topological usage
module Prof { advises M1; } module M1 { contains D (that calls objects in M3) exhibits X; uses M3; } module M2 { contains C (that calls objects in M3) } module M3 { exhibits X; } RESULT: Usage of M2 does not trigger X jps visible by Prof. Instances of X in M3 are generated and seen by Prof only in the cflow of M1. (removing "uses M3" in M1 would avoid this)