Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [aspectj-users] @DeclareMixin support

Hi Neale,

Thanks for the comments.  Yes, the cast is an annoyance - definetly for those used to code style and how it takes more control of the type system.  My hands are a really tied though - in that for annotation style I need the code to be pure java just in case the user uses javac to build it.  However, you have some nice ideas there where AJDT could help.

Your (1) - in an AJ aware editor, code assist could indeed be mixin aware and offer getName() because an @DeclareMixin that is around has modified the type SomeClass.  Inserting this code assist *would* put in the necessary cast and the getName() call.

Open type hierarchy could also be mixin aware.

The only time I'd feel completely comfortable straying from pure java is if the mixin syntax had a code style equivalent (so that ajc had to be used to build it).  But I'm not ready to do that until we are a bit further along with testing and feedback on @DeclareMixin.

cheers,
Andy.

2009/3/9 Neale Upstone <neale.upstone@xxxxxxxxxx>
Morning Andy.
 
Nice work on that one.  My ascent of the AspectJ learning curve has so far not required this approach, but, reading your documentation, it has had me thinking about the language of aspect oriented programming.
 
The cast to use the mixin is not ideal, and I wonder what patterns we might use to get around it.  The stronger compile-time type checking in Java 5 that generics has provided has me wanting the same sort of simplicity when developing AOP.
 
Do you think that AJDT should be able to auto-box the cast for your mixin?
 
I'd want to be able to replace typing: ((Named)new SomeClass()).getName(); with something simpler.
 
The wish list is probably:
1) Under AJ aware editors, the editor becomes mixin-aware, and should be able to propose getName() if I hit Ctrl-Space after typing: new SomeClass().
    This would then apply the cast (both with annotation and code style versions of the mixin)
2) Under AJDT the same as above happens, but the code is just: new SomeClass().getName(); (Ctrl-Space could give a choice based on whether we want the code to compile under standard Java, such as for LTW).
    This is perfectly valid code, as .getName() really does exist on SomeClass once weaving has happened.  We therefore shouldn't need the cast when doing code-style, just when doing annotation style.
3) When I hit F4 (Type Hierarchy) under AJDT, I should see Named as a parent type of SomeClass.

As far as I can work out, these features aren't there in AJDT (or maybe aren't yet in the JDT-Weaving implementation).
 
Cheers,
 
Neale
 
 

From: aspectj-users-bounces@xxxxxxxxxxx [mailto:aspectj-users-bounces@xxxxxxxxxxx] On Behalf Of Andy Clement
Sent: 06 March 2009 19:20
To: aspectj-users@xxxxxxxxxxx; aspectj-dev@xxxxxxxxxxx
Subject: [aspectj-users] @DeclareMixin support

We have many (valid!) bugs raised against AspectJ complaining that @DeclareParents is not the same as code style declare parents.  That is basically because @DeclareParents is not doing the same thing as code style declare parents, it is just a mixin.  To call out this difference and recognize the mixin pattern as being a nice solution to some kinds of problem, there is some new annotation style syntax.  This may even be useful in code style aspects.

This is in the latest AspectJ dev builds and some of it is even in the AJDT 1.6.4 release candidate (although you will have to keep doing full builds if trying it out in AJDT - incremental is broken).  It is still subject to change whilst I bed it in.

The new syntax is called @DeclareMixin - it is for mixing in an interface and associate delegate implementation into some target type.  It is effectively what @DeclareParents does today, but a rather neater syntax and addresses some of the problems users have had with @DeclareParents.  I'll now show it in action then talk about some of the open questions that we are still working through - any input on any of this is appreciated.

Best to show by example:

interface Named {
  public String getName();
  public void setName(String name);
}

class NamedImpl {
  String name;
  public String getName() { return this.name; }
  public void setName(String name) { this.name = name; }
}

class SomeClass {
}

aspect X {
  @DeclareMixin("SomeC*")
  public static Named createImpl() {
    return new NamedImpl();
  }
}

Instances of SomeClass can then be treated as if they implement Named (the type pattern for which types get the mixin is expressed as the annotation value):

  ((Named)new SomeClass()).getName();

Effectively the interface Named has been mixed-in to SomeClass and that means forwarding methods have been created within SomeClass that forward to a delegate implementation of Named, called NamedImpl.  Instances of the delegate are created through calls to the factory method that has been annotated.

This is what @DeclareParents actually does today but the syntax is not so friendly and there is no control over the factory method - it demands a no-arg constructor in the named implementation.

The flexibility with @DeclareMixin is that I can specify that the factory method takes a parameter:

  @DeclareMixin("SomeC*")
  public static Named createImpl(Object o) {
    return new NamedImpl(o);
  }

and when the factory method is called, the parameter value will be the instance of the target class for which the delegate is to be created - *this addresses an open bug we have about how does the mixin instance access the object for which it is being mixed in*.

You may notice that the factory method is static here - but it does not have to be.  If non-static then it can use aspect instance state that is accessible - but this is currently only supported for singleton aspects.

So there you have the basics - there are more details in this hastily put together piece of doc: http://www.eclipse.org/aspectj/doc/released/adk15notebook/ataspectj-itds.html

Open questions I am working through right now:

1) Does it need a simplified form for just mixing in a marker interface (that has no methods).  Here it is attached to just a field - the mixin interface is MarkerInterface:

@DeclareMixin("SomeC")
public static MarkerInterface foo;

(this is very similar to @DeclareParents)

2) What happens with clashing methods that already exist in the target.  Is the mixin considered to be a 'default implementation' (similar to our ITDs), or should it override whatever exists in the target, or should it be configurable as sometimes you'd want one scenario, sometimes the other.  I don't know enough about how this is handled in other languages that already support mixin's - if someone does, please chip in on this question since it would be silly to waste time solving something that other languages already have.

3) How to cleanly sort out the existing @DeclareParents.  Current thoughts are to simply deprecate defaultImpl - leaving @DeclareParents to more closely resemble code style 'declare parents' which just modifies the parent hierarchy, it doesn't add methods into the target (that is done by ITDs).  If someone wants to use defaultImpl with @DeclareParents, they should use migrate to @DeclareMixin instead.

comments? Thanks to Ramnivas for helping me get the syntax this far.
Andy.
**********************************************************************
IMPORTANT NOTICE.
Confidentiality:  This e-mail and its attachments are intended for the above named only and may be confidential.  If they have come to you in error you must take no action based on them, nor must you copy or show them to anyone; please reply to this e-mail and highlight the error.
Security Warning:  Please note that this e-mail has been created in the knowledge that Internet e-mail is not a 100% secure communications medium.
We advise that you understand and observe this lack of security when e-mailing us.
Viruses:  Although we have taken steps to ensure that this e-mail and attachments are free from any virus, we advise that in keeping with good computing practice the recipient should ensure they are actually virus free.
Monitoring and Scanning:  Cambridge Cognition has monitoring and scanning systems in place in relation to emails sent and received to: monitor / record business communications; prevent and detect crime; investigate the use of the Company's internal and external email system; and provide evidence of compliance with business practices.

Cambridge Cognition Limited
Company Registration Number 4338746
Registered address:
Tunbridge Court
Tunbridge Lane
Bottisham
Cambridge
CB25 9TU
UK
**********************************************************************


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



Back to the top