Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would one go about adding (minor) syntactic sugars to Java?

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?

like image 417
polygenelubricants Avatar asked Mar 07 '10 11:03

polygenelubricants


3 Answers

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.

like image 81
Grundlefleck Avatar answered Nov 02 '22 14:11

Grundlefleck


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:

  • Hacker's guide to the java compiler
  • Javac hacker resources

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

like image 33
ewernli Avatar answered Nov 02 '22 13:11

ewernli


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

like image 2
akuhn Avatar answered Nov 02 '22 14:11

akuhn