diff options
Diffstat (limited to 'docs/dist/doc/porting.adoc')
-rw-r--r-- | docs/dist/doc/porting.adoc | 279 |
1 files changed, 174 insertions, 105 deletions
diff --git a/docs/dist/doc/porting.adoc b/docs/dist/doc/porting.adoc index bc95dc5c7..cbf8ede6d 100644 --- a/docs/dist/doc/porting.adoc +++ b/docs/dist/doc/porting.adoc @@ -37,35 +37,36 @@ The following example program illustrates the differences in join point matching with the `call` pointcut designator between 1.4 and 1.3 compliance levels. -.... -01 class A { -02 public void doIt() {...}; -03 } -04 -05 class B extends A { -06 public void doThisToo() {...}; -07 } -08 -09 -10 public class CallsAandB { -11 -12 public static void main(String[] args) { -13 B b = new B(); -14 A bInDisguise = new B(); -15 -16 b.doIt(); // AspectJ 1.2 matches here -17 bInDisguise.doIt(); // this is never matched -18 } -19 -20 } -21 -22 aspect CallPCDMatchingExample { -23 -24 before() : call(* B.doIt(..)) { -25 System.out.println("About to call B.doIt(...)"); -26 } -27 -28 } +[source, java] +.... +/*01*/ class A { +/*02*/ public void doIt() {...}; +/*03*/ } +/*04*/ +/*05*/ class B extends A { +/*06*/ public void doThisToo() {...}; +/*07*/ } +/*08*/ +/*09*/ +/*10*/ public class CallsAandB { +/*11*/ +/*12*/ public static void main(String[] args) { +/*13*/ B b = new B(); +/*14*/ A bInDisguise = new B(); +/*15*/ +/*16*/ b.doIt(); // AspectJ 1.2 matches here +/*17*/ bInDisguise.doIt(); // this is never matched +/*18*/ } +/*19*/ +/*20*/ } +/*21*/ +/*22*/ aspect CallPCDMatchingExample { +/*23*/ +/*24*/ before() : call(* B.doIt(..)) { +/*25*/ System.out.println("About to call B.doIt(...)"); +/*26*/ } +/*27*/ +/*28*/ } .... When this program is compiled with AspectJ 1.2 using the default @@ -99,8 +100,8 @@ does not match at a join point, and a user may have expected it to. Compiling the above program using AspectJ 1.2 produces the following compiler output: +[source, text] .... - CallsAandB.java:24 warning does not match because declaring type is A, if match desired use target(B) [Xlint:unmatchedSuperTypeInCall] before() : call(* B.doIt(..)) { ^^^^^^^^^^^^^^^ @@ -109,7 +110,6 @@ before() : call(* B.doIt(..)) { 1 warning - .... The warning is telling us that the call pointcut associated with the @@ -147,6 +147,7 @@ an interface is now (correctly) prohibited, and there will no longer be a constructor-execution join point for the interface. To initialize a field declared on an interface, use initialization, e.g., +[source, java] .... int I.i; after(I i) returning: initialization(I) && this(i) { i.i = 2; } @@ -154,6 +155,7 @@ after(I i) returning: initialization(I) && this(i) { i.i = 2; } To pick out the constructor-execution for any implementation of I, try +[source, java] .... execution(I+.new(..)) .... @@ -172,6 +174,7 @@ older version of BCEL available earlier on your classpath than the version included in the 1.2 aspectjtools.jar then you will see errors like: +[source, text] .... C:\work\test\TestAspect.aj error Internal compiler error java.lang.NoSuchMethodError: org.apache.bcel.generic.InstructionFactory. @@ -219,6 +222,7 @@ Conflicts will be reported for no-argument constructors generated by compilers when no constructor is defined for a class. That means the following code will compile in 1.0 but not in 1.1: +[source, java] .... class C {} aspect A { @@ -243,6 +247,7 @@ The compiler will report an error that the form `aspect {name} dominates {list}...` is no longer supported. It has been replaced by a new declare statement: +[source, java] .... declare precedence : {name} {list}... .... @@ -269,6 +274,7 @@ returning advice. The main change that was made was of after returning advice for constructor execution join points. Previously, this advice was legal: +[source, java] .... after() returning (Foo f): execution(Foo.new(..)) { ... } .... @@ -280,6 +286,7 @@ constructor calls) do not return the value of the new object. Rather, void method. With that in mind, any code like the above should be conveted to the form. +[source, java] .... after(Foo f) returning: this(f) && execution(Foo.new(..)) { ... } .... @@ -287,6 +294,7 @@ after(Foo f) returning: this(f) && execution(Foo.new(..)) { ... } In compilers prior to 1.0.4, the following advice could pick out join points +[source, java] .... after() returning (String s): call(void foo()) { ... } .... @@ -294,6 +302,7 @@ after() returning (String s): call(void foo()) { ... } This is no longer picked out. This pattern was most commonly used in highly polymorphic contexts, such as +[source, java] .... after() returning (String s): call(* foo()) { ... } .... @@ -301,6 +310,7 @@ after() returning (String s): call(* foo()) { ... } If you want to capture all calls, binding null objects for those that would otherwise have no value, you must use the `Object` type. +[source, java] .... after() returning (Object o): call(* foo()) { ... } .... @@ -378,18 +388,20 @@ for example, you named a parameter of a pointcut "set", you should (for your own sanity -- the compiler doesn't require it) rename it in the rewritten pointcut. +[source, java] .... pointcut sort(Collection set): calls(void addAll(set)); -==> +// ==> pointcut sort(Collection mySet): call(void addAll(mySet)); .... While converting to use singular nouns for the primitive pointcuts, you may also want to remove the "s" from your user-defined pointcuts. +[source, java] .... pointcut publicCalls(): calls(public * *(..)); -==> +// ==> pointcut publicCall(): call(public * *(..)); .... @@ -412,9 +424,10 @@ straightforward, depending on whether the pointcut exposed state or not. Receptions pointcuts that did not expose state can simply be replaced by the new `call` and `target` pointcuts: +[source, java] .... receptions(void Foo.m()) -==> +// ==> target(Foo) && call(void m()) .... @@ -424,9 +437,10 @@ Some receptions pointcuts exposed the receiving object by replacing the receiving type with a pointcut formal. These PCDs should be rewritten to use the new `target` pointcut to expose the receiving object. +[source, java] .... pointcut fooCallees(Foo f): receptions(void f.m()); -==> +// ==> pointcut fooCallee(Foo f): target(f) && call(void m()); .... @@ -434,9 +448,10 @@ Like xref:#_1_0a1-fixing-state-access[other pointcuts], receptions pointcuts that exposed one or more arguments should be rewritten to use the `args` pointcut: +[source, java] .... pointcut intPassers(int i, int j): receptions(void Foo.m(i, j)); -==> +// ==> pointcut intPasser(int i, int j): args(i, j) && target(Foo) && call(void m(int, int)); .... @@ -453,9 +468,10 @@ but also of classes that extended C. If you want this behaviour, then you need to use the new subtypes operator, +, on the type name in question. So, +[source, java] .... receptions(C.new()) -==> +// ==> call(C+.new()) .... @@ -468,6 +484,7 @@ allow all kinds of advice it may be that the object isn't constructed yet (say, in before or around advice). This is a benefit, in that it allows caching constructed objects +[source, java] .... aspect Singleton { private C theC = null; @@ -482,9 +499,10 @@ aspect Singleton { but it does require some rewriting. The new object can be accessed as the return value in after returning advice. So, +[source, java] .... after(Point p) returning (): receptions(p.new(int, int)) { ... } -==> +// ==> after() returning (Point p): call(Point+.new(int, int)) { ... } .... @@ -509,15 +527,17 @@ Any time you have a pointcut that has a signature where one of the arguments was a pointcut or advice formal, just replace that formal with its type and add an `args` pointcut. +[source, java] .... pointcut intPassers(int i, int j): calls(void Foo.m(i, j)); -==> +// ==> pointcut intPasser(int i, int j): args(i, j) && call(void Foo.m(int, int)); .... +[source, java] .... pointcut stringPassers(String s): receptions(void Foo.m(s, ..)); -==> +// ==> pointcut stringPasser(String s): args(s, ..) && call(void Foo.m(String, ..)); .... @@ -525,6 +545,7 @@ pointcut stringPasser(String s): args(s, ..) && call(void Foo.m(String, ..)); If a calls pointcut exposed the the receiving object, such as +[source, java] .... pointcut fooCallees(Foo f): calls(void f.m()); .... @@ -532,6 +553,7 @@ pointcut fooCallees(Foo f): calls(void f.m()); then the new version should use the `target` pointcut to get at that object +[source, java] .... pointcut fooCallee(Foo f): target(f) && call(void Foo.m()); .... @@ -543,9 +565,10 @@ returning advice, when it is guaranteed that the object was successfully constructed. So instead of using the `target` pointcut to expose the value, you should use the normal `after returning` mechanism: +[source, java] .... after(Point p) returning (): calls(p.new(int, int)) { ... } -==> +// ==> after() returning (Point p): call(Point+.new(int, int)) { ... } .... @@ -555,15 +578,17 @@ Exposing the target object of a `gets` or `sets` pointcut should be done the same way it was for `calls` pointcuts, with the new `target` pointcut. +[source, java] .... before(Frame f): gets(Color f.color) { ... } -==> +// ==> before(Frame f): target(f) && get(Color Frame.color) { ... } .... +[source, java] .... before(Frame f): sets(Color f.color) { ... } -==> +// ==> before(Frame f): target(f) && set(Color Frame.color) { ... } .... @@ -573,11 +598,14 @@ the field yourself in the body. Depending on the rest of your system, you may need to restrict the advice from the aspect body to eliminiate the circularity. +[source, java] .... aspect A { before(Frame f, Color c): gets(Color f.color)[c] { ... } } -==> + +// ==> + aspect A { before(Frame f): target(f) && get(Color Frame.color) && !within(A) { @@ -590,11 +618,14 @@ aspect A { The same can be done for `around` advice. However, the only way to port after advice that needs the old value is to convert it to around advice. +[source, java] .... aspect A { after(Frame f, Color c) returning (): gets(Color f.color)[c] { ... } } -==> + +// ==> + aspect A { void around(Frame f): target(f) && get(Color Frame.color) && !within(A) { @@ -610,9 +641,10 @@ available, but not the way it was previously. Instead of using the square bracket syntax, we use an `args` pointcut. All set join points are assumed to have exactly one argument, which holds the new value. So, +[source, java] .... after(Color newColor): sets(Color Frame.color)[][newColor] { ... } -==> +// ==> after(Color newColor): args(newColor) && set(Color Frame.color) { ... } .... @@ -625,9 +657,10 @@ The value of the exception at an exception handler join point is now accessed through the `args` pointcut; all exception handler join points are treated as having exactly one argument, the exception value. So, +[source, java] .... before(NotFoundException e): handlers(e) { ... } -==> +// ==> before(NotFoundException e): args(e) && handler(NotFoundException) { ... } .... @@ -640,9 +673,10 @@ closed, and within can only take type patterns, not pointcut or advice formals. A use of the `this` pointcut will capture what previous implementations did: +[source, java] .... pointcut usesFoo(Foo f): within(f); -==> +// ==> pointcut usesFoo(Foo f): this(f) && within(Foo); .... @@ -667,6 +701,7 @@ to match. For example, the pointcut +[source, java] .... calls(void m(Object)) .... @@ -677,6 +712,7 @@ out method calls to methods that are defined to take exactly the type Object, which may be a lot fewer join points. If you want the old behaviour, simply convert to +[source, java] .... call(void m(Object+)) .... @@ -692,10 +728,11 @@ pointcut, composed (with `&&`) with another pointcut. If the other pointcut was a `receptions` pointcut, then `instanceof` should be converted to `target` (and `receptions` converted to `call`). So, +[source, java] .... pointcut stateChanges(Subject s): instanceof(s) && receptions(void Button.click()); -==> +// ==> pointcut stateChange(Subject s): target(s) && call(void Button.click()); .... @@ -703,15 +740,17 @@ pointcut stateChange(Subject s): In all other cases, `instanceof` referred to the currently executing object, and so should be converted into `this` +[source, java] .... before(Point p): instanceof(p) && executions(* makePolar(..)) { ... } -==> +// ==> before(Point p): this(p) && execution(* makePolar(..)) { ... } .... +[source, java] .... pointcut setup(Client c): instanceof(c) && calls(Remote Naming.lookup(String)); -==> +// ==> pointcut setup(Client c): this(c) && calls(Remote Naming.lookup(String)); .... @@ -728,9 +767,10 @@ fields. The old behaviour can be recovered with a simple rewrite. +[source, java] .... initializations(A) -==> +// ==> initialization(A.new(..)) && !execution(A.new(..)) .... @@ -760,20 +800,22 @@ If the aspect whose presense you are checking for was defined `of eachcflow`, `of eachcflowbelow`, or, more unlikely, `of eachJVM()`, then the conversion is simple: +[source, java] .... hasaspect(A) -==> +// ==> if(A.hasAspect()) .... If the aspect was defined `of eachobject`, then you will have to expose the current object in your pointcut or advice parameters: +[source, java] .... pointcut cut(): hasaspect(A) ... ; -==> +// ==> pointcut cut(Object o): this(o) && if(A.hasAspect(o)) ... ; -or +// or pointcut cut(Object o): target(o) && if(A.hasAspect(o)) ... ; .... @@ -782,11 +824,12 @@ aspect, then you can get the same state by using `A.aspectOf()` in the body of the advice. For example, if the aspect A were defined `of eachcflow`, then +[source, java] .... before(A myA): hasaspect(myA) { myA.checkStatus(); } -==> +// ==> before(): if(A.hasAspect()) { A myA = A.aspectOf(); myA.checkStatus(); @@ -801,9 +844,10 @@ of within and the xref:#_1_0a1-subtypes-to-plus[new subtypes operator], +, instead. You'll save two characters and be using a simpler and more orthogonal language. +[source, java] .... withinall(Foo) -==> +// ==> within(Foo+) .... @@ -813,9 +857,10 @@ within(Foo+) The returns keyword is no longer necessary for user-defined pointcuts. Simply remove it when you find it. +[source, java] .... pointcut publicIntCalls() returns int: calls(public int *(..)); -==> +// ==> pointcut publicIntCall(): call(public int *(..)); .... @@ -864,9 +909,10 @@ programs easier. There is one ugly idiom, however, that this change disposes of. If your program includes the type pattern `*..*`, which used to match all types, you can replace it with the much simpler *. +[source, java] .... pointcut unaryVoidMethods(): call(void *(*..*)); -==> +// ==> pointcut unaryVoidMethod(): call(void *(*)); .... @@ -882,11 +928,12 @@ wrote `subtypes(Foo)`, i.e., the subtypes of a single type, simply replace this with `Foo+`. Otherwise, use the + operator as appropriate in `TypePattern`. +[source, java] .... public void (subtypes(Target0 || Target1)).accept(Visitor v) { v.visit(this); } -==> +// ==> public void (Target0+ || Target1+).accept(Visitor v) { v.visit(this); } @@ -901,9 +948,10 @@ public void (Target0+ || Target1+).accept(Visitor v) { The returns keyword is no longer used for around advice. Instead, the return type is declared as it is for methods. So, +[source, java] .... around(Point p) returns void: setters(p) { ... } -==> +// ==> void around(Point p): setter(p) { ... } .... @@ -913,6 +961,7 @@ void around(Point p): setter(p) { ... } Around advice must now declare the checked exceptions it throws with a `throws` clause, much like a method. +[source, java] .... char around(char c) throws java.io.CharConversionException: converter(c) { char result; @@ -951,6 +1000,7 @@ This allows interesting advice interaction. In the following advice, for example, the `after throwing` advice will catch the exception thrown by the `before` advice +[source, java] .... aspect A { before(): call(void main(..)) { @@ -965,6 +1015,7 @@ aspect A { But reversing the order will give the `before` advice more precedence, making its exception uncatchable by the `after throwing` advice +[source, java] .... aspect A { after() throwing(RuntimeException e): call(void main(..)) { @@ -986,15 +1037,17 @@ If you use after returning advice and do not need to expose the return value, you no longer need to write an empty set of parentheses to indicate that fact. So, +[source, java] .... after(Formals) returning (): Pointcut { ... } -==> +// ==> after(Formals) returning: Pointcut { ... } .... The same syntax is now available for after throwing advice, in case you do not care what `Throwable` is thrown. +[source, java] .... after(Formals) throwing: Pointcut { ... } .... @@ -1013,6 +1066,7 @@ The `JoinPoint` object hierarchy has been folded into a single class, `org.aspectj.lang.JoinPoint`. A common pattern in logging, for example, was +[source, java] .... before() executions(* myMethod()) { ExecutionJoinPoint jp = (ExecutionJoinPoint)thisJoinPoint; @@ -1025,6 +1079,7 @@ before() executions(* myMethod()) { While there is still a rich hierarchy for signatures, there is only one `JoinPoint` type, so this can be rewritten as: +[source, java] .... before() executions(* myMethod()) { JoinPoint jp = thisJoinPoint; @@ -1045,12 +1100,14 @@ Some of the method names of `JoinPoint` have been reorganized, as well. The keywords `+implements` and `+extends` no longer exist. Instead, AspectJ uses the `declare` form for exactly the same functionality. +[source, java] .... Point +implements Serializable; => declare parents: Point implements Serializable; .... +[source, java] .... MyButton +extends ButtonAdaptor; => @@ -1063,6 +1120,7 @@ declare parents: MyButton extends ButtonAdaptor; Around advice advice no longer effects the static exception checking of Java. This means that the following code previously compiled: +[source, java] .... class C { void noExceptionDeclared() { @@ -1088,6 +1146,7 @@ exceptionDeclared() will not, actually, throw an exception, we now "soften" that exception, that is, take it out of the space of declared exceptions. +[source, java] .... declare soft: ExceptionType: Pointcut; .... @@ -1097,6 +1156,7 @@ would require runtime information. But picking out method calls is just fine. So in order to make the above example work, one new declaration is needed: +[source, java] .... declare soft: IOException: call(void C.exceptionDeclared()) && @@ -1109,9 +1169,10 @@ declare soft: IOException: The syntax of "of each" modifiers has changed. For `of eachcflow` and `of eachcflowbelow`, you can simply replace "of each" with "per". So, +[source, java] .... aspect A of eachcflow(...) { ... } -==> +// ==> aspect A percflow(...) { ... } .... @@ -1120,11 +1181,12 @@ remove that declaration entirely (because this is the default behaviour), or replace the `of eachJVM()` declaration with an `issingleton` declaration. +[source, java] .... aspect of eachJVM() { ... } -==> +// ==> aspect A { ... } -or +// or aspect A issingleton { ... } .... @@ -1135,13 +1197,16 @@ you replace with depends on the `Pointcut` you use. If you use a pointcut that picked out reception join points, then use `pertarget`, and rewrite the pointcut to pick out call join points. So +[source, java] .... aspect Shadow of eachobject(receptions(void Point.setX(int)) || receptions(void Point.setY(int))) { ... } -==> + +// ==> + aspect Shadow pertarget(call(void Point.setX(int)) || call(void Point.setY(int))) { ... @@ -1193,7 +1258,7 @@ In many cases, you may not care whether the points of `Pointcut` are included or not, and so can safely leave `cflow(Pointcut)` pointcut designators alone. However, if you use the idiom -[source,codeindent] +[source, java] ---- Pointcut && ! cflow(Pointcut) ---- @@ -1201,7 +1266,7 @@ Pointcut && ! cflow(Pointcut) to capture the non-recursive entries to a particular pointcut, you will definitely want to rewrite that as -[source,codeindent] +[source, java] ---- Pointcut && ! cflowbelow(Pointcut) ---- @@ -1212,14 +1277,14 @@ The primitive pointcut designator `cflowtop(Pointcut)` has been removed from the language, as it is expressible with `cflow` or `cflowbelow`. All uses of `cflowtop(Pointcut)` can be rewritten as: -[source,codeindent] +[source, java] ---- cflowbelow(Pointcut && ! cflowbelow(Pointcut)) ---- Though in most cases the following is sufficient -[source,codeindent] +[source, java] ---- cflow(Pointcut && ! cflowbelow(Pointcut)) ---- @@ -1232,7 +1297,7 @@ override all of its abstract pointcuts with an empty pointcut. AspectJ 0.8beta3 enforces the restriction that a concrete aspect may not have any abstract pointcuts. Thus the following extension: -[source,codeindent] +[source, java] ---- abstract aspect A { abstract pointcut pc(); @@ -1245,14 +1310,14 @@ will no longer compile. Adding the new empty pointcut designator -[source,codeindent] +[source, java] ---- pointcut Id(); ---- in the declaration of the concrete aspect fixes this problem. -[source,codeindent] +[source, java] ---- abstract aspect A { abstract pointcut pc(); @@ -1269,7 +1334,7 @@ aspect B { Previously, the compiler silently refrained from applying a piece of advice to join points within its own advice body. So, for example, in -[source,codeindent] +[source, java] ---- class C { static int i; @@ -1292,7 +1357,7 @@ Most cases of this error can be fixed by correctly specifying the desired pointcut: In the above example, the intention is clearly not to trace _all_ references of `C.i`, just those outside the aspect. -[source,codeindent] +[source, java] ---- class C { static int i; @@ -1310,7 +1375,7 @@ code in the aspect, but not in the particular piece of advice. In such cases, you can pull the body of the advice into a method and restrict away from that method (and away from calls to that method): -[source,codeindent] +[source, java] ---- class C { static int i; @@ -1353,10 +1418,10 @@ to the 0.8beta1 release of AspectJ. The syntax of introduction has changed. Porting most programs should require some simple editing. Anywhere you have an introduction block -[source,codeindent] +[source, java] ---- introduction GTN { - ... + // ... } ---- @@ -1368,7 +1433,7 @@ For field introduction, place the `GTN` in front of the field name, and for constructor introduction, place the `GTN` in front of the `new` identifier. -[source,codeindent] +[source, java] ---- introduction Foo { public void doStuff() { this.doStuffLater(); } @@ -1376,7 +1441,7 @@ introduction Foo { public new(int x) { super(); calorieCount = x; } } -==> +// ==> public void Foo.doStuff() { this.doStuffLater(); } public int Foo.calorieCount= 3; @@ -1387,14 +1452,14 @@ For implements and extends introduction, move the `GTN` in front of the new identifiers `implements` or `extends`, and place that in a `declare parents` form. -[source,codeindent] +[source, java] ---- introduction Foo { implements Comparable; extends Goo; } -==> +// ==> declare parents: Foo implements Comparable; declare parents: Foo extends Goo; @@ -1404,13 +1469,13 @@ In all cases, if the `GTN` is just a type name, it can be moved down on its own. However, if the `GTN` uses any of `&&`, `||`, and `!`, it must be parenthesized. -[source,codeindent] +[source, java] ---- introduction subtypes(Foo) && !Goo { int x; } -==> +// ==> int (Foo+ && !Goo).x; ---- @@ -1423,7 +1488,7 @@ need to modify your code to avoid this accessibility issue, or you will need to use the `privileged` modifier on the aspect that contains the introduction. -[source,codeindent] +[source, java] ---- class Counter { private int count = 2; @@ -1435,7 +1500,8 @@ aspect ExposeCountersPrivates { } } -==> +// ==> + // in 0.8, only privileged aspects can expose a class's privates privileged aspect ExposeCountersPrivates { public int Counter.getCount() { return count; } @@ -1446,7 +1512,7 @@ If you have introduced private or package-protected members, you will probably have to re-write some code. Most previous uses of introducing privates can be improved by using private introduction instead. -[source,codeindent] +[source, java] ---- class C { } @@ -1458,7 +1524,8 @@ aspect AddCounter { } } -==> +// ==> + aspect AddCounter { private int Counter.count; public int Counter.getCount() { return count; } @@ -1491,7 +1558,7 @@ clause or is declared "of eachJVM()", and is not extended by another aspect, simply remove the keyword "static" from all pieces of advice, and make sure the aspect is not defined with the "abstract" modifier. -[source,codeindent] +[source, java] ---- aspect Tracing { static before(): executions(* *(..)) { @@ -1499,7 +1566,7 @@ aspect Tracing { } } -==> +// ==> aspect Tracing { before(): execution(* *(..)) { @@ -1513,7 +1580,7 @@ advice, is extended, or is "of eachObject(...)" or "of eachcflowroot(...)", you should group your static advice together and put it in a new aspect, possibly even an inner aspect. -[source,codeindent] +[source, java] ---- aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) { static before(): executions(* *(..)) { @@ -1526,7 +1593,7 @@ aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) { // some other dynamic advice, fields, etc } -==> +// ==> aspect ComplexTracing of eachobject(cflow(executions(void Main.main(..)))) { static aspect AlwaysTracing { @@ -1551,7 +1618,7 @@ majority of your code the most serious change this requires is to add an explicit `abstract` modifier to a super-aspect that was already implicitly abstract. -[source,codeindent] +[source, java] ---- aspect BaseTracing { abstract pointcut traced(); @@ -1560,11 +1627,11 @@ aspect BaseTracing { } } -==> +// ==> // make this abstract aspect explicitly abstract abstract aspect BaseTracing { - ... + // ... } ---- @@ -1576,20 +1643,22 @@ instance of a subaspect back. This pattern was used in the Spacewar example in the AspectJ distribution. We had the class hierarchy +[source, text] .... - SpaceObject (abstract) - |- Ship - |- Bullet - |- EnergyPellet +SpaceObject (abstract) + |- Ship + |- Bullet + |- EnergyPellet .... And the aspect hierarchy +[source, text] .... - SpaceObjectDA (abstract) - |- ShipDA of eachobject(instanceof(Ship)) - |- BulletDA of eachobject(instanceof(Ship)) - |- EnergyPacketDA of eachobject(instanceof(Ship)) +SpaceObjectDA (abstract) + |- ShipDA of eachobject(instanceof(Ship)) + |- BulletDA of eachobject(instanceof(Ship)) + |- EnergyPacketDA of eachobject(instanceof(Ship)) .... And we would call `SpaceObjectDA.getAspect(SpaceObject)` to access the @@ -1609,7 +1678,7 @@ defined `of eachobject(instanceof(...))`. A prime example of this was the `BoundPoint` aspect of the bean example: which needed to associate each point with a `PropertyChangeSupport` object. -[source,codeindent] +[source, java] ---- aspect BoundPoint of eachobject(instanceof(Point)) { @@ -1630,7 +1699,7 @@ these state association is to use privately introduced fields. Instead of creating an aspect instance for every `Point` object, store the `PropertyChagneSupport` object in the `Point` objects themselves. -[source,codeindent] +[source, java] ---- aspect BoundPoint { private PropertyChangeSupport Point.support = new PropertyChangeSupport(this); |