io.github.freya022.botcommands.internal.MethodParameters.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
import io.github.freya022.botcommands.api.core.options.annotations.Aggregate
import io.github.freya022.botcommands.api.core.options.builder.OptionAggregateBuilder
import io.github.freya022.botcommands.api.core.options.builder.OptionBuilder
import io.github.freya022.botcommands.internal.core.options.builder.InternalAggregators
import io.github.freya022.botcommands.internal.parameters.AggregatorParameter
import io.github.freya022.botcommands.internal.utils.ReflectionUtils.function
import io.github.freya022.botcommands.internal.utils.ReflectionUtils.nonInstanceParameters
import io.github.freya022.botcommands.internal.utils.findDeclarationName
import io.github.freya022.botcommands.internal.utils.throwUser
import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.full.hasAnnotation
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.jvmErasure
internal class BasicOptionAggregateBuilder(
aggregatorParameter: AggregatorParameter,
aggregator: KFunction<*>
) : OptionAggregateBuilder(aggregatorParameter, aggregator) {
override fun constructNestedAggregate(aggregatorParameter: AggregatorParameter, aggregator: KFunction<*>) =
BasicOptionAggregateBuilder(aggregatorParameter, aggregator)
}
internal inline fun , R> Map.transform(aggregateBlock: (T) -> R) =
values.map(aggregateBlock)
internal fun List.transformParameters(
builderBlock: (function: KFunction<*>, parameter: KParameter, declaredName: String) -> OptionBuilder,
aggregateBlock: (OptionAggregateBuilder<*>) -> R
) = associate { parameter ->
val declaredName = parameter.findDeclarationName()
declaredName to when {
parameter.hasAnnotation() -> {
val constructor = parameter.type.jvmErasure.primaryConstructor
?: throwUser(parameter.function, "Found no constructor for aggregate type ${parameter.type}")
BasicOptionAggregateBuilder(AggregatorParameter.fromUserAggregate(constructor, declaredName), constructor).apply {
constructor.nonInstanceParameters.forEach { constructorParameter ->
this += builderBlock(constructor, constructorParameter, constructorParameter.findDeclarationName())
}
}
}
else -> BasicOptionAggregateBuilder(
AggregatorParameter.fromSelfAggregate(parameter.function, declaredName),
InternalAggregators.theSingleAggregator
).apply {
this += builderBlock(parameter.function, parameter, declaredName)
}
}
}.transform(aggregateBlock)