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

Generate bit flags #766

Merged
merged 107 commits into from
Aug 26, 2023
Merged

Generate bit flags #766

merged 107 commits into from
Aug 26, 2023

Conversation

DRSchlaubi
Copy link
Member

@DRSchlaubi DRSchlaubi commented Feb 18, 2023

This PR adds bit flag classes to the code generation in Kord (see #686 for the reasoning of generating boilerplate heavy parts of Kord).

It also tries to unify the API shape of all existing bit flag classes by deprecating some existing declarations and replacing them with declarations that all bit flag classes have in common. They now have this general API shape:

sealed class SomeFlag(val shift: Int) {
    val value: ValueType
    operator fun plus(flag: SomeFlag): SomeFlags
    operator fun plus(flags: SomeFlags): SomeFlags

    class Unknown : SomeFlag
    object Flag1 : SomeFlag
    object Flag2 : SomeFlag
    // ...

    companion object {
        val entries: List<SomeFlag>
        fun fromShift(shift: Int): SomeFlag
    }
}

@Serializable
class SomeFlags(val value: ValueType) {
    val values: Set<SomeFlag>
    operator fun contains(flag: SomeFlag): Boolean
    operator fun contains(flags: SomeFlags): Boolean
    operator fun plus(flag: SomeFlag): SomeFlags
    operator fun plus(flags: SomeFlags): SomeFlags
    operator fun minus(flag: SomeFlag): SomeFlags
    operator fun minus(flags: SomeFlags): SomeFlags
    fun copy(builder: Builder.() -> Unit): SomeFlags

    class Builder(value: ValueType = /* ... */) {
        operator fun SomeFlag.unaryPlus()
        operator fun SomeFlags.unaryPlus()
        operator fun SomeFlag.unaryMinus()
        operator fun SomeFlags.unaryMinus()
        fun build(): SomeFlags
    }
}

fun SomeFlags(builder: SomeFlags.Builder.() -> Unit): SomeFlags
fun SomeFlags(vararg flags: SomeFlag): SomeFlags
fun SomeFlags(vararg flags: SomeFlags): SomeFlags
fun SomeFlags(flags: Iterable<SomeFlag>): SomeFlags
fun SomeFlags(flags: Iterable<SomeFlags>): SomeFlags

This means that flag classes are no longer enum classes. Binary compatibility was preserved as far as possible, but the fact that these classes now no longer have java.lang.Enum as their supertype is a binary incompatible change.

This PR also

  • adds ActivityFlag.PartyPrivacyFriends, ActivityFlag.PartyPrivacyVoiceChannel and ActivityFlag.Embedded (these were missing before)
  • deprecates UserFlag.System (it was undocumented in 2021)
  • renames Intent.GuildBans to Intent.GuildModeration (see here)
  • fixes a bug where .copy{ /* ... */ } would also modify the original instance for bit flags based on DiscordBitSet
  • fixes some minus functions that would toggle instead of remove bits (this.value xor other.value -> this.value and other.value.inv())

Place the companion object last to preserve the order as before and
remove the duplicated comment at the top of the files.
Placed extensions under the right sections, renamed them to match the
original KotlinPoet names and added all available parameters from the
original functions.
Copy link
Member

@lukellmann lukellmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i somehow feel like it isn't a good idea to use the same annotation for generation kord enums and flags, although they are really similar, what do you think about this?

common/api/common.api Outdated Show resolved Hide resolved
ksp-processors/src/main/kotlin/KotlinPoetDsl.kt Outdated Show resolved Hide resolved
ksp-processors/build.gradle.kts Outdated Show resolved Hide resolved
ksp-processors/build.gradle.kts Outdated Show resolved Hide resolved
@lukellmann lukellmann marked this pull request as draft February 19, 2023 02:41
@lukellmann
Copy link
Member

marked this as a draft for now because i think there is still some significant work needed (e.g. convert all existing flags to be generated while mostly preserving binary compatibility)

@DRSchlaubi
Copy link
Member Author

i somehow feel like it isn't a good idea to use the same annotation for generation kord enums and flags, although they are really similar, what do you think about this?

I thought about this for a while and came to the conclusion that you would have essentially the same annotation twice

@lukellmann lukellmann force-pushed the feature/flag-generators branch from 4e35983 to f6bbd68 Compare August 21, 2023 18:50
@lukellmann lukellmann force-pushed the feature/flag-generators branch from c15894c to 916ce0c Compare August 21, 2023 19:03
@lukellmann lukellmann force-pushed the feature/flag-generators branch 2 times, most recently from 5cca08f to ef70748 Compare August 21, 2023 20:59
@lukellmann lukellmann force-pushed the feature/flag-generators branch from ef70748 to e1e75c4 Compare August 21, 2023 21:21
lukellmann added a commit that referenced this pull request Aug 23, 2023
@lukellmann lukellmann changed the title Improve code generation Generate bit flags Aug 24, 2023
@lukellmann lukellmann marked this pull request as ready for review August 24, 2023 22:36
Copy link
Member

@lukellmann lukellmann left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i think this is ready now, can you take another look @DRSchlaubi?

@lukellmann lukellmann merged commit fc1d70f into main Aug 26, 2023
@lukellmann lukellmann deleted the feature/flag-generators branch August 26, 2023 16:30
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

Successfully merging this pull request may close these issues.

2 participants