Tuesday, October 23, 2012

Introducing : Active Annotations

In this article I'd like to introduce you to a new important language feature for Xtend. Xtend is a statically-typed language which compiles down to readable Java source code.

Active Annotations in a Nutshell

Active Annotations allow for participating during the translation of Xtend code to Java source code. You basically declare an annotation and with it provide the processing instructions where you can
  • issue errors and warnings,
  • provide corresponding quickfixes,
  • apply all kind of changes and enhancements to the target Java classes,
  • introduce new Java types or
  • even update or create ordinary text files (e.g. web.xml).

To use such an annotation you just have to have it on your class path like any ordinary Java annotation.
You could for instance want to have an annotation called @Entity, which turns simple classes with fields into data classes tailored for your project-specific context. You'd define and maintain the definition of what an entity is right in your project and would version and distribute it just like any other API. The IDE will be fully aware of the processing changes. Not only will errors, warnings and quickfixes be available in the IDE but also the scopes, type computation and content assistance will behave according to your processing instructions.

General Use Cases

Let's have a look at some use cases. Xtend already comes with two annotations, whose processing for now is hard coded into the compiler. We did so, to gain some experience with the general idea and will of course replace the hard coded version with 100% library-based annotations in a future release.
One of these annotations is the @Property annotation, which translates a simple field into a Java-Bean property. That is given the following Xtend code
   // Xtend
   @Property String name
you'll get this Java code :
   // Java
   private String name;
   public String getName() {
      return this.name;
   }
   public void setName(String name) {
      this.name = name;
   }
The other annotation Xtend already has is @Data which translates a class with fields into a value object á la domain-driven design, i.e. it creates an immutable class with a value-based equals and hashcode implementation and a nice toString implementation. We will likely support other generic use cases such as @Delegate, which generated delegate methods for an annotated field and @Builder which will automatically derive a builder API for a set of classes.

Framework-specific Use Cases

You might have seen pre-built annotations which do participate in the compilation project with other technologies. The real coolness about active annotations in Xtend is that everybody can develop their own project specific ones easily. If you want to change the behavior, just navigate to the annotation and do your changes. You will instantly see the result, since every referencing Xtend file will be re compiled on change. And it is fully transparent since everything is translated to readable Java source code!
With this simplicity to develop and deploy them people will be able to use them to remove tedious structural boilerplate in many Java APIs. We for instance built two active annotations for GWT. One for remote services, which automatically derives the required interfaces and adds the required super class. Another which automatically adds fields declared in a UI-Binder XML file. You can find some slides here and the source code is on github.

Outlook

Today we have a working prototype, which you can play around with if you are brave enough. But there's no documentation and the API changes on a daily bases, so better wait a bit. We will release a beta version of this new feature with the next release (planned for December/January), but this will still lack some important features and the API will be subject to change.

I am very excited and think active annotations really solve a huge class of problems in a very nice way and am really curious with what kind of annotations people will come up in the future.

Alan Kay once said about Lisp that it is not a language but a building material. Active annotations bring the power of Lisp Macros to the statically typed Java world.

29 comments:

  1. Interesting feature, Xtend looks more interesting every day.

    Why did you choose @Data instead of @ValueObject, the term that's used in Domain Driven Design?

    ReplyDelete
  2. I have to confess that I initially thought of Xtend as just another Java without semicolons. However, I changed my mind after watching http://vimeo.com/48279068 and playing around with the language a bit. The active annotations seem to be another useful feature.

    BTW: links to "some slides" and "source code is on github" are broken

    ReplyDelete
  3. Really awesome stuff!
    One little note:
    in "FRAMEWORK-SPECIFIC USE CASES" paragraph, the links are broken (but it has been easy to reach the pages anyway)

    Also, where can I find @WithUiBinding source? Couldn't find! :(

    ReplyDelete
    Replies
    1. Fixed the links. @WithUiBinding can be found here : https://github.com/DJCordhose/todomvc-xtend-gwt/blob/master/gwtlib/org/eclipse/xtend/gwt/ui/WithUiBinding.macro

      Delete
    2. Oh, no... ".macro"! Yet Another Language to learn... :)
      Looking at it, looks like an xbase based DSL.
      Hope you'll make an intro post on it :)

      Awesome work, Sven!

      Delete
    3. hehe ... actually it's not that different from Xtend. But having a different file extension is the simplest solution to separate the compile-time scope from the runtime scope. You can have classes and the like which you use within the processing, but thos can not be regular Xtend or Java classes, since that must be interpreted.

      Delete
  4. This comment has been removed by the author.

    ReplyDelete
  5. I see all these code which is trying to reduce verbosity of Java and line of code, but doesn't they making debugging and troubleshooting tougher. If things goes wrong you need to look framework code than your application code.

    ReplyDelete
    Replies
    1. Since readable Java code is generated and since the debugger allows to step through Xtend code and the generated code at the same time, troubleshooting and debugging works nicely. The compiler even transforms long chained expressions into small statements and synthetic local variables, which you can inspect step by step during debugging.

      Delete
  6. Awesome! At this point, the precompiler approach of Xtend proves as being extremely powerful. Groovy for example has a similar feature, but there you must handle abstract syntax trees which can't be done als intuitively as dealing with generated Java code, I think.

    ReplyDelete
  7. Looks a lot like what Project Lombok (http://projectlombok.org/) does from within Java.

    ReplyDelete
    Replies
    1. Yes, it's very similar. The main differences are that everybody can very easily built their own annotations (that's quite involving with Lombok) and that it's just a library no special hacking or what's so ever.

      Delete
  8. Can you post a link to the implementation of @Property? Thanks!

    ReplyDelete
    Replies
    1. @Property has not yet been translated to the active annotation version. It's still hard coded in the compiler. I will post something as soon as we have done it.

      Delete
  9. This is, once again, HOT STUFF.. It sounds a bit like APT (e.g. https://github.com/vorburger/vorburgers-blueprints/blob/master/apt-example-processor/src/main/java/ch/vorburger/learnapt/SampleProcessor.java) - done right! ;-)

    ReplyDelete
    Replies
    1. Yes there are similarities to APT, Groovy AST transformations and Lombok. Actually also Scala's macros are very similar, with the difference that you do that for functions rather than annotations, which we will also support at some point, but IMHO has much fewer cool applications.

      Delete
  10. Though i gained many information about Java but i was unknown about X-tend which i came to from your site.I am always ready know about Java

    ReplyDelete
  11. Good stuff, I can't use this yet as I have elements that are provided=true but I get what you're doing.. i guess to support provided we could just list them as parameters to the active annotation?

    If not a special attribute on the ui:field I guess..

    ReplyDelete
    Replies
    1. It is meant to be an example. You can of course add support for provided UIFields yourself quite easily, once active annotations are available.

      Delete
    2. You bet, I can't wait to contribute to this!

      Delete
  12. Can you add to the behaviour of an existing annotation in a codebase?

    That would be super useful for - say - GWTP

    ReplyDelete
    Replies
    1. Not sure what you mean. Could you elaborate a bit?

      Delete
    2. I think he wants to add code generation based on pre-existing annotations(Annotations that exist in outside frameworks). From what you said above I believe that the correct way to handle this is have your own annotation and do one of two things.

      1. Have an annotation that reads other annotations and generates code accordingly

      2. Have an annotation that as part of the generation process generates the annotation into the code.

      Do I understand that correctly?

      Delete
    3. Thanks for getting back, eg. can we make existing annotations in a code base active annotations?

      I should probably just try..

      GWTP is very useful but has tons of boilerplate. Id like to start experimenting with writing some code generation on the back of your work here.

      Delete
    4. It's exactly like Caleb said. You can't change the semantics of existing annotation, but you can inspect and use them within your own active annotation.

      Delete
  13. Is there a public repository of Xtend where active annotations are developed? I can not wait to try it...

    ReplyDelete
    Replies
    1. Of course it's public but it's not trivial to build it on your own (we don't have a description of what to do yet). But you can just install the nightly build from the following update site : http://download.eclipse.org/modeling/tmf/xtext/updates/composite/latest/

      Be warned: The annotations feature is very beta currently! I doubt that you can have much fun with them today.

      Delete
  14. Very magical and magical functions

    ReplyDelete