CS 541 Meeting -*- Outline -*- * AspectJ as a language Motivation: to design and analyze aspect languages, we have to understand their semantics. This is also helpful for programming. Pass out the AspectJ "quick reference" ** Additions to Java Not a completely new language, but an add-on to Java Q: Why is that reasonable? ** how AspectJ is (currently) implemented ajc only "controls" code it is given to compile, so join points, etc. only apply to the controlled code ** patterns *** identifiers (method names, types) ------------------------------------------ IDENTIFIER (TYPE NAME) PATTERNS IdPattern ::= * | IdChars | IdPattern IdPattern | IdPattern .. IdPattern IdChars ::= IdChar | IdChars IdChar IdChar ::= a Java Identifier character | . SEMANTICS Matches: IdPattern, IdChars -> Boolean Matches(*, x) = x does not contain '.' Matches(i, x) = (x == i) and i in IdChars Matches(y z, x) = (\exists x1, x2 :: (x == x1+x2) and Matches(y,x1) and Matches(z,x2)) Matches(y .. z, x) = (\exists x1, x2, x3 :: (x == x1+x2+x3) and Matches(y,x1) and Matches(z,x3) and x2 is in IdChars and x2[0] == '.' and x2[x2.length()-1] == '.') Examples: Matches(get*X, getterX) Matches(org..Point, org.asj.Point) Matches(org..P*t, org.asj.Point) Matches(org..Point, org.Point) ------------------------------------------ The .. pattern can match a single '.' So it matches a package and all its subpackages ------------------------------------------ TYPE PATTERNS TypePattern ::= IdPattern | IdPattern + | TypePattern Arrays | ! TypePattern | TypePattern && TypePattern | TypePattern || TypePattern | ( TypePattern ) Arrays ::= [] | Arrays [] ------------------------------------------ Q: How would you formalize the meaning of this? ------------------------------------------ SIGNATURE (METHOD AND CONSTRUCTOR) PATTERNS Signature ::= MethodPattern | ConstructorPattern MethodPattern ::= Modifiers TypePattern TypeDotOpt IdPattern ( TypePatternListOpt ) ThrowsOpt ConstructorPattern ::= Modifiers TypeDotOpt new ( TypePatternListOpt ) ThrowsOpt Modifiers ::= | Modifiers TypeDotOpt ::= | TypePattern . TypePatternListOpt ::= | TypePatternList TypePatternList ::= ListTypePattern | TypePatternList , ListTypePattern ListTypePattern ::= .. | TypePattern ThrowsOpt ::= | ThrowsPattern ThrowsPattern ::= ------------------------------------------ Q: What should be the syntax of ThrowsPattern? ThrowsPattern ::= throws ETypePatternList ETypePatternList ::= TypePattern | ETypePatternList , TypePattern Q: What would be the semantics of these patterns? There are also FieldPatterns: FieldPattern ::= ModifiersPatternOpt TypePattern TypeDotOpt IdPattern Q: What kinds of patterns could we have in Smalltalk? Q: Do we have dots (packages)? Types? Formals? STIdPattern ::= * | STIdChars | STIdPattern STIdPattern | STIdPattern :: STIdPattern STIdChars ::= STIdChar | STIdChars STIdChar STIdChar ::= a Smalltalk Identifier character | : SEMANTICS Matches: STIdPattern, STIdChars -> Boolean Matches(*, x) = x does not contain ':' Matches(i, x) = (x == i), where i in STIdChars Matches(y z, x) = (\exists x1, x2 :: (x == x1+x2) and Matches(y,x1) and Matches(z,x2)) Matches(y :: z, x) = (\exists x1, x2, x3 :: (x == x1+x2+x3) and Matches(y,x1) and Matches(z,x3) and x2 is either empty or (x2 is in STIdChars and x2[0] == ':' and x2[x2.length()-1] == ':')) ** pointcuts ------------------------------------------ POINTCUT SYNTAX PointCut ::= | call(Signature) | execution(Signature) | initialization(ConstructorPattern) | preinitialization(ConstructorPattern) | staticinitialization(TypePattern) | get(FieldPattern) | set(FieldPattern) | handler(TypePattern) | adviceexecution() | within(TypePattern) | withincode(Signature) | cflow(PointCut) | cflowbelow(PointCut) | if(Expression) | this(TypePatternOrVar) | target(TypePatternOrVar) | args(TypePatternOrVarList) | PointCut && PointCut | PointCut || PointCut | ! PointCut | Id(TypePatternOrVarList) TypePatternOrVar ::= TypePattern | Id TypePatternOrVarList ::= TypePatternOrVar | .. | TypePatternOrVarList , TypePatternOrVar | TypePatternOrVarList , .. ------------------------------------------ *** call(Signature) *** execution(Signature) *** initialization(ConstructorPattern) Q: How is this different than an execution join point for a constructor? includes variable declaration initializers and instance initializer bodies Q: How does this generalize to Smalltalk? *** preinitialization(ConstructorPattern) This is for formation of arguments in super calls in constructors *** staticinitialization(TypePattern) Q: How is this different than initialization? It occurs during class loading, not at object creation time Q: Does this make sense in Smalltalk? Is it needed? *** get/set(FieldPattern) Q: Does this make sense in Smalltalk? Is it needed? *** handler(TypePattern) when an exception that matches the type pattern is handled in a catch block. Q: Does this make sense in Smalltalk? Is it needed? *** adviceexecution() mostly useful in preventing unwanted recursion, in combination with ! pointcuts *** within(TypePattern) Pointcuts in the body of types matched by the type pattern ------------------------------------------ AVOIDING INFINITE LOOPS aspect A { before() : call(* *(..)) && !within(A) { System.out.println("before"); } after() returning : call(* *(..)) && !within(A) { System.out.println("after"); } } ------------------------------------------ *** withincode(Signature) Pointcuts in the body of methods matched by the signature. *** cflow(PointCut) and cflowbelow(PointCut) **** cflow Join points in the control flow of the join points specified by Pointcut (i.e., the matched join point is earlier on the run time stack) **** cflowbelow Join points in the control flow of the join points specified by Pointcut (i.e., the matched join point is earlier on the run time stack), but not including the matched join points. **** examples ------------------------------------------ CFLOW and CFLOWBELOW EXAMPLES From Kiselev Ch. 14: public class PtrnJPMain { public void test() { System.out.println( "*** Inside test ***"); } public static void main(String args[]) { System.out.println( "*** Calling test ***"); new PtrnJPMain().test(); } } public aspect PtrnJPSelected { pointcut begin() : execution(* *.main(..)); pointcut end() : execution(void PtrnJPMain.test()); pointcut p() : cflow(begin()) && !cflowbelow(end()); before() : p() && !within(PtrnJPSelected) { System.out.println(thisJoinPoint); } } ------------------------------------------ *** if(Expression) set of join points where the expression evaluates to true "this" in the Expression refers to the aspect Q: What join points does if(true) match? *** context join points **** this(TypePatternOrVar) TypePatternOrVar ::= TypePattern | Id join points where the current "this" matches the type pattern, or the type of var **** target(TypePatternOrVar) call join points where the call is to an object of the type pattern or the type of var **** args(TypePatternOrVarList) TypePatternOrVarList ::= TypePatternOrVar | .. | TypePatternOrVarList , TypePatternOrVar | TypePatternOrVarList , .. to give the types of arguments present at a join point Q: What if you have args(.., int, ..) and a join point is a call with 2 or more int arguments? Then it's a (static) error (ambiguous match). *** discussion Q: How could we formalize the semantics of these? Q: Which of these apply to Smalltalk? ** pointcut definitions ------------------------------------------ POINTCUT DECLARATIONS AspectMemberDecl ::= PointCutDeclaration | ... PointCutDeclaration ::= Modifiers pointcut Id(Formals); | Modifiers pointcut Id(Formals) : PointCut; Modifiers ::= | Modifiers Modifier Modifiers ::= abstract | public | ... E.g., abstract aspect AA { public abstract pointcut p(); public pointcut getCalls(Object o) : call(public * get(..)); } ------------------------------------------ Q: What changes would be made in Smalltalk? ** advice ------------------------------------------ ADVICE SYNTAX AspectMemberDecl ::= PointCutDeclaration | AdviceDeclaration | ... AdviceDeclaration ::= StrictFPOpt AdviceType ThrowsListOpt : PointCut { Body } StrictFPOpt ::= | strictfp AdviceType ::= | before(Formals) | after(Formals) | after(Formals) returning ResultOpt | after(Formals) throwing ResultOpt | Type around(Formals) ResultOpt ::= | (Formal) ThrowsListOpt ::= | throws TypeList ------------------------------------------ ------------------------------------------ Examples of AdviceType: after (long x) returning after (long x) returning (long ret) after () throwing after () throwing (Exception e) int around(Stack s) throws Exception ------------------------------------------ Q: What does "this" mean in the body of advice? the aspect (not the this object in the call) Why? helps with type checking. You can get access to the this argument at the join point by using methods of thisJoinPoint. Q: What changes would be made in Smalltalk? Q: How to explain the semantics of this? *** special forms ------------------------------------------ SPECIAL FORMS IN ADVICE Expression ::= ... | thisJoinPoint | thisJoinPointStaticPart | thisEnclosingJoinPointStaticPart | proceed( Arguments ) ------------------------------------------ thisJoinPoint and variants give reflective info about the join point, it has type JoinPoint proceed takes the "same number and type" of argumets "as the parameters of the advice" (quick reference card) NB. it's not the number and type of arguments as the join point. *** syntactic sugars Q: Can we translate before and after advice into around advice? *** compilation semantics work through Kiselev's Showcase example with its output ** aspects ------------------------------------------ ASPECT SYNTAX Aspect ::= PrivilegedOpt Modifiers aspect Id ExtendsOpt ImplementsOpt PerClauseOpt { AspectBody } PrivilegedOpt ::= | privileged ExtendsOpts ::= | extends Type ImplementsOpts ::= | implements TypeList PerClauseOpts ::= | PerClause PerClause ::= pertarget (PointCut) | perthis (PointCut) | percflow (PointCut) | percflowbelow (PointCut) | issingleton AspectBody ::= | AspectBody AspectMemberDecl ------------------------------------------ Q: When must an aspect be abstract? When can it? Q: Can an aspect extend a Java class? Is that ok? Q: How would this map to Smalltalk?