A Kotlin Symbol Processor to list sealed object instances.

Overview

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() {
    object Logs: Debug(true)
    object Traces: Debug()
    object StrictMode: Debug()
}
// UI.kt
sealed class UI(override val isEnabled: Boolean = false): FeatureFlag() {
    object Animations: UI()
    object Framerate: UI()
}

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

  • 🙅 Manually keep a list of objects somewhere, but this is cumbersome and error-prone.
  • 🤷 Use Kotlin reflection to browse the class declaration, with the following extension FeatureFlag::class.reflectSealedObjectInstances(), but this can become an expensive operation if you have a lot of objects and a deeply nested structure.
  • 🙆 Use Kotlin Symbol Processing (KSP) to create the list of objects at compile time.

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()

Setup

In the module's build script, apply the com.google.devtools.ksp plugin with the current Kotlin version and add this library to the list of dependencies.

plugins {
    id("com.google.devtools.ksp") version "1.7.10-1.0.6"
}

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

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

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:

  • Android project
    androidComponents.onVariants {
        kotlin.sourceSets.findByName(it.name)?.kotlin?.srcDirs(
            file("$buildDir/generated/ksp/${it.name}/kotlin")
        )
    }
  • Kotlin JVM project
    kotlin {
        sourceSets.main {
            kotlin.srcDir("build/generated/ksp/main/kotlin")
        }
        sourceSets.test {
            kotlin.srcDir("build/generated/ksp/test/kotlin")
        }
    }

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

  • Having multiple sealed classes/interfaces with the same name in the same package is currently not supported, and the KSP will fail.
  • KT-8970: Using the extension from a static context (e.g. companion object), will return null values. A simple solution is to delegate to a lazy initializer: val values by lazy(MySealedClass::class::sealedObjectInstances).
You might also like...
Kafka Streams Processor to unwrap CØSMOS blocks into CØSMOS transactions
Kafka Streams Processor to unwrap CØSMOS blocks into CØSMOS transactions

Kafka Processor CØSMOS-Block A Kafka Streams Processor to unwrap CØSMOS blocks into CØSMOS transactions. Purpose The Kafka Processor CØSMOS-Block is b

An annotation processor library that automatically creates Hilt's `@Binds` functions and modules.
An annotation processor library that automatically creates Hilt's `@Binds` functions and modules.

HiltBinder An annotation processor library that automatically creates Hilt's @Binds functions and modules. If you think this library is useful, please

Demonstration of Object Pool Design Pattern using Kotlin language and Coroutine
Demonstration of Object Pool Design Pattern using Kotlin language and Coroutine

Object Pool Design Pattern with Kotlin Demonstration of Thread Safe Object Pool Design Pattern using Kotlin language and Coroutine. Abstract The objec

To-Do-List - Create a To Do List-style App from scratch and drive the entire development process using Kotlin
To-Do-List - Create a To Do List-style App from scratch and drive the entire development process using Kotlin

To-Do-List! Crie um App no estilo "To Do List" do zero e conduza todo o processo

Mutator for Immutable Object

Mutator Why Mutator? As the immutable object becomes the default pattern of functional programming language, such as Value Object in Java, and Data Cl

Map-vs-list-comparator - The project compares the time needed to find a given element in a map vs the time needed to find a given element in a list.

Map vs List Comparator The project compares the time needed to find a given element in a map vs the time needed to find a given element in a list. To

Kotlin app that shows a list of characters using the api SWAPI
Kotlin app that shows a list of characters using the api SWAPI

StarWarsCharacters Kotlin app that shows a list of characters using the api SWAPI (https://swapi.dev) This is a clean architecture app example built w

To-do-List - Creating a Reminders and Tasks app with Kotlin
To-do-List - Creating a Reminders and Tasks app with Kotlin

To do List 📋 App de Lembretes e Tarefas com Kotlin Telas do App Tecnologias Kot

Simple Todo list API using Spring-Boot, Webflux, Kotlin, Coroutines, & PostgreSQL

Simple Todo list API using Spring-Boot, Webflux, Kotlin, Coroutines, & PostgreSQL

Comments
  • Bump com.gradle.enterprise from 3.12 to 3.12.1

    Bump com.gradle.enterprise from 3.12 to 3.12.1

    Bumps com.gradle.enterprise from 3.12 to 3.12.1.

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump com.gradle.enterprise from 3.11.4 to 3.12

    Bump com.gradle.enterprise from 3.11.4 to 3.12

    Bumps com.gradle.enterprise from 3.11.4 to 3.12.

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump com.gradle.enterprise from 3.11.3 to 3.11.4

    Bump com.gradle.enterprise from 3.11.3 to 3.11.4

    Bumps com.gradle.enterprise from 3.11.3 to 3.11.4.

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
  • Bump com.gradle.enterprise from 3.11.2 to 3.11.3

    Bump com.gradle.enterprise from 3.11.2 to 3.11.3

    Bumps com.gradle.enterprise from 3.11.2 to 3.11.3.

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    dependencies 
    opened by dependabot[bot] 0
Releases(1.5.0)
Owner
Simon Marquis
Android Engineer
Simon Marquis
Kotlin Symbol Processor library to create Mutable and Immutable variants of objects.

implier Kotlin Symbol Processor plugin to create Mutable and Immutable variants of objects. Examples @ImmutableImpl @MutableImpl public interface Samp

Vadim Yaroschuk 14 Nov 8, 2022
glide's ksp compiler ,use kotlin symbol processor

glide-ksp glide's ksp compiler ,use kotlin symbol processor requirements library version kotlin >= 1.6.10 ksp 1.6.10-1.0.2 usage add jitpack repositor

Mistletoe 24 Oct 17, 2022
Mocking for Kotlin/Native and Kotlin Multiplatform using the Kotlin Symbol Processing API (KSP)

Mockative Mocking for Kotlin/Native and Kotlin Multiplatform using the Kotlin Symbol Processing API (KSP). Installation Mockative uses KSP to generate

Mockative 121 Dec 26, 2022
Clean MVVM with eliminating the usage of context from view models by introducing hilt for DI and sealed classes for displaying Errors in views using shared flows (one time event), and Stateflow for data

Clean ViewModel with Sealed Classes Following are the purposes of this repo Showing how you can remove the need of context in ViewModels. I. By using

Kashif Mehmood 22 Oct 26, 2022
Simplify the processing of sealed class/interface

shiirudo Generates DSL to simplify processing branching by when expressions in sealed class/interface. Setup Refer to the KSP quickstart guide to make

KeitaTakahashi 2 Nov 1, 2022
Exploring Kotlin Symbol Processing - KSP. This is just an experiment.

KSP example Exploring Kotlin Symbol Processing - KSP. This is just an experiment. Project contains 2 modules Processing Example Processing module is t

Merab Tato Kutalia 12 Aug 23, 2022
Kotlin Symbol Processing (KSP) sample project

Kotlin Symbol Processing (KSP) Sample Project Sample annotation processor created with Kotlin Symbol Processing (KSP) API. The repository supplements

Pavlo Stavytskyi 33 Dec 23, 2022
BindsAdapter is an Android library to help you create and maintain Adapter class easier via ksp( Kotlin Symbol Processing).

BindsAdapter BindsAdapter is an Android library to help you create and maintain Adapter class easier via ksp( Kotlin Symbol Processing). Installation

Jintin 5 Jul 30, 2022
KSP annotation processor for Toothpick

toothpick-ksp KSP annotation processor for Toothpick. All credits go to olivierperez/ksp for the initial work on a KSP processor. Bear in mind this is

null 0 Oct 19, 2021
Event State Processor Generator plugin is compatible with IntelliJ and Android Studio.

Event State Processor Generator plugin is compatible with IntelliJ and Android Studio. It provides source code generation for the EventStateProcessor Library to increase code productivity in Flutter apps development.

Extreme Vietnam Public 2 Dec 7, 2021