Get enclosing class from extension function not working from 2.0.0

Hi!

While upgrading Kotlin I noticed a difference in behaviour on ‘javaClass.enclosingClass’. This no longer seems to work from an extension. See the test below, it fails from version 2.0.0:

class EnclosingClassTest {

    @Test
    fun test() {
        val enclosingClass = someExtension {}

        // works in 1.9.25, but not in 2.0.0 or newer
        assertEquals(EnclosingClassTest::class.java, enclosingClass)
    }
}

fun <T> someExtension(call: () -> T): Class<*>? {
    return call.javaClass.enclosingClass
}

Was this intended?

Regards,
Pepijn

My guess would be there were never guarantees that it behaves as you expected. I don’t think Kotlin specifies where exactly is the lambda located in the resulting bytecode.

This is probably because lamdas are no longer compiled to nested classes. See What's new in Kotlin 2.0.0 | Kotlin Documentation

1 Like

Thanks for pointing that out, you’re right! To get the old behaviour you can annotate the lambda with @JvmSerializableLambda:

class EnclosingClassTest {

    @Test
    fun test() {
        val enclosingClass = someExtension @JvmSerializableLambda {}

        assertEquals(EnclosingClassTest::class.java, enclosingClass)
    }
}

fun <T> someExtension(call: () -> T): Class<*>? {
    return call.javaClass.enclosingClass
}
1 Like