6

I am trying to get joint/mixed compilation between all of Java, Groovy and Kotlin. I am currently working on a theory that it should be possible if groovyc can be made to just emit stub-files as a first stage.

Can it? Otherwise, any pointers towards making such a feature out of the sources of Groovy?

Here's the idea of full mixed compilation:

  1. Have Groovyc create Java-stubs for all its classes. AFAIU, it does this "blind", file by file, without seeing any other sources. (This is the kicker, and what this question is about: Have groovyc (or some part of it) generate only the stubs).
  2. Have Kotlinc compile Kotlin-files, basing typing on the Java files for Java, and the Java-stubs for Groovy (by adding them to kotlinc's classpath)
  3. Have Javac compile Java-files, basing typing on the Java-stubs of Groovy, and the class-files of Kotlin (by adding them to javac's classpath, or employ -sourcepath for the Java-stubs).
  4. Have Groovyc compile Groovy-files, basing typing on class-files for Java, and the class-files for Kotlin (by adding them to groovyc's classpath).
stolsvik
  • 5,253
  • 7
  • 43
  • 52

2 Answers2

1

This is relatively easy to do programmatically but not something currently supported from the command line. For programmatic usage, you'd need something like [1], but with the phase on the referenced line changed to SEMANTIC_ANALYSIS. You'd also need to keep the stubs as per [2].

To enable this from the command line, the FileSystemCompiler would need to know about a finishing phase and the unit.compile() statements at [3] would need to be made aware of that phase. But I haven't actually tried those changes myself.

[1] https://github.com/apache/groovy/blob/master/src/test/groovy/bugs/Groovy6086Bug.groovy#L63

[2] https://github.com/apache/groovy/blob/master/src/test/groovy/bugs/Groovy9031.groovy#L33

[3] https://github.com/apache/groovy/blob/master/src/main/java/org/codehaus/groovy/tools/FileSystemCompiler.java#L309-L317

Paul King
  • 627
  • 4
  • 6
-1

Use a build tool such as Gradle or Maven.

There is a standard project file layout for them which specifies the directory structure and naming conventions. You’ll put groovy source files under /src/groovy/ and java source files under /src/java/ and similar for kotlin.

Use the chosen build tool to init the project directory and prepare the base build config. If the build config tells the tool that there are multiple languages then they’ll automatically know about each other at compile time. And more importantly if you use an IDE such as IntelliJ (even the free version), the editor will understand the build config and know about the multiple languages and offer import advice and class/method completion.

Groovy calling to Java is something I use every day, Java to Groovy is possible too but you need to understand how Groovy works in the sense that there are many Groovy coding idioms that cannot be directly called from Java, but standard classes work perfectly.

Similar restrictions apply for Kotlin.

  • This is exactly what I do not want. I want to mix the files in one directory. I want interoperability between all types of files. I have this setup going just nice for Java/Groovy, and I can get it working somewhat with Kotlin, but then I cannot have "three ways" interop. Which I want. If I get an answer to my question, I can have it. (PS: I of course use a build tool, I prefer Gradle.) – stolsvik Dec 29 '18 at 15:17
  • 1
    how you did it for groovy/java? all done through groovyc - right? – daggett Sep 09 '20 at 18:36
  • @daggett Yes, "joint compilation" feature of groovyc. This is, AFAIU, that Groovy creates Java stub files for the Groovy files, then compiles Java using javac and with the stubs on the classpath, and then itself compiles the Groovy files, now with the compiled Java classes on the classpath. Or something like that. – stolsvik Oct 21 '20 at 06:44
  • 1
    @stolsvik that process is essentially correct. There is a limitation in that stubs are generated early on in the compilation process, so not all AST transformation results will be reflected in the stubs at present. In your scenario, you'd still want to hide Groovy classes with heavy AST/trait usage behind interfaces. – Paul King Oct 21 '20 at 07:52