
com.freya02.botcommands.internal.utils.AnnotationUtils.kt Maven / Gradle / Ivy
package com.freya02.botcommands.internal.utils
import com.freya02.botcommands.api.annotations.AppendMode
import com.freya02.botcommands.api.commands.annotations.BotPermissions
import com.freya02.botcommands.api.commands.annotations.UserPermissions
import com.freya02.botcommands.api.commands.application.annotations.Test
import com.freya02.botcommands.internal.BContextImpl
import com.freya02.botcommands.internal.enumSetOf
import com.freya02.botcommands.internal.simpleNestedName
import com.freya02.botcommands.internal.throwInternal
import com.freya02.botcommands.internal.utils.ReflectionUtils.declaringClass
import gnu.trove.set.TLongSet
import gnu.trove.set.hash.TLongHashSet
import net.dv8tion.jda.api.Permission
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.full.declaredMemberProperties
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.findAnnotations
internal object AnnotationUtils {
//List order is from deepest to most effective
//aka class --> method
private fun getEffectiveAnnotations(function: KFunction<*>, annotation: KClass): List {
return function.findAnnotations(annotation) + function.declaringClass.findAnnotations(annotation)
}
fun getEffectiveTestGuildIds(context: BContextImpl, function: KFunction<*>): TLongSet {
val testIds: TLongSet = TLongHashSet(context.applicationConfig.testGuildIds)
val effectiveAnnotations = getEffectiveAnnotations(function, Test::class)
for (test in effectiveAnnotations) {
val ids: LongArray = test.guildIds
val mode: AppendMode = test.mode
if (mode == AppendMode.SET) {
testIds.clear()
testIds.addAll(ids)
return testIds
} else if (mode == AppendMode.ADD) {
testIds.addAll(ids)
}
}
return testIds
}
@JvmStatic
fun getEffectiveAnnotation(function: KFunction<*>, annotationType: KClass): A? {
val methodAnnot = function.findAnnotations(annotationType)
return when {
methodAnnot.isNotEmpty() -> methodAnnot.first()
else -> function.declaringClass.findAnnotations(annotationType).firstOrNull()
}
}
fun getUserPermissions(func: KFunction<*>): EnumSet {
val annotation = func.findAnnotation() ?: return enumSetOf()
return enumSetOf().also { set ->
set += annotation.value
if (annotation.mode == AppendMode.SET) {
return set
}
set += func.declaringClass.findAnnotation()?.value ?: emptyArray()
}
}
fun getBotPermissions(func: KFunction<*>): EnumSet {
val annotation = func.findAnnotation() ?: return enumSetOf()
return enumSetOf().also { set ->
set += annotation.value
if (annotation.mode == AppendMode.SET) {
return set
}
set += func.declaringClass.findAnnotation()?.value ?: emptyArray()
}
}
@Suppress("UNCHECKED_CAST")
fun getAnnotationValue(annotation: A, methodName: String): T {
val kFunction = annotation.annotationClass.declaredMemberProperties.find { it.name == methodName }
?: throwInternal("Could not read '$methodName' from annotation '${annotation.annotationClass.simpleName}'")
return kFunction.call(annotation) as? T
?: throwInternal("Could not read '$methodName' from annotation '${annotation.annotationClass.simpleName}' as the type is incorrect, annotation type: ${kFunction.returnType.simpleNestedName}")
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy