ForteScarlet / kotlin-suspend-transform-compiler-plugin

A Kotlin compiler plugin for transforming suspend functions to platform-compatible non-suspend functions, such as the JVM Blocking API and CompletableFuture or JS Promise, etc. 🐱
MIT License
36 stars 3 forks source link

Issue when overriding an Interface #67

Closed FeernandoOFF closed 1 month ago

FeernandoOFF commented 1 month ago

Hello,First I'd like to thank your project it has been a life saver and the last piece that I needed to start my Kotlin-JS interop project so, thanks!

I'm experiencing an issue where I have an Interface that has a suspend function in it and an Implementation but it seems that the override goes to the exported JS, so Given the following code the compiler will throw the next exception:

'getDataAsync' overrides nothing.

Interface:

interface FooInterface {
    suspend fun getData(): String
}

Implementation:

@JsExport
class Foo(
    private val httpClient: HttpClient = HttpModule().client
): FooInterface  {
    @JsExport.Ignore
    @JsPromise
    override suspend fun getData(): String {
        val response = httpClient.get(CivRoutes()).bodyAsText()
        return response
    }
}

Is there a way that the generated JS just ignores the override?

ForteScarlet commented 1 month ago

Hello! I'm glad this plugin helped you! 😊

Currently it looks like the override of the synthesized function will come directly from the source function causing this problem. The fastest temporary solution is to add the appropriate annotations directly to the interface's pending functions as well:

interface FooInterface {
    @JsPromise
    suspend fun getData(): String
}

I'll try to fix this in a later release, like making the synthesized function also look to the parents to see if an inheritable function exists, or... Maybe just marking open will fix it?

FeernandoOFF commented 1 month ago

Hey @ForteScarlet Thank you so much for your workaround! thank should do it!

FeernandoOFF commented 1 month ago

~~Update: It didn't 😆 ~~ It did work but I need to have the following format, leaving it in case somebody else finds it useful

@JsExport
interface FooInterface {
    @JsPromise
    @JsExport.Ignore
    suspend fun getData():String
}

@JsExport
class Foo(
    private val httpClient: HttpClient = HttpModule().client
): FooInterface {

    @JsExport.Ignore
    @JsPromise
    override suspend fun getData(): String {
        val response: String = httpClient.get(CivRoutes.Map()).bodyAsText()
        return response
    }
}
FeernandoOFF commented 1 month ago

Thanks! <3

ForteScarlet commented 1 month ago

👌 It will be released in the next *-0.9.3 release. Maybe it will be 2.1.0-0.9.3? if kt's 2.1.0 is coming soon XD