Hi all,

I recently spend some time talking with AI about this project I had in mind for a long time: a new joint compiler working on the AST level.

The goal was to allow transforms in Groovy to run and add methods and other class structures and give the Javacode a chance to see them.
Basic problem:

A.groovy:
package pa
@MyTransform
class A{def b}

B.java:
package pb;
import pa.*;
public class B extends A {}

C.groovy:
package pc
import pb.*
class C extends B {}

D.java:
package pd;
import pc.C;
public class D extends C {}


To compile the java code you need the Groovy code, but to compile the Groovy code you also need the Java code.

Current solution: generate stubs for the Groovy code
This is a lot like having headers in C, where you compile against those instead of the full source files. But the real problem is resolving classes. In C.groovy we cannot resolve B, since it is in Java. Thus we write the import also in the stub and just assume, that Java will resolve the class the same way Groovy would do. Which is a "mostly true" assumption, but not fully. While the property b in A is no problem, if MyTransform adds a method or anything like that in a late phase, then it will not be visible to the Java compiler when compiling against the stubs.

So the idea was to create AST ClassNodes from the Java files, compile the Groovy code and then compile the java code against the final Groovy class files. The problem here is that class names need to be resolved. And that would then happen in the Groovy compiler. Basically an extra resolver for those Java source based ClassNodes for resolving in a "Java manner". This can become quite complex.

Then I was wondering if the Java compiler could help or maybe a JDT based solution. But the resolver in the Java compiler is not made for this kind of usage really. You need internals and they will change. JDT is better suited but here too it is not quite doing what we want. Both will try to resolve too much.

So my thinking was that a hand-written resolver will be needed for this. And here I was wondering if it is really worth it. I mean the complexity and somebody needs to maintain it as well. In the end the situation is like this: if java uses something like lombok, which may add constructors fields and methods then we will not see these things in Groovy. It is a bit like a reversal of the situation with the transforms.

The best solution so far is for me to not mix groovy and java code in one src folder, and keep them in different sub projects. The situation on top of the post would mandate 4 such sub projects. Advantages are that you may not need to compile everything again, you do not generate hundreds of small files, that need to be parsed by Javac... Disadvantages are of course that you pay for the startup of the compilers several times and you can not freely mix.

Do you think I am wrong? I really would like to hear some opinions.... even if it is like "joint compilation is not important to us"

bye Jochen

Reply via email to