Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Migrate compiler plugin to KSP #57

Closed
rickclephas opened this issue Mar 29, 2022 · 6 comments
Closed

Migrate compiler plugin to KSP #57

rickclephas opened this issue Mar 29, 2022 · 6 comments
Milestone

Comments

@rickclephas
Copy link
Owner

rickclephas commented Mar 29, 2022

When the current compiler plugin was created KSP didn't support Kotlin/Native and a custom compiler plugin would allow us to modify classes instead of creating extension functions (which seemed a great idea at the time).
However the current compiler plugin has some issues:

Using KSP would solve all these issues. The only downside being that we can no longer modify the classes and would need to generate extension properties/functions, which might not be exposed to ObjC/Swift in the same way.

@ankushg
Copy link
Contributor

ankushg commented Mar 29, 2022

Instead of generating extension properties/functions (which IIRC aren't handled well in JS), it might also be possible to generate an entirely new class that wraps that just wraps the JVM class:

// original class
class MyClass {
    suspend fun myFun(): String { … }
}

// NativeCoroutines-generated
class MyClassNative(private val delegate: MyClass) {
   suspend fun myFun = delegate.myFun()

    fun myFunNative() = 
        nativeSuspend { delegate.myFun() }
}

Consumers would have to manually convert MyClass to MyClassNative, but they'd be able to avoid relying on extension functions.

@rickclephas
Copy link
Owner Author

Hmm alright didn't know about any limitations with extensions in JS.

I am actually not a big fan of such wrapper classes. Mainly because:

  • all properties and functions have to be wrapped (not just the coroutines once)
  • using this from Swift/ObjC/JS wouldn't be "straightforward"

I guess it would probably need some more code to get a single wrapper object as well, else you'll be creating a lot of wrapper objects in the client code.

How exactly are extension functions handled in JS?
In Swift they are actually exposed as extension functions on classes, the "problem" there is with interfaces (and inline classes).

@ankushg
Copy link
Contributor

ankushg commented Mar 29, 2022

In Kotlin/JS, you need to annotate everything with @JsExport in order for it to be visible from regular JS code.

@JsExport's documentation says that it doesn't support extension properties 😔

@ankushg
Copy link
Contributor

ankushg commented Mar 30, 2022

On further inspection -- it looks like you can @JsExport an extension function, just not extension properties

The way this gets exposed though is by converting the receiver to a parameter. This can cause naming collisions:

class MyClass {
    suspend fun myFun(): String { … }
}

@JsExport
fun MyClass.myFunNative() = nativeSuspend { this.myFun() }
// will generate a method that can be called in JS using `myFunNative(myClassInstance)`

class MyOtherClass {
    suspend fun myFun(): String { … }
}

@JsExport
fun MyOtherClass.myFunNative() = nativeSuspend { this.myFun() }
// will generate conflicting method that can be called in JS using `myFunNative(myOtherClassInstance)`

This likely means that we need to use @JsName to avoid naming collisions, and still doesn't have the same convenient syntax of extension functions in Swift, but is still better than wrapping I suppose

@litclimbing
Copy link
Contributor

This would be fantastic. I've been really enjoying this plugin but chasing down all the recursive crashes when I switch from Android to iOS builds are really frustrating. Let me know if there is anything I can do to help push this along.

@rickclephas rickclephas added this to the v1.0 milestone Apr 3, 2022
@rickclephas
Copy link
Owner Author

If the compiler plugin is migrated to KSP we won't be able to modify any of the source code, making #63 impossible.
Perhaps a better solution would be to generate the native extensions in the customer compiler (just like KSP would).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants