aboutsummaryrefslogtreecommitdiffstats
path: root/docs/progGuideDB/semantics.adoc
diff options
context:
space:
mode:
Diffstat (limited to 'docs/progGuideDB/semantics.adoc')
-rw-r--r--docs/progGuideDB/semantics.adoc310
1 files changed, 112 insertions, 198 deletions
diff --git a/docs/progGuideDB/semantics.adoc b/docs/progGuideDB/semantics.adoc
index 1943aa609..aa46cf18d 100644
--- a/docs/progGuideDB/semantics.adoc
+++ b/docs/progGuideDB/semantics.adoc
@@ -63,11 +63,7 @@ Constructor call::
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.
@@ -80,15 +76,7 @@ Object pre-initialization::
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
+ 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::
@@ -97,11 +85,7 @@ Object initialization::
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
+ 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
@@ -180,219 +164,84 @@ build up other pointcuts. The primitive pointcuts and combinators
provided by the language are:
`call(MethodPattern)`::
- Picks out each method call join point whose signature matches
- +
- MethodPattern
- +
- .
+ Picks out each method call join point whose signature matches `_MethodPattern_`.
`execution(MethodPattern)`::
- Picks out each method execution join point whose signature matches
- +
- MethodPattern
- +
- .
+ Picks out each method execution join point whose signature matches `_MethodPattern_`.
`get(FieldPattern)`::
- Picks out each field reference join point whose signature matches
- +
- FieldPattern
- +
- . [Note that references to constant fields (static final fields bound
+ Picks out each field reference join point whose signature matches `_FieldPattern_`. [Note that references to constant fields (static final fields bound
to a constant string object or primitive value) are not join points,
since Java requires them to be inlined.]
`set(FieldPattern)`::
- Picks out each field set join point whose signature matches
- +
- FieldPattern
- +
- . [Note that the initializations of constant fields (static final
+ Picks out each field set join point whose signature matches `_FieldPattern_`. [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.]
`call(ConstructorPattern)`::
- Picks out each constructor call join point whose signature matches
- +
- ConstructorPattern
- +
- .
+ Picks out each constructor call join point whose signature matches `_ConstructorPattern_`.
`execution(ConstructorPattern)`::
Picks out each constructor execution join point whose signature
- matches
- +
- ConstructorPattern
- +
- .
+ matches `_ConstructorPattern_`.
`initialization(ConstructorPattern)`::
Picks out each object initialization join point whose signature
- matches
- +
- ConstructorPattern
- +
- .
+ matches `_ConstructorPattern_`.
`preinitialization(ConstructorPattern)`::
Picks out each object pre-initialization join point whose signature
- matches
- +
- ConstructorPattern
- +
- .
+ matches `_ConstructorPattern_`.
`staticinitialization(TypePattern)`::
Picks out each static initializer execution join point whose signature
- matches
- +
- TypePattern
- +
- .
+ matches `_TypePattern_`.
`handler(TypePattern)`::
- Picks out each exception handler join point whose signature matches
- +
- TypePattern
- +
- .
+ Picks out each exception handler join point whose signature matches `_TypePattern_`.
`adviceexecution()`::
Picks out all advice execution join points.
`within(TypePattern)`::
Picks out each join point where the executing code is defined in a
- type matched by
- +
- TypePattern
- +
- .
+ type matched by `_TypePattern_`.
`withincode(MethodPattern)`::
Picks out each join point where the executing code is defined in a
- method whose signature matches
- +
- MethodPattern
- +
- .
+ method whose signature matches `_MethodPattern_`.
`withincode(ConstructorPattern)`::
Picks out each join point where the executing code is defined in a
- constructor whose signature matches
- +
- ConstructorPattern
- +
- .
+ constructor whose signature matches `_ConstructorPattern_`.
`cflow(Pointcut)`::
- Picks out each join point in the control flow of any join point
- +
- P
- +
- picked out by
- +
- Pointcut
- +
- , including
- +
- P
- +
- itself.
+ Picks out each join point in the control flow of any join point `_P_` picked out by `_Pointcut_` , including `_P_` itself.
`cflowbelow(Pointcut)`::
- Picks out each join point in the control flow of any join point
- +
- P
- +
- picked out by
- +
- Pointcut
- +
- , but not
- +
- P
- +
- itself.
+ Picks out each join point in the control flow of any join point `_P_` picked out by `_Pointcut_`, but not `_P_` itself.
`this(Type or Id)`::
Picks out each join point where the currently executing object (the
- object bound to
- +
- this
- +
- ) is an instance of
- +
- Type
- +
- , or of the type of the identifier
- +
- Id
- +
- (which must be bound in the enclosing advice or pointcut definition).
+ object bound to `_this_`) is an instance of `_Type_` , or of the type of the identifier `_Id_` (which must be bound in the enclosing advice or pointcut definition).
Will not match any join points from static contexts.
`target(Type or Id)`::
Picks out each join point where the target object (the object on which
- a call or field operation is applied to) is an instance of
- +
- Type
- +
- , or of the type of the identifier
- +
- Id
- +
- (which must be bound in the enclosing advice or pointcut definition).
+ a call or field operation is applied to) is an instance of `_Type_` , or of the type of the identifier `_Id_` (which must be bound in the enclosing advice or pointcut definition).
Will not match any calls, gets, or sets of static members.
`args(Type or Id, ...)`::
Picks out each join point where the arguments are instances of the
- appropriate type (or type of the identifier if using that form). A
- +
- null
- +
- argument is matched iff the static type of the argument (declared
+ appropriate type (or type of the identifier if using that form). A `_null_` argument is matched iff the static type of the argument (declared
parameter type or field type) is the same as, or a subtype of, the
specified args type.
`PointcutId(TypePattern or Id, ...)`::
Picks out each join point that is picked out by the user-defined
- pointcut designator named by
- +
- PointcutId
- +
- .
+ pointcut designator named by `_PointcutId_` .
`if(BooleanExpression)`::
- Picks out each join point where the boolean expression evaluates to
- +
- true
- +
- . The boolean expression used can only access static members,
- parameters exposed by the enclosing pointcut or advice, and
- +
- thisJoinPoint
- +
- forms. In particular, it cannot call non-static methods on the aspect
+ Picks out each join point where the boolean expression evaluates to `_true_` . The boolean expression used can only access static members,
+ parameters exposed by the enclosing pointcut or advice, and `_thisJoinPoint_` forms. In particular, it cannot call non-static methods on the aspect
or use return values or exceptions exposed by after advice.
`! Pointcut`::
- Picks out each join point that is not picked out by
- +
- Pointcut
- +
- .
+ Picks out each join point that is not picked out by `_Pointcut_` .
`Pointcut0 && Pointcut1`::
- Picks out each join points that is picked out by both
- +
- Pointcut0
- +
- and
- +
- Pointcut1
- +
- .
+ Picks out each join points that is picked out by both `_Pointcut0_` and `_Pointcut1_` .
`Pointcut0 || Pointcut1`::
- Picks out each join point that is picked out by either pointcuts.
- +
- Pointcut0
- +
- or
- +
- Pointcut1
- +
- .
+ Picks out each join point that is picked out by either pointcuts. `_Pointcut0_` or `_Pointcut1_` .
`( Pointcut )`::
- Picks out each join points picked out by
- +
- Pointcut
- +
- .
+ Picks out each join points picked out by `_Pointcut_` .
==== Pointcut definition
Pointcuts are defined and named by the programmer with the `pointcut`
declaration.
+[source, java]
....
pointcut publicIntCall(int i):
call(public * *(int)) && args(i);
@@ -402,6 +251,7 @@ A named pointcut may be defined in either a class or aspect, and is
treated as a member of the class or aspect where it is found. As a
member, it may have an access modifier such as `public` or `private`.
+[source, java]
....
class C {
pointcut publicCall(int i):
@@ -418,6 +268,7 @@ Pointcuts that are not final may be declared abstract, and defined
without a body. Abstract pointcuts may only be declared within abstract
aspects.
+[source, java]
....
abstract aspect A {
abstract pointcut publicCall(int i);
@@ -426,6 +277,7 @@ abstract aspect A {
In such a case, an extending aspect may override the abstract pointcut.
+[source, java]
....
aspect B extends A {
pointcut publicCall(int i): call(public Foo.m(int)) && args(i);
@@ -444,6 +296,7 @@ is different than the scope of other members; the scope of other members
is the enclosing class _body_. This means that the following code is
legal:
+[source, java]
....
aspect B percflow(publicCall()) {
pointcut publicCall(): call(public Foo.m(int));
@@ -466,6 +319,7 @@ collection of types. The pointcut designators that allow this are
rather than a type does two things. First, it selects join points as
based on the type of the formal parameter. So the pointcut
+[source, java]
....
pointcut intArg(int i): args(i);
....
@@ -477,6 +331,7 @@ advice or pointcut.
Values can be exposed from named pointcuts as well, so
+[source, java]
....
pointcut publicCall(int x): call(public *.*(int)) && intArg(x);
pointcut intArg(int i): args(i);
@@ -489,6 +344,7 @@ There is one special case for this kind of exposure. Exposing an
argument of type Object will also match primitive typed arguments, and
expose a "boxed" version of the primitive. So,
+[source, java]
....
pointcut publicCall(): call(public *.*(..)) && args(Object);
....
@@ -496,6 +352,7 @@ pointcut publicCall(): call(public *.*(..)) && args(Object);
will pick out all unary methods that take, as their only argument,
subtypes of Object (i.e., not primitive types like `int`), but
+[source, java]
....
pointcut publicCall(Object o): call(public *.*(..)) && args(o);
....
@@ -507,6 +364,7 @@ argument was an `int`, then the value passed to advice will be of type
The "boxing" of the primitive value is based on the _original_ primitive
type. So in the following program
+[source, java]
....
public class InstanceOf {
@@ -569,6 +427,7 @@ field is being set to, so at a set join point, that value can be
accessed with an `args` pointcut. So an aspect guarding a static integer
variable x declared in type T might be written as
+[source, java]
....
aspect GuardedX {
static final int MAX_CHANGE = 100;
@@ -632,6 +491,7 @@ the exception being handled. That value can be accessed with an `args`
pointcut. So an aspect used to put `FooException` objects into some
normal form before they are handled could be written as
+[source, java]
....
aspect NormalizeFooException {
before(FooException e): handler(FooException) && args(e) {
@@ -650,6 +510,7 @@ of advice
This can be used, for example, to filter out any join point in the
control flow of advice from a particular aspect.
+[source, java]
....
aspect TraceStuff {
pointcut myAdvice(): adviceexecution() && within(TraceStuff);
@@ -719,6 +580,7 @@ Object). If it is the "*" wildcard, then any argument will match, and if
it is the special wildcard "..", then any number of arguments will
match, just like in signature patterns. So the pointcut
+[source, java]
....
args(int, .., String)
....
@@ -762,6 +624,7 @@ Anytime such state is accessed, it is accessed through the _most recent_
control flow that matched. So the "current arg" that would be printed by
the following program is zero, even though it is in many control flows.
+[source, java]
....
class Test {
public static void main(String[] args) {
@@ -842,6 +705,7 @@ false. Within this expression, the `thisJoinPoint` object is available.
So one (extremely inefficient) way of picking out all call join points
would be to use the pointcut
+[source, java]
....
if(thisJoinPoint.getKind().equals("call"))
....
@@ -922,6 +786,7 @@ while constructor declarations omit the return type and replace the
method name with the class name. The start of a particular method
declaration, in class `Test`, for example, might be
+[source, java]
....
class C {
public final void foo() throws ArrayOutOfBoundsException { ... }
@@ -931,12 +796,14 @@ class C {
In AspectJ, method signature patterns have all these, but most elements
can be replaced by wildcards. So
+[source, java]
....
call(public final void C.foo() throws ArrayOutOfBoundsException)
....
picks out call join points to that method, and the pointcut
+[source, java]
....
call(public final void *.*() throws ArrayOutOfBoundsException)
....
@@ -949,12 +816,14 @@ throw `ArrayOutOfBounds` exceptions.
The defining type name, if not present, defaults to *, so another way of
writing that pointcut would be
+[source, java]
....
call(public final void *() throws ArrayOutOfBoundsException)
....
The wildcard `..` indicates zero or more parameters, so
+[source, java]
....
execution(void m(..))
....
@@ -962,6 +831,7 @@ execution(void m(..))
picks out execution join points for void methods named `m`, of any
number of arguments, while
+[source, java]
....
execution(void m(.., int))
....
@@ -974,6 +844,7 @@ signature pattern should match methods without a particular modifier,
such as all non-public methods, the appropriate modifier should be
negated with the `!` operator. So,
+[source, java]
....
withincode(!public void foo())
....
@@ -981,6 +852,7 @@ withincode(!public void foo())
picks out all join points associated with code in null non-public void
methods named `foo`, while
+[source, java]
....
withincode(void foo())
....
@@ -991,12 +863,14 @@ named `foo`, regardless of access modifier.
Method names may contain the * wildcard, indicating any number of
characters in the method name. So
+[source, java]
....
call(int *())
....
picks out all call join points to `int` methods regardless of name, but
+[source, java]
....
call(int get*())
....
@@ -1009,6 +883,7 @@ than using a particular class name. So the execution join points of
private null constructor of a class C defined to throw an
ArithmeticException can be picked out with
+[source, java]
....
execution(private C.new() throws ArithmeticException)
....
@@ -1027,6 +902,7 @@ type used to access the method. A common mistake is to specify a
declaring type for the `call` pointcut that is a subtype of the
originally-declaring type. For example, given the class
+[source, java]
....
class Service implements Runnable {
public void run() { ... }
@@ -1035,12 +911,14 @@ class Service implements Runnable {
the following pointcut
+[source, java]
....
call(void Service.run())
....
would fail to pick out the join point for the code
+[source, java]
....
((Runnable) new Service()).run();
....
@@ -1049,6 +927,7 @@ Specifying the originally-declaring type is correct, but would pick out
any such call (here, calls to the `run()` method of any Runnable). In
this situation, consider instead picking out the target type:
+[source, java]
....
call(void run()) && target(Service)
....
@@ -1058,6 +937,7 @@ method signature specifies a declaring type, the pointcut will only
match methods declared in that type, or methods that override methods
declared in or inherited by that type. So the pointcut
+[source, java]
....
execution(public void Middle.*())
....
@@ -1068,6 +948,7 @@ Middle, even if those methods are overridden in a subclass of Middle. So
the pointcut would pick out the method-execution join point for Sub.m()
in this code:
+[source, java]
....
class Super {
protected void m() { ... }
@@ -1085,6 +966,7 @@ Type patterns may be used to pick out methods and constructors based on
their throws clauses. This allows the following two kinds of extremely
wildcarded pointcuts:
+[source, java]
....
pointcut throwsMathlike():
// each call to a method with a throws clause containing at least
@@ -1190,6 +1072,7 @@ So exact type patterns match based on usual Java scope rules.
There is a special type name, *, which is also a type pattern. * picks
out all types, including primitive types. So
+[source, java]
....
call(void foo(*))
....
@@ -1202,6 +1085,7 @@ 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]
....
handler(java.util.*Map)
....
@@ -1209,6 +1093,7 @@ handler(java.util.*Map)
picks out the types java.util.Map and java.util.java.util.HashMap, among
others, and
+[source, java]
....
handler(java.util.*)
....
@@ -1221,6 +1106,7 @@ 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]
....
within(com.xerox..*)
....
@@ -1238,6 +1124,7 @@ It is possible to pick out all subtypes of a type (or a collection of
types) with the "+" wildcard. The "+" wildcard follows immediately a
type name pattern. So, while
+[source, java]
....
call(Foo.new())
....
@@ -1245,6 +1132,7 @@ call(Foo.new())
picks out all constructor call join points where an instance of exactly
type Foo is constructed,
+[source, java]
....
call(Foo+.new())
....
@@ -1252,6 +1140,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
+[source, java]
....
call(*Handler+.new())
....
@@ -1271,6 +1160,7 @@ Type patterns are built up out of type name patterns, subtype patterns,
and array type patterns, and constructed with boolean operators `&&`,
`||`, and `!`. So
+[source, java]
....
staticinitialization(Foo || Bar)
....
@@ -1278,6 +1168,7 @@ staticinitialization(Foo || Bar)
picks out the static initializer execution join points of either Foo or
Bar, and
+[source, java]
....
call((Foo+ && ! Foo).new(..))
....
@@ -1289,6 +1180,7 @@ not Foo itself, is constructed.
Here is a summary of the pattern syntax used in AspectJ:
+[source, text]
....
MethodPattern =
[ModifiersPattern] TypePattern
@@ -1397,6 +1289,7 @@ interpretations of after advice: After the execution of a join point
completes normally, after it throws an exception, or after it does
either one. AspectJ allows after advice for any of these situations.
+[source, java]
....
aspect A {
pointcut publicCall(): call(public Object *(..));
@@ -1415,6 +1308,7 @@ aspect A {
After returning advice may not care about its returned object, in which
case it may be written
+[source, java]
....
after() returning: call(public Object *(..)) {
System.out.println("Returned normally");
@@ -1448,6 +1342,7 @@ must be declared with a return type, like a method.
Thus, a simple use of around advice is to make a particular method
constant:
+[source, java]
....
aspect A {
int around(): call(int C.foo()) {
@@ -1459,6 +1354,7 @@ aspect A {
Within the body of around advice, though, the computation of the
original join point can be executed with the special syntax
+[source, java]
....
proceed( ... )
....
@@ -1468,6 +1364,7 @@ pointcut, and returns whatever the around is declared to return. So the
following around advice will double the second argument to `foo`
whenever it is called, and then halve its result:
+[source, java]
....
aspect A {
int around(int i): call(int C.foo(Object, int)) && args(i) {
@@ -1483,6 +1380,7 @@ is originally a primitive value. And when the advice returns an Object
value, that value is converted back to whatever representation it was
originally. So another way to write the doubling and halving advice is:
+[source, java]
....
aspect A {
Object around(int i): call(int C.foo(Object, int)) && args(i) {
@@ -1500,6 +1398,7 @@ program the first call to proceed will be treated as a method call to
the `ICanProceed` instance, whereas the second call to proceed is
treated as the special proceed form.
+[source, java]
....
aspect A {
Object around(ICanProceed canProceed) : execution(* *(..)) && this(canProceed) {
@@ -1519,6 +1418,7 @@ method parameters. In particular, assigning to any parameter affects
only the value of the parameter, not the value that it came from. This
means that
+[source, java]
....
aspect A {
after() returning (int i): call(int C.foo()) {
@@ -1536,6 +1436,7 @@ less-precedent advice and the underlying join point by supplying
different values for the variables. For example, this aspect replaces
the string bound to `s` in the named pointcut `privateData`:
+[source, java]
....
aspect A {
Object around(String s): MyPointcuts.privateData(s) {
@@ -1551,6 +1452,7 @@ In the following aspect, the around advice replaces the declared target
`List` with an `ArrayList`. This is valid code at compile-time since the
types match.
+[source, java]
....
import java.util.*;
@@ -1565,6 +1467,7 @@ But imagine a simple program where the actual target is `LinkedList`. In
this case, the advice would cause a `ClassCastException` at runtime, and
`peek()` is not declared in `ArrayList`.
+[source, java]
....
public class Test {
public static void main(String[] args) {
@@ -1577,6 +1480,7 @@ The `ClassCastException` can occur even in situations where it appears
to be unnecessary, e.g., if the program is changed to call `size()`,
declared in `List`:
+[source, java]
....
public class Test {
public static void main(String[] args) {
@@ -1605,6 +1509,7 @@ signalled by the compiler.
For example, in the following declarations:
+[source, java]
....
import java.io.FileNotFoundException;
@@ -1626,22 +1531,14 @@ aspect A {
both pieces of advice are illegal. The first because the body throws an
undeclared checked exception, and the second because field get join
-points cannot throw `FileNotFoundException`s.
+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::
@@ -1649,11 +1546,7 @@ 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.
@@ -1700,6 +1593,7 @@ precedence over the one that appears later.
These rules can lead to circularity, such as
+[source, java]
....
aspect A {
before(): execution(void main(String[] args)) {}
@@ -1747,6 +1641,7 @@ encapsulates some of the context of the advice's current or enclosing
join point. These variables exist because some pointcuts may pick out
very large collections of join points. For example, the pointcut
+[source, java]
....
pointcut publicCall(): call(public * *(..));
....
@@ -1843,6 +1738,7 @@ The effect of such a declaration is to make <OnType> support the new
method. Even if <OnType> is an interface. Even if the method is neither
public nor abstract. So the following is legal AspectJ code:
+[source, java]
....
interface Iface {}
@@ -1979,6 +1875,7 @@ Inter-type declarations raise the possibility of conflicts among locally
declared members and inter-type members. For example, assuming
`otherPackage` is not the package containing the aspect `A`, the code
+[source, java]
....
aspect A {
private Registry otherPackage.onType.r;
@@ -2001,6 +1898,7 @@ there is no conflict: The aspect cannot see such a field, and no code in
If `onType` defines a public field "`r`", there is a conflict: The
expression
+[source, java]
....
this.r = r
....
@@ -2071,6 +1969,7 @@ might define appropriate inter-type `void
fulfills the `Runnable` interface. In order to implement the methods in
the `Runnable` interface, the inter-type `run()` method must be public:
+[source, java]
....
aspect A {
declare parents: SomeClass implements Runnable;
@@ -2091,9 +1990,10 @@ initializers. The order of super-interface instantiation is observable.
We fix this order with the following properties: A supertype is
initialized before a subtype, initialized code runs only once, and the
initializers for a type's superclass are run before the initializers for
-its superinterfaces. Consider the following hierarchy where \{`Object`,
-`C`, `D`, `E`} are classes, \{`M`, `N`, `O`, `P`, `Q`} are interfaces.
+its superinterfaces. Consider the following hierarchy where {`Object`,
+`C`, `D`, `E`} are classes, {`M`, `N`, `O`, `P`, `Q`} are interfaces.
+[source, text]
....
Object M O
\ / \ /
@@ -2106,6 +2006,7 @@ its superinterfaces. Consider the following hierarchy where \{`Object`,
when a new `E` is instantiated, the initializers run in this order:
+[source, text]
....
Object M C O N D Q P E
....
@@ -2158,6 +2059,7 @@ Pointcut
For example, the aspect
+[source, java]
....
aspect A {
declare soft: Exception: execution(void main(String[] args));
@@ -2169,6 +2071,7 @@ Would, at the execution join point, catch any `Exception` and rethrow a
This is similar to what the following advice would do
+[source, java]
....
aspect A {
void around() execution(void main(String[] args)) {
@@ -2187,6 +2090,7 @@ Like advice, the declare soft form has no effect in an abstract aspect
that is not extended by a concreate aspect. So the following code will
not compile unless it is compiled with an extending concrete aspect:
+[source, java]
....
abstract aspect A {
abstract pointcut softeningPC();
@@ -2223,6 +2127,7 @@ of their name should have precedence over all other aspects, and (2) the
Logging aspect (and any aspect that extends it) should have precedence
over all non-security aspects, can be expressed by:
+[source, java]
....
declare precedence: *..*Security*, Logging+, *;
....
@@ -2235,6 +2140,7 @@ accomplished by stating that CountEntry has precedence over
DisallowNulls. This declaration could be in either aspect, or in
another, ordering aspect:
+[source, java]
....
aspect Ordering {
declare precedence: CountEntry, DisallowNulls;
@@ -2259,6 +2165,7 @@ aspect CountEntry {
It is an error for any aspect to be matched by more than one TypePattern
in a single decare precedence, so:
+[source, java]
....
declare precedence: A, B, A ; // error
....
@@ -2267,6 +2174,7 @@ However, multiple declare precedence forms may legally have this kind of
circularity. For example, each of these declare precedence is perfectly
legal:
+[source, java]
....
declare precedence: B, A;
declare precedence: A, B;
@@ -2280,6 +2188,7 @@ idiom that can be used to enforce that A and B are strongly independent.
Consider the following library aspects:
+[source, java]
....
abstract aspect Logging {
abstract pointcut logged();
@@ -2313,12 +2222,14 @@ aspects, say, MyLogging and MyProfiling. Because advice only applies
from concrete aspects, the declare precedence form only matters when
declaring precedence with concrete aspects. So
+[source, java]
....
declare precedence: Logging, Profiling;
....
has no effect, but both
+[source, java]
....
declare precedence: MyLogging, MyProfiling;
declare precedence: Logging+, Profiling+;
@@ -2526,6 +2437,7 @@ 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
that must occur before asopect instantiation. For example:
+[source, java]
....
public class Client
{
@@ -2574,6 +2486,7 @@ private or protected resources of other types. To allow this, aspects
may be declared `privileged`. Code in priviliged aspects has access to
all members, even private ones.
+[source, java]
....
class C {
private int i = 0;
@@ -2594,6 +2507,7 @@ If a privileged aspect can access multiple versions of a particular
member, then those that it could see if it were not privileged take
precedence. For example, in the code
+[source, java]
....
class C {
private int i = 0;