Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[aspectj-users] Can you explain what AspectJ's cFlow(P && Q) does, by means of example?

Hi all!

I'm struggeling to understand what cFlow(P) && cFlow(Q) and cFlow(P &&
Q) do, how they differ - and why.

I've already posted to StackOverflow, but there don't seem that many
AspectJ users around, so I thought I'd ask the question again, on the
mailing list. (Here's the URL to the original post, by the way:
http://stackoverflow.com/q/30039559/2018047 )

Basically, I was looking at the doc's section on Pointcut composition:
https://www.eclipse.org/aspectj/doc/released/progguide/language-joinPoints.html#pointcut-composition

As I already pointed out, I'm a bit confused how the two concepts,
cFlow(P) && cFlow(Q) and cFlow(P && Q), work.
I did a bit of googeling, and found a rather helpful PowerPoint
presentation (for a course at the university of Utrecht), which
explains:

>>cflow is the collection of join points flowing from the argument pointcut. This means that cflow(P) && cflow(Q) is the intersection of the two collections, while cflow(P && Q) means that you first combine the pointcuts P and Q, and all the join points flowing from that are in this collection.<<

They go on to list all join points for cFlow(P) && cFlow(Q) (pointcut
flowPAndflowQ() : cflow(execution(* Example.P(..))) &&
cflow(execution(* Example.Q(..))) && within(Example);), and to me it
looks like an intersection of all the control flow points of the
individual statements - P ∩ Q, if you will (just like they said):

Flow from P - execution(void Example.P())
Flow from P - call(void Example.Q())
Flow from P - execution(void Example.Q())
Flow from Q - execution(void Example.Q())
Flow from P && flow from Q - execution(void Example.Q())

(Their example is like the one in the AspectJ docs, except for the
lacking println() statement.)

What I still struggle with is to understand what cFlow(P && Q) does,
and how it differs from cFlow(P) && cFlow(Q).

On StackOverflow, medvedev1088 tried to explain it, and pointed out
that the last section of the quote above should read >>cflow(P && Q)
means that you first _intersect_ the pointcuts P and Q, and all the
join points flowing from that are in this collection<<

But I still don't really get it. (For example, how can both be an
intersection?) Could someone please provide me with an example when
cFlow(P && Q) would work, maybe even with a list of all the join
points concerned, like above?

Initially, I had thought it meant 'add all flow points in P and Q
(i.e. P + Q)', which should be the superset (union) to P ∩ Q, P ∪ Q?
But apparently, that's not it. I've also been told it's not all flow
points that could be triggered by both, P and Q, i.e. all flow points
within X() below:

public void P() { X(); }
public void Q() { X(); }
public void X() { /* all that is in the body of X() */ }

medvedev1088 pointed out that >>pointcut P defines a single join
point: execution(void Example.P()), and pointcut Q defines a single
join point: execution(void Example.Q()). Because these join points are
different the intersection for them is an empty set. cflow taken from
an empty set is an empty set too.<< But for the above example, isn't
that precisely what the execution of X() would represent? (Or would
that only be true if both, P and Q would call X() together and at the
same time?)

Just for my own sake, I think cFlow(P && Q) would look as follows when
written out, right?
pointcut cFlowOfPandQ : cFlow(execution(* Example.P()) && execution(*
Example.Q())) && within(Example);
Is the whole point that you can't execute P and Q at the same time?
(Isn't that what happens when P calls Q, though?)

Any help in disentangling this for me would be much appreciated!

Kind regards,

Christian


Back to the top