diff options
author | Alexander Kriegisch <Alexander@Kriegisch.name> | 2024-02-01 11:57:10 +0700 |
---|---|---|
committer | Alexander Kriegisch <Alexander@Kriegisch.name> | 2024-02-01 11:57:10 +0700 |
commit | bbe629bc4a5e8c76a0b31686eedc88add5d71360 (patch) | |
tree | c03cca36ccdd16f37e23ff66c191381a41b5ed8a /docs/progguide/semantics.adoc | |
parent | d6056515f8078572dd35cd091fb31ba48e9d8b53 (diff) | |
download | aspectj-bbe629bc4a5e8c76a0b31686eedc88add5d71360.tar.gz aspectj-bbe629bc4a5e8c76a0b31686eedc88add5d71360.zip |
Always use ":leveloffset: +1" with ":doctype: book"
Headlines per ADOC file should start at level 1, not 2. Adjusting the
level offset for books helps to avoid warnings when including book
chapters, but still allows to also use the chapters as stand-alone
documents.
Signed-off-by: Alexander Kriegisch <Alexander@Kriegisch.name>
Diffstat (limited to 'docs/progguide/semantics.adoc')
-rw-r--r-- | docs/progguide/semantics.adoc | 134 |
1 files changed, 67 insertions, 67 deletions
diff --git a/docs/progguide/semantics.adoc b/docs/progguide/semantics.adoc index 0cb513ad0..d993d2fcb 100644 --- a/docs/progguide/semantics.adoc +++ b/docs/progguide/semantics.adoc @@ -1,8 +1,8 @@ [[semantics]] -== Language Semantics += Language Semantics [[semantics-intro]] -=== Introduction +== Introduction AspectJ extends Java by overlaying a concept of join points onto the existing Java semantics and adding a few new program elements to Java: @@ -35,7 +35,7 @@ possible to do reasoning at compile time. Aspects are defined by the `aspect` declaration. [[semantics-joinPoints]] -=== Join Points +== Join Points While aspects define types that crosscut, the AspectJ system does not allow completely arbitrary crosscutting. Rather, aspects define types @@ -152,7 +152,7 @@ bodies or static initializers. methods or fields. [[semantics-pointcuts]] -=== Pointcuts +== Pointcuts A pointcut is a program element that picks out join points and exposes data from the execution context of those join points. Pointcuts are used @@ -233,7 +233,7 @@ provided by the language are: `( Pointcut )`:: Picks out each join points picked out by `_Pointcut_` . -==== Pointcut definition +=== Pointcut definition Pointcuts are defined and named by the programmer with the `pointcut` declaration. @@ -300,7 +300,7 @@ aspect B percflow(publicCall()) { } .... -==== Context exposure +=== Context exposure Pointcuts have an interface; they expose some parts of the execution context of the join points they pick out. For example, the PublicIntCall @@ -384,9 +384,9 @@ aspect IntToLong { The pointcut will match and expose the integer argument, but it will expose it as an `Integer`, not a `Long`. -==== Primitive pointcuts +=== Primitive pointcuts -===== Method-related pointcuts +==== Method-related pointcuts AspectJ provides two primitive pointcut designators designed to capture method call and execution join points. @@ -394,7 +394,7 @@ method call and execution join points. * `call( MethodPattern )` * `execution( MethodPattern )` -===== Field-related pointcuts +==== Field-related pointcuts AspectJ provides two primitive pointcut designators designed to capture field reference and set join points: @@ -419,7 +419,7 @@ aspect GuardedX { } .... -===== Object creation-related pointcuts +==== Object creation-related pointcuts AspectJ provides primitive pointcut designators designed to capture the initializer execution join points of objects. @@ -429,14 +429,14 @@ initializer execution join points of objects. * `initialization( ConstructorPattern )` * `preinitialization( ConstructorPattern )` -===== Class initialization-related pointcuts +==== Class initialization-related pointcuts AspectJ provides one primitive pointcut designator to pick out static initializer execution join points. * `staticinitialization( TypePattern )` -===== Exception handler execution-related pointcuts +==== Exception handler execution-related pointcuts AspectJ provides one primitive pointcut designator to capture execution of exception handlers: @@ -457,7 +457,7 @@ aspect NormalizeFooException { } .... -===== Advice execution-related pointcuts +==== Advice execution-related pointcuts AspectJ provides one primitive pointcut designator to capture execution of advice @@ -478,7 +478,7 @@ aspect TraceStuff { } .... -===== State-based pointcuts +==== State-based pointcuts Many concerns cut across the dynamic times when an object of a particular type is executing, being operated on, or being passed around. @@ -521,7 +521,7 @@ args(int, .., String) will pick out all join points where the first argument is an `int` and the last is a `String`. -===== Control flow-based pointcuts +==== Control flow-based pointcuts Some concerns cut across the control flow of the program. The `cflow` and `cflowbelow` primitive pointcut designators capture join points @@ -540,7 +540,7 @@ entry and exit of each join point `P` picked out by `Pointcut`, but not including `P` itself. Hence, it picks out the join points _below_ the control flow of the join points picked out by `Pointcut`. -====== Context exposure from control flows +===== Context exposure from control flows The `cflow` and `cflowbelow` pointcuts may expose context state through enclosed `this`, `target`, and `args` pointcuts. @@ -577,7 +577,7 @@ aspect A { It is an error to expose such state through _negated_ control flow pointcuts, such as within `!cflowbelow(P)`. -===== Program text-based pointcuts +==== Program text-based pointcuts While many concerns cut across the runtime structure of the program, some must deal with the lexical structure. AspectJ allows aspects to @@ -603,7 +603,7 @@ expressions of the method or constructor. It also includes any join points that are associated with code in a method or constructor's local or anonymous types. -===== Expression-based pointcuts +==== Expression-based pointcuts * `if( BooleanExpression )` @@ -623,13 +623,13 @@ a join point is undefined. Writing `if` pointcuts that have side-effects is considered bad style and may also lead to potentially confusing or even changing behavior with regard to when or if the test code will run. -==== Signatures +=== Signatures One very important property of a join point is its signature, which is used by many of AspectJ's pointcut designators to select particular join points. -===== Methods +==== Methods Join points associated with methods typically have method signatures, consisting of a method name, parameter types, return type, the types of @@ -645,7 +645,7 @@ means that the signature for the join point created from the call At a method execution join point, the signature is a method signature whose qualifying type is the declaring type of the method. -===== Fields +==== Fields Join points associated with fields typically have field signatures, consisting of a field name and a field type. A field reference join @@ -653,7 +653,7 @@ point has such a signature, and no parameters. A field set join point has such a signature, but has a has a single parameter whose type is the same as the field type. -===== Constructors +==== Constructors Join points associated with constructors typically have constructor signatures, consisting of a parameter types, the types of the declared @@ -669,7 +669,7 @@ signature is the constructor signature for the constructor that started this initialization: the first constructor entered during this type's initialization of this object. -===== Others +==== Others At a handler execution join point, the signature is composed of the exception type that the handler handles. @@ -679,7 +679,7 @@ aspect type, the parameter types of the advice, the return type (void for all but around advice) and the types of the declared (checked) exceptions. -==== Matching +=== Matching The `withincode`, `call`, `execution`, `get`, and `set` primitive pointcut designators all use signature patterns to determine the join @@ -796,7 +796,7 @@ private null constructor of a class `C` defined to throw an execution(private C.new() throws ArithmeticException) .... -===== Matching based on the declaring type +==== Matching based on the declaring type The signature-matching pointcuts all specify a declaring type, but the meaning varies slightly for each join point signature, in line with Java @@ -869,7 +869,7 @@ class Sub extends Middle { } .... -===== Matching based on the `throws` clause +==== Matching based on the `throws` clause Type patterns may be used to pick out methods and constructors based on their `throws` clauses. This allows the following two kinds of extremely @@ -927,13 +927,13 @@ declares that it `throws IOException`. [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 +=== Type patterns Type patterns are a way to pick out collections of types and use them in places where you would otherwise use only one type. The rules for using type patterns are simple. -===== Exact type pattern +==== Exact type pattern First, all type names are also type patterns. So `Object`, `java.util.HashMap`, `Map.Entry`, `int` are all type patterns. @@ -953,7 +953,7 @@ then the matching works just like normal type lookup in Java: So exact type patterns match based on usual Java scope rules. -===== Type name patterns +==== Type name patterns There is a special type name, `\*`, which is also a type pattern. `*` picks out all types, including primitive types. So @@ -1004,7 +1004,7 @@ 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 that are imported into an Aspect's declaring file. -===== Subtype patterns +==== 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 @@ -1034,13 +1034,13 @@ 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. -===== Array type patterns +==== Array type patterns A type name pattern or subtype pattern can be followed by one or more sets of square brackets to make array type patterns. So `Object[]` is an array type pattern, and so is `com.xerox..*[][]`, and so is `Object+[]`. -===== Type patterns +==== Type patterns Type patterns are built up out of type name patterns, subtype patterns, and array type patterns, and constructed with boolean operators `&&`, @@ -1062,7 +1062,7 @@ call((Foo+ && ! Foo).new(..)) picks out the constructor call join points when a subtype of `Foo`, but not `Foo` itself, is constructed. -==== Pattern Summary +=== Pattern Summary Here is a summary of the pattern syntax used in AspectJ: @@ -1093,7 +1093,7 @@ ModifiersPattern = .... [[semantics-advice]] -=== Advice +== Advice Each piece of advice is of the form @@ -1338,13 +1338,13 @@ prove that there won't be a runtime binary-compatible change in the hierarchy of `LinkedList` or some other advice on the join point that requires a `LinkedList`. -==== Advice modifiers +=== Advice modifiers The `strictfp` modifier is the only modifier allowed on advice, and it has the effect of making all floating-point expressions within the advice be FP-strict. -==== Advice and checked exceptions +=== Advice and checked exceptions An advice declaration must include a `throws` clause listing the checked exceptions the body may throw. This list of checked exceptions must be @@ -1394,12 +1394,12 @@ pre-initialization and initialization:: advice execution:: any exception that is in the `throws` clause of the advice. -==== Advice precedence +=== Advice precedence Multiple pieces of advice may apply to the same join point. In such cases, the resolution order of the advice is based on advice precedence. -===== Determining precedence +==== Determining precedence There are a number of rules that determine whether a particular piece of advice has precedence over another when they advise the same join point. @@ -1438,7 +1438,7 @@ aspect A { such circularities will result in errors signalled by the compiler. -===== Effects of precedence +==== Effects of precedence At a particular join point, advice is ordered by precedence. @@ -1466,7 +1466,7 @@ Running `after` advice will run the advice of next precedence, or the computation under the join point if there is no further advice. Then the body of the advice will run. -==== Reflective access to the join point +=== Reflective access to the join point Three special variables are visible within bodies of advice and within `if()` pointcut expressions: `thisJoinPoint`, `thisJoinPointStaticPart`, @@ -1503,14 +1503,14 @@ to `thisJoinPoint` is `org.aspectj.lang.JoinPoint`, while `org.aspectj.lang.JoinPoint.StaticPart`. [[semantics-declare]] -=== Static crosscutting +== Static crosscutting Advice declarations change the behavior of classes they crosscut, but do not change their static type structure. For crosscutting concerns that do operate over the static structure of type hierarchies, AspectJ provides inter-type member declarations and other `declare` forms. -==== Inter-type member declarations +=== Inter-type member declarations AspectJ allows the declaration of members by aspects that are associated with other types. @@ -1576,7 +1576,7 @@ 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. -==== Access modifiers +=== Access modifiers Inter-type member declarations may be `public` or `private`, or have default (package-protected) visibility. AspectJ does not provide protected @@ -1604,7 +1604,7 @@ public interface. This is illegal because it would say that a public interface has a constraint that only non-public implementors must fulfill. This would not be compatible with Java's type system. -==== Conflicts +=== Conflicts Inter-type declarations raise the possibility of conflicts among locally declared members and inter-type members. For example, assuming @@ -1663,7 +1663,7 @@ This is true both when the precedence is declared explicitly with `declare precedence` as well as when when sub-aspects implicitly have precedence over their super-aspect. -==== Extension and Implementation +=== Extension and Implementation 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 @@ -1687,7 +1687,7 @@ aspect A { } .... -==== Interfaces with members +=== Interfaces with members Through the use of inter-type members, interfaces may now carry (non-public-static-final) fields and (non-public-abstract) methods that @@ -1721,7 +1721,7 @@ when a new `E` is instantiated, the initializers run in this order: Object M C O N D Q P E .... -==== Warnings and Errors +=== Warnings and Errors An aspect may specify that a particular join point should never be reached. @@ -1733,7 +1733,7 @@ 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 `String` for its message. -==== Softened exceptions +=== Softened exceptions An aspect may specify that a particular kind of exception, if thrown at a join point, should bypass Java's usual static exception checking @@ -1790,7 +1790,7 @@ abstract aspect A { .... [[advice-precedence-cross]] -==== Advice Precedence +=== Advice Precedence An aspect may declare a precedence relationship between concrete aspects with the `declare precedence` form: @@ -1844,7 +1844,7 @@ aspect CountEntry { } .... -===== Various cycles +==== Various cycles It is an error for any aspect to be matched by more than one TypePattern in a single decare precedence, so: @@ -1868,7 +1868,7 @@ 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. -===== Applies to concrete aspects +==== Applies to concrete aspects Consider the following library aspects: @@ -1922,7 +1922,7 @@ declare precedence: Logging+, Profiling+; are meaningful. -==== Statically determinable pointcuts +=== Statically determinable pointcuts Pointcuts that appear inside of `declare` forms have certain restrictions. Like other pointcuts, these pick out join points, but they @@ -1943,17 +1943,17 @@ defined in terms of all of which can discriminate on runtime information. [[semantics-aspects]] -=== Aspects +== Aspects An aspect is a crosscutting type defined by the `aspect` declaration. -==== Aspect Declaration +=== Aspect Declaration The `aspect` declaration is similar to the `class` declaration in that it defines a type and an implementation for that type. It differs in a number of ways: -===== Aspect implementation can cut across other types +==== Aspect implementation can cut across other types In addition to normal Java class declarations such as methods and fields, aspect declarations can include AspectJ declarations such as @@ -1961,45 +1961,45 @@ advice, pointcuts, and inter-type declarations. Thus, aspects contain implementation declarations that can can cut across other types (including those defined by other aspect declarations). -===== Aspects are not directly instantiated +==== Aspects are not directly instantiated Aspects are not directly instantiated with a new expression, with cloning, or with serialization. Aspects may have one constructor definition, but if so it must be of a constructor taking no arguments and throwing no checked exceptions. -===== Nested aspects must be `static` +==== Nested aspects must be `static` Aspects may be defined either at the package level, or as a `static` nested aspect -- that is, a `static` member of a class, interface, or aspect. If it is not at the package level, the aspect _must_ be defined with the `static` keyword. Local and anonymous aspects are not allowed. -==== Aspect Extension +=== Aspect Extension To support abstraction and composition of crosscutting concerns, aspects can be extended in much the same way that classes can. Aspect extension adds some new rules, though. -===== Aspects may extend classes and implement interfaces +==== Aspects may extend classes and implement interfaces An aspect, abstract or concrete, may extend a class and may implement a set of interfaces. Extending a class does not provide the ability to instantiate the aspect with a new expression: The aspect may still only define a null constructor. -===== Classes may not extend aspects +==== Classes may not extend aspects It is an error for a class to extend or implement an aspect. -===== Aspects extending aspects +==== Aspects extending aspects Aspects may extend other aspects, in which case not only are fields and methods inherited but so are pointcuts. However, aspects may only extend abstract aspects. It is an error for a concrete aspect to extend another concrete aspect. -==== Aspect instantiation +=== Aspect instantiation Unlike class expressions, aspects are not instantiated with `new` expressions. Rather, aspect instances are automatically created to cut @@ -2015,7 +2015,7 @@ then by default the aspect is a singleton aspect. How an aspect is instantiated controls the form of the `aspectOf(..)` method defined on the concrete aspect class. -===== Singleton Aspects +==== Singleton Aspects * `aspect Id { ... }` * `aspect Id issingleton() { ... }` @@ -2035,7 +2035,7 @@ chance to run at all such join points. the aspect `A`, so there will be one instantiation for each time `A` is loaded by a different classloader.) -===== Per-object aspects +==== Per-object aspects * `aspect Id perthis( Pointcut ) { ... }` * `aspect Id pertarget( Pointcut ) { ... }` @@ -2062,7 +2062,7 @@ Both `perthis` and `pertarget` aspects may be affected by code the AspectJ compiler controls, as discussed in the xref:implementation.adoc#implementation[Implementation Notes] appendix. -===== Per-control-flow aspects +==== Per-control-flow aspects * `aspect Id percflow( Pointcut ) { ... }` * `aspect Id percflowbelow( Pointcut ) { ... }` @@ -2076,7 +2076,7 @@ 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 the aspect is created upon entry into each such control flow. -===== Aspect instantiation and advice +==== Aspect instantiation and advice All advice runs in the context of an aspect instance, but it is possible to write a piece of advice with a pointcut that picks out a join point @@ -2111,7 +2111,7 @@ compile time. If advice runs before its aspect is instantiated, AspectJ will throw a xref:../api/org/aspectj/lang/NoAspectBoundException.html[`org.aspectj.lang.NoAspectBoundException`]. -==== Aspect privilege +=== Aspect privilege * `privileged aspect Id { ... }` |