Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] How do you update "reception" calls?

Neither receptions(..) nor calls(..) works in AspectJ 1.0 or later
(see the CHANGES file for language history), so use

   target(Foo) && call(void m())

As for the difference between 

   target(Foo) && call(void m())

and

   call(void Foo.m())

target is a dynamic test on the reference which matches if instanceof does,
while call works from the method declaration, with Foo matching the 
declaring type of the method call join point. (This account ignores some
unnecessary caveats; for a better account, read the corresponding 
sections of the programming guide.)  That addresses your questions:

> 1.1.  How does "target(FigureElement)" work that it is able to select
> instances of Line, Point and FigureElement?  Shouldn't it only select
> instnaces of FigureElement?

target(F) picks out F or any subtype thereof, as does instanceof.

> 1.2.  Shouldn't "calls(void FigureElement.incrXY())" only select objects
> referenced by variable of type FigureElement?

It should pick out calls to a methed incrXY declared by FigureElement,
even if the method is implemented, overridden, or inherited in a 
FigureElement subclass like Line and that is the type of the reference.

Consider the case of a call to a subclass not overriding a method:

    ...
    new Foo().m();
    ...

    class SuperFoo {
        void m(){}
    }
    class Foo extends SuperFoo {
    }

This pointcut will match

   target(Foo) && call(void m())

but this one will not match

   call(void Foo.m())

though this will match, because m() is defined in SuperFoo:

   call(void SuperFoo.m())

So if you do use the declaring type in the call form, then you'll 
usually want to specify the declaring type of the method (SuperFoo) 
-- but this can be hard in practice.  Most programmers "mean" 

  target(Foo) && call(void m())

But note also the converse error, where

   target(Foo) && call(void m())

will not match the call 

   new SuperFoo().m()

(but most programmers would not expect it to match).

Make sense?  Below is some code to experiment with.

Wes

--------------- TargetVCall.java
import org.aspectj.lang.JoinPoint;

public class TargetVCall {
    public static void main (String[] args) {
        new SuperM().m();   // 5
        new M().m();        // 6
        new SuperN().n();   // 7
        new N().n();        // 8 
    } 
}

class SuperM { void m(){} }
class M extends SuperM { void m(){} }
class SuperN { void n(){} }
class N extends SuperN { }

aspect A {
    static void log(JoinPoint jp, String pc) {
        System.out.println(jp.getSourceLocation().getLine() + pc);
    }
    before() : call(void SuperM.m()) { 
        log(thisJoinPoint, ": call(void SuperM.m()) ");
    }
    before() : call(void M.m()) { 
        log(thisJoinPoint, ": call(void M.m()) ");
    }
    before() : target(M) && call(void m()) { 
        log(thisJoinPoint, ": target(M) && call(void m()) ");
    }
    before() : target(SuperM) && call(void m()) { 
        log(thisJoinPoint, ": target(SuperM) && call(void m()) ");
    }
    before() : call(void SuperN.n()) { 
        log(thisJoinPoint, ": call(void SuperN.n()) ");
    }
    before() : call(void N.n()) { 
        log(thisJoinPoint, ": call(void N.n()) ");
    }
    before() : target(N) && call(void n()) { 
        log(thisJoinPoint, ": target(N) && call(void n()) ");
    }
    before() : target(SuperN) && call(void n()) { 
        log(thisJoinPoint, ": target(SuperN) && call(void n()) ");
    }
}

Donal Lafferty wrote:
> 
> Preamble:
> 
> Looking at the ECOOP 2001 paper
> (http://aspectj.org/documentation/papersAndSlides/ECOOP2001-Overview.pdf
> ), there is a lot of use of the "receptions" primitive pointcut
> designator.  These examples are updated to use "calls" in corresponding
> presentation (see
> http://aspectj.org/documentation/papersAndSlides/ECOOP2001.pdf).
> However, the "Recent Changes" section that corresponds to the
> deprecation of "receptions" says that the target type should be
> specified using the 'Target' primitive pointcut (see
> http://dev.eclipse.org/viewcvs/indextech.cgi/~checkout~/aspectj-home/doc
> /changes.html#1.0alpha1).
> 
> Question:
> 
> The paper presents three classes, FigureElement and its descendents
> Point and Line.  It also presents this troublesome pointcut:
> 
>         receptions(void FigureElement.incrXY(int, int));
> 
> Which "intuitively refers to every time any kind of figure element (i.e.
> an instance of Point or Line) receives a call"
> 
> Since "receptions" is deprecated, the FAQ says to use :
> 
>         target(FigureElement)&& call(void incrXY(int,int))
> 
> But the ECOOP presentation uses
> 
>         calls(void FigureElement.incrXY());
> 
> 1.  Are these three pointcuts equivalent?  I.e.
> 1.1.  How does "target(FigureElement)" work that it is able to select
> instances of Line, Point and FigureElement?  Shouldn't it only select
> instnaces of FigureElement?
> 1.2.  Shouldn't "calls(void FigureElement.incrXY())" only select objects
> referenced by a referenced by variable of type FigureElement?
> 
> DL
> 
> ________________________________________________________
> Donal Lafferty, P.Eng., BSc. Computer Engineering
> <http://www.dsg.cs.tcd.ie/~laffertd/>
> 
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> http://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top