commonMain.co.touchlab.skie.kir.util.FindAnnotationExtension.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlin-compiler-linker-plugin-kgp_1.9.20 Show documentation
Show all versions of kotlin-compiler-linker-plugin-kgp_1.9.20 Show documentation
Kotlin compiler plugin that improves Swift interface of a Kotlin Multiplatform framework.
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