Home > Net >  When I use the generic method in Route then I am getting compiler Backend Internal error: Exception
When I use the generic method in Route then I am getting compiler Backend Internal error: Exception

Time:11-28

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

  • Related