Acquire annotation parameters (or annotation instance) from Kotlin PSI

305 views Asked by At

I have a Kotlin annotation:

@Retention(AnnotationRetention.SOURCE)
@Target(AnnotationTarget.CLASS)
annotation class Type(
    val type: String
)

It can be used on the Kotlin classes in two ways: using the named parameter syntax, or using the positional parameter syntax:

@Type(type = "named")
data class Named(
    …
)

@Type("positional")
data class Positional
    …
)

I use this annotation in my custom detekt rules for some extra checks. I need to extract the value of the type parameter to perform some check based on it. I do that like:

private fun getType(klass: KtClass): String? {
    val annotation = klass
        .annotationEntries
        .find {
            "Type" == it?.shortName?.asString()
        }
    val type = (annotation
        ?.valueArguments
        ?.find {
            it.getArgumentName()?.asName?.asString() == "type"
        }
        ?.getArgumentExpression() as? KtStringTemplateExpression)
        ?.takeUnless { it.hasInterpolation() }
        ?.plainContent

    return type
}

But this code works only with "named" parameters syntax, and fails for the positional one. Is there any way to get the value of an annotation parameter no matter what syntax was used? It would be perfect if I could acquire my Type annotation instance directly from PSI / AST / KtElements and use it like usually. Is it possible to instantiate an annotation from the PSI tree?

0

There are 0 answers