io.github.freya022.botcommands.internal.utils.AnnotationUtils.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of BotCommands Show documentation
Show all versions of BotCommands Show documentation
A Kotlin-first (and Java) framework that makes creating Discord bots a piece of cake, using the JDA library.
package io.github.freya022.botcommands.internal.utils
import gnu.trove.set.TLongSet
import gnu.trove.set.hash.TLongHashSet
import io.github.freya022.botcommands.api.commands.annotations.BotPermissions
import io.github.freya022.botcommands.api.commands.annotations.UserPermissions
import io.github.freya022.botcommands.api.commands.application.annotations.Test
import io.github.freya022.botcommands.api.core.BContext
import io.github.freya022.botcommands.api.core.Filter
import io.github.freya022.botcommands.api.core.service.getService
import io.github.freya022.botcommands.api.core.utils.*
import io.github.freya022.botcommands.internal.utils.ReflectionUtils.declaringClass
import net.dv8tion.jda.api.Permission
import java.util.*
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.full.declaredMemberProperties
import io.github.freya022.botcommands.api.commands.annotations.Filter as FilterAnnotation
internal object AnnotationUtils {
internal fun getEffectiveTestGuildIds(context: BContext, func: KFunction<*>): TLongSet {
val set = TLongHashSet(context.applicationConfig.testGuildIds)
val annotation = func.findAnnotationRecursive() ?: return set
val methodValue = annotation.guildIds
set.addAll(methodValue)
if (!annotation.append && methodValue.isNotEmpty()) {
return set
}
val classValue: LongArray = func.declaringClass.findAnnotationRecursive()?.guildIds ?: LongArray(0)
set.addAll(classValue)
return set
}
internal fun getUserPermissions(func: KFunction<*>): EnumSet {
val set: EnumSet = enumSetOf()
val annotation = func.findAnnotationRecursive() ?: return set
val methodPermissions = annotation.permissions
set += methodPermissions
if (annotation.append) {
val classPermissions = func.declaringClass.findAnnotationRecursive()?.permissions ?: emptyArray()
set += classPermissions
}
return set
}
internal fun getBotPermissions(func: KFunction<*>): EnumSet {
val set: EnumSet = enumSetOf()
val annotation = func.findAnnotationRecursive() ?: return set
val methodPermissions = annotation.permissions
set += methodPermissions
if (annotation.append) {
val classPermissions = func.declaringClass.findAnnotationRecursive()?.permissions ?: emptyArray()
set += classPermissions
}
return set
}
@Suppress("UNCHECKED_CAST")
internal fun getFilters(context: BContext, func: KFunction<*>, filterType: KClass): List {
return func.findAllAnnotations()
.flatMap { it.classes }
.onEach {
require(it.isSubclassOf(filterType)) {
"Filter ${it.simpleNestedName} must implement ${filterType.simpleNestedName}"
}
}
.map { context.getService(it) as T }
}
@Suppress("UNCHECKED_CAST")
internal 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}")
}
}