Kotlin / kotlin-jupyter

Kotlin kernel for Jupyter/IPython
Apache License 2.0
1.09k stars 106 forks source link

Can not use object expresssions #341

Closed holgerbrandl closed 2 years ago

holgerbrandl commented 2 years ago

Consider the following example


val sim = object : ArrayList<String>() {
}

When using sim in a second code-cell this fails with:

Enclosing constructor not found
java.lang.InternalError: Enclosing constructor not found
    at java.base/java.lang.Class.getEnclosingConstructor(Class.java:1447)
    at kotlin.reflect.jvm.internal.impl.descriptors.runtime.structure.ReflectClassUtilKt.getClassId(reflectClassUtil.kt:62)
    at kotlin.reflect.jvm.internal.RuntimeTypeMapper.mapJvmClassToKotlinClassId(RuntimeTypeMapper.kt:272)
    at kotlin.reflect.jvm.internal.KClassImpl.getClassId(KClassImpl.kt:186)
    at kotlin.reflect.jvm.internal.KClassImpl.access$getClassId(KClassImpl.kt:44)
    at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:49)
    at kotlin.reflect.jvm.internal.KClassImpl$Data$descriptor$2.invoke(KClassImpl.kt:48)
    at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
    at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
    at kotlin.reflect.jvm.internal.KClassImpl$Data.getDescriptor(KClassImpl.kt:48)
    at kotlin.reflect.jvm.internal.KClassImpl$Data$supertypes$2.invoke(KClassImpl.kt:125)
    at kotlin.reflect.jvm.internal.KClassImpl$Data$supertypes$2.invoke(KClassImpl.kt:124)
    at kotlin.reflect.jvm.internal.ReflectProperties$LazySoftVal.invoke(ReflectProperties.java:93)
    at kotlin.reflect.jvm.internal.ReflectProperties$Val.getValue(ReflectProperties.java:32)
    at kotlin.reflect.jvm.internal.KClassImpl$Data.getSupertypes(KClassImpl.kt:124)
    at kotlin.reflect.jvm.internal.KClassImpl.getSupertypes(KClassImpl.kt:254)
    at kotlin.reflect.full.KClasses.getSuperclasses(KClasses.kt:184)
    at kotlin.reflect.full.KClasses$isSubclassOf$1.get(KClasses.kt:233)
    at kotlin.jvm.internal.PropertyReference1.invoke(PropertyReference1.java:35)
    at kotlin.reflect.full.KClasses$sam$org_jetbrains_kotlin_utils_DFS_Neighbors$0.getNeighbors(KClasses.kt)
    at kotlin.reflect.jvm.internal.impl.utils.DFS.doDfs(DFS.java:98)
    at kotlin.reflect.jvm.internal.impl.utils.DFS.dfs(DFS.java:27)
    at kotlin.reflect.jvm.internal.impl.utils.DFS.dfs(DFS.java:37)
    at kotlin.reflect.jvm.internal.impl.utils.DFS.ifAny(DFS.java:47)
    at kotlin.reflect.full.KClasses.isSubclassOf(KClasses.kt:233)
    at org.jetbrains.kotlinx.jupyter.util.ReflectonKt.isSubclassOfCatching(reflecton.kt:9)
    at org.jetbrains.kotlinx.jupyter.api.SubtypeRendererTypeHandler.acceptsType(renderersHandling.kt:138)
    at org.jetbrains.kotlinx.jupyter.api.RendererTypeHandler$DefaultImpls.accepts(renderersHandling.kt:62)
    at org.jetbrains.kotlinx.jupyter.api.PrecompiledRendererTypeHandler$DefaultImpls.accepts(renderersHandling.kt)
    at org.jetbrains.kotlinx.jupyter.api.SubtypeRendererTypeHandler.accepts(renderersHandling.kt:117)
    at org.jetbrains.kotlinx.jupyter.codegen.RenderersProcessorImpl.renderResult(RenderersProcessorImpl.kt:20)
    at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1$rendered$1$1.invoke(repl.kt:432)
    at org.jetbrains.kotlinx.jupyter.config.LoggingKt.catchAll(logging.kt:41)
    at org.jetbrains.kotlinx.jupyter.config.LoggingKt.catchAll$default(logging.kt:40)
    at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:431)
    at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl$evalEx$1.invoke(repl.kt:408)
    at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.withEvalContext(repl.kt:372)
    at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.evalEx(repl.kt:408)
    at org.jetbrains.kotlinx.jupyter.ReplForJupyterImpl.eval(repl.kt:456)
    at org.jetbrains.kotlinx.jupyter.ProtocolKt$shellMessagesHandler$res$1.invoke(protocol.kt:290)
    at org.jetbrains.kotlinx.jupyter.ProtocolKt$shellMessagesHandler$res$1.invoke(protocol.kt:289)
    at org.jetbrains.kotlinx.jupyter.JupyterConnection$runExecution$execThread$1.invoke(connection.kt:166)
    at org.jetbrains.kotlinx.jupyter.JupyterConnection$runExecution$execThread$1.invoke(connection.kt:164)
    at kotlin.concurrent.ThreadsKt$thread$thread$1.run(Thread.kt:30)

image

Since object expressions are a very useful tool when prototyping (i.e. working with notebooks), it would be most wonderful if this language feature could be fixed/enabled for the kernel.

Used kernel version: Kotlin kernel v. 0.10.3.20, Kotlin v. 1.6.20-dev-3702

altavir commented 2 years ago

Reproduced: https://datalore.jetbrains.com/notebook/ptQDfQAcrjNxzIO0AEqovZ/tIacK6wZqJGl8123ilQJyz/

ileasile commented 2 years ago

@holgerbrandl thanks for reporting! It seems to be one more problem of scripts code generation, but can be easily workarounded on kernel side. I'll try to provide a better solution on scripting side later.

ileasile commented 2 years ago

The downside of this workaround is that if you have defined a renderer for type A, and defined anonymous object object : A() {}, it will not be rendered with A's renderer.

ileasile commented 2 years ago

@holgerbrandl @altavir try updating to 0.10.3.31

altavir commented 2 years ago

Works in DataLore on 0.10.3.31.

ileasile commented 2 years ago

Just to remember: reproducer in Kotlin JvmReplTest:

fun testAnonymousObjectReflection() {
    JvmTestRepl()
        .use { repl ->
            assertEvalResult(repl, "42", 42)
            assertEvalUnit(repl, "val sim = object : ArrayList<String>() {}")

            val compiledSnippet = checkCompile(repl, "sim")
            val evalResult = repl.eval(compiledSnippet!!)

            val a = (evalResult.valueOrThrow().get().result as ResultValue.Value).value!!
            assertTrue(a::class.isSubclassOf(Any::class))
        }
}
holgerbrandl commented 2 years ago

Works like charm now. Thank you so much for your great and blazingly fast support.