Skip to content
This repository was archived by the owner on Jan 20, 2023. It is now read-only.

Commit 0985a5b

Browse files
authored
Merge pull request #22 from k163377/fix_duplicate_name_arg
Fix duplicate name arg.
2 parents f4ed366 + e58add3 commit 0985a5b

File tree

2 files changed

+51
-48
lines changed

2 files changed

+51
-48
lines changed

src/main/kotlin/com/mapk/core/KFunctionForCall.kt

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,17 @@
11
package com.mapk.core
22

33
import com.mapk.annotations.KConstructor
4+
import com.mapk.annotations.KParameterFlatten
5+
import com.mapk.core.internal.ArgumentBinder
46
import com.mapk.core.internal.BucketGenerator
57
import com.mapk.core.internal.ParameterNameConverter
8+
import com.mapk.core.internal.getAliasOrName
69
import com.mapk.core.internal.isUseDefaultArgument
710
import kotlin.reflect.KClass
811
import kotlin.reflect.KFunction
912
import kotlin.reflect.KParameter
1013
import kotlin.reflect.full.companionObjectInstance
14+
import kotlin.reflect.full.findAnnotation
1115
import kotlin.reflect.full.functions
1216
import kotlin.reflect.full.primaryConstructor
1317
import kotlin.reflect.jvm.isAccessible
@@ -41,16 +45,32 @@ class KFunctionForCall<T> internal constructor(
4145
// この関数には確実にアクセスするためアクセシビリティ書き換え
4246
function.isAccessible = true
4347

44-
val filteredParameters = parameters.filter { it.kind == KParameter.Kind.VALUE && !it.isUseDefaultArgument() }
48+
val binders: List<ArgumentBinder> = parameters
49+
.filter { it.kind == KParameter.Kind.VALUE && !it.isUseDefaultArgument() }
50+
.map { it.toArgumentBinder(parameterNameConverter) }
51+
4552
bucketGenerator = BucketGenerator(
4653
parameters,
47-
filteredParameters,
48-
instance,
49-
parameterNameConverter
54+
binders,
55+
instance
5056
)
5157

52-
requiredParameters = bucketGenerator.valueParameters
53-
requiredParametersMap = requiredParameters.associateBy { it.name }
58+
requiredParameters = binders.fold(ArrayList()) { acc, elm ->
59+
when (elm) {
60+
is ArgumentBinder.Value<*> -> acc.add(elm)
61+
is ArgumentBinder.Function -> acc.addAll(elm.requiredParameters)
62+
}
63+
acc
64+
}
65+
66+
requiredParametersMap = HashMap<String, ValueParameter<*>>().apply {
67+
requiredParameters.forEach {
68+
if (containsKey(it.name))
69+
throw IllegalArgumentException("The argument name ${it.name} is duplicated.")
70+
71+
this[it.name] = it
72+
}
73+
}
5474
}
5575

5676
fun getArgumentAdaptor(): ArgumentAdaptor = ArgumentAdaptor(requiredParametersMap)
@@ -84,3 +104,26 @@ internal fun <T : Any> KClass<T>.toKConstructor(parameterNameConverter: Paramete
84104
@Suppress("UNCHECKED_CAST")
85105
fun <T : Any> KClass<T>.toKConstructor(parameterNameConverter: (String) -> String): KFunctionForCall<T> =
86106
this.toKConstructor(ParameterNameConverter.Simple(parameterNameConverter))
107+
108+
private fun KParameter.toArgumentBinder(parameterNameConverter: ParameterNameConverter): ArgumentBinder {
109+
val name = getAliasOrName()!!
110+
111+
return findAnnotation<KParameterFlatten>()?.let { annotation ->
112+
// 名前の変換処理
113+
val converter: ParameterNameConverter = if (annotation.fieldNameToPrefix) {
114+
// 結合が必要な場合は結合機能のインスタンスを持ってきて対応する
115+
parameterNameConverter.nest(name, annotation.nameJoiner.objectInstance!!)
116+
} else {
117+
// プレフィックスを要求しない場合は全てsimpleでマップするように修正
118+
parameterNameConverter.toSimple()
119+
}
120+
121+
ArgumentBinder.Function((type.classifier as KClass<*>).toKConstructor(converter), index, annotations)
122+
} ?: ArgumentBinder.Value(
123+
index,
124+
annotations,
125+
isOptional,
126+
parameterNameConverter.convert(name),
127+
type.classifier as KClass<*>
128+
)
129+
}
Lines changed: 2 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,63 +1,23 @@
11
package com.mapk.core.internal
22

3-
import com.mapk.annotations.KParameterFlatten
43
import com.mapk.core.ArgumentAdaptor
5-
import com.mapk.core.ValueParameter
6-
import com.mapk.core.toKConstructor
7-
import kotlin.reflect.KClass
84
import kotlin.reflect.KParameter
9-
import kotlin.reflect.full.findAnnotation
105

116
internal class BucketGenerator(
127
private val parameters: List<KParameter>,
13-
filteredParameters: List<KParameter>, // フィルタリングは外でもやっているため、ここでは引数として受け取る
14-
instance: Any?,
15-
parameterNameConverter: ParameterNameConverter
8+
private val binders: List<ArgumentBinder>,
9+
instance: Any?
1610
) {
17-
private val binders: List<ArgumentBinder> = filteredParameters.map { it.toArgumentBinder(parameterNameConverter) }
1811
private val originalValueArray: Array<Any?> = arrayOfNulls(parameters.size)
1912
private val originalInitializationStatus: Array<Boolean> = Array(parameters.size) { false }
20-
val valueParameters: List<ValueParameter<*>>
2113

2214
init {
2315
if (instance != null) {
2416
originalValueArray[0] = instance
2517
originalInitializationStatus[0] = true
2618
}
27-
28-
// TODO: 仮置き、これを生成するのはKFunctionForCallの方が良さげ
29-
valueParameters = binders.fold(ArrayList()) { acc, elm ->
30-
when (elm) {
31-
is ArgumentBinder.Value<*> -> acc.add(elm)
32-
is ArgumentBinder.Function -> acc.addAll(elm.requiredParameters)
33-
}
34-
acc
35-
}
3619
}
3720

3821
fun generate(adaptor: ArgumentAdaptor): ArgumentBucket =
3922
ArgumentBucket(parameters, originalValueArray.clone(), originalInitializationStatus.clone(), binders, adaptor)
4023
}
41-
42-
private fun KParameter.toArgumentBinder(parameterNameConverter: ParameterNameConverter): ArgumentBinder {
43-
val name = getAliasOrName()!!
44-
45-
return findAnnotation<KParameterFlatten>()?.let { annotation ->
46-
// 名前の変換処理
47-
val converter: ParameterNameConverter = if (annotation.fieldNameToPrefix) {
48-
// 結合が必要な場合は結合機能のインスタンスを持ってきて対応する
49-
parameterNameConverter.nest(name, annotation.nameJoiner.objectInstance!!)
50-
} else {
51-
// プレフィックスを要求しない場合は全てsimpleでマップするように修正
52-
parameterNameConverter.toSimple()
53-
}
54-
55-
ArgumentBinder.Function((type.classifier as KClass<*>).toKConstructor(converter), index, annotations)
56-
} ?: ArgumentBinder.Value(
57-
index,
58-
annotations,
59-
isOptional,
60-
parameterNameConverter.convert(name),
61-
type.classifier as KClass<*>
62-
)
63-
}

0 commit comments

Comments
 (0)