[
Date Prev][
Date Next][
Thread Prev][
Thread Next][
Date Index][
Thread Index]
[
List Home]
[aspectj-users] Revamping simplified ITD syntax
|
Hi all AspectJ users.
There has been a discussion, about one year ago, about a simplified
syntax for ITDs. The discussion then diverged in another thread about
various ways of implementing ITD, which was not the original proposal
made by Dave Whittaker.
During one more year of heavy ITD usage in my Apache "Magma" Lab, I had
time to think about it much deeper, and concluded that the original
Dave's idea is quite right, but could even be improved.
So I'm writing to ask your ideas and comments on what follows.
The problem is that the current syntax that AspectJ use to alter the
Java type system (ITDs, but also declare parents, declare @xxx etc..) is
perfect if you are modifying a large number of classes. For example, all
classes annotated with such and such will implement this interface.
However, it is becoming more and more common the need to modify a single
class, adding a few methods, or adding annotations to it. In fact
annotations are becoming more and more important in Java programming,
with lots of framework depending on them, and lots of JSRs being
published to exploit annotations as much as possible. Having the ability
to "add" annotation on a class on a separate aspect, which could be
applied or not, is a very nice feature, but currently painful to obtain.
Think for example of applying JSR-303 validation annotations or JPA ones
on existing code using current syntax. Since annotations will be
different for each field, it is quite a pain and quite unreadable. The
power of patterns is, in these case, useless and counterproductive.
Dave's case of declaring fields and methods on the interface then used
in a declare parents, is a special and very common case of this situation.
So, taking from Dave's proposal of introducing a new "intertype"
keyword, I'd like to put the bar a little higher and propose the
introduction of the "on" keyword. Please note that this syntax is not a
complete alternative to the existing one, but is a complementary syntax
for the described use cases.
A simple example will give a quick idea of how it could work :
public class MyOldBean {
private String name;
private String surname;
public MyOldBean(int i) { ... }
public void doThat() { ... }
}
public aspect RevampMyOldBean {
@ClassLevelAnnotation
on MyOldBean implements NewInterface {
// new field
@FieldLevelAnnotation
private String newField;
// new constructor
@ConstructorAnnotation
public MyOldBean(String _newfield) {
...
}
// new method
@MethodLevelAnnotation
public String getNewField() {
...
}
// Existing field
@FieldLevelAnnotation
on String name;
// Existing method
@MethodLevelAnnotation
on void doThat();
// Existing constructor
@ConstructorAnnotation
on MyOndBean(int);
}
// Dave's case
on NewInterface {
public void doThis() { ... }
}
}
If you think of how this has to be written with current syntax, you'll
notice how less readable and more error prone it is. I'm not saying it
will be necessarily "longer" in the sense of typing, except for Dave's
case where there is an obvious reduction of typing, I'm thinking about
readability and complexity more than mere number of keystrokes, but I'm
pretty sure also number of keystrokes will be reduced.
Moreover, refactoring methods from inside a class to an ITD aspect (or
the opposite) would be a matter of cut and paste.
I'm not a guru when it comes to formal language definition, but I think
the "on" keyword could be defined like this :
[<annotations>]
on <Type> [extends <TypeList>][implements <TypeList>][ { <ITDBlock> }
* Annotations declared before the "on" keyword have to be applied to
the specified type and are interpreted as "declare @type"
* The "extends" and "implements" clauses, if present, are to be
applied to the specified type and are interpreted as "declare parents"
* The ITDBlock will contain new methods and/or the second form of
the on keyword.
The second form appear inside the ITDBlock of another "on" keyword.
[<annotations>]
on <MethodSig>|<FieldSig>|<ConstructorSig>;
* Annotations declared before the "on" keyword have to be applied to
the specified member and are interpreted as "declare @method" or
"declare @field" or "declare @constructor"
* Eventually, instead of signatures patterns could be used, given
that a complete signature is a specialized form of pattern.
As you can see, this could be implemented as plain syntactical sugar, it
could even be possible to write a set of regular expressions or a simple
parser to convert from this new syntax to the current one.
I'd love to try to code this inside AspectJ, and make this my first real
code contribution to the project.
WDYT?
Simone
--
Simone Gianni CEO Semeru s.r.l. Apache Committer
http://www.simonegianni.it/