kotlinkotlin-reflect

Kotlin - return all properties that implement an interface and are annotated


I have a simple kotlin 1.7.10 program - I have an interface called Rule and property annotation called NextRule + 2 implementations like

import kotlin.reflect.KClass

interface Rule {
    fun process(s: String): String
}

@Target(AnnotationTarget.PROPERTY)
@Retention(AnnotationRetention.SOURCE)
@MustBeDocumented
annotation class NextRule


class EndRule() : Rule {

    override fun process(s: String) = "$s END"
}

class StartRule(
    @NextRule
    private val endRule: EndRule
) : Rule {
    override fun process(s: String): String = "$s START"
}

I want to create a function that would take an object that implements Rule interface and return for each field that also implements a Rule and is annotated with NextRule its KClass - basically a function like Rule -> Seq<KClass<out Rule>> - something like

fun getAllNextRuleAnnotatedClasses(rule: Rule): List<KClass<out Rule>> {
    for(property in rule::class.properties){
        if(property.returnType.class implements Rule && property isAnnotatedWith NextRule){
            yield property::class
        }
    }
}

How to achieve that ?


Solution

  • You can try this :

    fun getAllNextRuleAnnotatedClasses(rule: Rule): List<KClass<out Rule>> {
        return rule::class.memberProperties
            .filter { it.returnType.classifier == Rule::class }
            .filter { it.findAnnotation<NextRule>() != null }
            .map { it.returnType.classifier as KClass<out Rule> }
    }