Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
RE: [aspectj-users] Language: support for modifiers in TypePatterns


Jim Wrote:
> Here are what your examples would look like if we extend ModifiersPat to
> include attributes and at the same type allow a ModifiersPat to be added to
> a TypePat.  I think that these examples show that extending ModifiersPat
> doesn't interfere with the ability to manage complex expressions.
>
> target(@AttributeOne *) -- and we could make the * optional
> call(* *(..)) && target(@AttributeOne @AttributeTwo Foo)
> pointcut attrOneAndTwo(): target(@AttributeOne @AttributeTwo *);
> call(* *(..)) && target(Foo) && attrOneAndTwo();
> call(* *(..)) && (target(Foo) || attrOneAndTwo());
> execution( (private *) *(..)) - all methods that return a private type

These are looking good. I'm persuaded by the use of '*' that this is the way to go.

> I think it would be dangerously non-orthogonal to extend ModifiersPat for
> MethodPat, ConstructorPat and FieldPat to include attribute patterns, but
> not to do the same for TypePat.  This would also prevent us from specifying
> some interesting things, i.e.


I don't disagree with this statement at all (or to put it more plainly, I agree ;) ). My point was only that modifiers in TypePat are the ones that cause the most complexity in expressions, since TypePat can be used in so many positions in an _expression_.

Given the compelling argument from the first set of examples to extend TypePat with attributes, and the desire for consistent treatment, I'm thinking that we have to allow TypePat to contain attributes, and for the attribute form to be usable everywhere a TypePat is usable (i.e. my contrived example would be perfectly legal - and Jim makes a very good point that you can  write virtually the same thing today anyway). The jury is out on how people will actually use attributes, but my guess is that they will increase the use of more complex type patterns. If this turns out to be the case, I'd like in the long run to explore the ability to name and compose patterns so that users can simplify pointcut expressions that make heavy use of more complex patterns ('declare pattern' anyone??? ;) ). Of course, 'anonymous' patterns as we have today would still be supported too, so there is nothing stopping us pursuing extended pattern syntax now, and coming back to naming patterns at a later date.

-- Adrian
Adrian_Colyer@xxxxxxxxxx



"Jim Hugunin" <lists@xxxxxxxxxxx>
Sent by: aspectj-users-admin@xxxxxxxxxxx

18/12/2003 00:22
Please respond to aspectj-users

       
        To:        <aspectj-users@xxxxxxxxxxx>
        cc:        
        Subject:        RE:  [aspectj-users] Language: support for modifiers in TypePatterns



This message is about what support for annotations in AspectJ might look
like.  We should spend a little time on this discussion because it is
surprisingly coupled to extending TypePatterns to include modifiers.

Adrian Colyer wrote:
> JSR 175 basically says that annotations can occur on any declaration:
<snip>

JSR 175 also says that "an annotation is a new kind of modifier...
Annotations are conventionally placed before all other modifiers, but this
is not a requirement; they may be freely intermixed with other modifiers."

This rule puts a lot of pressure on us to allow annotations to be used in
any ModifierPattern.  JSR 175 lets me write the following method
declaration:
 public @TxRequired void updateAccount() { ... }

I'd expect to be able to write the corresponding pointcut:
 execution(public @TxRequired void updateAccount())


Here are what your examples would look like if we extend ModifiersPat to
include attributes and at the same type allow a ModifiersPat to be added to
a TypePat.  I think that these examples show that extending ModifiersPat
doesn't interfere with the ability to manage complex expressions.

> target(@AttributeOne)
target(@AttributeOne *) -- and we could make the * optional

> // target must be of type Foo, with both attr one and attr two
> call(* *(..)) && target(Foo) && target(@AttributeOne) &&
> target(@AttributeTwo)

call(* *(..)) && target(@AttributeOne @AttributeTwo Foo)

> the former style gives us more flexibility to manage complex expressions,
> e.g.
>
> pointcut attrOneAndTwo() : target(@AttributeOne) && target(@AttributeTwo);
> call(* *(..)) && target(Foo) && attrOneAndTwo();

pointcut attrOneAndTwo(): target(@AttributeOne @AttributeTwo *);
call(* *(..)) && target(Foo) && attrOneAndTwo();

> It also lets us write:
> call(* *(..)) && (target(Foo) || attrOneAndTwo());

call(* *(..)) && (target(Foo) || attrOneAndTwo());

> For compile-time (static) matching, we currently define MethodPat,
> ConstructorPat, and FieldPat as
>
> [ModifiersPat] TypePat [TypePat . ] IdPat (TypePat, ... )
> [ModifiersPat] TypePat . ] new (TypePat , ... )
> [ModifiersPat] TypePat [TypePat.]IdPat
>
> respectively.
>
> It seems straight-forward and unambiguous (as Wes suggests) to extend the
> ModifiersPat to contain attribute patterns, and these would refer to the
> method, constructor, or field declaration as appropriate.

I think it would be dangerously non-orthogonal to extend ModifiersPat for
MethodPat, ConstructorPat and FieldPat to include attribute patterns, but
not to do the same for TypePat.  This would also prevent us from specifying
some interesting things, i.e.
 execution( (private *) *(..)) - all methods that return a private type

> Where the examples we've looked at so far start to get confusing (to my
> eye), is when TypePat is extended to allow attribute patterns also. Try
> the
> following execution example on for size:
>
> execution((@TxRequired || @TxMandatory) public (@SessionBean ||
> @EntityBean)
> (com.myco..* && @BusinessDomain).*(..,@SensitiveData) throws @Auditable)

I'd like to point out that this example isn't any less confusing if you
replace the attributes with subtype checks which you can do today, i.e.
execution(public (SessionBean+ || EntityBean+)
         (com.myco..* && BusinessDomain+).*(..,@SensitiveData)
         throws Auditable+)


Wes Isberg wrote:
> This
>
>   target(@ClassType *)
>
> refers to the run-time type of the target object, but
>
>   call(@ClassType void *(..)) // err?
>
> is a mistake since @ClassType is an attribute of types,
> not methods.  Same result, converse reason, for
>
>   call((@TransactionRequired *) *(..)) // err?
>
> except that @TransactionRequired is an arbitrary user-
> specified attribute, while @ClassType is one we specify
> is to be used only for types (or to be otherwise
> disambiguated via qualification).
>
> Which raises the question: should we be able to detect
> these mistakes?

This is a good set of examples.  The good news is that the compiler/weaver
can and will be able to detect these kinds of mistakes.  The attribute spec
includes tags for attributes to specify what kinds of declarations they can
be applied to.  So long as the user has correctly specified the
@TransactionRequired attribute to only be allowed on methods then the
compiler/weaver will be able to signal an error in the case you show.

-Jim


_______________________________________________
aspectj-users mailing list
aspectj-users@xxxxxxxxxxx
http://dev.eclipse.org/mailman/listinfo/aspectj-users


Back to the top