From 6450c7d744c2be34767105626b70df518ac38631 Mon Sep 17 00:00:00 2001 From: Alexander Kriegisch Date: Sat, 17 Jul 2021 11:42:41 +0700 Subject: [PATCH] Finish AsciiDoc improvements in ADK Developer's Notebook (WIP) Signed-off-by: Alexander Kriegisch --- docs/adk15ProgGuideDB/adk15notebook.adoc | 26 ++-- docs/adk15ProgGuideDB/ataspectj.adoc | 113 +++++++------- docs/adk15ProgGuideDB/autoboxing.adoc | 25 ++- docs/adk15ProgGuideDB/covariance.adoc | 8 +- docs/adk15ProgGuideDB/enumeratedtypes.adoc | 2 +- docs/adk15ProgGuideDB/generics.adoc | 170 ++++++--------------- docs/adk15ProgGuideDB/grammar.adoc | 119 ++++++++------- docs/adk15ProgGuideDB/ltw.adoc | 4 +- docs/adk15ProgGuideDB/miscellaneous.adoc | 8 +- docs/adk15ProgGuideDB/pertypewithin.adoc | 2 +- docs/adk15ProgGuideDB/reflection.adoc | 2 +- docs/adk15ProgGuideDB/varargs.adoc | 29 ++-- docs/progGuideDB/language.adoc | 152 +++++++++--------- docs/progGuideDB/semantics.adoc | 6 +- 14 files changed, 299 insertions(+), 367 deletions(-) diff --git a/docs/adk15ProgGuideDB/adk15notebook.adoc b/docs/adk15ProgGuideDB/adk15notebook.adoc index bd7ed20b2..9e4594335 100644 --- a/docs/adk15ProgGuideDB/adk15notebook.adoc +++ b/docs/adk15ProgGuideDB/adk15notebook.adoc @@ -14,28 +14,28 @@ AspectJ, we recommend you start by reading the programming guide. ATTENTION: Please do not remove blank lines in between 'include::' statements. Otherwise, section numbers in the table of contents (TOC) can be wrong and the first section of each document missing completely. //// -include::joinpointsignatures.adoc[] +include::joinpointsignatures.adoc[Join Point Signatures] -include::annotations.adoc[] +include::annotations.adoc[Annotations] -include::generics.adoc[] +include::generics.adoc[Generics] -include::autoboxing.adoc[] +include::autoboxing.adoc[Autoboxing and Unboxing] -include::covariance.adoc[] +include::covariance.adoc[Covariance] -include::varargs.adoc[] +include::varargs.adoc[Varargs] -include::enumeratedtypes.adoc[] +include::enumeratedtypes.adoc[Enumerated Types] -include::pertypewithin.adoc[] +include::pertypewithin.adoc[The `pertypewithin` Aspect Instantiation Model] -include::ataspectj.adoc[] +include::ataspectj.adoc[An Annotation Based Development Style] -include::reflection.adoc[] +include::reflection.adoc[New Reflection Interfaces] -include::miscellaneous.adoc[] +include::miscellaneous.adoc[Other Changes in AspectJ 5] -include::ltw.adoc[] +include::ltw.adoc[Load-Time Weaving] -include::grammar.adoc[] +include::grammar.adoc[A Grammar for the AspectJ 5 Language] diff --git a/docs/adk15ProgGuideDB/ataspectj.adoc b/docs/adk15ProgGuideDB/ataspectj.adoc index 7f480f667..3b4d2ae59 100644 --- a/docs/adk15ProgGuideDB/ataspectj.adoc +++ b/docs/adk15ProgGuideDB/ataspectj.adoc @@ -210,7 +210,8 @@ is equivalent to... [source, java] .... -pointcut someCallWithIfTest(int i) : call(* *.*(int)) && args(i) && if(i > 0); +pointcut someCallWithIfTest(int i) : + call(* *.*(int)) && args(i) && if(i > 0); .... and the following is also a valid form: @@ -321,8 +322,7 @@ annotation style. .... @Before("call(* org.aspectprogrammer..*(..)) && this(foo)") public void callFromFoo(JoinPoint thisJoinPoint, Foo foo) { - System.out.println("Call from Foo: " + foo + " at " - + thisJoinPoint); + System.out.println("Call from Foo: " + foo + " at " + thisJoinPoint); } .... @@ -331,8 +331,7 @@ is equivalent to... [source, java] .... before(Foo foo) : call(* org.aspectprogrammer..*(..)) && this(foo) { - System.out.println("Call from Foo: " + foo + " at " - + thisJoinPoint); + System.out.println("Call from Foo: " + foo + " at " + thisJoinPoint); } .... @@ -341,9 +340,11 @@ Advice that needs all three variables would be declared: [source, java] .... @Before("call(* org.aspectprogrammer..*(..)) && this(Foo)") -public void callFromFoo(JoinPoint thisJoinPoint, - JoinPoint.StaticPart thisJoinPointStaticPart, - JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart) { +public void callFromFoo( + JoinPoint thisJoinPoint, + JoinPoint.StaticPart thisJoinPointStaticPart, + JoinPoint.EnclosingStaticPart thisEnclosingJoinPointStaticPart +) { // ... } .... @@ -388,7 +389,7 @@ after() returning(Foo f) : call(Foo+.new(..)) { } .... -(Note the use of the "pointcut=" prefix in front of the pointcut +(Note the use of the `pointcut=` prefix in front of the pointcut expression in the returning case). After throwing advice works in a similar fashion, using the `throwing` @@ -460,73 +461,63 @@ public aspect ProceedAspect { .... Note that the ProceedingJoinPoint does not need to be passed to the -proceed(..) arguments. +`proceed(..)` arguments. In code style, the proceed method has the same signature as the advice, any reordering of actual arguments to the joinpoint that is done in the advice signature must be respected. Annotation style is different. The -proceed(..) call takes, in this order: - -* If 'this()' was used in the pointcut -+ -for binding -+ -, it must be passed first in proceed(..). -* If 'target()' was used in the pointcut -+ -for binding -+ -, it must be passed next in proceed(..) - it will be the first argument -to proceed(..) if this() was not used for binding. -* Finally come -+ -all -+ -the arguments expected at the join point, in the order they are supplied -at the join point. Effectively the advice signature is ignored - it -doesn't matter if a subset of arguments were bound or the ordering was -changed in the advice signature, the proceed(..) calls takes all of them -in the right order for the join point. - -Since proceed(..) in this case takes an Object array, AspectJ cannot do +`proceed(..)` call takes, in this order: + +* If `this()` was used in the pointcut for binding, it must be passed first in + `proceed(..)`. +* If `target()` was used in the pointcut for binding, it must be passed next in + `proceed(..)` - it will be the first argument to `proceed(..)` if `this()` + was not used for binding. +* Finally come all the arguments expected at the join point, in the order they + are supplied at the join point. Effectively the advice signature is ignored - + it doesn't matter if a subset of arguments were bound or the ordering was + changed in the advice signature, the `proceed(..)` calls takes all of them + in the right order for the join point. + +Since `proceed(..)` in this case takes an `Object` array, AspectJ cannot do as much compile time checking as it can for code style. If the rules -above aren't obeyed then it will unfortunately manifest as a runtime +above aren't obeyed, then it will unfortunately manifest as a runtime error. [[ataspectj-itds]] === Inter-type Declarations Inter-type declarations are challenging to support using an annotation -style. For code style aspects compiled with the ajc compiler, the entire +style. For code style aspects compiled with the _ajc_ compiler, the entire type system can be made aware of inter-type declarations (new supertypes, new methods, new fields) and the completeness and correctness of it can be guaranteed. Achieving this with an annotation style is hard because the source code may simply be compiled with javac where the type system cannot be influenced and what is compiled must be -'pure java'. +'pure Java'. -AspectJ 1.5.0 introduced @DeclareParents, an attempt to offer something +AspectJ 1.5.0 introduced `@DeclareParents`, an attempt to offer something like that which is achievable with code style declare parents and the other intertype declarations (fields, methods, constructors). However, it has proved too challenging to get close to the expressiveness and -capabilities of code style in this area and effectively @DeclareParents -is offering just a mixin strategy. The definition of mixin I am using -here is that when some interface I is mixed into some target type T then -this means that all the methods from I are created in T and their +capabilities of code style in this area and effectively `@DeclareParents` +is offering just a mixin strategy. The definition of mixin `I` am using +here is that when some `interface I` is mixed into some target type `T` then +this means that all the methods from `I` are created in `T` and their implementations are simple forwarding methods that call a delegate which -that provides an implementation of I. +that provides an implementation of `I`. -The next section covers @DeclareParents but AspectJ 1.6.4 introduces -@DeclareMixin - an improved approach to defining a mixin and the choice +The next section covers `@DeclareParents` but AspectJ 1.6.4 introduces +`@DeclareMixin` - an improved approach to defining a mixin and the choice of a different name for the annotation will hopefully alleviate some of -the confusion about why @DeclareParents just doesn't offer the same -semantics as the code style variant. Offering @DeclareMixin also gives +the confusion about why `@DeclareParents` just doesn't offer the same +semantics as the code style variant. Offering `@DeclareMixin` also gives code style developers a new tool for a simple mixin whereas previously -they would have avoided @DeclareParents thinking what it could only do +they would have avoided `@DeclareParents`, thinking what it could only do was already achievable with code style syntax. -The defaultImpl attribute of @DeclareParents may become deprecated if -@DeclareMixin proves popular, leaving @DeclareParents purely as a way to +The `defaultImpl` attribute of `@DeclareParents` may become deprecated if +`@DeclareMixin` proves popular, leaving `@DeclareParents` purely as a way to introduce a marker interface. [[atDeclareParents]] @@ -595,13 +586,13 @@ public class MoodIndicator { This is very similar to the mixin mechanism supported by AspectWerkz. The effect of the `@DeclareParents` annotation is equivalent to a declare parents statement that all types matching the type pattern -implement the given interface (in this case Moody). Each method declared +implement the given interface (in this case `Moody`). Each method declared in the interface is treated as an inter-type declaration. Note how this scheme operates within the constraints of Java type checking and ensures that `this` has access to the exact same set of members as in the code style example. -Note that it is illegal to use the @DeclareParents annotation on an +Note that it is illegal to use the `@DeclareParents` annotation on an aspect' field of a non-interface type. The interface type is the inter-type declaration contract that dictates which methods are declared on the target type. @@ -680,7 +671,7 @@ and a method that returns the mood. Within the body of the inter-type declared method `getMoody`, the type of `this` is `Moody` (the target type of the inter-type declaration). -Using the annotation style this aspect can be written: +Using the annotation style, this aspect can be written: [source, java] .... @@ -779,7 +770,7 @@ public class Foo { Although the interface type is usually determined purely from the return type of the factory method, it can be specified in the annotation if necessary. In this example the return type of the method extends -multiple other interfaces and only a couple of them (I and J) should be +multiple other interfaces and only a couple of them (`I` and `J`) should be mixed into any matching targets: [source, java] @@ -805,14 +796,13 @@ delegate forwarding methods created in the matched target type. === Declare statements The previous section on inter-type declarations covered the case of -declare parents ... implements. The 1.5.0 release of AspectJ 5 does not -support annotation style declarations for declare parents ... extends -and declare soft (programs with these declarations would not in general +`declare parents ...` implements. The 1.5.0 release of AspectJ 5 does not +support annotation style declarations for `declare parents ... extends` +and `declare soft` (programs with these declarations would not in general be compilable by a regular Java 5 compiler, reducing the priority of their implementation). These may be supported in a future release. -Declare annotation is also not supported in the 1.5.0 release of AspectJ -5. +Declare annotation is also not supported in the 1.5.0 release of AspectJ 5. Declare precedence _is_ supported. For declare precedence, use the `@DeclarePrecedence` annotation as in the following example: @@ -821,7 +811,6 @@ Declare precedence _is_ supported. For declare precedence, use the .... public aspect SystemArchitecture { declare precedence : Security*, TransactionSupport, Persistence; - // ... } .... @@ -871,12 +860,12 @@ static final String badIFooImplementors = "Only foo types can implement IFoo"; @DeclareError("execution(* IFoo+.*(..)) && !within(org.foo..*)") static final String badIFooImplementorsCorrupted = getMessage(); static String getMessage() { - return "Only foo types can implement IFoo " + System.currentTimeMillis(); + return "Only foo types can implement IFoo " + System.currentTimeMillis(); } .... [[ataspectj-aspectof]] -=== aspectOf() and hasAspect() methods +=== `aspectOf()` and `hasAspect()` methods A central part of AspectJ's programming model is that aspects written using the code style and compiled using ajc support `aspectOf` and diff --git a/docs/adk15ProgGuideDB/autoboxing.adoc b/docs/adk15ProgGuideDB/autoboxing.adoc index 8426ea45f..fa3842950 100644 --- a/docs/adk15ProgGuideDB/autoboxing.adoc +++ b/docs/adk15ProgGuideDB/autoboxing.adoc @@ -5,8 +5,8 @@ === Autoboxing and Unboxing in Java 5 Java 5 (and hence AspectJ 1.5) supports automatic conversion of -primitive types (int, float, double etc.) to their object equivalents -(Integer, Float, Double,...) in assignments and method and constructor +primitive types (`int`, `float`, `double` etc.) to their object equivalents +(`Integer`, `Float`, `Double` etc.) in assignments and method and constructor invocations. This conversion is know as autoboxing. Java 5 also supports automatic unboxing, where wrapper types are @@ -18,9 +18,8 @@ For example: [source, java] .... int i = 0; -i = new Integer(5); // auto-unboxing - -Integer i2 = 5; // autoboxing +i = new Integer(5); // auto-unboxing +Integer i2 = 5; // autoboxing .... [[autoboxing-in-aspectj5]] @@ -43,13 +42,13 @@ autoboxing and unboxing in determining argument matching. In other words, `args(Integer)` will match any join point at which there is a single argument of type `Integer` or of type `int`. -* args(Integer) and args(int) are equivalent -* args(Float) and args(float) are equivalent -* args(Double) and args(double) are equivalent -* args(Short) and args(short) are equivalent -* args(Byte) and args(byte) are equivalent -* args(Long) and args(long) are equivalent -* args(Boolean) and args(boolean) are equivalent +* `args(Integer)` and `args(int)` are equivalent +* `args(Float)` and `args(float)` are equivalent +* `args(Double)` and `args(double)` are equivalent +* `args(Short)` and `args(short)` are equivalent +* `args(Byte)` and `args(byte)` are equivalent +* `args(Long)` and `args(long)` are equivalent +* `args(Boolean)` and `args(boolean)` are equivalent Autoboxing and unboxing are also applied when binding pointcut or advice parameters, for example: @@ -59,7 +58,7 @@ parameters, for example: pointcut foo(int i) : args(i); before(Integer i) : foo(i) { - ... + // ... } .... diff --git a/docs/adk15ProgGuideDB/covariance.adoc b/docs/adk15ProgGuideDB/covariance.adoc index 793b134f2..2349bf52c 100644 --- a/docs/adk15ProgGuideDB/covariance.adoc +++ b/docs/adk15ProgGuideDB/covariance.adoc @@ -64,13 +64,13 @@ Following the join point matching rules given in xref:joinpointsignatures.adoc#j `call(A B.whoAreYou())`:: Does not match anything - neither of the call join points has a signature matched by this pattern. A lint warning is given for the - call `a.whoAreYou()` ("does not match because declaring type is A, if - match required use target(B)"). + call `a.whoAreYou()` ("does not match because declaring type is `A`, if + match required use ``target(B)``"). `call(A+ B.whoAreYou())`:: Matches the call to `b.whoAreYou()` since the signature pattern matches the signature `B B.whoAreYou()`. A lint warning is given for - the call `a.whoAreYou()` ("does not match because declaring type is A, - if match required use target(B)"). + the call `a.whoAreYou()` ("does not match because declaring type is `A`, + if match required use ``target(B)``"). `call(B A.whoAreYou())`:: Does not match anything since neither join point has a signature matched by this pattern. diff --git a/docs/adk15ProgGuideDB/enumeratedtypes.adoc b/docs/adk15ProgGuideDB/enumeratedtypes.adoc index 1149d06f3..64a96d2f6 100644 --- a/docs/adk15ProgGuideDB/enumeratedtypes.adoc +++ b/docs/adk15ProgGuideDB/enumeratedtypes.adoc @@ -31,7 +31,7 @@ does. Because of the special restrictions Java 5 places around enumerated types, AspectJ makes the following additional restrictions: * You cannot use declare parents to change the super type of an enum. -* You cannot use declare parents to declare java.lang.Enum as the parent +* You cannot use declare parents to declare `java.lang.Enum` as the parent of any type. * You cannot make inter-type constructor declarations on an enum. * You cannot extend the set of values in an enum via any ITD-like diff --git a/docs/adk15ProgGuideDB/generics.adoc b/docs/adk15ProgGuideDB/generics.adoc index 7d1c41a57..8fc99bdbe 100644 --- a/docs/adk15ProgGuideDB/generics.adoc +++ b/docs/adk15ProgGuideDB/generics.adoc @@ -251,80 +251,20 @@ defines the rules for determing the erasure of a type as follows. Let `|T|` represent the erasure of some type `T`. Then: -The erasure of a parameterized type +* The erasure of a parameterized type `T` is `|T|`. + For example, the erasure of `List` is `List`. -T +* The erasure of a nested type `T.C` is `|T|.C`. + For example, the erasure of the nested type `Foo.Bar` is `Foo.Bar`. -is +* The erasure of an array type `T[]` is `|T|[]`. + For example, the erasure of `List[]` is `List[]`. -|T| +* The erasure of a type variable is its leftmost bound. + For example, the erasure of a type variable `P` is `Object`, + and the erasure of a type variable `N extends Number` is `Number`. -. For example, the erasure of - -List - -is - -List - -. - -The erasure of a nested type - -T.C - -is - -|T|.C - -. For example, the erasure of the nested type - -Foo.Bar - -is - -Foo.Bar - -. - -The erasure of an array type - -T[] - -is - -|T|[] - -. For example, the erasure of - -List[] - -is - -List[] - -. - -The erasure of a type variable is its leftmost bound. For example, the -erasure of a type variable - -P - -is - -Object - -, and the erasure of a type variable - -N extends Number - -is - -Number - -. - -The erasure of every other type is the type itself +* The erasure of every other type is the type itself. Applying these rules to the earlier examples, we find that the methods defined in `Utils` can be matched by a signature pattern matching @@ -409,9 +349,7 @@ the methods: .... class C { public void foo(List listOfSomeNumberType) {} - public void bar(List listOfSomeType) {} - public void goo(List listOfDoubles) {} } .... @@ -508,24 +446,26 @@ public class C { .... `args(List)`:: - will match an execution or call join point for any of these methods +will match an execution or call join point for any of these methods + `args(List)`:: - will match an execution or call join point for `foo`. +will match an execution or call join point for `foo`. + `args(List)`:: - matches an execution or call join point for `bar`, and _may_ match at - an execution or call join point for `goo` since it is legitimate to - pass an object of type `List` to a method expecting a - `List`. - + - In this situation a runtime test would normally be applied to - ascertain whether or not the argument was indeed an instance of the - required type. However, in the case of parameterized types such a test - is not possible and therefore AspectJ 5 considers this a match, but - issues an _unchecked_ warning. For example, compiling the aspect `A` - below with the class `C` produces the compilation warning: "unchecked - match of List with List when argument is an - instance of List at join point method-execution(void C.goo(List)) [Xlint:uncheckedArgument]"; +matches an execution or call join point for `bar`, and _may_ match at +an execution or call join point for `goo` since it is legitimate to +pass an object of type `List` to a method expecting a +`List`. ++ +In this situation, a runtime test would normally be applied to +ascertain whether or not the argument was indeed an instance of the +required type. However, in the case of parameterized types such a test +is not possible and therefore AspectJ 5 considers this a match, but +issues an _unchecked_ warning. For example, compiling the aspect `A` +below with the class `C` produces the compilation warning: `unchecked +match of List with List when argument is an +instance of List at join point method-execution(void C.goo(List)) [Xlint:uncheckedArgument]`; [source, java] .... @@ -622,9 +562,9 @@ aspect A { From the signature of `foo` all we know is that the runtime argument will be an instance of `Object`.Compiling this program gives the -unchecked argument warning: "unchecked match of List +unchecked argument warning: `unchecked match of List with List when argument is an instance of List at join point -method-execution(void C.foo(Object)) [Xlint:uncheckedArgument]". The +method-execution(void C.foo(Object)) [Xlint:uncheckedArgument]`. The advice will not execute at the call join point for `c.foo("hi")` since `String` is not an instance of `List`. The advice _will_ execute at the call join points for `c.foo(ls)` and `c.foo(ld)` since in both cases the @@ -685,9 +625,7 @@ Given the class .... public class C { public List foo(List listOfStrings) {...} - public List bar(List listOfDoubles) {...} - public List goo(List listOfSomeNumberType) {...} } .... @@ -764,8 +702,8 @@ specification: ` T Utils.max(T first, T second) {...}`:: Declares a generic instance method `max` on the class `Util`. The `max` method takes two arguments, `first` and `second` which must both - be of the same type (and that type must be Number or a subtype of - Number) and returns an instance of that type. + be of the same type (and that type must be `Number` or a subtype of + `Number`) and returns an instance of that type. `static E Utils.first(List elements) {...}`:: Declares a static generic method `first` on the class `Util`. The `first` method takes a list of elements of some type, and returns an @@ -965,52 +903,40 @@ could declare the concrete aspect: .... public aspect ASTNodeContainment extends ParentChildRelationship { before(ASTNode parent, ASTNode child) : addingChild(parent, child) { - ... + // ... } } .... As a result of this declaration, `ASTNode` gains members: -List children - -ASTNode parent - -ListgetChildren() - -ASTNode getParent() - -void addChild(ASTNode child) - -void removeChild(ASTNode child) - -void setParent(ASTNode parent) +* `List children` +* `ASTNode parent` +* `ListgetChildren()` +* `ASTNode getParent()` +* `void addChild(ASTNode child)` +* `void removeChild(ASTNode child)` +* `void setParent(ASTNode parent)` In a system managing orders, we could declare the concrete aspect: [source, java] .... -public aspect OrderItemsInOrders extends ParentChildRelationship { -} +public aspect OrderItemsInOrders extends ParentChildRelationship {} .... As a result of this declaration, `Order` gains members: -List children - -List getChildren() - -void addChild(OrderItem child) - -void removeChild(OrderItem child) +* `List children` +* `List getChildren()` +* `void addChild(OrderItem child)` +* `void removeChild(OrderItem child)` and `OrderItem` gains members: -Order parent - -Order getParent() - -void setParent(Order parent) +* `Order parent` +* `Order getParent()` +* `void setParent(Order parent)` A second example of an abstract aspect, this time for handling exceptions in a uniform manner, is shown below: diff --git a/docs/adk15ProgGuideDB/grammar.adoc b/docs/adk15ProgGuideDB/grammar.adoc index 3e1f345e5..42b0a0fa5 100644 --- a/docs/adk15ProgGuideDB/grammar.adoc +++ b/docs/adk15ProgGuideDB/grammar.adoc @@ -5,22 +5,24 @@ .... === type patterns === -TypePattern := SimpleTypePattern | - '!' TypePattern | - '(' AnnotationPattern? TypePattern ')' - TypePattern '&&' TypePattern | - TypePattern '||' TypePattern +TypePattern := + SimpleTypePattern | + '!' TypePattern | + '(' AnnotationPattern? TypePattern ')' + TypePattern '&&' TypePattern | + TypePattern '||' TypePattern SimpleTypePattern := DottedNamePattern '+'? '[]'* -DottedNamePattern := FullyQualifiedName RestOfNamePattern? | - '*' NotStarNamePattern? +DottedNamePattern := + FullyQualifiedName RestOfNamePattern? | + '*' NotStarNamePattern? -RestOfNamePattern := '..' DottedNamePattern | - '*' NotStarNamePattern? +RestOfNamePattern := '..' DottedNamePattern | '*' NotStarNamePattern? -NotStarNamePattern := FullyQualifiedName RestOfNamePattern? | - '..' DottedNamePattern +NotStarNamePattern := + FullyQualifiedName RestOfNamePattern? | + '..' DottedNamePattern FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)* @@ -28,22 +30,21 @@ FullyQualifiedName := JavaIdentifierCharacter+ ('.' JavaIdentifierCharacter+)* AnnotationPattern := '!'? '@' AnnotationTypePattern AnnotationPattern* - -AnnotationTypePattern := FullyQualifiedName | - '(' TypePattern ')' +AnnotationTypePattern := FullyQualifiedName | '(' TypePattern ')' === signature patterns === -- field -- FieldPattern := - AnnotationPattern? FieldModifiersPattern? - TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern + AnnotationPattern? FieldModifiersPattern? + TypePattern (TypePattern DotOrDotDot)? SimpleNamePattern FieldModifiersPattern := '!'? FieldModifier FieldModifiersPattern* -FieldModifier := 'public' | 'private' | 'protected' | 'static' | - 'transient' | 'final' +FieldModifier := + 'public' | 'private' | 'protected' | 'static' | + 'transient' | 'final' DotOrDotDot := '.' | '..' @@ -52,18 +53,20 @@ SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)? -- method -- MethodPattern := - AnnotationPattern? MethodModifiersPattern? TypePattern - (TypePattern DotOrDotDot)? SimpleNamePattern - '(' FormalsPattern ')' ThrowsPattern? + AnnotationPattern? MethodModifiersPattern? TypePattern + (TypePattern DotOrDotDot)? SimpleNamePattern + '(' FormalsPattern ')' ThrowsPattern? MethodModifiersPattern := '!'? MethodModifier MethodModifiersPattern* -MethodModifier := 'public' | 'private' | 'protected' | 'static' | - 'synchronized' | 'final' +MethodModifier := + 'public' | 'private' | 'protected' | 'static' | + 'synchronized' | 'final' -FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? | - OptionalParensTypePattern (',' FormalsPattern)* | - TypePattern '...' +FormalsPattern := + '..' (',' FormalsPatternAfterDotDot)? | + OptionalParensTypePattern (',' FormalsPattern)* | + TypePattern '...' FormalsPatternAfterDotDot := OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | @@ -76,27 +79,28 @@ TypePatternList := TypePattern (',' TypePattern)* -- constructor -- ConstructorPattern := - AnnotationPattern? ConstructorModifiersPattern? - (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')' - ThrowsPattern? + AnnotationPattern? ConstructorModifiersPattern? + (TypePattern DotOrDotDot)? 'new' '(' FormalsPattern ')' + ThrowsPattern? -ConstructorModifiersPattern := '!'? ConstructorModifier ConstructorModifiersPattern* +ConstructorModifiersPattern := + '!'? ConstructorModifier ConstructorModifiersPattern* ConstructorModifier := 'public' | 'private' | 'protected' === Pointcuts === PointcutPrimitive := - Call | Execution | Get | Set | Handler | - Initialization | PreInitialization | - StaticInitialization | AdviceExecution | - This | Target | Args | CFlow | CFlowBelow | - Within | WithinCode | If | - AnnotationPointcut - -AnnotationPointcut := AtAnnotation | AtThis | AtTarget | - AtWithin | AtWithinCode | AtArgs + Call | Execution | Get | Set | Handler | + Initialization | PreInitialization | + StaticInitialization | AdviceExecution | + This | Target | Args | CFlow | CFlowBelow | + Within | WithinCode | If | + AnnotationPointcut +AnnotationPointcut := + AtAnnotation | AtThis | AtTarget | + AtWithin | AtWithinCode | AtArgs Call := 'call' '(' MethodOrConstructorPattern ')' @@ -124,13 +128,13 @@ TypeOrIdentifier := FullyQualifiedName ('[' ']')* | Identifier Identifier := JavaIdentifierChar+ FormalsOrIdentifiersPattern := - '..' (',' FormalsOrIdentifiersPatternAfterDotDot)? | - TypeOrIdentifier (',' FormalsOrIdentifiersPattern)* | - '*' (',' FormalsOrIdentifiersPattern)* + '..' (',' FormalsOrIdentifiersPatternAfterDotDot)? | + TypeOrIdentifier (',' FormalsOrIdentifiersPattern)* | + '*' (',' FormalsOrIdentifiersPattern)* FormalsOrIdentifiersPatternAfterDotDot := - TypeOrIdentifier (',' FormalsOrIdentifiersPatternAfterDotDot)* | - '*' (',' FormalsOrIdentifiersPatternAfterDotDot)* + TypeOrIdentifier (',' FormalsOrIdentifiersPatternAfterDotDot)* | + '*' (',' FormalsOrIdentifiersPatternAfterDotDot)* AtAnnotation := '@annotation' '(' AnnotationOrIdentifier ')' AtThis := '@this' '(' AnnotationOrIdentifer ')' @@ -143,31 +147,32 @@ AnnotationOrIdentifier := FullyQualifiedName | Identifier AtArgs := '@args' '(' AnnotationsOrIdentifiersPattern ')' AnnotationsOrIdentifiersPattern := - '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? | - AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* | - '*' (',' AnnotationsOrIdentifiersPattern)* + '..' (',' AnnotationsOrIdentifiersPatternAfterDotDot)? | + AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPattern)* | + '*' (',' AnnotationsOrIdentifiersPattern)* AnnotationsOrIdentifiersPatternAfterDotDot := - AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* | - '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)* + AnnotationOrIdentifier (',' AnnotationsOrIdentifiersPatternAfterDotDot)* | + '*' (',' AnnotationsOrIdentifiersPatternAfterDotDot)* -PointcutDeclaration := PointcutModifiers? 'pointcut' Identifier Formals - ':' PointcutExpression +PointcutDeclaration := + PointcutModifiers? 'pointcut' Identifier Formals ':' PointcutExpression PointcutModifiers := PointcutModifier* -PointcutModifier := 'public' | 'private' | 'protected' | 'abstract' +PointcutModifier := 'public' | 'private' | 'protected' | 'abstract' Formals := '(' ParamList? ')' ParamList := FullyQualifiedName Identifier (',' ParamList)* ReferencePointcut := (FullyQualifiedName '.')? Identifier Formals -PointcutExpression := (PointcutPrimitive | ReferencePointcut) | - '!' PointcutExpression | - '(' PointcutExpression ')' | - PointcutExpression '&&' PointcutExpression | - PointcutExpression '||' PointcutExpression +PointcutExpression := + (PointcutPrimitive | ReferencePointcut) | + '!' PointcutExpression | + '(' PointcutExpression ')' | + PointcutExpression '&&' PointcutExpression | + PointcutExpression '||' PointcutExpression === Advice === diff --git a/docs/adk15ProgGuideDB/ltw.adoc b/docs/adk15ProgGuideDB/ltw.adoc index 18fe224dd..6e8a2adce 100644 --- a/docs/adk15ProgGuideDB/ltw.adoc +++ b/docs/adk15ProgGuideDB/ltw.adoc @@ -4,5 +4,5 @@ [[ltw-introduction]] === Introduction -See Developer's Guide for information on load-time weaving support in -AspectJ 5. +See xref:../devGuideDB/ltw.adoc#ltw[Developer's Guide] for information on +load-time weaving support in AspectJ 5. diff --git a/docs/adk15ProgGuideDB/miscellaneous.adoc b/docs/adk15ProgGuideDB/miscellaneous.adoc index 0043c965b..a61f704b8 100644 --- a/docs/adk15ProgGuideDB/miscellaneous.adoc +++ b/docs/adk15ProgGuideDB/miscellaneous.adoc @@ -10,8 +10,9 @@ example, AspectJ 1.2.1 does not allow: [source, java] .... -pointcut foo(Foo foo) : (execution(* *(..)) && this(foo) ) || - (set(* *) && target(foo)); +pointcut foo(Foo foo) : + (execution(* *(..)) && this(foo) ) || + (set(* *) && target(foo)); .... whereas this expression is permitted in AspectJ 5. Each context variable @@ -33,7 +34,8 @@ XLint warning will be issued: .... declare soft : SomeRuntimeException : execution(* *(..)); ->> "SomeRuntimeException will not be softened as it is already a RuntimeException" [XLint:runtimeExceptionNotSoftened] +// "SomeRuntimeException will not be softened as it is already a +// RuntimeException" [XLint:runtimeExceptionNotSoftened] .... This XLint message can be controlled by setting the diff --git a/docs/adk15ProgGuideDB/pertypewithin.adoc b/docs/adk15ProgGuideDB/pertypewithin.adoc index 6d7b12a0e..32295fc1f 100644 --- a/docs/adk15ProgGuideDB/pertypewithin.adoc +++ b/docs/adk15ProgGuideDB/pertypewithin.adoc @@ -1,5 +1,5 @@ [[pertypewithin]] -== The pertypewithin Aspect Instantiation Model +== The `pertypewithin` Aspect Instantiation Model AspectJ 5 defines a new per-clause type for aspect instantiation: `pertypewithin`. Unlike the other per-clauses, `pertypewithin` takes a diff --git a/docs/adk15ProgGuideDB/reflection.adoc b/docs/adk15ProgGuideDB/reflection.adoc index acb8c0b75..b39919229 100644 --- a/docs/adk15ProgGuideDB/reflection.adoc +++ b/docs/adk15ProgGuideDB/reflection.adoc @@ -8,7 +8,7 @@ reflection APIs are only supported when running under Java 5 and for code compiled by the AspectJ 5 compiler at target level 1.5. [[reflection_api]] -=== Using AjTypeSystem +=== Using `AjTypeSystem` The starting point for using the reflection apis is `org.aspectj.lang.reflect.AjTypeSystem` which provides the method diff --git a/docs/adk15ProgGuideDB/varargs.adoc b/docs/adk15ProgGuideDB/varargs.adoc index 0f5a7b3df..3f13ab31a 100644 --- a/docs/adk15ProgGuideDB/varargs.adoc +++ b/docs/adk15ProgGuideDB/varargs.adoc @@ -5,12 +5,11 @@ Java 5 (and hence AspectJ 5) allows you to specify methods that take a variable number of arguments of a specified type. This is achieved using -an ellipsis (...) in the method signature as shown: +an ellipsis (`...`) in the method signature as shown: [source, java] .... -public void foo(int i, String... strings) { -} +public void foo(int i, String... strings) {} .... A method or constructor may take at most one variable length argument, @@ -69,13 +68,14 @@ last argument position of a method or constructor signature. [source, text] .... -FormalsPattern := '..' (',' FormalsPatternAfterDotDot)? | - OptionalParensTypePattern (',' FormalsPattern)* | - TypePattern '...' +FormalsPattern := + '..' (',' FormalsPatternAfterDotDot)? | + OptionalParensTypePattern (',' FormalsPattern)* | + TypePattern '...' FormalsPatternAfterDotDot := - OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | - TypePattern '...' + OptionalParensTypePattern (',' FormalsPatternAfterDotDot)* | + TypePattern '...' .... Method and constructor patterns are used in the `call`, `execution`, @@ -84,16 +84,16 @@ designators. Some examples of usage follow: `call(* org.xyz.*.*(int, String...))`:: Matches a call join point for a call to a method defined in the - `org.xyz` package, taking an `int` and a `String vararg`. + `org.xyz` package, taking an `int` and a `String` _vararg_. `execution(* org.xyz.*.*(Integer...))`:: Matches an execution join point for the execution of a method defined - in the `org.xyz` package, taking an `Integer vararg`. + in the `org.xyz` package, taking an `Integer` _vararg_. `initialization(org.xyz.*.new((Foo || Goo)...))`:: Matches the initialization join point for the construction of an object in the `org.xyz` package via a constructor taking either a variable number of `Foo` parameters or a variable number of `Goo` parameters. (This example illustrating the use of a type pattern with - ...). + `...`). A variable argument parameter and an array parameter are treated as distinct signature elements, so given the method definitions: @@ -118,8 +118,7 @@ pointcut designator. Given a method [source, java] .... -public void foo(int i, String... strings) { -} +public void foo(int i, String... strings) {} .... The call or execution join points for `foo` will be matched by the @@ -143,7 +142,7 @@ designator, you also cannot use the varargs syntax to declare advice parameters. Note: the proposal in this section does not allow you to distinguish -between a join point with a signature (int, String...) and a join point -with a signature (int, String[]) based _solely_ on the use of the `args` +between a join point with a signature `(int, String...)` and a join point +with a signature `(int, String[])` based _solely_ on the use of the `args` pointcut designator. If this distinction is required, `args` can always be coupled with `call` or `execution`. diff --git a/docs/progGuideDB/language.adoc b/docs/progGuideDB/language.adoc index 3aeb5eebd..21d3d1857 100644 --- a/docs/progGuideDB/language.adoc +++ b/docs/progGuideDB/language.adoc @@ -200,9 +200,9 @@ Pointcuts pick out these join points. For example, the pointcut [source, java] .... -pointcut setter(): target(Point) && - (call(void setX(int)) || - call(void setY(int))); +pointcut setter(): + target(Point) && + (call(void setX(int)) || call(void setY(int))); .... picks out each call to `setX(int)` or `setY(int)` when called on an @@ -242,8 +242,8 @@ when the join point is in the control flow of a call to a ``Test``'s no-argument `main` method:: `cflow(call(void Test.main()))` -Pointcuts compose through the operations `or` ("`||`"), `and` ("`&&`") -and `not` ("`!`"). +Pointcuts compose through the operations `OR` (`||`), `ANT` (`&&`) +and `NOT` (`!`). * It is possible to use wildcards. So [arabic] @@ -272,9 +272,7 @@ so long as it takes exactly two ``int``s as arguments. . `target(Point) && call(int *())` . `call(* *(..)) && (within(Line) || within(Point))` . `within(*) && execution(*.new(int))` -. ` - !this(Point) && call(int *(..)) - ` +. `!this(Point) && call(int *(..))` + means (1) any call to an `int` method with no arguments on an instance of `Point`, regardless of its name, (2) any call to any method where the @@ -287,7 +285,7 @@ on negations of modifiers. For example, you can say: [arabic] . `call(public * *(..))` . `execution(!static * *(..))` -. ` execution(public !static * *(..))` +. `execution(public !static * *(..))` + which means (1) any call to a public method, (2) any execution of a non-static method, and (3) any execution of a public, non-static method. @@ -319,12 +317,12 @@ number of differences: Firstly, the lexical pointcut declarations `within` and `withincode` match differently. At a call join point, the enclosing code is that of -the call site. This means that `call(void m()) - && withincode(void m())` will only capture directly recursive +the call site. This means that `call(void m()) && withincode(void m())` +will only capture directly recursive calls, for example. At an execution join point, however, the program is already executing the method, so the enclosing code is the method -itself: `execution(void m()) - && withincode(void m())` is the same as `execution(void m())`. +itself: `execution(void m()) && withincode(void m())` is the same as +`execution(void m())`. Secondly, the call join point does not capture super calls to non-static methods. This is because such super calls are different in Java, since @@ -346,7 +344,7 @@ pointcuts. This composition can be somewhat confusing when used with primitive pointcuts like `cflow` and `cflowbelow`. Here's an example: `cflow(P)` picks out each join point in the control flow of the join -points picked out by

. So, pictorially: +points picked out by `P`. So, pictorially: [source, text] .... @@ -356,9 +354,8 @@ P --------------------- \ .... -What does `cflow(P) && - cflow(Q)` pick out? Well, it picks out each join point that is -in both the control flow of

and in the control flow of . So... +What does `cflow(P) && cflow(Q)` pick out? Well, it picks out each join point that is +in both the control flow of `P` and in the control flow of `Q`. So... [source, text] .... @@ -374,12 +371,11 @@ Q -------------\------- \ \ .... -Note that

and might not have any join points in common... but +Note that `P` and `Q` might not have any join points in common... but their control flows might have join points in common. -But what does `cflow(P - && Q)` mean? Well, it means the control flow of those join -points that are both picked out by

and picked out by . +But what does `cflow(P && Q)` mean? Well, it means the control flow of those join +points that are both picked out by `P` and picked out by `Q`. [source, text] .... @@ -389,10 +385,9 @@ P && Q ------------------- \ .... -and if there are _no_ join points that are both picked by

and picked -out by , then there's no chance that there are any join points in the -control flow of `(P && - Q)`. +and if there are _no_ join points that are both picked by `P` and picked +out by `Q`, then there's no chance that there are any join points in the +control flow of `(P && Q)`. Here's some code that expresses this. @@ -437,23 +432,23 @@ Consider again the first pointcut definition in this chapter: [source, java] .... -pointcut setter(): target(Point) && - (call(void setX(int)) || - call(void setY(int))); +pointcut setter(): + target(Point) && + (call(void setX(int)) || call(void setY(int))); .... As we've seen, this pointcut picks out each call to `setX(int)` or `setY(int)` methods where the target is an instance of `Point`. The -pointcut is given the name `setters` and no parameters on the left-hand +pointcut is given the name `setter` and no parameters on the left-hand side. An empty parameter list means that none of the context from the join points is published from this pointcut. But consider another version of version of this pointcut definition: [source, java] .... -pointcut setter(Point p): target(p) && - (call(void setX(int)) || - call(void setY(int))); +pointcut setter(Point p): + target(p) && + (call(void setX(int)) || call(void setY(int))); .... This version picks out exactly the same join points. But in this @@ -469,13 +464,14 @@ defining pointcut parameters: [source, java] .... -pointcut testEquality(Point p): target(Point) && - args(p) && - call(boolean equals(Object)); +pointcut testEquality(Point p): + target(Point) && + args(p) && + call(boolean equals(Object)); .... This pointcut also has a parameter of type `Point`. Similar to the -`setters` pointcut, this means that anyone using this pointcut has +`setter` pointcut, this means that anyone using this pointcut has access to a `Point` from each join point. But in this case, looking at the right-hand side we find that the object named in the parameters is not the target `Point` object that receives the call; it's the argument @@ -486,19 +482,20 @@ pointcut definition that would expose target `Point p1` and argument [source, java] .... -pointcut testEquality(Point p1, Point p2): target(p1) && - args(p2) && - call(boolean equals(Object)); +pointcut testEquality(Point p1, Point p2): + target(p1) && + args(p2) && + call(boolean equals(Object)); .... -Let's look at another variation of the `setters` pointcut: +Let's look at another variation of the `setter` pointcut: [source, java] .... -pointcut setter(Point p, int newval): target(p) && - args(newval) && - (call(void setX(int)) || - call(void setY(int))); +pointcut setter(Point p, int newval): + target(p) && + args(newval) && + (call(void setX(int)) || call(void setY(int))); .... In this case, a `Point` object and an `int` value are exposed by the @@ -514,8 +511,8 @@ following pointcut definition will result in a compilation error: [source, java] .... pointcut badPointcut(Point p1, Point p2): - (target(p1) && call(void setX(int))) || - (target(p2) && call(void setY(int))); + (target(p1) && call(void setX(int))) || + (target(p2) && call(void setY(int))); .... because `p1` is only bound when calling `setX`, and `p2` is only bound @@ -588,11 +585,11 @@ in the definition. Basically there are three kinds of pointcut designator: kinded, scoping and context: * Kinded designators are those which select a particular kind of join -point. For example: execution, get, set, call, handler +point. For example: `execution, get, set, call, handler` * Scoping designators are those which select a group of join points of -interest (of probably many kinds). For example: within, withincode +interest (of probably many kinds). For example: `within, withincode` * Contextual designators are those that match (and optionally bind) -based on context. For example: this, target, @annotation +based on context. For example: `this, target, @annotation` A well written pointcut should try and include at least the first two types (kinded and scoping), whilst the contextual designators may be @@ -616,13 +613,15 @@ pointcut: [source, java] .... -pointcut setter(Point p1, int newval): target(p1) && args(newval) - (call(void setX(int) || - call(void setY(int))); +pointcut setter(Point p1, int newval): + target(p1) && args(newval) + (call(void setX(int) || call(void setY(int))); before(Point p1, int newval): setter(p1, newval) { - System.out.println("About to set something in " + p1 + - " to the new value " + newval); + System.out.println( + "About to set something in " + p1 + + " to the new value " + newval + ); } .... @@ -630,11 +629,14 @@ And here is exactly the same example, but using an anonymous pointcut: [source, java] .... -before(Point p1, int newval): target(p1) && args(newval) - (call(void setX(int)) || - call(void setY(int))) { - System.out.println("About to set something in " + p1 + - " to the new value " + newval); +before(Point p1, int newval): + target(p1) && args(newval) + (call(void setX(int)) || call(void setY(int))) +{ + System.out.println( + "About to set something in " + p1 + + " to the new value " + newval + ); } .... @@ -646,7 +648,7 @@ This before advice runs just before the join points picked out by the [source, java] .... before(Point p, int x): target(p) && args(x) && call(void setX(int)) { - if (!p.assertX(x)) return; + if (!p.assertX(x)) return; } .... @@ -656,8 +658,10 @@ throws an exception: [source, java] .... -after(Point p, int x): target(p) && args(x) && call(void setX(int)) { - if (!p.assertX(x)) throw new PostConditionViolation(); +after(Point p, int x): + target(p) && args(x) && call(void setX(int)) +{ + if (!p.assertX(x)) throw new PostConditionViolation(); } .... @@ -668,8 +672,10 @@ return value is returned: [source, java] .... -after(Point p) returning(int x): target(p) && call(int getX()) { - System.out.println("Returning int value " + x + " for p = " + p); +after(Point p) returning(int x): + target(p) && call(int getX()) +{ + System.out.println("Returning int value " + x + " for p = " + p); } .... @@ -680,7 +686,9 @@ The advice re-raises the exception after it's done: [source, java] .... -after() throwing(Exception e): target(Point) && call(void setX(int)) { +after() throwing(Exception e): + target(Point) && call(void setX(int)) +{ System.out.println(e); } .... @@ -691,11 +699,13 @@ join point can be invoked through the special `proceed` call: [source, java] .... -void around(Point p, int x): target(p) - && args(x) - && call(void setX(int)) { - if (p.assertX(x)) proceed(p, x); - p.releaseResources(); +void around(Point p, int x): + target(p) + && args(x) + && call(void setX(int)) +{ + if (p.assertX(x)) proceed(p, x); + p.releaseResources(); } .... @@ -880,7 +890,7 @@ aspect PointAssertions { .... [[language-thisJoinPoint]] -=== thisJoinPoint +=== `thisJoinPoint` AspectJ provides a special reference variable, `thisJoinPoint`, that contains reflective information about the current join point for the diff --git a/docs/progGuideDB/semantics.adoc b/docs/progGuideDB/semantics.adoc index 261d6c944..d1a90673b 100644 --- a/docs/progGuideDB/semantics.adoc +++ b/docs/progGuideDB/semantics.adoc @@ -978,8 +978,10 @@ pointcut doesNotThrowMathlike(): A `ThrowsClausePattern` is a comma-separated list of ``ThrowsClausePatternItem``s, where -`ThrowsClausePatternItem`: :: - `[ ! ] TypeNamePattern` +[source, text] +.... +ThrowsClausePatternItem := [ ! ] TypeNamePattern +.... A `ThrowsClausePattern` matches the `throws` clause of any code member signature. To match, each `ThrowsClausePatternItem` must match the -- 2.39.5