From c099958b3da9bdf22830f1f549846d637bf457d2 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 03:34:18 +0900 Subject: [PATCH 01/11] =?UTF-8?q?IDE=E3=81=AE=E3=82=A2=E3=83=83=E3=83=97?= =?UTF-8?q?=E3=83=87=E3=83=BC=E3=83=88=E3=81=AB=E4=BC=B4=E3=81=86=E8=BF=BD?= =?UTF-8?q?=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .idea/compiler.xml | 6 ++++++ .idea/misc.xml | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 .idea/compiler.xml diff --git a/.idea/compiler.xml b/.idea/compiler.xml new file mode 100644 index 0000000..61a9130 --- /dev/null +++ b/.idea/compiler.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml index bc8d0a3..38167d7 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,7 +1,7 @@ - + \ No newline at end of file From b13dbef8466b0f86c16934e5475a4009e49edd88 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 03:34:41 +0900 Subject: [PATCH 02/11] =?UTF-8?q?=E3=83=90=E3=83=BC=E3=82=B8=E3=83=A7?= =?UTF-8?q?=E3=83=B3=E3=82=A2=E3=83=83=E3=83=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 6073570..92a94d4 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "com.mapk" -version = "0.22" +version = "0.23" java { sourceCompatibility = JavaVersion.VERSION_1_8 From b3a25538031a882bc2340a46e2c1496c99a95c5f Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 03:35:28 +0900 Subject: [PATCH 03/11] =?UTF-8?q?kotlin=201.3.72=E3=81=B8=E3=81=AE?= =?UTF-8?q?=E3=82=A2=E3=83=83=E3=83=97=E3=83=87=E3=83=BC=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ついでにgradleプラグインは余計なバージョンを指定しないように修正 --- build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index 92a94d4..4c3159b 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,7 +1,7 @@ plugins { id("maven") id("java") - id("org.jetbrains.kotlin.jvm") version "1.3.71" + id("org.jetbrains.kotlin.jvm") version "1.3.72" id("org.jlleitschuh.gradle.ktlint") version "9.2.1" } @@ -18,7 +18,7 @@ buildscript { } dependencies { - classpath(kotlin("gradle-plugin", version = "1.3.71")) + classpath(kotlin("gradle-plugin")) } } From 40c94d662052d27557b5e4426cef7a1f6d812329 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 03:35:59 +0900 Subject: [PATCH 04/11] =?UTF-8?q?shared=E3=81=AE=E3=82=A2=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=83=87=E3=83=BC=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 4c3159b..650133c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -30,7 +30,7 @@ repositories { dependencies { implementation("org.jetbrains.kotlin:kotlin-stdlib-jdk8") implementation(kotlin("reflect")) - api("com.github.ProjectMapK:Shared:0.10") + api("com.github.ProjectMapK:Shared:0.11") // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter testImplementation(group = "org.junit.jupiter", name = "junit-jupiter", version = "5.6.1") { From dfb7d6b79eebb5b799e0e52813d8432d2c8bd7b5 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 03:36:42 +0900 Subject: [PATCH 05/11] =?UTF-8?q?JUnit5=E3=81=AE=E3=82=A2=E3=83=83?= =?UTF-8?q?=E3=83=97=E3=83=87=E3=83=BC=E3=83=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index 650133c..166966d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -33,7 +33,7 @@ dependencies { api("com.github.ProjectMapK:Shared:0.11") // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter - testImplementation(group = "org.junit.jupiter", name = "junit-jupiter", version = "5.6.1") { + testImplementation(group = "org.junit.jupiter", name = "junit-jupiter", version = "5.6.2") { exclude(group = "org.junit.vintage", module = "junit-vintage-engine") } // 現状プロパティ名の変換はテストでしか使っていないのでtestImplementation From 69cb85398535514009109e9c552e815d693ae96c Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 04:19:28 +0900 Subject: [PATCH 06/11] =?UTF-8?q?=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E5=8F=96=E5=BE=97=E5=87=A6=E7=90=86=E3=82=92=E3=83=A9?= =?UTF-8?q?=E3=83=A0=E3=83=80=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8F=E5=80=8B?= =?UTF-8?q?=E3=80=85=E3=81=AE=E5=9E=8B=E3=81=A7=E7=AE=A1=E7=90=86=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mapk/kmapper/BoundParameterForMap.kt | 86 ++++++++++++++----- 1 file changed, 64 insertions(+), 22 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt b/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt index 03d0d96..a0b576f 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt @@ -2,41 +2,83 @@ package com.mapk.kmapper import com.mapk.core.EnumMapper import java.lang.IllegalArgumentException +import java.lang.reflect.Method import kotlin.reflect.KClass +import kotlin.reflect.KFunction import kotlin.reflect.KParameter import kotlin.reflect.KProperty1 import kotlin.reflect.full.isSubclassOf import kotlin.reflect.jvm.javaGetter @Suppress("UNCHECKED_CAST") -internal class BoundParameterForMap(val param: KParameter, property: KProperty1) { - val map: (S) -> Any? +internal sealed class BoundParameterForMap { + abstract val param: KParameter + abstract val propertyGetter: Method - init { - // ゲッターが無いならエラー - val propertyGetter = property.javaGetter - ?: throw IllegalArgumentException("${property.name} does not have getter.") - propertyGetter.isAccessible = true + abstract fun map(src: S): Any? - val paramClazz = param.type.classifier as KClass<*> - val propertyClazz = property.returnType.classifier as KClass<*> + class Plain( + override val param: KParameter, + override val propertyGetter: Method + ) : BoundParameterForMap() { + override fun map(src: S): Any? = propertyGetter.invoke(src) + } + + class UseConverter( + override val param: KParameter, + override val propertyGetter: Method, + private val converter: KFunction<*> + ) : BoundParameterForMap() { + override fun map(src: S): Any? = converter.call(propertyGetter.invoke(src)) + } + + class ToEnum( + override val param: KParameter, + override val propertyGetter: Method, + private val paramClazz: Class<*> + ) : BoundParameterForMap() { + override fun map(src: S): Any? = EnumMapper.getEnum(paramClazz, propertyGetter.invoke(src) as String) + } + + class ToString( + override val param: KParameter, + override val propertyGetter: Method + ) : BoundParameterForMap() { + override fun map(src: S): String? = propertyGetter.invoke(src).toString() + } + + companion object { + fun newInstance(param: KParameter, property: KProperty1): BoundParameterForMap { + // ゲッターが無いならエラー + val propertyGetter = property.javaGetter + ?: throw IllegalArgumentException("${property.name} does not have getter.") + propertyGetter.isAccessible = true + + val paramClazz = param.type.classifier as KClass<*> + val propertyClazz = property.returnType.classifier as KClass<*> - val converter = paramClazz.getConverters() - .filter { (key, _) -> propertyClazz.isSubclassOf(key) } - .let { - if (1 < it.size) throw IllegalArgumentException("${param.name} has multiple converter. $it") + // コンバータが取れた場合 + paramClazz.getConverters() + .filter { (key, _) -> propertyClazz.isSubclassOf(key) } + .let { + if (1 < it.size) throw IllegalArgumentException("${param.name} has multiple converter. $it") - it.singleOrNull()?.second + it.singleOrNull()?.second + }?.let { + return UseConverter(param, propertyGetter, it) + } + + if (paramClazz.isSubclassOf(propertyClazz)) { + return Plain(param, propertyGetter) } - map = when { - converter != null -> { { converter.call(propertyGetter.invoke(it)) } } - paramClazz.isSubclassOf(propertyClazz) -> { { propertyGetter.invoke(it) } } - paramClazz.java.isEnum && propertyClazz == String::class -> { { - EnumMapper.getEnum(paramClazz.java, propertyGetter.invoke(it) as String) - } } - paramClazz == String::class -> { { propertyGetter.invoke(it).toString() } } - else -> throw IllegalArgumentException("Can not convert $propertyClazz to $paramClazz") + val javaClazz = paramClazz.java + + return when { + javaClazz.isEnum && propertyClazz == String::class -> ToEnum(param, propertyGetter, javaClazz) + paramClazz == String::class -> ToString(param, propertyGetter) + else -> throw IllegalArgumentException("Can not convert $propertyClazz to $paramClazz") + } } } } From d2aa1a24f418980d5d9340f16c11a77d8f19c57b Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 04:19:45 +0900 Subject: [PATCH 07/11] =?UTF-8?q?=E7=94=9F=E6=88=90=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E3=81=AE=E5=A4=89=E6=9B=B4=E3=81=AB=E4=BC=B4=E3=81=86=E4=BF=AE?= =?UTF-8?q?=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt index d487b30..d947859 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt @@ -45,7 +45,7 @@ class BoundKMapper private constructor( .filter { it.kind != KParameter.Kind.INSTANCE && !it.isUseDefaultArgument() } .mapNotNull { val temp = srcPropertiesMap[parameterNameConverter(it.getAliasOrName()!!)]?.let { property -> - BoundParameterForMap(it, property) + BoundParameterForMap.newInstance(it, property) } // 必須引数に対応するプロパティがsrcに定義されていない場合エラー From d7ee597afb60835ea2723d6f8f28ed021b86f371 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 04:43:10 +0900 Subject: [PATCH 08/11] =?UTF-8?q?=E9=81=A9=E5=88=87=E3=81=AA=E3=82=B9?= =?UTF-8?q?=E3=82=B3=E3=83=BC=E3=83=97=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../kotlin/com/mapk/kmapper/BoundParameterForMap.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt b/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt index a0b576f..0f954ab 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt @@ -13,18 +13,18 @@ import kotlin.reflect.jvm.javaGetter @Suppress("UNCHECKED_CAST") internal sealed class BoundParameterForMap { abstract val param: KParameter - abstract val propertyGetter: Method + protected abstract val propertyGetter: Method abstract fun map(src: S): Any? - class Plain( + private class Plain( override val param: KParameter, override val propertyGetter: Method ) : BoundParameterForMap() { override fun map(src: S): Any? = propertyGetter.invoke(src) } - class UseConverter( + private class UseConverter( override val param: KParameter, override val propertyGetter: Method, private val converter: KFunction<*> @@ -32,7 +32,7 @@ internal sealed class BoundParameterForMap { override fun map(src: S): Any? = converter.call(propertyGetter.invoke(src)) } - class ToEnum( + private class ToEnum( override val param: KParameter, override val propertyGetter: Method, private val paramClazz: Class<*> @@ -40,7 +40,7 @@ internal sealed class BoundParameterForMap { override fun map(src: S): Any? = EnumMapper.getEnum(paramClazz, propertyGetter.invoke(src) as String) } - class ToString( + private class ToString( override val param: KParameter, override val propertyGetter: Method ) : BoundParameterForMap() { From 6f67bfe8692a2ee48a26eb2cde009d512ccc2dd5 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 04:48:18 +0900 Subject: [PATCH 09/11] =?UTF-8?q?=E4=B8=8D=E8=A6=81=E3=81=AA=E3=83=87?= =?UTF-8?q?=E3=83=95=E3=82=A9=E3=83=AB=E3=83=88=E5=BC=95=E6=95=B0=E3=82=92?= =?UTF-8?q?=E5=89=8A=E9=99=A4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt index d947859..d9b6e7e 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt @@ -20,7 +20,7 @@ import kotlin.reflect.jvm.jvmName class BoundKMapper private constructor( private val function: KFunctionForCall, src: KClass, - parameterNameConverter: (String) -> String = { it } + parameterNameConverter: (String) -> String ) { constructor(function: KFunction, src: KClass, parameterNameConverter: (String) -> String = { it }) : this( KFunctionForCall(function), src, parameterNameConverter From 47c263e79fe7ba3c912d3aec3675b0b929cb8792 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 05:20:55 +0900 Subject: [PATCH 10/11] =?UTF-8?q?=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E5=8F=96=E5=BE=97=E5=87=A6=E7=90=86=E3=82=92=E3=83=A9?= =?UTF-8?q?=E3=83=A0=E3=83=80=E3=81=A7=E3=81=AF=E3=81=AA=E3=81=8F=E5=80=8B?= =?UTF-8?q?=E3=80=85=E3=81=AE=E5=9E=8B=E3=81=A7=E7=AE=A1=E7=90=86=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=82=88=E3=81=86=E3=81=AB=E5=A4=89=E6=9B=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mapk/kmapper/ParameterForMap.kt | 38 ++++++++++++++----- 1 file changed, 29 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt b/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt index 25d1875..eceec68 100644 --- a/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt +++ b/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt @@ -15,33 +15,33 @@ internal class ParameterForMap private constructor(val param: KParamete // リストの長さが小さいと期待されるためこの形で実装しているが、理想的にはmap的なものが使いたい private val converters: Set, KFunction>> = clazz.getConverters() - private val convertCache: ConcurrentMap, (Any) -> Any?> = ConcurrentHashMap() + private val convertCache: ConcurrentMap, ParameterProcessor> = ConcurrentHashMap() fun mapObject(value: U): Any? { val valueClazz: KClass<*> = value::class // 取得方法のキャッシュが有ればそれを用いる - convertCache[valueClazz]?.let { return it(value) } + convertCache[valueClazz]?.let { return it.process(value) } // パラメータに対してvalueが代入可能(同じもしくは親クラス)であればそのまま用いる if (clazz.isSuperclassOf(valueClazz)) { - convertCache.putIfAbsent(valueClazz) { it } + convertCache.putIfAbsent(valueClazz, ParameterProcessor.Plain) return value } val converter: KFunction<*>? = converters.getConverter(valueClazz) - val lambda: (Any) -> Any? = when { + val processor: ParameterProcessor = when { // converterに一致する組み合わせが有れば設定されていればそれを使う - converter != null -> { { converter.call(it) } } + converter != null -> ParameterProcessor.UseConverter(converter) // 要求された値がenumかつ元が文字列ならenum mapperでマップ - javaClazz.isEnum && value is String -> { { EnumMapper.getEnum(javaClazz, it as String) } } + javaClazz.isEnum && value is String -> ParameterProcessor.ToEnum(javaClazz) // 要求されているパラメータがStringならtoStringする - clazz == String::class -> { { it.toString() } } + clazz == String::class -> ParameterProcessor.ToString else -> throw IllegalArgumentException("Can not convert $valueClazz to $clazz") } - convertCache.putIfAbsent(valueClazz, lambda) - return lambda(value) + convertCache.putIfAbsent(valueClazz, processor) + return processor.process(value) } companion object { @@ -50,3 +50,23 @@ internal class ParameterForMap private constructor(val param: KParamete } } } + +private sealed class ParameterProcessor { + abstract fun process(value: Any): Any? + + object Plain : ParameterProcessor() { + override fun process(value: Any): Any? = value + } + + class UseConverter(private val converter: KFunction<*>) : ParameterProcessor() { + override fun process(value: Any): Any? = converter.call(value) + } + + class ToEnum(private val javaClazz: Class<*>) : ParameterProcessor() { + override fun process(value: Any): Any? = EnumMapper.getEnum(javaClazz, value as String) + } + + object ToString : ParameterProcessor() { + override fun process(value: Any): Any? = value.toString() + } +} From 2345dbb7e340168ff26bb9e629f3689a0861d3db Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 19 Apr 2020 05:33:30 +0900 Subject: [PATCH 11/11] =?UTF-8?q?=E3=83=90=E3=82=A4=E3=83=B3=E3=83=89?= =?UTF-8?q?=E5=87=A6=E7=90=86=E3=82=92=E3=82=AF=E3=83=A9=E3=82=B9=E3=81=A8?= =?UTF-8?q?=E3=81=97=E3=81=A6=E5=88=87=E3=82=8A=E5=87=BA=E3=81=97?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/KMapper.kt | 31 ++++++++++++--------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/KMapper.kt b/src/main/kotlin/com/mapk/kmapper/KMapper.kt index 910cead..4faff9a 100644 --- a/src/main/kotlin/com/mapk/kmapper/KMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/KMapper.kt @@ -33,7 +33,7 @@ class KMapper private constructor( .filter { it.kind != KParameter.Kind.INSTANCE && !it.isUseDefaultArgument() } .associate { (parameterNameConverter(it.getAliasOrName()!!)) to ParameterForMap.newInstance(it) } - private val getCache: ConcurrentMap, List<(Any, ArgumentBucket) -> Unit>> = ConcurrentHashMap() + private val getCache: ConcurrentMap, List> = ConcurrentHashMap() private fun bindArguments(argumentBucket: ArgumentBucket, src: Any) { val clazz = src::class @@ -41,11 +41,11 @@ class KMapper private constructor( // キャッシュヒットしたら登録した内容に沿って取得処理を行う getCache[clazz]?.let { getters -> // 取得対象フィールドは十分絞り込んでいると考えられるため、終了判定は行わない - getters.forEach { it(src, argumentBucket) } + getters.forEach { it.bindArgument(src, argumentBucket) } return } - val tempCacheArrayList = ArrayList<(Any, ArgumentBucket) -> Unit>() + val tempBinderArrayList = ArrayList() src::class.memberProperties.forEach outer@{ property -> // propertyが公開されていない場合は処理を行わない @@ -64,19 +64,14 @@ class KMapper private constructor( parameterMap[alias ?: property.name]?.let { param -> javaGetter.isAccessible = true - val tempCache = { value: Any, bucket: ArgumentBucket -> - // 初期化済みであれば高コストな取得処理は行わない - if (!bucket.containsKey(param.param)) { - // javaGetterを呼び出す方が高速 - bucket.putIfAbsent(param.param, javaGetter.invoke(value)?.let { param.mapObject(it) }) - } - } - tempCache(src, argumentBucket) - tempCacheArrayList.add(tempCache) + val binder = ArgumentBinder(param, javaGetter) + + binder.bindArgument(src, argumentBucket) + tempBinderArrayList.add(binder) // キャッシュの整合性を保つため、ここでは終了判定を行わない } } - getCache.putIfAbsent(clazz, tempCacheArrayList) + getCache.putIfAbsent(clazz, tempBinderArrayList) } private fun bindArguments(argumentBucket: ArgumentBucket, src: Map<*, *>) { @@ -131,3 +126,13 @@ class KMapper private constructor( return function.call(bucket) } } + +private class ArgumentBinder(private val param: ParameterForMap<*>, private val javaGetter: Method) { + fun bindArgument(value: Any, bucket: ArgumentBucket) { + // 初期化済みであれば高コストな取得処理は行わない + if (!bucket.containsKey(param.param)) { + // javaGetterを呼び出す方が高速 + bucket.putIfAbsent(param.param, javaGetter.invoke(value)?.let { param.mapObject(it) }) + } + } +}