Hey, I want to make a kotlin compiler plugin (KCP)...
# compiler
r
Hey, I want to make a kotlin compiler plugin (KCP), to auto generate the function wrapper the suspend function(through runBlocking function) that can be called in java, How do I insert a new function? I already created a kcp plugin but when I test it, it thorw an exception
Copy code
Caused by: java.lang.AssertionError: FUN name:testJvmBlocking visibility:public modality:FINAL <> () returnType:kotlin.Unit has no continuation; can't call FUN name:test visibility:public modality:FINAL <> ($this:test.Main) returnType:kotlin.Unit [suspend]
My code is here(just the insert function part):
Copy code
val generatedFunction = pluginContext.irFactory.buildFun {
                name = Name.identifier(newFunctionName)
                isSuspend = false
                visibility = func.visibility
                returnType = func.returnType
                modality = func.modality
                startOffset = func.startOffset
                endOffset = func.endOffset
            }.apply {
                parent = declaration
                func.valueParameters.forEach { param -> valueParameters += param.copyTo(this) }
                body = pluginContext.irBuilder(symbol).irBlockBody {
                    val suspendCall = pluginContext.irBuilder(func.symbol).run {
                        irCall(func).apply {
                            if (func.valueParameters.isNotEmpty()) {
                                func.valueParameters.forEachIndexed { index, param ->
                                    putValueArgument(index, irGet(valueParameters[index]))
                                }
                            }
                        }
                    }
                    val runBlockingCall = pluginContext.irBuilder(func.symbol).run {
                        irCall(runBlockingFun).apply {
                            putTypeArgument(0, func.returnType)
                            putValueArgument(0, suspendCall)
                        }
                    }
                    +irReturn(runBlockingCall)
                }
            }
            declaration.declarations += generatedFunction
p
What you've generated, is equivalent of
runBlocking(foo())
, while you probably wanted to generate
runBlocking { foo() }
.
r
runBlocking { foo() }
I'm beginner on kcp lol
p
I can suggest you to write code you want to write manually, see what compiler generate from it, and produce same IR.
h
Unrelated to the compiler code, but are you sure that you want to generate code that uses runBlocking under the hood at all? You should use runBlocking rarely and explicitly.
3
j
I think @simon.vergauwen already created this
s
I was investigating this in the past for a work project, and I agree with Philip above that you should not use
runBlocking
for this. There exists a library for this though, https://github.com/ForteScarlet/kotlin-suspend-transform-compiler-plugin and it supports
CompletableFuture
alongside
runBlocking
and even has support for
JsPromise
.