Expanding KSP and annotation capabilities

KSP is a great tool but is not very useful if I can’t collect the required meta-data. Annotations are very limited with respect to supported field types. My proposal is to expand this with some compiler help, and we don’t even need to break the current compatibility.

My proposal is to have a different set of annotations that validates and captures more meta-data for the KSP processor; and also an extension to the reflection API to get such meta-data.

For instance the following KSP annotation marked with “annotation ksp” or anything else:

/* not possible
   @Target(AnnotationTarget.FIELD)
   annotation ksp Discard<T>(vararg val fields: KProperty1<T, *>, onlyIf: ((T) -> Boolean)?)
*/

// when using "annotation ksp" - annotation expands into
@Target(AnnotationTarget.FIELD)
annotation class Discard(val spec: KClass<out IDiscard<*>>)

// T will be the captured field type
interface IDiscard<T> {
    val fields: List<KProperty1<T, *>>
    val onlyIf: ((T) -> Boolean)?
}

it can now be used like this:

class User(
    val name: String,
    val email: String,
    val password: String
)

class UserView(
    /* not possible
       @Discard(User::password, {it.name != "ADMIN"})
       val user: User
    */
    
    // expands into
    @Discard(UserView_discard_user_1::class)
    val user: User
)

// helper object class with captured field type
object UserView_discard_user_1: IDiscard<User> {
    override val fields = listOf(User::password)
    override val onlyIf = { it: User -> it.name != "ADMIN" }
}

Besides having more meta-data, can also do some compile time checks:

class Other(val name: String)

class OtherView (
    //@Discard(Other::name)
    @Discard(OtherView_discard_other_1::class)
    val other: User
)

// helper object class with captured field type
object OtherView_discard_other_1: IDiscard<User> {
    override val fields = listOf(Other::name) // ERROR - ...not a subtype of...
    override val onlyIf = null
}

I believe this would not be much of an effort for an experimental feature.