Skip to content
This repository was archived by the owner on Jan 20, 2023. It is now read-only.
2 changes: 1 addition & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ plugins {
}

group = "com.mapk"
version = "0.12"
version = "0.13"

java {
sourceCompatibility = JavaVersion.VERSION_1_8
Expand Down
26 changes: 26 additions & 0 deletions src/main/kotlin/com/mapk/core/Functions.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.mapk.core

import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.full.companionObject
import kotlin.reflect.full.functions

inline fun <reified A : Annotation> KClass<*>.getAnnotatedFunctionsFromCompanionObject(): Pair<Any, List<KFunction<*>>>? {
return this.companionObject?.let { companionObject ->
val temp = companionObject.functions.filter { functions -> functions.annotations.any { it is A } }

if (temp.isEmpty()) {
// 空ならその後の処理をしてもしょうがないのでnullに合わせる
null
} else {
companionObject.objectInstance!! to temp
}
}
}

inline fun <reified A : Annotation, T> Collection<KFunction<T>>.getAnnotatedFunctions(): List<KFunction<T>> {
return filter { function -> function.annotations.any { it is A } }
}

fun KParameter.getKClass(): KClass<*> = type.classifier as KClass<*>
22 changes: 9 additions & 13 deletions src/main/kotlin/com/mapk/core/KFunctionForCall.kt
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,7 @@ import com.mapk.core.internal.isUseDefaultArgument
import kotlin.reflect.KClass
import kotlin.reflect.KFunction
import kotlin.reflect.KParameter
import kotlin.reflect.full.companionObjectInstance
import kotlin.reflect.full.findAnnotation
import kotlin.reflect.full.functions
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.isAccessible
import kotlin.reflect.jvm.jvmName
Expand Down Expand Up @@ -91,17 +89,15 @@ class KFunctionForCall<T> internal constructor(
internal fun <T : Any> KClass<T>.toKConstructor(parameterNameConverter: ParameterNameConverter): KFunctionForCall<T> {
val constructors = ArrayList<KFunctionForCall<T>>()

this.companionObjectInstance?.let { companionObject ->
companionObject::class.functions
.filter { it.annotations.any { annotation -> annotation is KConstructor } }
.forEach {
constructors.add(KFunctionForCall(it, parameterNameConverter, companionObject) as KFunctionForCall<T>)
}
this.getAnnotatedFunctionsFromCompanionObject<KConstructor>()?.let { (instance, functions) ->
functions.forEach {
constructors.add(KFunctionForCall(it as KFunction<T>, parameterNameConverter, instance))
}
}

this.constructors
.filter { it.annotations.any { annotation -> annotation is KConstructor } }
.forEach { constructors.add(KFunctionForCall(it, parameterNameConverter)) }
this.constructors.getAnnotatedFunctions<KConstructor, T>().forEach {
constructors.add(KFunctionForCall(it, parameterNameConverter))
}

if (constructors.size == 1) return constructors.single()

Expand All @@ -127,12 +123,12 @@ private fun KParameter.toArgumentBinder(parameterNameConverter: ParameterNameCon
parameterNameConverter.toSimple()
}

ArgumentBinder.Function((type.classifier as KClass<*>).toKConstructor(converter), index, annotations)
ArgumentBinder.Function(getKClass().toKConstructor(converter), index, annotations)
} ?: ArgumentBinder.Value(
index,
annotations,
isOptional,
parameterNameConverter.convert(name),
type.classifier as KClass<*>
getKClass()
)
}