livefront/sealed-enum

Duplicate labels in when and duplicate objects in `values` caused by sealed interface hierarchy with an object implementing multiple interfaces

Closed this issue · 0 comments

kyay10 commented

Minimum reproducer:

sealed interface MultiInterfaceFlag {
    sealed interface FirstInterface : MultiInterfaceFlag
    sealed interface SecondInterface : MultiInterfaceFlag
    object FirstFlag : FirstInterface
    object SecondFlag : SecondInterface
    object BothFlags : FirstInterface, SecondInterface

    @GenSealedEnum
    companion object
}

Generates:

public object MultiInterfaceFlagSealedEnum : SealedEnum<MultiInterfaceFlag> {
    public override val values: List<MultiInterfaceFlag> by lazy(mode =
            LazyThreadSafetyMode.PUBLICATION) {
        listOf(
            MultiInterfaceFlag.BothFlags,
            MultiInterfaceFlag.FirstFlag,
            MultiInterfaceFlag.BothFlags,
            MultiInterfaceFlag.SecondFlag
        )
    }


    public override fun ordinalOf(obj: MultiInterfaceFlag): Int = when (obj) {
        is MultiInterfaceFlag.BothFlags -> 0
        is MultiInterfaceFlag.FirstFlag -> 1
        is MultiInterfaceFlag.BothFlags -> 2
        is MultiInterfaceFlag.SecondFlag -> 3
    }

    public override fun nameOf(obj: MultiInterfaceFlag): String = when (obj) {
        is MultiInterfaceFlag.BothFlags -> "MultiInterfaceFlag_BothFlags"
        is MultiInterfaceFlag.FirstFlag -> "MultiInterfaceFlag_FirstFlag"
        is MultiInterfaceFlag.BothFlags -> "MultiInterfaceFlag_BothFlags"
        is MultiInterfaceFlag.SecondFlag -> "MultiInterfaceFlag_SecondFlag"
    }

    public override fun valueOf(name: String): MultiInterfaceFlag = when (name) {
        "MultiInterfaceFlag_BothFlags" -> MultiInterfaceFlag.BothFlags
        "MultiInterfaceFlag_FirstFlag" -> MultiInterfaceFlag.FirstFlag
        "MultiInterfaceFlag_BothFlags" -> MultiInterfaceFlag.BothFlags
        "MultiInterfaceFlag_SecondFlag" -> MultiInterfaceFlag.SecondFlag
        else -> throw IllegalArgumentException("""No sealed enum constant $name""")
    }
}

I'm not quite sure what the right way to fix this is. Should we simply remove any duplicate label in order? Should we special-case any multiple-inheritor of an interface? I'm just not sure what the right solution is that preserves the traversal order. I'm ready to roll a PR for this, I just need guidance as to what the right approach is