[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] New intertype syntax ...new meaning?


I haven't used the 'declare warning' pattern with ITDs you showed in a while. But you are right that there are use cases where the distinction between the lexical scope of the introduced members matters.

I guess one if the question to ponder: what is the interaction between within() and the new syntax-introduced members. For Roo-like usage, where aspects are used in "open classes" spirit, it seems that selection through within() should match even the code in the "intertype" (assuming that is the syntax AspectJ goes with) blocks.

Alternatively, within() maintains its strict lexical scope selection criteria and we introduce another pointcut (within+()?) to select intertyped elements.


On Tue, Nov 24, 2009 at 11:37 AM, Matthew Adams <matthew@xxxxxxxxxxxxxxx> wrote:
I really like the idea of transparent advices/ITDs, and I think that
the example that you've given is not something that I've come across.
I don't know if it's a corner case or not for everyone, though.

I'm not sure I understand the @Inline annotation.  Can you elaborate
on that one?

Here's the primary usage I have of ITDs:

@Entity @Coded public class Thing { /* ... */ }
public interface Coded { String getCode(); }
public aspect CodedMixin {
 public interface IntroducedCoded extends Coded {}
 declare parents: ((@Entity *) && (@Coded *)) implements IntroducedCoded;

 @Column(name="code") private String IntroducedCoded.code;

 public String IntroducedCoded.getCode() { return code; }
 public void IntroducedCoded.setCode(String code) { this.code = code; }

I do this to allow for any implementation of Coded, while introducing
a specific implementation of Coded to those that I want to, in
particular, @Entity's annotated with @Coded.  This results in a
postweaving class declaration of Thing that implements
IntroducedCoded, which uses a scary mangled name
(...$CodedMixin$IntroducedCoded) and has a public field with a mangled
field name for "code".

With fully transparent ITDs, I'd like to be able to say that
@Coded-annotated @Entity's implement Coded (not IntroducedCoded), with
an implementation of the one in the aspect, with no indication that it
was introduced, and with a non-mangled, non-public field name such
that decompiling Thing after weaving would result in the following:

public class Thing implements Coded {
 protected String coded; // note non-public
 public String getCode() { return code; }
 public void setCode(String code) { this.code = code; }

Make sense?


On Tue, Nov 24, 2009 at 11:14 AM, Andy Clement <andrew.clement@xxxxxxxxx> wrote:
> I'm nervous about making changes to what happens for weaving todays
> ITD syntax - meaning the ongoing discussions about mangling,
> visibility, etc.  A common request I am now seeing is that users want
> completely transparent application of ITDs.  What does what mean?  It
> would mean in the bytecode it looked *exactly* as if the user had made
> the ITD declaration in the target type.  I am thinking about whether
> the new syntax block (intertype X {}) could implement this new
> functionality and the user makes a deliberate decision about whether
> they need the features that come with non-transparent ITDs, or if they
> are happy with full inlining (and so choose the new syntax):
> What goes wrong if fully inlined?  Here is a scenario:
> class Foo
>  public void m() {
>    System.out.println("hey!");
>  }
> }
> aspect Bar {
>  public void Foo.run2() {
>    System.out.println("hey2!");
>  }
> declare warning: execution(* run2(..)) && !within(Bar): "Only Bar
> should be providing a run2 implementation";
> }
> This is (a crude representation of) a common pattern where an aspect
> and bunch of ITDs implement some feature, but there is also a guard
> "declare warning" in the aspect to make sure no-one attempts to
> duplicate what the ITDs are already responsible for.  The above works
> because post compilation the implementation of run2() is still
> considered to be in Bar, with various accessors/dispatchers added to
> Foo to support running the code in Bar.
> If full inlining is performed, it would not be possible to tell that
> Bar had provided the implementation of run2() into Foo - the bytecode
> will look exactly like the code had been written:
> class Foo {
>  public void m() {
>    System.out.println("hey!");
>  }
>  public void run2() {
>    System.out.println("hey2!");
>  }
> }
> I *think* there is a certain class of aspect that does fit this model
> and doesn't need the distinction to be maintained in the bytecode
> (remember, AspectJ is a bytecode weaver and does not really allow
> source knowledge to influence weaving).  If you use ITDs, do you use
> declare warning guards that would be impacted by fully inlined ITDs?
> (Of course, even if this were happening, AspectJ will still be
> informing the user of all the clashes that may be occurring due to
> ITDs interfering or clashing with existing members)
> Changing the meaning of existing syntax to do inlining could be made optional
> @Inline public void Foo.run2() {}
> but I'm thinking that inlining may be default for the new syntax,
> perhaps unless deliberately switched off.  or is that too confusing?
> any thoughts?
> Andy
> _______________________________________________
> aspectj-users mailing list
> aspectj-users@xxxxxxxxxxx
> https://dev.eclipse.org/mailman/listinfo/aspectj-users

aspectj-users mailing list