touchlab / SKIE

SKIE - Swift Kotlin Interface Enhancer
https://skie.touchlab.co/
Apache License 2.0
768 stars 8 forks source link

Sealed interface with cross-cutting interface generates too many enum constants #113

Open edenman opened 2 months ago

edenman commented 2 months ago

What is the problem?

The generated code is not what I would like it to be. Given this interface

sealed interface CrossSealedInterface {
  sealed interface WithFoo : CrossSealedInterface {
    val foo: String
  }

  sealed interface WithBar : CrossSealedInterface {
    val bar: String
  }

  sealed class A : CrossSealedInterface {
    data class AFoo(override val foo: String) : A(), WithFoo
    data class ABar(override val bar: String) : A(), WithBar
    data class AFooBar(override val foo: String, override val bar: String) : A(), WithFoo, WithBar
  }

  sealed class B : CrossSealedInterface {
    data class BFoo(override val foo: String) : B(), WithFoo
    data class BBar(override val bar: String) : B(), WithBar
    data class BFooBar(override val foo: String, override val bar: String) : B(), WithFoo, WithBar
  }
}

SKIE generates the following enum:

extension MyKMPLib.Skie.Shared.CrossSealedInterface {
    @frozen
    public enum __Sealed {
        case a(MyKMPLib.CrossSealedInterfaceA)
        case b(MyKMPLib.CrossSealedInterfaceB)
        case withBar(MyKMPLib.CrossSealedInterfaceWithBar)
        case withFoo(MyKMPLib.CrossSealedInterfaceWithFoo)
    }
}

I can't tell if this is expected behavior, but it would be nice if SKIE could generate an enum that only includes the top level subtypes (A and B) and leave out the subtypes that are already covered. Maybe too hard of a problem for the compiler since you'd have to try all the combinations to find the minimal set? If so, it'd be nice to have the ability to customize this enum.

What versions of SKIE, Kotlin, and Gradle do you use?

skie 0.8.2, kotlin 1.9.23, gradle 8.5

What is your SKIE Gradle configuration?

skie {
  build {
    produceDistributableFramework()
  }
}

Repro project

https://github.com/edenman/kmpPlayground/pull/2

(the content of the skie {} block in your build.gradle file)