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

com.dailystudio.devbricksx.ksp.utils.AnnotationUtils.kt Maven / Gradle / Ivy

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())
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy