I am trying to create a dynamic service based on the data class model defined by user and they registerDataModels() method appDataModule() it should automatically create all based method in the router service. When I try to achive using generics in those method I am getting a compiler error. Is there any other better way to dynamically create route methods like by defining the datamodel by developer and then service should be automatically created?
org.jetbrains.kotlin.backend.common.BackendException: Backend Internal error: Exception during IR lowering
File being compiled: */api/AppConfigService.kt
The root cause java.lang.RuntimeException was thrown at: org.jetbrains.kotlin.backend.jvm.codegen.FunctionCodegen.generate(FunctionCodegen.kt:47)
File is unknown
The root cause java.lang.AssertionError was thrown at: org.jetbrains.kotlin.codegen.coroutines.CoroutineTransformerMethodVisitor.spillVariables(CoroutineTransformerMethodVisitor.kt:636)
fun Application.registerDataModels() {
appDataModule<M1>()
appDataModule<M2>()
appDataModule<M3>()
}
inline fun <reified T: DBModel> Application.appDataModule() {
routing {
createAppData<T>()
updateAppData<T>()
deleteAppData<T>()
}
}
inline fun <reified T: DBModel> Route.createAppData() {
put("/api/data/${getName<T>()}/create") {
authenticated {
create<T>{}
}
}
}
inline fun <reified T: DBModel> Route.updateAppData() {
put("/api/data/${getName<T>()}/update") {
authenticated {
update<T>{}
}
}
}
inline fun <reified T: DBModel> Route.deleteAppData() {
put("/api/data/${getName<T>()}/delete") {
authenticated {
delete<T>{}
}
}
}
CodePudding user response:
You are using inline
functions with reified
.
To make a long story short, inline
functions are compiled and 'copied' to the location where they are being used, already with a fixed (thats what reified does) class. So when you use an inline function
inline fun <reified T> foo(t: T): T { ... }
and you call it like this:
val myVal = foo("test").uppercase()
then at compile time of that calling line of code, the type of T is known to be String and the target line is compiled accordingly, so you know at runtime which type T is within your function. It is (for this one calling line) as if that function was like this to begin with:
fun foo(t: String): String { ... }
Because you want to compile these classes dynamically, however, this process fails, because the class obviously does not exist yet. This is simply due to the nature of reified
. If you can somehow remove it, it might work.
I agree that the error message of the compiler could be more telling here. Maybe you can raise a task on kotlin's issue tracking platform?: https://youtrack.jetbrains.com/issues/kt?_gl=1*5r6x4d*_ga*MTQyMDYxMjc2MS4xNjMzMzQwMzk5*_ga_9J976DJZ68*MTY2OTM1NjM1MS4yMS4xLjE2NjkzNTYzNTcuMC4wLjA.&_ga=2.265829455.1332696793.1669356352-1420612761.1633340399