views:

179

answers:

4

Suppose I want to add minor syntactic sugars to Java. Just little things like adding regex pattern literals, or perhaps base-2 literals, or multiline strings, etc. Nothing major grammatically (at least for now).

How would one go about doing this?

Do I need to extend the bytecode compiler? (Is that possible?)

Can I write Eclipse plugins to do simple source code transforms before feeding it to the standard Java compiler?

+4  A: 

I would take a look at Project Lombok and try to reuse the attempt they take. They use Java 5 annotations to hook in a Java agent which can manipulate the abstract syntax tree before the code is compiled. They are currently working on creating an API to allow custom transformers to be written which can be used with javac, or the major IDEs such as Eclipse and NetBeans. As well as annotations which trigger code to be generated, they are also planning on adding syntax changes (possibly mixin or pre-Java 7 closure syntax).

(I may have some of the details slightly off, but I think I'm pretty close).

Lombok is open source so studying their code and trying to build on that would probably be a good start.

Failing that, you could attempt to change the javac compiler. Though from what I've heard that's likely to be a hair-pulling exercise in frustration for anyone who is not a compiler and Java expert.

Grundlefleck
+3  A: 

You can hack javac with JSR 269 (pluggable annotation processing) notably. You can hook into the visitor that traverse the statements in the source code and transform it.

Here is for instance the core of a transformation to add support for roman number in java (read of course the complete post for more details). It seems relatively easy.

public class Transform extends TreeTranslator {
    @Override
    public void visitIdent(JCIdent tree) {
        String name = tree.getName().toString();
        if (isRoman(name)) {
            result = make.Literal(numberize(name));
            result.pos = tree.pos;
        } else {
            super.visitIdent(tree);
        }
    }
}

Here are additional resources:

I don't know if project Lombok (cited in the other answer) uses the same technique, but I guess yes.

ewernli
AFAIK, Lombok uses annotations only to bootstrap their Java agent, which hooks directly into the compiler. Annotation processing has limits to what it can do, I think Lombok sidesteps these limits. All the arguments of power and flexibility vs. forward compatibility and adhering to standards apply, the better approach will ultimately depend on what exactly the OP is trying to do :)
Grundlefleck
That is some excellent pointers. I'm still not sure if I can do what I want to do easily, since I may not have the luxury of visiting a tree to transform without extending the grammar, but I definitely have a place to start reading.
polygenelubricants
+2  A: 

Charles Nutter, the tech lead of JRuby, extended Javac with literal regular expressions. He had to change about 3 lines of case, as far I recall.

See http://twitter.com/headius/status/1319031705

Adrian
This is awesome guys!
polygenelubricants
I joined this answer to the other one, because I can only pick one official answer.
polygenelubricants
All right, thanks for doing so!
Adrian
+2  A: 

Charles Nutter, the tech lead of JRuby, extended Javac with literal regular expressions. He had to change about 3 lines of case, as far I recall.

See http://twitter.com/headius/status/1319031705


And here is an awesome tutorial on how to add a new operator to javac, http://www.ahristov.com/tutorial/java-compiler.html

For more links like that, see my list of Links for javac hackers .

Adrian
+1 As the original author of the post I cite in my answer, the credit goes to you.
ewernli
This is awesome guys!
polygenelubricants