Loading Top-Level Method From Parent Classloader

I’ve run into a strange situation when compiling Kotlin code and I’m hoping someone here understands what’s going on.

We have a small library for doing fully in-memory Kotlin compilation, similar but somewhat different from the approach used by the Kotlin playground backend.

When compiled together in one pass, the following code works:

// Test.kt
fun blah() = "blah"
// Main.kt
fun main() {
  blah()
}

The top-level method blah declared in Test.kt is correctly loaded by Main.kt without requiring an import. So far so good.

However, when compiled separately the code above fails. Specifically, our workflow is:

  1. Compile Test.kt which produces a ClassLoader and JavaFileManager containing TestKt.class.
  2. Compile Main.kt, setting the parent ClassLoader to the one produced by compiling Test.kt and using the JavaFileManager created by compiling Test.kt to establish a content root before initiating the second compilation.

Invariably this results in a “Unresolved reference: blah” compiler error.

I’ve tried a variety of different ways to import blah with no success, although it’s not clear why the import would be required in the second case. I’ve also tried moving the files into separate packages, which also doesn’t work.

It’s quite possible that we’re setting up the compilation incorrectly here. But I guess my first question is: Is this expected to work? I would assume it would have to, since otherwise I don’t know you’d use top-level methods provided by other packages.

OK, NM, answering my own question: we were not correctly saving the META-INF/main.kotlin_module file during compilation. Fixing that seems to work.