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