Home

Awesome

Sealed Object Instances Status

A Kotlin Symbol Processor to list sealed object instances.

Usage

Let's say you have a similar structure of sealed classes (or interfaces):

// FeatureFlag.kt
sealed class FeatureFlag {
    abstract val isEnabled: Boolean
}
// Debug.kt
sealed class Debug(override val isEnabled: Boolean = false) : FeatureFlag() {
    data object Logs : Debug(true)
    data object Traces : Debug()
    data object StrictMode : Debug()
}
// UI.kt
sealed class UI(override val isEnabled: Boolean = false) : FeatureFlag() {
    data object Animations : UI()
    data object Framerate : UI()
}

And you want to automatically list all FeatureFlags, then you have at least 3 options:

This is exactly what this project does. You simply need to add the SealedObjectInstances annotation on the sealed class:

@SealedObjectInstances
sealed class FeatureFlag { /*...*/ }

And then you'll have access to the sealedObjectInstances() extension on the corresponding type:

val flags: Set<FeatureFlag> = FeatureFlag::class.sealedObjectInstances()

[!NOTE]
You can annotate the companion object to access a simpler extension function (no more ::class prefix).

sealed class FeatureFlag {
    @SealedObjectInstances companion object;
    /*...*/
}

val flags: Set<FeatureFlag> = FeatureFlag.sealedObjectInstances()

Setup

In the module's build script, apply the com.google.devtools.ksp plugin with the matching Kotlin version: Maven Central

plugins {
    id("com.google.devtools.ksp") version "<version>"
}

Then add the library dependencies: Maven Central Sonatype Nexus (Snapshots)

dependencies {
    implementation("fr.smarquis.sealed:sealed-object-instances:<latest-version>")
    ksp("fr.smarquis.sealed:sealed-object-instances:<latest-version>")
}
<details><summary>🐙 GitHub Packages</summary>

GitHub release (latest SemVer)

[!NOTE]
You'll need to create a personal access token (PAT) with the read:packages permission to be able to download from this repository. https://docs.github.com/en/packages/learn-github-packages

repositories {
    maven {
        url = uri("https://maven.pkg.github.com/SimonMarquis/SealedObjectInstances")
        credentials {
            username = System.getenv("GITHUB_USERNAME")
            password = System.getenv("GITHUB_PACKAGES_READ_TOKEN")
        }
    }
}

dependencies {
    implementation("fr.smarquis.sealed:sealed-object-instances:<latest-version>")
    ksp("fr.smarquis.sealed:sealed-object-instances:<latest-version>")
}
</details> <details><summary>🚀 JitPack.io</summary>

JitPack.io

repositories {
    maven {
        url = uri("https://jitpack.io")
    }
}

dependencies {
    implementation("com.github.SimonMarquis:SealedObjectInstances:<latest-version>")
    ksp("com.github.SimonMarquis:SealedObjectInstances:<latest-version>")
}
</details>

Make IDE aware of generated code

By default, IntelliJ IDEA or other IDEs don't know about the generated code. So it will mark references to generated symbols unresolvable. To make an IDE be able to reason about the generated symbols, mark the following paths as generated source roots:

Configuration

SealedObjectInstances annotation can be configured to produce different outputs, and is also repeatable:

@SealedObjectInstances
@SealedObjectInstances(name = "values", rawType = Array)
sealed class FeatureFlag { /*...*/ }

This code will produce these two extensions:

// The default extension
fun KClass<FeatureFlag>.sealedObjectInstances(): Set<FeatureFlag>
// The custom extension with different name and raw type
fun KClass<FeatureFlag>.values(): Array<FeatureFlag>

Known issues