All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commonMain.co.touchlab.skie.kir.util.FindAnnotationExtension.kt Maven / Gradle / Ivy

The newest version!
package co.touchlab.skie.kir.util

import org.jetbrains.kotlin.descriptors.annotations.Annotated
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.annotations.argumentValue
import org.jetbrains.kotlin.resolve.constants.AnnotationValue
import org.jetbrains.kotlin.resolve.constants.ArrayValue
import org.jetbrains.kotlin.resolve.constants.ConstantValue
import org.jetbrains.kotlin.resolve.constants.EnumValue
import org.jetbrains.kotlin.resolve.constants.KClassValue
import kotlin.reflect.KClass
import kotlin.reflect.KParameter

inline fun  Annotated.hasAnnotation(): Boolean =
    hasAnnotation(T::class)

fun  Annotated.hasAnnotation(annotation: KClass): Boolean =
    this.annotations.any { it.fqName?.asString() == annotation.qualifiedName }

inline fun  Annotated.findAnnotation(): T? =
    findAnnotation(T::class)

fun  Annotated.findAnnotation(annotationClass: KClass): T? {
    val annotation = this.annotations.firstOrNull { it.fqName?.asString() == annotationClass.qualifiedName } ?: return null

    val constructor = annotationClass.constructors.first()

    val parametersWithArguments = assignArgumentsToParameters(constructor.parameters, annotation)

    return constructor.callBy(parametersWithArguments)
}

private fun assignArgumentsToParameters(
    parameters: List,
    annotation: AnnotationDescriptor,
): Map =
    parameters
        .mapNotNull { parameter ->
            val argumentExpression = annotation.argumentValue(parameter.name!!) ?: return@mapNotNull null

            parameter to argumentExpression.runtimeValue
        }
        .toMap()

private val ConstantValue<*>.runtimeValue: Any?
    get() = when (this) {
        is KClassValue, is EnumValue, is ArrayValue, is AnnotationValue -> {
            throw AssertionError("Unsupported annotation parameter type $this.")
        }

        else -> this.value
    }

fun AnnotationDescriptor.hasArgumentValue(parameterName: String): Boolean =
    Name.identifier(parameterName) in this.allValueArguments




© 2015 - 2024 Weber Informatics LLC | Privacy Policy