diff --git a/.idea/Shared.iml b/.idea/Shared.iml new file mode 100644 index 0000000..78b2cc5 --- /dev/null +++ b/.idea/Shared.iml @@ -0,0 +1,2 @@ + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index 38167d7..38b4a97 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,6 +1,9 @@ + + diff --git a/src/main/kotlin/com/mapk/core/KFunctionForCall.kt b/src/main/kotlin/com/mapk/core/KFunctionForCall.kt index 06e3036..422d50f 100644 --- a/src/main/kotlin/com/mapk/core/KFunctionForCall.kt +++ b/src/main/kotlin/com/mapk/core/KFunctionForCall.kt @@ -15,6 +15,7 @@ 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 import org.jetbrains.annotations.TestOnly class KFunctionForCall internal constructor( @@ -49,28 +50,33 @@ class KFunctionForCall internal constructor( .filter { it.kind == KParameter.Kind.VALUE && !it.isUseDefaultArgument() } .map { it.toArgumentBinder(parameterNameConverter) } - bucketGenerator = BucketGenerator( - parameters, - binders, - instance - ) + bucketGenerator = BucketGenerator(parameters, binders, instance) - requiredParameters = binders.fold(ArrayList()) { acc, elm -> - when (elm) { - is ArgumentBinder.Value<*> -> acc.add(elm) - is ArgumentBinder.Function -> acc.addAll(elm.requiredParameters) + val tempList = ArrayList>(binders.size) + val tempMap = HashMap>(binders.size) + + binders.forEach { binder -> + when (binder) { + is ArgumentBinder.Value<*> -> addArgs(binder, tempList, tempMap) + is ArgumentBinder.Function -> binder.requiredParameters.forEach { + addArgs(it, tempList, tempMap) + } } - acc } - requiredParametersMap = HashMap>().apply { - requiredParameters.forEach { - if (containsKey(it.name)) - throw IllegalArgumentException("The argument name ${it.name} is duplicated.") + requiredParameters = tempList + requiredParametersMap = tempMap + } - this[it.name] = it - } - } + private fun addArgs( + parameter: ValueParameter<*>, + tempList: ArrayList>, + tempMap: MutableMap> + ) { + if (tempMap.containsKey(parameter.name)) + throw IllegalArgumentException("The argument name ${parameter.name} is duplicated.") + tempMap[parameter.name] = parameter + tempList.add(parameter) } fun getArgumentAdaptor(): ArgumentAdaptor = ArgumentAdaptor(requiredParametersMap) @@ -83,22 +89,25 @@ class KFunctionForCall internal constructor( @Suppress("UNCHECKED_CAST") internal fun KClass.toKConstructor(parameterNameConverter: ParameterNameConverter): KFunctionForCall { - val factoryConstructor: List> = - this.companionObjectInstance?.let { companionObject -> - companionObject::class.functions - .filter { it.annotations.any { annotation -> annotation is KConstructor } } - .map { KFunctionForCall(it, parameterNameConverter, companionObject) as KFunctionForCall } - } ?: emptyList() - - val constructors: List> = factoryConstructor + this.constructors + val constructors = ArrayList>() + + this.companionObjectInstance?.let { companionObject -> + companionObject::class.functions + .filter { it.annotations.any { annotation -> annotation is KConstructor } } + .forEach { + constructors.add(KFunctionForCall(it, parameterNameConverter, companionObject) as KFunctionForCall) + } + } + + this.constructors .filter { it.annotations.any { annotation -> annotation is KConstructor } } - .map { KFunctionForCall(it, parameterNameConverter) } + .forEach { constructors.add(KFunctionForCall(it, parameterNameConverter)) } if (constructors.size == 1) return constructors.single() if (constructors.isEmpty()) return KFunctionForCall(this.primaryConstructor!!, parameterNameConverter) - throw IllegalArgumentException("Find multiple target.") + throw IllegalArgumentException("${this.jvmName} has multiple ${KConstructor::class.jvmName}.") } @Suppress("UNCHECKED_CAST")