com.dailystudio.devbricksx.ksp.utils.AnnotationUtils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of devbricksx-compiler Show documentation
Show all versions of devbricksx-compiler Show documentation
DevBricks eXetrems Annotation KSP Processor
package com.dailystudio.devbricksx.ksp.utils
import com.google.devtools.ksp.KspExperimental
import com.google.devtools.ksp.getAnnotationsByType
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.symbol.*
import com.squareup.kotlinpoet.ksp.toClassName
import kotlin.reflect.KClass
fun KSDeclaration.hasAnnotation(
annotationClass: KClass,
resolver: Resolver? = null,
): Boolean = (getAnnotation(annotationClass, resolver) != null)
/*
@OptIn(KspExperimental::class)
fun KSDeclaration.getAnnotation(
annotationClass: KClass,
resolver: Resolver? = null,
): T? {
if (resolver == null) {
return getAnnotationsByType(annotationClass).firstOrNull()
} else {
val annotation = getAnnotationsByType(annotationClass).firstOrNull()
if (annotation != null || this !is KSClassDeclaration) {
return annotation
}
return toShadowClass(resolver)?.getAnnotation(annotationClass)
}
}
*/
fun KSDeclaration.getAnnotation(
annotationClass: KClass,
resolver: Resolver? = null,
): T? {
return getAnnotation(annotationClass, 0, resolver)
}
fun KSDeclaration.getAnnotation(
annotationClass: KClass,
position: Int = 0,
resolver: Resolver? = null,
): T? {
val annotations = getAnnotations(annotationClass, resolver)
return if (position < annotations.size) {
annotations[position]
} else {
if (annotations.isNotEmpty()) {
return annotations[0]
} else {
null
}
}
}
@OptIn(KspExperimental::class)
fun KSDeclaration.getAnnotations(
annotationClass: KClass,
resolver: Resolver? = null,
): List {
if (resolver == null) {
return getAnnotationsByType(annotationClass).toList()
} else {
val list = getAnnotationsByType(annotationClass).toList()
if (list.isNotEmpty() || this !is KSClassDeclaration) {
return list
}
return toShadowClass(resolver)?.getAnnotations(annotationClass) ?: emptyList()
}
}
/*fun KSDeclaration.getKSAnnotation(
annotationClass: KClass,
resolver: Resolver
): KSAnnotation? {
var found: KSAnnotation? = null
for (annotation in this.annotations) {
if (annotation.annotationType.resolve() == annotationClass.asAnnotationType(resolver)) {
found = annotation
break
}
}
if (found != null || this !is KSClassDeclaration) {
return found
}
return toShadowClass(resolver)?.getKSAnnotation(
annotationClass, resolver)
}*/
fun KSDeclaration.getKSAnnotation(
annotationClass: KClass,
resolver: Resolver
): KSAnnotation? {
return getKSAnnotation(annotationClass, 0, resolver)
}
fun KSDeclaration.getKSAnnotation(
annotationClass: KClass,
position: Int = 0,
resolver: Resolver
): KSAnnotation? {
val annotations = getKSAnnotations(annotationClass, resolver)
return if (position < annotations.size) {
annotations[position]
} else {
if (annotations.isNotEmpty()) {
return annotations[0]
} else {
null
}
}
}
fun KSDeclaration.getKSAnnotations(
annotationClass: KClass,
resolver: Resolver
): List {
val found = mutableListOf()
for (annotation in this.annotations) {
if (annotation.annotationType.resolve() == annotationClass.asAnnotationType(resolver)) {
found.add(annotation)
}
}
if (found.isNotEmpty() || this !is KSClassDeclaration) {
return found
}
return toShadowClass(resolver)?.getKSAnnotations(
annotationClass, resolver) ?: emptyList()
}
inline fun KSAnnotation.findArgument(argName: String): R {
return arguments.first {
it.name?.getShortName() == argName
}.value as R
}
fun KSClassDeclaration.collectTypesInAnnotationArguments(
annotationClass: KClass,
nameOfArgument: String,
resolver: Resolver): Set {
val companion = getKSAnnotation(annotationClass, resolver)
val converters = mutableSetOf()
if (superClassType() != TypeNameUtils.typeOfKotlinAny(resolver)) {
val convertersInSuperType =
superClassType().collectTypesInAnnotationArguments(annotationClass,
nameOfArgument, resolver)
if (convertersInSuperType.isNotEmpty()) {
converters.addAll(convertersInSuperType)
}
}
companion?.findArgument>(nameOfArgument)?.let { it ->
converters.addAll(it)
}
return converters
}
fun KSClassDeclaration.collectObjectsInAnnotationArguments(
annotationClass: KClass,
nameOfArgument: String,
resolver: Resolver): Set {
val companion = getKSAnnotation(annotationClass, resolver)
val objects = mutableSetOf()
if (superClassType() != TypeNameUtils.typeOfKotlinAny(resolver)) {
val convertersInSuperType =
superClassType().collectObjectsInAnnotationArguments(annotationClass,
nameOfArgument, resolver)
if (convertersInSuperType.isNotEmpty()) {
objects.addAll(convertersInSuperType)
}
}
companion?.findArgument>(nameOfArgument)?.let { it ->
objects.addAll(it)
}
return objects
}
fun KSClassDeclaration.packageName(): String {
return this.toClassName().packageName
}
fun KSClassDeclaration.typeName(): String {
return this.toClassName().simpleName
}
fun KSClassDeclaration.superClassType(): KSClassDeclaration {
return superTypes
.map { it.resolve().declaration }
.filterIsInstance()
// .filter { it.classKind == ClassKind.CLASS }
.first()
}
fun KClass.asAnnotationType(resolver: Resolver): KSType? {
val clazzName = this.qualifiedName ?: return null
val ksName = resolver.getKSNameFromString(clazzName)
return resolver.getClassDeclarationByName(ksName)?.asType(emptyList())
}