LogicAJ Pointcuts

Logic Meta-Variables

The main distinction between LogicAJ and AspectJ is LogicAJ's concept of logic meta-variables:

  • A logic meta-variable (LMV) is a metavariable that matches one base language element (e.g. a field access). Syntactically, it is an identifier with a prepended question mark: LMV ::=?Identifier
  • A logic list meta-variable (LLMV) is a metavariable that matches a list of base langauge elements (e.g. a parameter list). Syntactically, it is an identifier with two prepended question marks: LLMV ::=??Identifier

Meta-variables are like named wildcards. Unlike with wildcards, one can refer to the value matched by a meta-variable by using the same meta-variable in another expression within the same scope. All occurrences of the same meta-variable in a scope must match the same value.

If a meta-variable occurs only once in a scope it can be replaced by the “anonymous” metavariable, whose name is the underscore: ”?_”. Every occurrence of the anonymous meta-variable is considered to be a different meta-variable (matches of the anonymous metavariable do not need to agree on the matched value). The underscore can also be used as an anonymous list meta-variable, ”??_”.

Anonymous meta-variables are the equivlent of simple wildcards. ”?_” is equivalent to ”*” and ”??_” is equivalent to ”..”. Although meta-variables subsume wildcards, the AspectJ-like wildcard syntax is supported in LogicAJ for backward compatibility and for the convenience of former AspectJ programmers.

Valid Bindings

A “binding” is a value for a meta-variable. Valid (component) types for meta-variables bindings are:

  • string - String literals (“value”)
  • float - float values
  • int - integer values
  • identifier - a Java identifier
  • type - fully qualified names (e.g. java.lang.Object)
  • param - method parameters (e.g. ??params in method( ?_ ?type.??params(..))
  • expr - expressions (e.g. ??args in args(??args) )

Checking the type of meta-variables is done at weave-time, not at compile-time of individual aspects. So you will get weaving errors if e.g. a variable of type identifier is used in an arithmetic expression. However, you will never get run-time exceptions because of wrong types, as would be the case if you used reflection. Compile-time checking of meta-variable types will be part of a future release.

You may use fully qualified names, identifiers or strings where a value of type type is expected and vice versa. The value will be automatically converted, e.g.:

type(?stringType) &&
equals(?stringType, java.lang.String)

is equivalent to

equals(?stringType, "java.lang.String")

Also an automatic conversion is attempted for string values used in arithmetic expressions. Of course, this will result in a weaving error if the value can not be converted.

Patterns with Metavariables

Meta-variables and list meta-variables can be used in advice, introductions and the patterns of pointcuts. In patterns, they can be used (at least) wherever wildcards (*, **, or ..) can be used in AspectJ:

MethodPat ::=
        [ ModifiersPat ] TypePat TypePat . NamePat ( [ ArgOrParamListPat ] ) [ throws TypeListPat ]
FieldPat ::=
        [ ModifiersPat ] TypePat TypePat . NamePat
TypeListPat ::=
       
TypePat ( , TypePat)*
TypePat::=
         ( NamePat . )* NamePat ( [] )*
        |  ! TypePat
        |  TypePat && TypePat
        |  TypePat || TypePat
ArgOrParamListPat ::=
       
ArgOrParamPat ( , ArgOrParamPat ) *
ArgOrParamPat
::=
       TypePat

       | AdviceParamName
       | ..
       
| LLMV
AdviceParamName ::=
       Identifier
NamePat ::=
           LMV
         |
( *| \? | Identifier )+
ModifiersPat::=
           LLMV
         |
( [ ! ] Modifier )+
Modifier::=
           public
         |
protected
        
...
         | volatile

Pointcuts Documentation

Below, the type of an argument is postfixed to the argument name separated by a colon. If the type is omitted arbitrary meta-variable types can be used. See also the the Valid Bindings paragraph above.

Selective Pointcuts With Metavariables

General SyntaxExamples
call(MethodPat|ConstructorPat)call ( void Foo.m(int) )
a call to the method void Foo.m(int)
call ( Foo.new(..) )
a call to any constructor of Foo
execution(MethodPat|ConstructorPat)execution ( * Foo.*(..) throws IOException )
the execution of any method of Foo that is declared to throw IOException
execution ( !public Foo .new(..) )
the execution of any non-public constructor of Foo
withincode(MethodPat|ConstructorPat)withincode ( void Figure.move() )
any join point where the associated code is defined in the method void Figure.move()
get(FieldPat)get ( int Point.x )
when int Point.x is read
set(FieldPat)set ( !private * Point.* )
when any field of Point is assigned
within(TypePat)within( com.bigboxco.* )
any join point where the associated code is defined in the package com.bigboxco
target(TypePat | Var)target( java.io.InputPort )
any join point where the target (receiver) object is an instance of java.io.InputPort
The target pointcut can also be used to bind advice parameters: after(Object o) : call(..) && target(o) {...}
this(TypePat | Var)this( Point )
any join point where the currently executing object is an instance of Point
args(ArgsPat)args( java.io.InputPort, int )any join point where there are two arguments,
the first an instance of java.io.InputPort, and the second an int

args( *, int )
any join point where there are two arguments,
the second of which is an int.

args( short, .., short )
any join point with at least two arguments, the first and last of which are shorts
receiverIsThis()checks that the receiver of the join point is this

Predicate Pointcuts

General SyntaxExamples
equals( Arg1, Arg2)Checks if first and second argument equal
jointPoint(Arg:string)
constructName(Name:string)
replace(?String:string,?SearchCharacter:string,?ReplaceCharacter:string,?Result:string)e.g. replace("asdf","s","f","afdf"
var(?var)Checks if ?var is not bound.
debug(Message:string, ?lmv1:lmv,...)Generates trace data for the current pointcut definition, see also Pointcut Debugging
Class Member
method(MethodPat)selects matching methods and binds meta-variables in the pattern; the optional LMV binds the body of the method, e.g:
method ( void Foo.?m(int) )
    selects all method in the type Foo with return type void and int parameter;
    all method names are bound to ?m
field(FieldPat)selects matching fields and binds meta-variables in the pattern; the optional LMV binds the initializer of the field
directsubtype(Subtype:type, Supertype:type)binds Subtype to direct subtype of the second argument Supertype
subtype(Subtype:type, Supertype:type)binds Subtype to all subtypes (interfaces or classes) of the second argument Supertype
inner(InnerClass:type)binds InnerClass to inner classes
local(LocalClass:type)binds LocalClass to local classes~n e.g. void m() { class C { ...}; }
String Literal
subString(?String:string, ?Start:int, ?Length:int, ?After:int, ?Sub:string) substring maintains the following relation:Sub is a sub-string of Str that starts at Before, has Len characters and Str contains After characters after the match.
camelCase(?Identifier:identifier, ?CamelCaseIdentifier:identifier)example: camelCase(myField,MyField)
upperCase(?AnyCase:string, ?UpperCase:string)Converts the characters of ?AnyCase into upper case and binds the string to ?UpperCase.
lowerCase(?AnyCase:string, ?LowerCase:string)Converts the characters of AnyCase into lower case and binds the string to LowerCase.
stringToCharacters(?String,??Characters)Converts between a ?String and and a list of ??Characters. Characters are Strings of length one.
List
member(Member,List:list)Checks if the first argument is a member of the list bound to the second argument; the second argument must already be bound
length(List:list,Int:int)Succeeds if Int represents the number of elements of list List.
outer(Inner:type, Outer:type)Binds Outer to the outer class of an inner/local/anonymous class
split(?Head, ??TailList:list, ??List:list)Separates ??List in the ?Head element and the Tail of the list. Tail can be an empty list.
concat(Arg1:string, Arg2:string, Arg3:string)The third Arg forms the concatenation of the first and the second Arg
concat(Arg1:string, Arg2:string, Arg3:string, Arg4:string)Arg4 forms the concatenation of Arg1,..,Arg3
concat(Arg1:string, Arg2:string, Arg3:string, Arg4:string, Arg5:string)Arg5 forms the concatenation of Arg1,..,Arg4
removeElements(??RemoveElements:list, ??FromList:list, ??ResultList:list)Removes ??RemoveElements from ??FromList and binds the resulting list to ??ResultList.
Types
concreteAspect(?Type:type)Bind ?Type to the enclosing concrete aspect's class.
pattern( Arg, RegEx:string [, groupX:string] )Checks if the pattern RegEx matches the first argument.

E.g. pattern("bbacc","(.*)a(.*)",?Match1, "cc") where ?Match1 matches the first group ("aa").

Be aware: Shorthand characters like \w do not work. Use [a-z] etc. instead.

For details on the RegEx flavour see also the last paragraph of the SWI-Prolog RegEx documentation.

types(??Elements:list, ??Types:list)Unifies ??Types with the list of types of ??Elements, where Elements may contain parameter declarations or argument expressions
package(?Package:string)Unifies ?Package with the packages defined in the project
sourcetype(PType:type)Checks if Type is available in source code. Otherwise it was read from a library (as byte code). This is important since LogicAJ only weaves aspects into source classes.
typename(?Type:type,?SimpleTypeName:string)binds the type name of ?Type to ?SimpleTypeName
typepackage(?Type:type,?PackageName:string)binds the package name of ?Type to ?PackageName
packagetolist(?Package:string,??PackageNames:list)e.g. packagetolist("org.cs3", ["org","cs3"])
arrayType(?ComponentType:type, ?Arity:int, ?Type:type)e.g. arrayType("java.lang.Object[]",1, "java.lang.Object[]")
aspect(?Type:type)check if ?Type is an aspect class
type(?Type:type)selects matching types and binds meta-variables in the pattern, e.g.:
type(?type) or
type(?packagename.?name)
binds ?package to the complete package name of the package of all types and ?name to the name of the type
notice:
in future ?packagename will only bind package name parts without dots, e.g. pack1;lists of (sub-)package names may be bound with ??package,
e.g. type(??prefix.?api.internal.??rest.?classname)
class(?Class:type)like type(..), but ensures that TypePat is a class
interface(?Interface:type)Checks if ?Interface is an interface.
enum(?Enumeration:type)Checks if ?Enumeration is an enumeraration.
annotationType(?Annotation:type)Checks if ?Annotation is an annotation type.
Arithmetic
lt(Number1:int,Number2:int)True if Number1 is smaller than Number2
le(Number1:int,Number2:int)True if Number1 is smaller or equal to Number2
gt(Number1:int, Number2:int)True if Number1 is greater than Number2
ge(Number1:int, Number2:int)True if Number1 is greater or equal to Number2
ge(Number1:int, Number2:int,Sum:int)True if Sum=Number1+Number2. At least two of the three arguments must be instantiated to integers.

Last modified: 2014/08/01 19:55
*