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
33 stars 3 forks source link

Issue when overriding an Interface #67

Open FeernandoOFF opened 19 hours ago

FeernandoOFF commented 19 hours 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 17 hours 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 17 hours ago

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

FeernandoOFF commented 16 hours 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
    }
}