From d851d3f377a8c4b0c5f8056f9dee22f29dc349c8 Mon Sep 17 00:00:00 2001 From: Alexander Kriegisch Date: Fri, 16 Jul 2021 18:45:52 +0700 Subject: [PATCH] More AsciiDoc improvements, mostly about code formatting (WIP) Signed-off-by: Alexander Kriegisch --- docs/adk15ProgGuideDB/annotations.adoc | 89 ++- docs/adk15ProgGuideDB/covariance.adoc | 16 +- docs/adk15ProgGuideDB/generics.adoc | 68 +- .../adk15ProgGuideDB/joinpointsignatures.adoc | 15 +- docs/adk15ProgGuideDB/varargs.adoc | 6 +- docs/devGuideDB/ajc.adoc | 98 +-- docs/devGuideDB/ltw.adoc | 56 +- docs/progGuideDB/semantics.adoc | 628 +++++------------- 8 files changed, 343 insertions(+), 633 deletions(-) diff --git a/docs/adk15ProgGuideDB/annotations.adoc b/docs/adk15ProgGuideDB/annotations.adoc index e0e56fc71..5fcf74608 100644 --- a/docs/adk15ProgGuideDB/annotations.adoc +++ b/docs/adk15ProgGuideDB/annotations.adoc @@ -61,17 +61,13 @@ Annotations can have one of three retention policies: Source-file retention:: Annotations with source-file retention are read by the compiler during - the compilation process, but are not rendered in the generated - `.class` files. + the compilation process, but are not rendered in the generated `.class` files. Class-file retention:: This is the default retention policy. Annotations with class-file - retention are read by the compiler and also retained in the generated - ` - .class` files. + retention are read by the compiler and also retained in the generated `.class` files. Runtime retention:: Annotations with runtime retention are read by the compiler, retained - in the generated ` - .class` files, and also made available at + in the generated `.class` files, and also made available at runtime. Local variable annotations are not retained in class files (or at @@ -201,7 +197,6 @@ public aspect AnAspect { pointcut anInterfaceOperation() : execution(* AnInterface.*(..)); - @SuppressAjWarnings // may not match if there are no implementers of the interface... before() : anInterfaceOperation() { // do something... @@ -229,8 +224,8 @@ etc.), an annotation pattern can be used to match against the set of annotations on the annotated element.An annotation pattern element has one of two basic forms: -* @, for example, @Foo, or @org.xyz.Foo. -* @(), for example, @(org.xyz..*), or @(Foo || Boo) +* `@`, for example, `@Foo`, or `@org.xyz.Foo`. +* `@()`, for example, `@(org.xyz..*)`, or `@(Foo || Boo)` These simple elements may be negated using `!`, and combined by simple concatentation. The pattern `@Foo @Boo` matches an annotated element @@ -239,21 +234,21 @@ that has both an annotation of type `Foo` and an annotation of type Some examples of annotation patterns follow: -@Immutable:: +`@Immutable`:: Matches any annotated element which has an annotation of type `Immutable`. -!@Persistent:: +`!@Persistent`:: Matches any annotated element which does not have an annotation of type `Persistent`. -@Foo @Goo:: +`@Foo @Goo`:: Matches any annotated element which has both an annotation of type `Foo` and an annotation of type `Goo`. -@(Foo || Goo):: +`@(Foo || Goo)`:: Matches any annotated element which has either an annotation of a type matching the type pattern `(Foo || Goo)`. In other words, an annotated element with either an annotation of type `Foo` or an annotation of type `Goo` (or both). (The parenthesis are required in this example). -@(org.xyz..*):: +`@(org.xyz..*)`:: Matches any annotated element which has either an annotation of a type matching the type pattern `(org.xyz..*)`. In other words, an annotated element with an annotation that is declared in the org.xyz package or @@ -299,25 +294,25 @@ OptionalParensTypePattern := AnnotationPattern? TypePattern The following examples illustrate the use of annotations in type patterns: -(@Immutable *):: +`(@Immutable *)`:: Matches any type with an `@Immutable` annotation. -(!@Immutable *):: +`(!@Immutable *)`:: Matches any type which does not have an `@Immutable` annotation. -(@Immutable (org.xyz.* || org.abc.*)):: +`(@Immutable (org.xyz.* || org.abc.*))`:: Matches any type in the `org.xyz` or `org.abc` packages with the `@Immutable` annotation. -((@Immutable Foo+) || Goo):: +`((@Immutable Foo+) || Goo)`:: Matches a type `Foo` or any of its subtypes, which have the `@Immutable` annotation, or a type `Goo`. -((@(Immutable || NonPersistent) org.xyz..*):: +`((@(Immutable || NonPersistent) org.xyz..*)`:: Matches any type in a package beginning with the prefix `org.xyz`, which has either the `@Immutable` annotation or the `@NonPersistent` annotation. -(@Immutable @NonPersistent org.xyz..*):: +`(@Immutable @NonPersistent org.xyz..*)`:: Matches any type in a package beginning with the prefix `org.xyz`, which has both an `@Immutable` annotation and an `@NonPersistent` annotation. -(@(@Inherited *) org.xyz..*):: +`(@(@Inherited *) org.xyz..*)`:: Matches any type in a package beginning with the prefix `org.xyz`, which has an inheritable annotation. The annotation pattern `@(@Inherited *)` matches any annotation of a type matching the type @@ -352,20 +347,20 @@ SimpleNamePattern := JavaIdentifierChar+ ('*' SimpleNamePattern)? If present, the `AnnotationPattern` restricts matches to fields with annotations that match the pattern. For example: -@SensitiveData * *:: +`@SensitiveData * *`:: Matches a field of any type and any name, that has an annotation of type `@SensitiveData` -@SensitiveData List org.xyz..*.*:: +`@SensitiveData List org.xyz..*.*`:: Matches a member field of a type in a package with prefix `org.xzy`, where the field is of type `List`, and has an annotation of type `@SensitiveData` -(@SensitiveData *) org.xyz..*.*:: +`(@SensitiveData *) org.xyz..*.*`:: Matches a member field of a type in a package with prefix `org.xzy`, where the field is of a type which has a `@SensitiveData` annotation. -@Foo (@Goo *) (@Hoo *).*:: +`@Foo (@Goo *) (@Hoo *).*`:: Matches a field with an annotation `@Foo`, of a type with an annotation `@Goo`, declared in a type with annotation `@Hoo`. -@Persisted @Classified * *:: +`@Persisted @Classified * *`:: Matches a field with an annotation `@Persisted` and an annotation `@Classified`. @@ -418,37 +413,37 @@ The optional `AnnotationPattern` at the beginning of a method or constructor pattern restricts matches to methods/constructors with annotations that match the pattern. For example: -@Oneway * *(..):: +`@Oneway * *(..)`:: Matches a method with any return type and any name, that has an annotation of type `@Oneway`. -@Transaction * (@Persistent org.xyz..*).*(..):: +`@Transaction * (@Persistent org.xyz..*).*(..)`:: Matches a method with the `@Transaction` annotation, declared in a type with the `@Persistent` annotation, and in a package beginning with the `org.xyz` prefix. -* *.*(@Immutable *,..):: +`* *.*(@Immutable *,..)`:: Matches any method taking at least one parameter, where the parameter type has an annotation `@Immutable`. ==== Example Pointcuts -within(@Secure *):: +`within(@Secure *)`:: Matches any join point where the code executing is declared in a type with an `@Secure` annotation. The format of the `within` pointcut designator in AspectJ 5 is `'within' '(' OptionalParensTypePattern ')'`. -staticinitialization(@Persistent *):: +`staticinitialization(@Persistent *)`:: Matches the staticinitialization join point of any type with the `@Persistent` annotation. The format of the `staticinitialization` pointcut designator in AspectJ 5 is `'staticinitialization' '(' OptionalParensTypePattern ')'`. -call(@Oneway * *(..)):: +`call(@Oneway * *(..))`:: Matches a call to a method with a `@Oneway` annotation. -execution(public (@Immutable *) org.xyz..*.*(..)):: +`execution(public (@Immutable *) org.xyz..*.*(..))`:: The execution of any public method in a package with prefix `org.xyz`, where the method returns an immutable result. -set(@Cachable * *):: +`set(@Cachable * *)`:: Matches the set of any cachable field. -handler(!@Catastrophic *):: +`handler(!@Catastrophic *)`:: Matches the handler join point for the handling of any exception that is not `Catastrophic`. The format of the `handler` pointcut designator in AspectJ 5 is `'handler' '(' OptionalParensTypePattern ')'`. @@ -501,10 +496,10 @@ name are analogous to their counterparts that take a single type name. They match at join points where the object bound to `this` (or `target`, respectively) has an annotation of the specified type. For example: -@this(Foo):: +`@this(Foo)`:: Matches any join point where the object currently bound to 'this' has an annotation of type `Foo`. -call(* *(..)) && @target(Classified):: +`call(* *(..)) && @target(Classified)`:: Matches a call to any object where the target of the call has a `@Classified` annotation. @@ -573,10 +568,10 @@ AtWithinCode := '@withincode' '(' AnnotationOrIdentifier ')' Some examples of using these designators follow: -@within(Foo):: +`@within(Foo)`:: Matches any join point where the executing code is defined within a type which has an annotation of type `Foo`. -pointcut insideCriticalMethod(Critical c) : @withincode(c);:: +`pointcut insideCriticalMethod(Critical c) : @withincode(c);`:: Matches any join point where the executing code is defined in a method or constructor which has an annotation of type `@Critical`, and exposes the value of the annotation in the parameter `c`. @@ -777,10 +772,10 @@ specification, it is now possible to match types based on the presence of annotations _with either class-file or runtime retention_. For example: -declare parents : (@Secured *) implements SecuredObject;:: +`declare parents : (@Secured *) implements SecuredObject;`:: All types with the `@Secured` annotation implement the `SecuredObject` inteface. -declare parents : (@Secured BankAccount+) implements SecuredObject;:: +`declare parents : (@Secured BankAccount+) implements SecuredObject;`:: The subset of types drawn from the `BankAccount` type and any subtype of `BankAccount`, where the `@Secured` annotation is present, implement the `SecuredObject` interface. @@ -804,7 +799,7 @@ declare precedence : TypePatList; AspectJ 5 allows the type patterns in the list to include annotation information as part of the pattern specification. For example: -declare precedence : (@Security *),*;:: +`declare precedence : (@Security *),*;`:: All aspects with the `@Security` annotation take precedence over any other aspects in the system. (Or, more informally, all security-related aspects take precedence). @@ -843,18 +838,18 @@ ElementPattern := TypePattern | The following examples illustrate the use of `declare annotation`. -declare @type : org.xyz.model..* : @BusinessDomain ;:: +`declare @type : org.xyz.model..* : @BusinessDomain ;`:: All types defined in a package with the prefix `org.xyz.model` have the `@BusinessDomain` annotation. declare @method : public * BankAccount+.*(..) : -@Secured(role="supervisor"):: +`@Secured(role="supervisor")`:: All public methods in `BankAccount` and its subtypes have the annotation `@Secured(role="supervisor")`. declare @constructor : BankAccount+.new(..) : -@Secured(role="supervisor"):: +`@Secured(role="supervisor")`:: All constructors in `BankAccount` and its subtypes have the annotation `@Secured(role="supervisor")`. -declare @field : * DAO+.* : @Persisted;:: +`declare @field : * DAO+.* : @Persisted;`:: All fields defined in `DAO` or its subtypes have the `@Persisted` annotation. diff --git a/docs/adk15ProgGuideDB/covariance.adoc b/docs/adk15ProgGuideDB/covariance.adoc index 49dda35ee..793b134f2 100644 --- a/docs/adk15ProgGuideDB/covariance.adoc +++ b/docs/adk15ProgGuideDB/covariance.adoc @@ -52,31 +52,31 @@ B B.whoAreYou() Following the join point matching rules given in xref:joinpointsignatures.adoc#jpsigs[Join Point Signatures]. -call(* whoAreYou()):: +`call(* whoAreYou())`:: Matches both calls, (since each call join point has at least one matching signature). -call(* A.whoAreYou()):: +`call(* A.whoAreYou())`:: Matches both calls, (since each call join point has at least one matching signature). -call(A whoAreYou()):: +`call(A whoAreYou())`:: Matches both calls, (since each call join point has at least one matching signature). -call(A B.whoAreYou()):: +`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+ B.whoAreYou()):: +`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)"). -call(B A.whoAreYou()):: +`call(B A.whoAreYou())`:: Does not match anything since neither join point has a signature matched by this pattern. -call(B whoAreYou()):: +`call(B whoAreYou())`:: Matches the call to `b.whoAreYou()` only. -call(B B.whoAreYou()):: +`call(B B.whoAreYou())`:: Matches the call to `b.whoAreYou()` only. The rule for signature matching at call and execution join points is diff --git a/docs/adk15ProgGuideDB/generics.adoc b/docs/adk15ProgGuideDB/generics.adoc index cd9c101b1..7d1c41a57 100644 --- a/docs/adk15ProgGuideDB/generics.adoc +++ b/docs/adk15ProgGuideDB/generics.adoc @@ -41,18 +41,18 @@ addition to simple type parameter names, type parameter declarations can also constrain the set of types allowed by using the `extends` keyword. Some examples follow: -class Foo \{...}:: +`class Foo {...}`:: A class `Foo` with one type parameter, `T`. -class Foo \{...}:: +`class Foo {...}`:: A class `Foo` with two type parameters, `T` and `S`. -class Foo \{...}:: +`class Foo {...}`:: A class `Foo` with one type parameter `T`, where `T` must be instantiated as the type `Number` or a subtype of `Number`. -class Foo \{...}:: +`class Foo {...}`:: A class `Foo` with two type parameters, `T` and `S`. `Foo` must be instantiated with a type `S` that is a subtype of the type specified for parameter `T`. -class Foo \{...}:: +`class Foo {...}`:: A class `Foo` with one type parameter, `T`. `Foo` must be instantiated with a type that is a subtype of `Number` and that implements `Comparable`. @@ -91,13 +91,13 @@ stands for "some type". The `extends` and `super` keywords may be used in conjunction with the wildcard to provide upper and lower bounds on the types that may satisfy the type constraints. For example: -List:: +`List`:: A list containing elements of some type, the type of the elements in the list is unknown. -List:: +`List`:: A list containing elements of some type that extends Number, the exact type of the elements in the list is unknown. -List:: +`List`:: A list containing elements of some type that is a super-type of Double, the exact type of the elements in the list is unknown. @@ -105,24 +105,24 @@ A generic type may be extended as any other type. Given a generic type `Foo` then a subtype `Goo` may be declared in one of the following ways: -class Goo extends Foo:: +`class Goo extends Foo`:: Here `Foo` is used as a raw type, and the appropriate warning messages will be issued by the compiler on attempting to invoke methods in `Foo`. -class Goo extends Foo:: +`class Goo extends Foo`:: `Goo` is a generic type, but the super-type `Foo` is used as a raw type and the appropriate warning messages will be issued by the compiler on attempting to invoke methods defined by `Foo`. -class Goo extends Foo:: +`class Goo extends Foo`:: This is the most usual form. `Goo` is a generic type with one parameter that extends the generic type `Foo` with that same parameter. So `Goo`. -class Goo extends Foo:: +`class Goo extends Foo`:: `Goo` is a generic type with two parameters that extends the generic type `Foo` with the first type parameter of `Goo` being used to parameterize `Foo`. So `Goo`. -class Goo extends Foo:: +`class Goo extends Foo`:: `Goo` is a type that extends the parameterized type `Foo`. A generic type may implement one or more generic interfaces, following @@ -416,14 +416,14 @@ class C { } .... -execution(* C.*(List)):: +`execution(* C.*(List))`:: Matches an execution join point for any of the three methods. -execution(* C.*(List)):: +`execution(* C.*(List))`:: matches only the execution of `foo`, and _not_ the execution of `goo` since `List` and `List` are distinct types. -execution(* C.*(List)):: +`execution(* C.*(List))`:: matches only the execution of `bar`. -execution(* C.*(List)):: +`execution(* C.*(List))`:: matches both the execution of `foo` and the execution of `bar` since the upper bound of `List` is implicitly `Object`. @@ -507,11 +507,11 @@ public class C { } .... -args(List):: +`args(List)`:: will match an execution or call join point for any of these methods -args(List):: +`args(List)`:: will match an execution or call join point for `foo`. -args(List):: +`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 @@ -761,17 +761,16 @@ members on generic types. For generic methods, the syntax is exactly as for a regular method declaration, with the addition of the target type specification: - T Utils.max(T first, T second) \{...}:: +` 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. -static E Utils.first(List elements) \{...}:: +`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 instance of that type. - Sorter.new(List elements,Comparator comparator) -\{...}:: + Sorter.new(List elements,Comparator comparator) `{...}`:: Declares a constructor on the class `Sorter`. The constructor takes a list of elements of some type, and a comparator that can compare instances of the element type. @@ -783,17 +782,17 @@ match the number of type parameters in the generic type declaration. Type parameter _names_ do not have to match. For example, given the generic type `Foo` then: -String Foo.getName() \{...}:: +`String Foo.getName() {...}`:: Declares a `getName` method on behalf of the type `Foo`. It is not possible to refer to the type parameters of Foo in such a declaration. -public R Foo.getMagnitude() \{...}:: +`public R Foo.getMagnitude() {...}`:: Declares a method `getMagnitude` on the generic class `Foo`. The method returns an instance of the type substituted for the second type parameter in an invocation of `Foo` If `Foo` is declared as `Foo {...}` then this inter-type declaration is equivalent to the declaration of a method `public N getMagnitude()` within the body of `Foo`. -R Foo.getMagnitude() \{...}:: +`R Foo.getMagnitude() {...}`:: Results in a compilation error since a bounds specification is not allowed in this form of an inter-type declaration (the bounds are determined from the declaration of the target type). @@ -814,7 +813,7 @@ would be well-formed in accordance with Java's sub-typing rules). Generic types may also be used as the target type of a `declare parents` statement. -declare parents: Foo implements List:: +`declare parents: Foo implements List`:: The `Foo` type implements the `List` interface. If `Foo` already implements some other parameterization of the `List` interface (for example, `List` then a compilation error will result @@ -840,25 +839,22 @@ Given the aspect declaration: [source, java] .... public abstract aspect ParentChildRelationship { - ... + // ... } .... then -public aspect FilesInFolders extends -ParentChildRelationship \{...:: +`public aspect FilesInFolders extends ParentChildRelationship {...`:: declares a concrete sub-aspect, `FilesInFolders` which extends the parameterized abstract aspect `ParentChildRelationship`. -public aspect FilesInFolders extends ParentChildRelationship \{...:: +`public aspect FilesInFolders extends ParentChildRelationship {...`:: results in a compilation error since the `ParentChildRelationship` aspect must be fully parameterized. -public aspect ThingsInFolders extends -ParentChildRelationship:: +`public aspect ThingsInFolders extends ParentChildRelationship`:: results in a compilation error since concrete aspects may not have type parameters. -public abstract aspect ThingsInFolders extends -ParentChildRelationship:: +`public abstract aspect ThingsInFolders extends ParentChildRelationship`:: declares a sub-aspect of `ParentChildRelationship` in which `Folder` plays the role of parent (is bound to the type variable `P`). diff --git a/docs/adk15ProgGuideDB/joinpointsignatures.adoc b/docs/adk15ProgGuideDB/joinpointsignatures.adoc index 07df75f92..1ed54baa8 100644 --- a/docs/adk15ProgGuideDB/joinpointsignatures.adoc +++ b/docs/adk15ProgGuideDB/joinpointsignatures.adoc @@ -10,16 +10,13 @@ annotations, generics, covariance, varargs, and autoboxing. === Join Point Matching AspectJ supports 11 different kinds of join points. These are the -`method call, method execution, constructor call, - constructor execution, field get, field set, pre-initialization, - initialization, static initialization, handler,` and -`advice execution` join points. +`method call, method execution, constructor call, constructor execution, field get, +field set, pre-initialization, initialization, static initialization, handler,` +and `advice execution` join points. The _kinded_ pointcut designators match based on the kind of a join -point. These are the `call, - execution, get, set, preinitialization, initialization, - staticinitialization, handler,` and `adviceexecution` -designators. +point. These are the `call, execution, get, set, preinitialization, initialization, +staticinitialization, handler,` and `adviceexecution` designators. A kinded pointcut is written using patterns, some of which match based on _signature_, and some of which match based on _modifiers_. For @@ -100,7 +97,7 @@ of the target): [source, java] .... T t = new T(); -t.m("hello"); <= call join point occurs when this line is executed +t.m("hello"); // <= call join point occurs when this line is executed .... Then the signature `R(T) T.m(parameter_types)` is a signature of the diff --git a/docs/adk15ProgGuideDB/varargs.adoc b/docs/adk15ProgGuideDB/varargs.adoc index bf644ace3..0f5a7b3df 100644 --- a/docs/adk15ProgGuideDB/varargs.adoc +++ b/docs/adk15ProgGuideDB/varargs.adoc @@ -82,13 +82,13 @@ Method and constructor patterns are used in the `call`, `execution`, `initialization`, `preinitialization`, and `withincode` pointcut designators. Some examples of usage follow: -call(* org.xyz.*.*(int, String...)):: +`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`. -execution(* org.xyz.*.*(Integer...)):: +`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`. -initialization(org.xyz.*.new((Foo || Goo)...)):: +`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` diff --git a/docs/devGuideDB/ajc.adoc b/docs/devGuideDB/ajc.adoc index fcbc8f492..ff789be2d 100644 --- a/docs/devGuideDB/ajc.adoc +++ b/docs/devGuideDB/ajc.adoc @@ -40,22 +40,22 @@ destination directory on the inpath and rebuild.) [[ajc_options]] ==== Options --injars :: +`-injars `:: deprecated: since 1.2, use -inpath, which also takes directories. --inpath :: +`-inpath `:: Accept as source bytecode any .class files in the .jar files or directories on Path. The output will include these classes, possibly as woven with any applicable aspects. Path is a single argument containing a list of paths to zip files or directories, delimited by the platform-specific path delimiter. --aspectpath :: +`-aspectpath `:: Weave binary aspects from jar files and directories on path into all sources. The aspects should have been output by the same version of the compiler. When running the output classes, the run classpath should contain all aspectpath entries. Path, like classpath, is a single argument containing a list of paths to jar files, delimited by the platform- specific classpath delimiter. --argfile :: +`-argfile `:: The file contains a line-delimited list of arguments. Each line in the file should contain one option, filename, or argument string (e.g., a classpath or inpath). Arguments read from the file are inserted into @@ -67,82 +67,82 @@ destination directory on the inpath and rebuild.) specifying options like <-classpath> in argument files unlike the argument file is the only build specification. The form <@file> is the same as specifying <-argfile file>. --outjar :: +`-outjar `:: Put output classes in zip file output.jar. --outxml:: +`-outxml`:: Generate aop.xml file for load-time weaving with default name. --outxmlfile :: +`-outxmlfile `:: Generate aop.xml file for load-time weaving with custom name. --incremental:: +`-incremental`:: Run the compiler continuously. After the initial compilation, the compiler will wait to recompile until it reads a newline from the standard input, and will quit when it reads a 'q'. It will only recompile necessary components, so a recompile should be much faster than doing a second compile. This requires -sourceroots. --sourceroots :: +`-sourceroots `:: Find and build all .java or .aj source files under any directory listed in DirPaths. DirPaths, like classpath, is a single argument containing a list of paths to directories, delimited by the platform- specific classpath delimiter. Required by -incremental. --crossrefs:: +`-crossrefs`:: Generate a build .ajsym file into the output directory. Used for viewing crosscutting references by tools like the AspectJ Browser. --emacssym:: +`-emacssym`:: Generate .ajesym symbol files for emacs support (deprecated). --Xlint:: +`-Xlint`:: Same as -Xlint:warning (enabled by default) --Xlint:\{level}:: +`-Xlint:{level}`:: Set default level for messages about potential programming mistakes in crosscutting code. \{level} may be ignore, warning, or error. This overrides entries in org/aspectj/weaver/XlintDefault.properties from aspectjtools.jar, but does not override levels set using the -Xlintfile option. --Xlintfile :: +`-Xlintfile `:: Specify properties file to set levels for specific crosscutting messages. PropertyFile is a path to a Java .properties file that takes the same property names and values as org/aspectj/weaver/XlintDefault.properties from aspectjtools.jar, which it also overrides. --help:: +`-help`:: Emit information on compiler options and usage --version:: +`-version`:: Emit the version of the AspectJ compiler --classpath :: +`-classpath `:: Specify where to find user class files. Path is a single argument containing a list of paths to zip files or directories, delimited by the platform-specific path delimiter. --bootclasspath :: +`-bootclasspath `:: Override location of VM's bootclasspath for purposes of evaluating types when compiling. Path is a single argument containing a list of paths to zip files or directories, delimited by the platform-specific path delimiter. --extdirs :: +`-extdirs `:: Override location of VM's extension directories for purposes of evaluating types when compiling. Path is a single argument containing a list of paths to directories, delimited by the platform-specific path delimiter. --d :: +`-d `:: Specify where to place generated .class files. If not specified, defaults to the current working dir. --target <[1.1 to 1.5]>:: +`-target <[1.1 to 1.5]>`:: Specify classfile target setting (1.1 to 1.5, default is 1.2) --1.3:: +`-1.3`:: Set compliance level to 1.3 This implies -source 1.3 and -target 1.1. --1.4:: +`-1.4`:: Set compliance level to 1.4 (default) This implies -source 1.4 and -target 1.2. --1.5:: +`-1.5`:: Set compliance level to 1.5. This implies -source 1.5 and -target 1.5. --source <[1.3|1.4|1.5]>:: +`-source <[1.3|1.4|1.5]>`:: Toggle assertions (1.3, 1.4, or 1.5 - default is 1.4). When using -source 1.3, an assert() statement valid under Java 1.4 will result in a compiler error. When using -source 1.4, treat `assert` as a keyword and implement assertions according to the 1.4 language spec. When using -source 1.5, Java 5 language features are permitted. --nowarn:: +`-nowarn`:: Emit no warnings (equivalent to '-warn:none') This does not suppress messages generated by `declare warning` or `Xlint`. --warn: :: +`-warn: `:: Emit warnings for any instances of the comma-delimited list of questionable code (eg '-warn:unusedLocals,deprecation'): + @@ -160,13 +160,13 @@ none suppress all compiler warnings + `-warn:none` does not suppress messages generated by `declare warning` or `Xlint`. --deprecation:: +`-deprecation`:: Same as -warn:deprecation --noImportError:: +`-noImportError`:: Emit no errors for unresolved imports --proceedOnError:: +`-proceedOnError`:: Keep compiling after error, dumping class files with problem methods --g<:[lines,vars,source]>:: +`-g<:[lines,vars,source]>`:: debug attributes level, that may take three forms: + [source, text] @@ -176,54 +176,54 @@ none suppress all compiler warnings -g:{items} debug info for any/all of [lines, vars, source], e.g., -g:lines,source .... --preserveAllLocals:: +`-preserveAllLocals`:: Preserve all local variables during code generation (to facilitate debugging). --referenceInfo:: +`-referenceInfo`:: Compute reference information. --encoding :: +`-encoding `:: Specify default source encoding format. Specify custom encoding on a per file basis by suffixing each input source file/folder name with '[encoding]'. --verbose:: +`-verbose`:: Emit messages about accessed/processed compilation units --showWeaveInfo:: +`-showWeaveInfo`:: Emit messages about weaving --log :: +`-log `:: Specify a log file for compiler messages. --progress:: +`-progress`:: Show progress (requires -log mode). --time:: +`-time`:: Display speed information. --noExit:: +`-noExit`:: Do not call System.exit(n) at end of compilation (n=0 if no error) --repeat :: +`-repeat `:: Repeat compilation process N times (typically to do performance analysis). --XterminateAfterCompilation:: +`-XterminateAfterCompilation`:: Causes compiler to terminate before weaving --XaddSerialVersionUID:: +`-XaddSerialVersionUID`:: Causes the compiler to calculate and add the SerialVersionUID field to any type implementing Serializable that is affected by an aspect. The field is calculated based on the class before weaving has taken place. --Xreweavable[:compress]:: +`-Xreweavable[:compress]`:: (Experimental - deprecated as now default) Runs weaver in reweavable mode which causes it to create woven classes that can be rewoven, subject to the restriction that on attempting a reweave all the types that advised the woven type must be accessible. --XnoInline:: +`-XnoInline`:: (Experimental) do not inline around advice --XincrementalFile :: +`-XincrementalFile `:: (Experimental) This works like incremental mode, but using a file rather than standard input to control the compiler. It will recompile each time file is changed and and halt when file is deleted. --XserializableAspects:: +`-XserializableAspects`:: (Experimental) Normally it is an error to declare aspects Serializable. This option removes that restriction. --XnotReweavable:: +`-XnotReweavable`:: (Experimental) Create class files that can't be subsequently rewoven by AspectJ. --Xajruntimelevel:1.2, ajruntimelevel:1.5:: +`-Xajruntimelevel:1.2, ajruntimelevel:1.5`:: (Experimental) Allows code to be generated that targets a 1.2 or a 1.5 level AspectJ runtime (default 1.5) diff --git a/docs/devGuideDB/ltw.adoc b/docs/devGuideDB/ltw.adoc index 7b216ba76..7f25562db 100644 --- a/docs/devGuideDB/ltw.adoc +++ b/docs/devGuideDB/ltw.adoc @@ -83,35 +83,37 @@ interfaces for integration of AspectJ load-time weaving in custom environments. Agents:: - AspectJ 5 ships with a load-time weaving agent that enables load-time - weaving. This agent and its configuration is execution environment - dependent. Configuration for the supported environments is discussed - later in this chapter. - + - Using Java 5 JVMTI you can specify the - `-javaagent:pathto/aspectjweaver.jar` option to the JVM. - + - Since AspectJ 1.9.7, the obsolete Oracle/BEA JRockit agent is no - longer part of AspectJ. JRockit JDK never supported Java versions - higher than 1.6. Several JRockit JVM features are now part of HotSpot - and tools like Mission Control available for OpenJDK and Oracle JDK. +AspectJ 5 ships with a load-time weaving agent that enables load-time +weaving. This agent and its configuration is execution environment +dependent. Configuration for the supported environments is discussed +later in this chapter. ++ +Using Java 5 JVMTI you can specify the +`-javaagent:pathto/aspectjweaver.jar` option to the JVM. ++ +Since AspectJ 1.9.7, the obsolete Oracle/BEA JRockit agent is no +longer part of AspectJ. JRockit JDK never supported Java versions +higher than 1.6. Several JRockit JVM features are now part of HotSpot +and tools like Mission Control available for OpenJDK and Oracle JDK. + Command-line wrapper scripts `aj`:: - The `aj` command runs Java programs in Java 1.4 or later by setting up - `WeavingURLClassLoader` as the system class loader. For more - information, see xref:#aj[`aj`, the AspectJ load-time weaving launcher]. - + - The `aj5` command runs Java programs in Java 5 by using the - `-javaagent:pathto/aspectjweaver.jar` option described above. For more - information, see xref:#aj[`aj`, the AspectJ load-time weaving launcher]. +The `aj` command runs Java programs in Java 1.4 or later by setting up +`WeavingURLClassLoader` as the system class loader. For more +information, see xref:#aj[`aj`, the AspectJ load-time weaving launcher]. ++ +The `aj5` command runs Java programs in Java 5 by using the +`-javaagent:pathto/aspectjweaver.jar` option described above. For more +information, see xref:#aj[`aj`, the AspectJ load-time weaving launcher]. + Custom class loader:: - A public interface is provided to allow a user written class loader to - instantiate a weaver and weave classes after loading and before - defining them in the JVM. This enables load-time weaving to be - supported in environments where no weaving agent is available. It also - allows the user to explicitly restrict by class loader which classes - can be woven. For more information, see xref:#aj[`aj`, the AspectJ load-time weaving launcher] and the API - documentation and source for `WeavingURLClassLoader` and - `WeavingAdapter`. +A public interface is provided to allow a user written class loader to +instantiate a weaver and weave classes after loading and before +defining them in the JVM. This enables load-time weaving to be +supported in environments where no weaving agent is available. It also +allows the user to explicitly restrict by class loader which classes +can be woven. For more information, see xref:#aj[`aj`, the AspectJ load-time weaving launcher] and the API +documentation and source for `WeavingURLClassLoader` and +`WeavingAdapter`. [[configuring-load-time-weaving-with-aopxml-files]] ==== Configuring Load-time Weaving with aop.xml files diff --git a/docs/progGuideDB/semantics.adoc b/docs/progGuideDB/semantics.adoc index aa46cf18d..261d6c944 100644 --- a/docs/progGuideDB/semantics.adoc +++ b/docs/progGuideDB/semantics.adoc @@ -52,41 +52,38 @@ Method execution:: When the body of code for an actual method executes. Constructor call:: When an object is built and that object's initial constructor is - called (i.e., not for "super" or "this" constructor calls). The object + called (i.e., not for `super` or `this` constructor calls). The object being constructed is returned at a constructor call join point, so its return type is considered to be the type of the object, and the object - itself may be accessed with - + - after returning - + - advice. + itself may be accessed with `after returning` advice. Constructor execution:: When the body of code for an actual constructor executes, after its this or super constructor call. The object being constructed is the - currently executing object, and so may be accessed with the `_this_` pointcut. The constructor execution join point for a constructor that + currently executing object, and so may be accessed with the `this()` pointcut. + The constructor execution join point for a constructor that calls a super constructor also includes any non-static initializers of enclosing class. No value is returned from a constructor execution - join point, so its return type is considered to be void. + join point, so its return type is considered to be `void`. Static initializer execution:: When the static initializer for a class executes. No value is returned from a static initializer execution join point, so its return type is - considered to be void. + considered to be `void`. Object pre-initialization:: Before the object initialization code for a particular class runs. This encompasses the time between the start of its first called constructor and the start of its parent's constructor. Thus, the execution of these join points encompass the join points of the - evaluation of the arguments of `_this()_` and `_super()_` constructor calls. No value is returned from an object - pre-initialization join point, so its return type is considered to be - void. + evaluation of the arguments of `this()` and `super()` constructor calls. + No value is returned from an object pre-initialization join point, so its + return type is considered to be `void`. Object initialization:: When the object initialization code for a particular class runs. This encompasses the time between the return of its parent's constructor and the return of its first called constructor. It includes all the dynamic initializers and constructors used to create the object. The object being constructed is the currently executing object, and so may - be accessed with the `_this_` pointcut. No value is returned from a constructor execution join - point, so its return type is considered to be void. + be accessed with the `this()` pointcut. No value is returned from a constructor + execution join point, so its return type is considered to be `void`. Field reference:: When a non-constant field is referenced. [Note that references to constant fields (static final fields bound to a constant string object @@ -96,8 +93,8 @@ Field set:: When a field is assigned to. Field set join points are considered to have one argument, the value the field is being set to. No value is returned from a field set join point, so its return type is considered - to be void. [Note that the initializations of constant fields (static - final fields where the initializer is a constant string object or + to be void. [Note that the initializations of constant fields (`static final` + fields where the initializer is a constant string object or primitive value) are not join points, since Java requires their references to be inlined.] Handler execution:: @@ -979,43 +976,42 @@ pointcut doesNotThrowMathlike(): call(* *(..) throws !*..*Math*); .... -A is a comma-separated list of -s, where +A `ThrowsClausePattern` is a comma-separated list of ``ThrowsClausePatternItem``s, where - ::: - [ ! ] - + - TypeNamePattern +`ThrowsClausePatternItem`: :: + `[ ! ] TypeNamePattern` -A matches the throws clause of any code member +A `ThrowsClausePattern` matches the `throws` clause of any code member signature. To match, each `ThrowsClausePatternItem` must match the throws clause of the member in question. If any item doesn't match, then the whole pattern doesn't match. -If a ThrowsClausePatternItem begins with "!", then it matches a +If a `ThrowsClausePatternItem` begins with `!`, then it matches a particular throws clause if and only if _none_ of the types named in the -throws clause is matched by the `TypeNamePattern`. +`throws` clause is matched by the `TypeNamePattern`. -If a does not begin with "!", then it matches -a throws clause if and only if _any_ of the types named in the throws -clause is matched by the _TypeNamePattern_. +If a `ThrowsClausePatternItem` does not begin with `!`, then it matches +a throws clause if and only if _any_ of the types named in the `throws` +clause is matched by the `TypeNamePattern`. -The rule for "!" matching has one potentially surprising property, in +The rule for `!` matching has one potentially surprising property, in that these two pointcuts -* call(* *(..) throws !IOException) -* call(* *(..) throws (!IOException)) +. `call(* *(..) throws !IOException)` +. `call(* *(..) throws (!IOException))` will match differently on calls to -____ -void m() throws RuntimeException, IOException \{} -____ +[source, java] +.... +void m() throws RuntimeException, IOException {} +.... + +[1] will *not* match the method `m()`, because ``m``'s throws clause +declares that it `throws IOException`. -[1] will NOT match the method m(), because method m's throws clause -declares that it throws IOException. [2] WILL match the method m(), -because method m's throws clause declares the it throws some exception -which does not match IOException, i.e. RuntimeException. +[2] *will* match the method `m()`, because ``m``'s throws clause declares that +it throws some exception which does not match `IOException`, i.e. `RuntimeException`. ==== Type patterns @@ -1031,45 +1027,21 @@ First, all type names are also type patterns. So `Object`, If a type pattern is an exact type - if it doesn't include a wildcard - then the matching works just like normal type lookup in Java: -* Patterns that have the same names as primitive types (like -+ -int -+ -) match those primitive types. -* Patterns that are qualified by package names (like -+ -java.util.HashMap -+ -) match types in other packages. -* Patterns that are not qualified (like -+ -HashMap -+ -) match types that are resolved by Java's normal scope rules. So, for -example, -+ -HashMap -+ -might match a package-level type in the same package or a type that have -been imported with java's -+ -import -+ -form. But it would not match -+ -java.util.HashMap -+ -unless the aspect were in -+ -java.util -+ -or the type had been imported. +* Patterns that have the same names as primitive types (like `int`) match those + primitive types. +* Patterns that are qualified by package names (like `java.util.HashMap`) match + types in other packages. +* Patterns that are not qualified (like `HashMap`) match types that are resolved + by Java's normal scope rules. So, for example, `HashMap` might match a package-level + type in the same package or a type that have been imported with Java's `import` + form. But it would not match `java.util.HashMap` unless the aspect were in `java.util` + or the type had been imported. So exact type patterns match based on usual Java scope rules. ===== Type name patterns -There is a special type name, *, which is also a type pattern. * picks +There is a special type name, `\*`, which is also a type pattern. `*` picks out all types, including primitive types. So [source, java] @@ -1080,9 +1052,9 @@ call(void foo(*)) picks out all call join points to void methods named foo, taking one argument of any type. -Type names that contain the two wildcards "*" and "`..`" are also type -patterns. The * wildcard matches zero or more characters characters -except for ".", so it can be used when types have a certain naming +Type names that contain the two wildcards `\*` and `..` are also type +patterns. The `*` wildcard matches zero or more characters characters +except for `.`, so it can be used when types have a certain naming convention. So [source, java] @@ -1090,7 +1062,7 @@ convention. So handler(java.util.*Map) .... -picks out the types java.util.Map and java.util.java.util.HashMap, among +picks out the types `java.util.Map` and `java.util.java.util.HashMap`, among others, and [source, java] @@ -1098,12 +1070,12 @@ others, and handler(java.util.*) .... -picks out all types that start with "`java.util.`" and don't have any -more "."s, that is, the types in the `java.util` package, but not inner -types (such as java.util.Map.Entry). +picks out all types that start with `java.util.` and don't have any +more ``.``s, that is, the types in the `java.util` package, but not inner +types (such as `java.util.Map.Entry`). -The "`..`" wildcard matches any sequence of characters that start and -end with a ".", so it can be used to pick out all types in any +The `..` wildcard matches any sequence of characters that start and +end with a `.`, so it can be used to pick out all types in any subpackage, or all inner types. So [source, java] @@ -1112,7 +1084,7 @@ within(com.xerox..*) .... picks out all join points where the code is in any declaration of a type -whose name begins with "`com.xerox.`". +whose name begins with `com.xerox.`. Type patterns with wildcards do not depend on Java's usual scope rules - they match against all types available to the weaver, not just those @@ -1121,7 +1093,7 @@ that are imported into an Aspect's declaring file. ===== Subtype patterns It is possible to pick out all subtypes of a type (or a collection of -types) with the "+" wildcard. The "+" wildcard follows immediately a +types) with the `+` wildcard. The `+` wildcard follows immediately a type name pattern. So, while [source, java] @@ -1130,7 +1102,7 @@ call(Foo.new()) .... picks out all constructor call join points where an instance of exactly -type Foo is constructed, +type `Foo` is constructed, [source, java] .... @@ -1138,7 +1110,7 @@ call(Foo+.new()) .... picks out all constructor call join points where an instance of any -subtype of Foo (including Foo itself) is constructed, and the unlikely +subtype of `Foo` (including `Foo` itself) is constructed, and the unlikely [source, java] .... @@ -1146,7 +1118,7 @@ call(*Handler+.new()) .... picks out all constructor call join points where an instance of any -subtype of any type whose name ends in "Handler" is constructed. +subtype of any type whose name ends in `Handler` is constructed. ===== Array type patterns @@ -1165,16 +1137,16 @@ and array type patterns, and constructed with boolean operators `&&`, staticinitialization(Foo || Bar) .... -picks out the static initializer execution join points of either Foo or -Bar, and +picks out the static initializer execution join points of either `Foo` or +`Bar`, and [source, java] .... call((Foo+ && ! Foo).new(..)) .... -picks out the constructor call join points when a subtype of Foo, but -not Foo itself, is constructed. +picks out the constructor call join points when a subtype of `Foo`, but +not `Foo` itself, is constructed. ==== Pattern Summary @@ -1211,67 +1183,22 @@ ModifiersPattern = Each piece of advice is of the form -____ -[ strictfp ] - -AdviceSpec - -[ throws - -TypeList - -] : - -Pointcut - -\{ - -Body - -} -____ +[source, text] +.... +[ strictfp ] AdviceSpec [ throws TypeList ] : Pointcut { Body } +.... -where is one of +where `AdviceSpec` is one of -* before( -+ -Formals -+ -) -* after( -+ -Formals -+ -) returning [ ( -+ -Formal -+ -) ] -* after( -+ -Formals -+ -) throwing [ ( -+ -Formal -+ -) ] -* after( -+ -Formals -+ -) -* Type -+ -around( -+ -Formals -+ -) +* `before( Formals )` +* `after( Formals ) returning [ ( Formal ) ]` +* `after( Formals ) throwing [ ( Formal ) ]` +* `after( Formals )` +* `Type around( Formals )` -and where refers to a variable binding like those used for -method parameters, of the form `Type` `Variable-Name`, and -refers to a comma-delimited list of . +and where `Formal` refers to a variable binding like those used for +method parameters, of the form `Type` `Variable-Name`, and `Formals` +refers to a comma-delimited list of `Formal`. Advice defines crosscutting behavior. It is defined in terms of pointcuts. The code of a piece of advice runs at every join point picked @@ -1536,9 +1463,9 @@ points cannot throw ``FileNotFoundException``s. The exceptions that each kind of join point in AspectJ may throw are: method call and execution:: - the checked exceptions declared by the target method's `_throws_` clause. + the checked exceptions declared by the target method's `throws` clause. constructor call and execution:: - the checked exceptions declared by the target constructor's `_throws_` clause. + the checked exceptions declared by the target constructor's `throws` clause. field get and set:: no checked exceptions can be thrown from these join points. exception handler execution:: @@ -1546,9 +1473,9 @@ exception handler execution:: static initializer execution:: no checked exceptions can be thrown from these join points. pre-initialization and initialization:: - any exception that is in the throws clause of all constructors of the initialized class. + any exception that is in the `throws` clause of all constructors of the initialized class. advice execution:: - any exception that is in the throws clause of the advice. + any exception that is in the `throws` clause of the advice. ==== Advice precedence @@ -1563,33 +1490,23 @@ advice has precedence over another when they advise the same join point. If the two pieces of advice are defined in different aspects, then there are three cases: -* If aspect A is matched earlier than aspect B in some -+ -declare precedence -+ -form, then all advice in concrete aspect A has precedence over all -advice in concrete aspect B when they are on the same join point. -* Otherwise, if aspect A is a subaspect of aspect B, then all advice -defined in A has precedence over all advice defined in B. So, unless -otherwise specified with -+ -declare precedence -+ -, advice in a subaspect has precedence over advice in a superaspect. +* If aspect `A` is matched earlier than aspect `B` in some `declare precedence` + form, then all advice in concrete aspect `A` has precedence over all + advice in concrete aspect `B` when they are on the same join point. +* Otherwise, if aspect `A` is a subaspect of aspect `B`, then all advice + defined in `A` has precedence over all advice defined in `B`. So, unless + otherwise specified with `declare precedence`, advice in a subaspect has + precedence over advice in a superaspect. * Otherwise, if two pieces of advice are defined in two different -aspects, it is undefined which one has precedence. + aspects, it is undefined which one has precedence. If the two pieces of advice are defined in the same aspect, then there are two cases: -* If either are -+ -after -+ -advice, then the one that appears later in the aspect has precedence -over the one that appears earlier. +* If either are `after` advice, then the one that appears later in the aspect has precedence + over the one that appears earlier. * Otherwise, then the one that appears earlier in the aspect has -precedence over the one that appears later. + precedence over the one that appears later. These rules can lead to circularity, such as @@ -1650,16 +1567,16 @@ picks out calls to many methods. Yet the body of advice over this pointcut may wish to have access to the method name or parameters of a particular join point. -`thisJoinPoint` is bound to a complete join point object. +* `thisJoinPoint` is bound to a complete join point object. -`thisJoinPointStaticPart` is bound to a part of the join point object -that includes less information, but for which no memory allocation is -required on each execution of the advice. It is equivalent to -`thisJoinPoint.getStaticPart()`. +* `thisJoinPointStaticPart` is bound to a part of the join point object + that includes less information, but for which no memory allocation is + required on each execution of the advice. It is equivalent to + `thisJoinPoint.getStaticPart()`. -`thisEnclosingJoinPointStaticPart` is bound to the static part of the -join point enclosing the current join point. Only the static part of -this enclosing join point is available through this mechanism. +* `thisEnclosingJoinPointStaticPart` is bound to the static part of the + join point enclosing the current join point. Only the static part of + this enclosing join point is available through this mechanism. Standard Java reflection uses objects from the `java.lang.reflect` hierarchy to build up its reflective objects. Similarly, AspectJ join @@ -1683,56 +1600,8 @@ with other types. An inter-type method declaration looks like -* [ -+ -Modifiers -+ -] -+ -Type -+ -OnType -+ -. -+ -Id -+ -( -+ -Formals -+ -) [ -+ -ThrowsClause -+ -] \{ -+ -Body -+ -} -* abstract [ -+ -Modifiers -+ -] -+ -Type -+ -OnType -+ -. -+ -Id -+ -( -+ -Formals -+ -) [ -+ -ThrowsClause -+ -] ; +* `[ Modifiers ] Type OnType . Id ( Formals ) [ ThrowsClause ] { Body }` +* `abstract [ Modifiers ] Type OnType . Id ( Formals ) [ ThrowsClause ] ;` The effect of such a declaration is to make support the new method. Even if is an interface. Even if the method is neither @@ -1755,27 +1624,7 @@ aspect A { An inter-type constructor declaration looks like -* [ -+ -Modifiers -+ -] -+ -OnType -+ -. new ( -+ -Formals -+ -) [ -+ -ThrowsClause -+ -] \{ -+ -Body -+ -} +* `[ Modifiers ] OnType . new ( Formals ) [ ThrowsClause ] { Body }` The effect of such a declaration is to make support the new constructor. It is an error for to be an interface. @@ -1793,43 +1642,11 @@ constructor is defined. An inter-type field declaration looks like one of -* [ -+ -Modifiers -+ -] -+ -Type -+ -OnType -+ -. -+ -Id -+ -= -+ -Expression -+ -; -* [ -+ -Modifiers -+ -] -+ -Type -+ -OnType -+ -. -+ -Id -+ -; +* `[ Modifiers ] Type OnType . Id = Expression ;` +* `[ Modifiers ] Type OnType . Id ;` -The effect of such a declaration is to make support the new -field. Even if is an interface. Even if the field is neither +The effect of such a declaration is to make `OnType` support the new +field. Even if `OnType` is an interface. Even if the field is neither public, nor static, nor final. The initializer, if any, of an inter-type field declaration runs before @@ -1837,7 +1654,7 @@ the class-local initializers defined in its target class. Any occurrence of the identifier `this` in the body of an inter-type constructor or method declaration, or in the initializer of an -inter-type field declaration, refers to the object rather than +inter-type field declaration, refers to the `OnType` object rather than to the aspect type; it is an error to access `this` in such a position from a `static` inter-type member declaration. @@ -1891,11 +1708,11 @@ however, is only accessible from the code inside of aspect `A`. The aspect also declares that `onType` has a method "`register`", but makes this method accessible from everywhere. -If `onType` already defines a private or package-protected field "`r`", +If `onType` already defines a private or package-protected field `r`, there is no conflict: The aspect cannot see such a field, and no code in -`otherPackage` can see the inter-type "`r`". +`otherPackage` can see the inter-type `r`. -If `onType` defines a public field "`r`", there is a conflict: The +If `onType` defines a public field `r`, there is a conflict: The expression [source, java] @@ -1903,33 +1720,22 @@ expression this.r = r .... -is an error, since it is ambiguous whether the private inter-type "`r`" -or the public locally-defined "`r`" should be used. +is an error, since it is ambiguous whether the private inter-type `r` +or the public locally-defined `r` should be used. -If `onType` defines a method "`register(Registry)`" there is a conflict, +If `onType` defines a method `register(Registry)` there is a conflict, since it would be ambiguous to any code that could see such a defined -method which "`register(Registry)`" method was applicable. +method which `register(Registry)` method was applicable. Conflicts are resolved as much as possible as per Java's conflict resolution rules: -* A subclass can inherit multiple -+ -fields -+ -from its superclasses, all with the same name and type. However, it is -an error to have an ambiguous -+ -reference -+ -to a field. -* A subclass can only inherit multiple -+ -methods -+ -with the same name and argument types from its superclasses if only zero -or one of them is concrete (i.e., all but one is abstract, or all are -abstract). +* A subclass can inherit multiple fields from its superclasses, all with the + same name and type. However, it is an error to have an ambiguous reference + to a field. +* A subclass can only inherit multiple methods with the same name and argument + types from its superclasses if only zero or one of them is concrete (i.e., all + but one is abstract, or all are abstract). Given a potential conflict between inter-type member declarations in different aspects, if one aspect has precedence over the other its @@ -1944,24 +1750,8 @@ An aspect may change the inheritance hierarchy of a system by changing the superclass of a type or adding a superinterface onto a type, with the `declare parents` form. -* declare parents: -+ -TypePattern -+ -extends -+ -Type -+ -; -* declare parents: -+ -TypePattern -+ -implements -+ -TypeList -+ -; +* `declare parents: TypePattern extends Type ;` +* `declare parents: TypePattern implements TypeList ;` For example, if an aspect wished to make a particular class runnable, it might define appropriate inter-type `void @@ -2016,28 +1806,12 @@ Object M C O N D Q P E An aspect may specify that a particular join point should never be reached. -* declare error: -+ -Pointcut -+ -: -+ -String -+ -; -* declare warning: -+ -Pointcut -+ -: -+ -String -+ -; +* `declare error: Pointcut : String ;` +* `declare warning: Pointcut : String ;` -If the compiler determines that a join point in could +If the compiler determines that a join point in `Pointcut` could possibly be reached, then it will signal either an error or warning, as -declared, using the for its message. +declared, using the `String` for its message. ==== Softened exceptions @@ -2047,15 +1821,7 @@ system and instead be thrown as a `org.aspectj.lang.SoftException`, which is subtype of `RuntimeException` and thus does not need to be declared. -* declare soft: -+ -Type -+ -: -+ -Pointcut -+ -; +* `declare soft: Type : Pointcut ;` For example, the aspect @@ -2109,17 +1875,13 @@ abstract aspect A { An aspect may declare a precedence relationship between concrete aspects with the `declare precedence` form: -* declare precedence : -+ -TypePatternList -+ -; +* `declare precedence : TypePatternList ;` This signifies that if any join point has advice from two concrete -aspects matched by some pattern in , then the +aspects matched by some pattern in `TypePatternList`, then the precedence of the advice will be the order of in the list. -In , the wildcard "*" can appear at most once, and it +In `TypePatternList`, the wildcard `*` can appear at most once, and it means "any type not matched by any other pattern in the list". For example, the constraints that (1) aspects that have Security as part @@ -2132,12 +1894,12 @@ over all non-security aspects, can be expressed by: declare precedence: *..*Security*, Logging+, *; .... -For another example, the CountEntry aspect might want to count the entry +For another example, the `CountEntry` aspect might want to count the entry to methods in the current package accepting a Type object as its first argument. However, it should count all entries, even those that the -aspect DisallowNulls causes to throw exceptions. This can be -accomplished by stating that CountEntry has precedence over -DisallowNulls. This declaration could be in either aspect, or in +aspect `DisallowNulls` causes to throw exceptions. This can be +accomplished by stating that `CountEntry` has precedence over +`DisallowNulls`. This declaration could be in either aspect, or in another, ordering aspect: [source, java] @@ -2145,17 +1907,19 @@ another, ordering aspect: aspect Ordering { declare precedence: CountEntry, DisallowNulls; } + aspect DisallowNulls { pointcut allTypeMethods(Type obj): call(* *(..)) && args(obj, ..); before(Type obj): allTypeMethods(obj) { - if (obj == null) throw new RuntimeException(); + if (obj == null) throw new RuntimeException(); } } + aspect CountEntry { pointcut allTypeMethods(Type obj): call(* *(..)) && args(obj, ..); static int count = 0; before(): allTypeMethods(Type) { - count++; + count++; } } .... @@ -2181,8 +1945,8 @@ declare precedence: A, B; .... And a system in which both constraints are active may also be legal, so -long as advice from A and B don't share a join point. So this is an -idiom that can be used to enforce that A and B are strongly independent. +long as advice from `A` and `B` don't share a join point. So this is an +idiom that can be used to enforce that `A` and `B` are strongly independent. ===== Applies to concrete aspects @@ -2248,12 +2012,12 @@ Consequently, such pointcuts may not include, directly or indirectly based on dynamic (runtime) context. Therefore, such pointcuts may not be defined in terms of -* cflow -* cflowbelow -* this -* target -* args -* if +* `cflow` +* `cflowbelow` +* `this` +* `target` +* `args` +* `if` all of which can discriminate on runtime information. @@ -2332,70 +2096,46 @@ the concrete aspect class. ===== Singleton Aspects -* aspect -+ -Id -+ -\{ ... } -* aspect -+ -Id -+ -issingleton() \{ ... } +* `aspect Id { ... }` +* `aspect Id issingleton() { ... }` By default (or by using the modifier `issingleton()`) an aspect has exactly one instance that cuts across the entire program. That instance is available at any time during program execution from the static method `aspectOf()` automatically defined on all concrete aspects -- so, in the -above examples, `A.aspectOf()` will return A's instance. This aspect +above examples, `A.aspectOf()` will return ``A``'s instance. This aspect instance is created as the aspect's classfile is loaded. Because the an instance of the aspect exists at all join points in the running of a program (once its class is loaded), its advice will have a chance to run at all such join points. -(In actuality, one instance of the aspect A is made for each version of -the aspect A, so there will be one instantiation for each time A is +(In actuality, one instance of the aspect `A` is made for each version of +the aspect `A`, so there will be one instantiation for each time `A` is loaded by a different classloader.) ===== Per-object aspects -* aspect -+ -Id -+ -perthis( -+ -Pointcut -+ -) \{ ... } -* aspect -+ -Id -+ -pertarget( -+ -Pointcut -+ -) \{ ... } +* `aspect Id perthis( Pointcut ) { ... }` +* `aspect Id pertarget( Pointcut ) { ... }` -If an aspect A is defined `perthis(Pointcut)`, then one object of type A -is created for every object that is the executing object (i.e., "this") -at any of the join points picked out by . The advice defined -in A will run only at a join point where the currently executing object -has been associated with an instance of A. +If an aspect `A` is defined `perthis(Pointcut)`, then one object of type `A` +is created for every object that is the executing object (i.e., `this`) +at any of the join points picked out by `Pointcut`. The advice defined +in `A` will run only at a join point where the currently executing object +has been associated with an instance of `A`. -Similarly, if an aspect A is defined `pertarget(Pointcut)`, then one -object of type A is created for every object that is the target object -of the join points picked out by . The advice defined in A +Similarly, if an aspect `A` is defined `pertarget(Pointcut)`, then one +object of type `A` is created for every object that is the target object +of the join points picked out by `Pointcut`. The advice defined in `A` will run only at a join point where the target object has been -associated with an instance of A. +associated with an instance of `A`. In either case, the static method call `A.aspectOf(Object)` can be used -to get the aspect instance (of type A) registered with the object. Each +to get the aspect instance (of type `A`) registered with the object. Each aspect instance is created as early as possible, but not before reaching a join point picked out by where there is no associated -aspect of type A. +aspect of type `A`. Both `perthis` and `pertarget` aspects may be affected by code the AspectJ compiler controls, as discussed in the xref:implementation.adoc#implementation[Implementation Notes] @@ -2403,32 +2143,16 @@ appendix. ===== Per-control-flow aspects -* aspect -+ -Id -+ -percflow( -+ -Pointcut -+ -) \{ ... } -* aspect -+ -Id -+ -percflowbelow( -+ -Pointcut -+ -) \{ ... } +* `aspect Id percflow( Pointcut ) { ... }` +* `aspect Id percflowbelow( Pointcut ) { ... }` -If an aspect A is defined `percflow(Pointcut)` or -`percflowbelow(Pointcut)`, then one object of type A is created for each -flow of control of the join points picked out by , either as +If an aspect `A` is defined `percflow(Pointcut)` or +`percflowbelow(Pointcut)`, then one object of type `A` is created for each +flow of control of the join points picked out by `Pointcut`, either as the flow of control is entered, or below the flow of control, -respectively. The advice defined in A may run at any join point in or +respectively. The advice defined in `A` may run at any join point in or under that control flow. During each such flow of control, the static -method `A.aspectOf()` will return an object of type A. An instance of +method `A.aspectOf()` will return an object of type `A`. An instance of the aspect is created upon entry into each such control flow. ===== Aspect instantiation and advice @@ -2468,11 +2192,7 @@ xref:../api/org/aspectj/lang/NoAspectBoundException.html[`org.aspectj.lang.NoAsp ==== Aspect privilege -* privileged aspect -+ -Id -+ -\{ ... } +* `privileged aspect Id { ... }` Code written in aspects is subject to the same access control rules as Java code when referring to members of classes or aspects. So, for @@ -2500,7 +2220,7 @@ privileged aspect A { } .... -In this case, if A had not been declared privileged, the field reference +In this case, if `A` had not been declared privileged, the field reference c.i would have resulted in an error signaled by the compiler. If a privileged aspect can access multiple versions of a particular @@ -2522,9 +2242,9 @@ privileged aspect A { } .... -A's private inter-type field C.i, initially bound to 999, will be +``A``'s private inter-type field C.i, initially bound to 999, will be referenced in the body of the advice in preference to C's privately -declared field, since the A would have access to its own inter-type +declared field, since `A` would have access to its own inter-type fields even if it were not privileged. Note that a privileged aspect can access private inter-type declarations -- 2.39.5