I’ve just replaced the old parser based approach too JTypeBuilder with an annotation processing tool. It’s currently very sketchy, but the code it produces now compiles, which is enough for me for the moment. :-)
Basically the idea is that you have an abstract class that looks something like the following:
public abstract class Test
public abstract String getFoo();
public abstract Badger getMushroom();
The type builder then extends this with the skeleton, filling in the implementations.
Next steps include tidying it up (it needs that really really badly. The code that’s curently there is basically just what I hacked together while figuring out APT), figuring out how to hook this up into the autodiscovery feature of annotation processing tools, and improving it so it only overrides equals, hashCode and toString if you declare them abstract. After that I have a bunch more annotations I intend to add in order to customise the behaviour and add extra functionality.
No further work done on it at the moment, but that’s because I’m rethinking its architecture.
Rather than building a DSL, I think it’s much more sensible to use abstract Java classes as the templates, with the generated classes subclassing a user defined abstract class and the abstract methods and annotations defining which methods are going to be generated.
This will let me switch to a more APT centric approach. I’ll probably start using apt-jelly for this, as it works quite well with the existing freemarker based approach.
Well, I’ve not done a *lot* of work on it since I last posted, but there are a few improvements. In particular the parser has been sanitised and expanded, support for generics has been (experimentally) added, and I’ve actually used the project in anger.
It’s currently insufficiently expressive to do most of the things I want, so I’ve been engaged in the great evil of editing generated code – using JTypeBuilder to generate *most* of the boiler plate and then adding my own bits of code to fix things.
I’m probably going to have to replace the code generation entirely at some point. Freemarker is very nice, and there are a lot of things I’d consider using it for. I’m not sure a compiler backend is one of them.
I’ve decided to start a new personal project, and I’m going to make it open source from day one. The project is called JTypeBuilder and is hosted at Google Code and released under an apache 2.0 license.
The basic idea is that it is used for generating data models and producing an awful lot of associated boiler plate code. It produces immutable classes for representing the data, mutable classes for generating the immutable ones and methods for passing back and forth between them. The immutable classes all have the obvious equals and hash code implementations, as well as a toString method which produces a JSON like representation of the class.
It currently just consists of a couple freemarker templates and some simple wrapper code for them. When I get around to it I’ll add a parser and command line interface for nice representation of the data models.
I have vague intentions of using this for some sort of simple ORM package. Another possibility is using it as part of a compiler backend for targeting the JVM – it can be used to generate the data types. All of this is in the future though – right now it’s simply a tool for reducing boiler plate code (and a fairly incomplete one at that).
Update: Phew. That was a succesful day. The parser and code generator now work, and are hooked together with an extremely rudimentary command line interface (it’s little more than a proof of concept). Still to do are improvements to the interface and customisability, as well as general improvements to code generation and parsing. Nonetheless, there is now a working tool there. Yay.
Actually, come to think of it, the biggest thing that needs fixing at the moment is the build.xml. It’s a really shocking piece of spaghetti XML put together with the intent of having something working quickly rather than actually producing a portable build script… Lots of hard coded paths.