From 69f445dff8757e8edd5c18e95ffa54862e19278b Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:04:54 +0900 Subject: [PATCH 01/21] =?UTF-8?q?ValueParameter=E3=81=8B=E3=82=89=E5=8F=96?= =?UTF-8?q?=E3=82=8B=E5=BD=A2=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/ParameterUtils.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/ParameterUtils.kt b/src/main/kotlin/com/mapk/kmapper/ParameterUtils.kt index 25c395d..9dd4d97 100644 --- a/src/main/kotlin/com/mapk/kmapper/ParameterUtils.kt +++ b/src/main/kotlin/com/mapk/kmapper/ParameterUtils.kt @@ -3,9 +3,9 @@ package com.mapk.kmapper import com.mapk.annotations.KConverter import com.mapk.conversion.KConvertBy import com.mapk.core.KFunctionWithInstance +import com.mapk.core.ValueParameter 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 @@ -54,7 +54,7 @@ private fun convertersFromCompanionObject(clazz: KClass): Set, KFunction<*>>> { +internal fun ValueParameter.getConverters(): Set, KFunction<*>>> { return annotations.mapNotNull { paramAnnotation -> paramAnnotation.annotationClass .findAnnotation() From 8fe842b72e3fe0e58014faba3e8b464461eec88f Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:09:26 +0900 Subject: [PATCH 02/21] =?UTF-8?q?=E3=82=A4=E3=83=B3=E3=83=87=E3=83=B3?= =?UTF-8?q?=E3=83=88=E3=81=8C=E3=81=84=E3=81=A4=E3=82=82=E3=81=A8=E9=81=95?= =?UTF-8?q?=E3=81=A3=E3=81=9F=E3=81=9F=E3=82=81=E4=BF=AE=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 | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt index 287c54f..1d26a58 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt @@ -33,13 +33,12 @@ class BoundKMapper private constructor( private val parameters: List> init { - val srcPropertiesMap: Map> = - src.memberProperties - .filter { - // アクセス可能かつignoreされてないもののみ抽出 - !(it.visibility != KVisibility.PUBLIC) && - it.getter.annotations.none { annotation -> annotation is KGetterIgnore } - }.associateBy { it.getter.findAnnotation()?.value ?: it.name } + val srcPropertiesMap: Map> = src.memberProperties + .filter { + // アクセス可能かつignoreされてないもののみ抽出 + !(it.visibility != KVisibility.PUBLIC) + && it.getter.annotations.none { annotation -> annotation is KGetterIgnore } + }.associateBy { it.getter.findAnnotation()?.value ?: it.name } parameters = function.parameters .filter { it.kind != KParameter.Kind.INSTANCE && !it.isUseDefaultArgument() } From 4008ed955c39861d7802628c83919ea3b000dbcf Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:18:40 +0900 Subject: [PATCH 03/21] =?UTF-8?q?ValueParameter=E3=82=92=E7=94=A8=E3=81=84?= =?UTF-8?q?=E3=82=8B=E5=88=9D=E6=9C=9F=E5=8C=96=E6=96=B9=E5=BC=8F=E3=81=AB?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mapk/kmapper/BoundParameterForMap.kt | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt b/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt index adac56a..3516e12 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundParameterForMap.kt @@ -1,31 +1,31 @@ package com.mapk.kmapper import com.mapk.core.EnumMapper +import com.mapk.core.ValueParameter 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 sealed class BoundParameterForMap { - abstract val param: KParameter + abstract val name: String protected abstract val propertyGetter: Method abstract fun map(src: S): Any? private class Plain( - override val param: KParameter, + override val name: String, override val propertyGetter: Method ) : BoundParameterForMap() { override fun map(src: S): Any? = propertyGetter.invoke(src) } private class UseConverter( - override val param: KParameter, + override val name: String, override val propertyGetter: Method, private val converter: KFunction<*> ) : BoundParameterForMap() { @@ -33,7 +33,7 @@ internal sealed class BoundParameterForMap { } private class UseKMapper( - override val param: KParameter, + override val name: String, override val propertyGetter: Method, private val kMapper: KMapper<*> ) : BoundParameterForMap() { @@ -42,7 +42,7 @@ internal sealed class BoundParameterForMap { } private class UseBoundKMapper( - override val param: KParameter, + override val name: String, override val propertyGetter: Method, private val boundKMapper: BoundKMapper ) : BoundParameterForMap() { @@ -50,7 +50,7 @@ internal sealed class BoundParameterForMap { } private class ToEnum( - override val param: KParameter, + override val name: String, override val propertyGetter: Method, private val paramClazz: Class<*> ) : BoundParameterForMap() { @@ -58,7 +58,7 @@ internal sealed class BoundParameterForMap { } private class ToString( - override val param: KParameter, + override val name: String, override val propertyGetter: Method ) : BoundParameterForMap() { override fun map(src: S): String? = propertyGetter.invoke(src).toString() @@ -66,7 +66,7 @@ internal sealed class BoundParameterForMap { companion object { fun newInstance( - param: KParameter, + param: ValueParameter<*>, property: KProperty1, parameterNameConverter: (String) -> String ): BoundParameterForMap { @@ -75,7 +75,7 @@ internal sealed class BoundParameterForMap { ?: throw IllegalArgumentException("${property.name} does not have getter.") propertyGetter.isAccessible = true - val paramClazz = param.type.classifier as KClass<*> + val paramClazz = param.requiredClazz val propertyClazz = property.returnType.classifier as KClass<*> // コンバータが取れた場合 @@ -86,25 +86,25 @@ internal sealed class BoundParameterForMap { it.singleOrNull()?.second }?.let { - return UseConverter(param, propertyGetter, it) + return UseConverter(param.name, propertyGetter, it) } if (paramClazz.isSubclassOf(propertyClazz)) { - return Plain(param, propertyGetter) + return Plain(param.name, propertyGetter) } val javaClazz = paramClazz.java return when { - javaClazz.isEnum && propertyClazz == String::class -> ToEnum(param, propertyGetter, javaClazz) - paramClazz == String::class -> ToString(param, propertyGetter) + javaClazz.isEnum && propertyClazz == String::class -> ToEnum(param.name, propertyGetter, javaClazz) + paramClazz == String::class -> ToString(param.name, propertyGetter) // SrcがMapやPairならKMapperを使わないとマップできない propertyClazz.isSubclassOf(Map::class) || propertyClazz.isSubclassOf(Pair::class) -> UseKMapper( - param, propertyGetter, KMapper(paramClazz, parameterNameConverter) + param.name, propertyGetter, KMapper(paramClazz, parameterNameConverter) ) // 何にも当てはまらなければBoundKMapperでマップを試みる else -> UseBoundKMapper( - param, propertyGetter, BoundKMapper(paramClazz, propertyClazz, parameterNameConverter) + param.name, propertyGetter, BoundKMapper(paramClazz, propertyClazz, parameterNameConverter) ) } } From 358b5d7807a4878adf37d70b5603bd8020ba6921 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:19:04 +0900 Subject: [PATCH 04/21] =?UTF-8?q?KFunctionForCall=E3=81=AE=E5=91=BC?= =?UTF-8?q?=E3=81=B3=E6=96=B9=E3=82=92=E4=BF=AE=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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt index 1d26a58..a4cf8eb 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt @@ -23,11 +23,11 @@ class BoundKMapper private constructor( parameterNameConverter: (String) -> String ) { constructor(function: KFunction, src: KClass, parameterNameConverter: (String) -> String = { it }) : this( - KFunctionForCall(function), src, parameterNameConverter + KFunctionForCall(function, parameterNameConverter), src, parameterNameConverter ) constructor(clazz: KClass, src: KClass, parameterNameConverter: (String) -> String = { it }) : this( - clazz.toKConstructor(), src, parameterNameConverter + clazz.toKConstructor(parameterNameConverter), src, parameterNameConverter ) private val parameters: List> From 140a1581f4a44caf90e962e16959f16e9cd525ef Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:19:24 +0900 Subject: [PATCH 05/21] =?UTF-8?q?=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=81=AE=E5=88=9D=E6=9C=9F=E5=8C=96=E6=96=B9=E6=B3=95?= =?UTF-8?q?=E3=82=92=E4=BF=AE=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 | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt index a4cf8eb..a28f9ef 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt @@ -40,16 +40,15 @@ class BoundKMapper private constructor( && it.getter.annotations.none { annotation -> annotation is KGetterIgnore } }.associateBy { it.getter.findAnnotation()?.value ?: it.name } - parameters = function.parameters - .filter { it.kind != KParameter.Kind.INSTANCE && !it.isUseDefaultArgument() } + parameters = function.requiredParameters .mapNotNull { - val temp = srcPropertiesMap[parameterNameConverter(it.getAliasOrName()!!)]?.let { property -> + val temp = srcPropertiesMap[it.name]?.let { property -> BoundParameterForMap.newInstance(it, property, parameterNameConverter) } // 必須引数に対応するプロパティがsrcに定義されていない場合エラー if (temp == null && !it.isOptional) { - throw IllegalArgumentException("Property ${it.name!!} is not declared in ${src.jvmName}.") + throw IllegalArgumentException("Property ${it.name} is not declared in ${src.jvmName}.") } temp From a98a31192c4c189d1dd871883a3ed0f4a630d0bf Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:19:39 +0900 Subject: [PATCH 06/21] =?UTF-8?q?=E5=91=BC=E3=81=B3=E5=87=BA=E3=81=97?= =?UTF-8?q?=E6=96=B9=E3=82=92=E4=BF=AE=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 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt index a28f9ef..37f22a0 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt @@ -56,12 +56,12 @@ class BoundKMapper private constructor( } fun map(src: S): D { - val bucket: ArgumentBucket = function.getArgumentBucket() + val adaptor = function.getArgumentAdaptor() parameters.forEach { - bucket.putIfAbsent(it.param, it.map(src)) + adaptor.putIfAbsent(it.name, it.map(src)) } - return function.call(bucket) + return function.call(adaptor) } } From e97f445b0692ecbcf92a4cad382a02dd72d47803 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:19:45 +0900 Subject: [PATCH 07/21] =?UTF-8?q?import=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt index 37f22a0..1231461 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt @@ -2,15 +2,11 @@ package com.mapk.kmapper import com.mapk.annotations.KGetterAlias import com.mapk.annotations.KGetterIgnore -import com.mapk.core.ArgumentBucket import com.mapk.core.KFunctionForCall -import com.mapk.core.getAliasOrName -import com.mapk.core.isUseDefaultArgument import com.mapk.core.toKConstructor import java.lang.IllegalArgumentException import kotlin.reflect.KClass import kotlin.reflect.KFunction -import kotlin.reflect.KParameter import kotlin.reflect.KProperty1 import kotlin.reflect.KVisibility import kotlin.reflect.full.findAnnotation From 4c25df598daec9d70e14debe4e2fc9a55db7712e Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:24:39 +0900 Subject: [PATCH 08/21] =?UTF-8?q?KFunction=E3=81=AE=E7=94=9F=E6=88=90?= =?UTF-8?q?=E6=96=B9=E6=B3=95=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/KMapper.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/KMapper.kt b/src/main/kotlin/com/mapk/kmapper/KMapper.kt index 5d89c6d..4eb305d 100644 --- a/src/main/kotlin/com/mapk/kmapper/KMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/KMapper.kt @@ -22,11 +22,11 @@ class KMapper private constructor( parameterNameConverter: (String) -> String ) { constructor(function: KFunction, parameterNameConverter: (String) -> String = { it }) : this( - KFunctionForCall(function), parameterNameConverter + KFunctionForCall(function, parameterNameConverter), parameterNameConverter ) constructor(clazz: KClass, parameterNameConverter: (String) -> String = { it }) : this( - clazz.toKConstructor(), parameterNameConverter + clazz.toKConstructor(parameterNameConverter), parameterNameConverter ) private val parameterMap: Map> = function.parameters From 9830590a363169917af96a6f4687103fd79326d8 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:30:01 +0900 Subject: [PATCH 09/21] =?UTF-8?q?=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=81=AE=E7=94=9F=E6=88=90=E6=96=B9=E5=BC=8F=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ParameterForMapの場合コンストラクタで処理が完結するようになったため、newInstanceメソッドは削除 --- .../kotlin/com/mapk/kmapper/ParameterForMap.kt | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt b/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt index 92c5a27..08f8293 100644 --- a/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt +++ b/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt @@ -1,6 +1,7 @@ package com.mapk.kmapper import com.mapk.core.EnumMapper +import com.mapk.core.ValueParameter import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap import kotlin.reflect.KClass @@ -8,11 +9,13 @@ import kotlin.reflect.KFunction import kotlin.reflect.KParameter import kotlin.reflect.full.isSuperclassOf -internal class ParameterForMap private constructor( - val param: KParameter, - private val clazz: KClass, +internal class ParameterForMap( + param: ValueParameter, private val parameterNameConverter: (String) -> String ) { + val name: String = param.name + private val clazz: KClass = param.requiredClazz + private val javaClazz: Class by lazy { clazz.java } @@ -52,12 +55,6 @@ internal class ParameterForMap private constructor( convertCache.putIfAbsent(valueClazz, processor) return processor.process(value) } - - companion object { - fun newInstance(param: KParameter, parameterNameConverter: (String) -> String): ParameterForMap<*> { - return ParameterForMap(param, param.type.classifier as KClass<*>, parameterNameConverter) - } - } } private sealed class ParameterProcessor { From c21a68bbe5dc76147b4a949dd815abda8a8392d8 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:30:29 +0900 Subject: [PATCH 10/21] =?UTF-8?q?adaptor=E3=81=AB=E5=AF=BE=E3=81=99?= =?UTF-8?q?=E3=82=8B=E3=83=90=E3=82=A4=E3=83=B3=E3=83=89=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E3=81=AB=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/KMapper.kt | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/KMapper.kt b/src/main/kotlin/com/mapk/kmapper/KMapper.kt index 4eb305d..86a9dd0 100644 --- a/src/main/kotlin/com/mapk/kmapper/KMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/KMapper.kt @@ -130,11 +130,11 @@ class KMapper private constructor( } private class ArgumentBinder(private val param: ParameterForMap<*>, private val javaGetter: Method) { - fun bindArgument(src: Any, bucket: ArgumentBucket) { + fun bindArgument(src: Any, adaptor: ArgumentAdaptor) { // 初期化済みであれば高コストな取得処理は行わない - if (!bucket.containsKey(param.param)) { + if (!adaptor.isInitialized(param.name)) { // javaGetterを呼び出す方が高速 - bucket.putIfAbsent(param.param, javaGetter.invoke(src)?.let { param.mapObject(it) }) + adaptor.putIfAbsent(param.name, javaGetter.invoke(src)?.let { param.mapObject(it) }) } } } From 574e5cb84c1800ffbdd1405a3b1cbfc6c84740f1 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:36:00 +0900 Subject: [PATCH 11/21] =?UTF-8?q?import=E6=95=B4=E7=90=86?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt b/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt index 08f8293..3842f67 100644 --- a/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt +++ b/src/main/kotlin/com/mapk/kmapper/ParameterForMap.kt @@ -6,7 +6,6 @@ import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap import kotlin.reflect.KClass import kotlin.reflect.KFunction -import kotlin.reflect.KParameter import kotlin.reflect.full.isSuperclassOf internal class ParameterForMap( From 03d1c9b63a638c4c0041e7d7270e97e74a47886a Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:36:15 +0900 Subject: [PATCH 12/21] =?UTF-8?q?=E3=83=95=E3=82=A9=E3=83=BC=E3=83=9E?= =?UTF-8?q?=E3=83=83=E3=83=88=E4=BF=AE=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 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt index 1231461..ec67db6 100644 --- a/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/BoundKMapper.kt @@ -32,8 +32,8 @@ class BoundKMapper private constructor( val srcPropertiesMap: Map> = src.memberProperties .filter { // アクセス可能かつignoreされてないもののみ抽出 - !(it.visibility != KVisibility.PUBLIC) - && it.getter.annotations.none { annotation -> annotation is KGetterIgnore } + !(it.visibility != KVisibility.PUBLIC) && + it.getter.annotations.none { annotation -> annotation is KGetterIgnore } }.associateBy { it.getter.findAnnotation()?.value ?: it.name } parameters = function.requiredParameters From f499eb20667d33d27149ed90abaa518f53c939bf Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:36:49 +0900 Subject: [PATCH 13/21] =?UTF-8?q?=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=81=AE=E5=88=9D=E6=9C=9F=E5=8C=96=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/KMapper.kt | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/KMapper.kt b/src/main/kotlin/com/mapk/kmapper/KMapper.kt index 86a9dd0..fb7aa04 100644 --- a/src/main/kotlin/com/mapk/kmapper/KMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/KMapper.kt @@ -29,11 +29,9 @@ class KMapper private constructor( clazz.toKConstructor(parameterNameConverter), parameterNameConverter ) - private val parameterMap: Map> = function.parameters - .filter { it.kind != KParameter.Kind.INSTANCE && !it.isUseDefaultArgument() } - .associate { - (parameterNameConverter(it.getAliasOrName()!!)) to ParameterForMap.newInstance(it, parameterNameConverter) - } + private val parameterMap: Map> = function.requiredParameters.associate { + it.name to ParameterForMap(it, parameterNameConverter) + } private val getCache: ConcurrentMap, List> = ConcurrentHashMap() From da0397434ac92eea1e97ff6cd3001d17a24f9b86 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:37:56 +0900 Subject: [PATCH 14/21] =?UTF-8?q?adaptor=E3=82=92=E7=94=A8=E3=81=84?= =?UTF-8?q?=E3=82=8B=E3=83=9E=E3=83=83=E3=83=97=E6=96=B9=E5=BC=8F=E3=81=AB?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/KMapper.kt | 53 ++++++++++----------- 1 file changed, 26 insertions(+), 27 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/KMapper.kt b/src/main/kotlin/com/mapk/kmapper/KMapper.kt index fb7aa04..3677df3 100644 --- a/src/main/kotlin/com/mapk/kmapper/KMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/KMapper.kt @@ -2,17 +2,14 @@ package com.mapk.kmapper import com.mapk.annotations.KGetterAlias import com.mapk.annotations.KGetterIgnore -import com.mapk.core.ArgumentBucket +import com.mapk.core.ArgumentAdaptor import com.mapk.core.KFunctionForCall -import com.mapk.core.getAliasOrName -import com.mapk.core.isUseDefaultArgument import com.mapk.core.toKConstructor import java.lang.reflect.Method import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentMap import kotlin.reflect.KClass import kotlin.reflect.KFunction -import kotlin.reflect.KParameter import kotlin.reflect.KVisibility import kotlin.reflect.full.memberProperties import kotlin.reflect.jvm.javaGetter @@ -35,13 +32,13 @@ class KMapper private constructor( private val getCache: ConcurrentMap, List> = ConcurrentHashMap() - private fun bindArguments(argumentBucket: ArgumentBucket, src: Any) { + private fun bindArguments(argumentAdaptor: ArgumentAdaptor, src: Any) { val clazz = src::class // キャッシュヒットしたら登録した内容に沿って取得処理を行う getCache[clazz]?.let { getters -> // 取得対象フィールドは十分絞り込んでいると考えられるため、終了判定は行わない - getters.forEach { it.bindArgument(src, argumentBucket) } + getters.forEach { it.bindArgument(src, argumentAdaptor) } return } @@ -66,7 +63,7 @@ class KMapper private constructor( val binder = ArgumentBinder(param, javaGetter) - binder.bindArgument(src, argumentBucket) + binder.bindArgument(src, argumentAdaptor) tempBinderArrayList.add(binder) // キャッシュの整合性を保つため、ここでは終了判定を行わない } @@ -74,56 +71,58 @@ class KMapper private constructor( getCache.putIfAbsent(clazz, tempBinderArrayList) } - private fun bindArguments(argumentBucket: ArgumentBucket, src: Map<*, *>) { + private fun bindArguments(argumentAdaptor: ArgumentAdaptor, src: Map<*, *>) { src.forEach { (key, value) -> parameterMap[key]?.let { param -> // 取得した内容がnullでなければ適切にmapする - argumentBucket.putIfAbsent(param.param, value?.let { param.mapObject(value) }) + argumentAdaptor.putIfAbsent(param.name, value?.let { param.mapObject(value) }) // 終了判定 - if (argumentBucket.isInitialized) return + if (argumentAdaptor.isFullInitialized()) return } } } - private fun bindArguments(argumentBucket: ArgumentBucket, srcPair: Pair<*, *>) { - parameterMap[srcPair.first.toString()]?.let { - argumentBucket.putIfAbsent(it.param, srcPair.second?.let { value -> it.mapObject(value) }) + private fun bindArguments(argumentAdaptor: ArgumentAdaptor, srcPair: Pair<*, *>) { + val key = srcPair.first.toString() + + parameterMap[key]?.let { + argumentAdaptor.putIfAbsent(key, srcPair.second?.let { value -> it.mapObject(value) }) } } fun map(srcMap: Map): T { - val bucket: ArgumentBucket = function.getArgumentBucket() - bindArguments(bucket, srcMap) + val adaptor: ArgumentAdaptor = function.getArgumentAdaptor() + bindArguments(adaptor, srcMap) - return function.call(bucket) + return function.call(adaptor) } fun map(srcPair: Pair): T { - val bucket: ArgumentBucket = function.getArgumentBucket() - bindArguments(bucket, srcPair) + val adaptor: ArgumentAdaptor = function.getArgumentAdaptor() + bindArguments(adaptor, srcPair) - return function.call(bucket) + return function.call(adaptor) } fun map(src: Any): T { - val bucket: ArgumentBucket = function.getArgumentBucket() - bindArguments(bucket, src) + val adaptor: ArgumentAdaptor = function.getArgumentAdaptor() + bindArguments(adaptor, src) - return function.call(bucket) + return function.call(adaptor) } fun map(vararg args: Any): T { - val bucket: ArgumentBucket = function.getArgumentBucket() + val adaptor: ArgumentAdaptor = function.getArgumentAdaptor() listOf(*args).forEach { arg -> when (arg) { - is Map<*, *> -> bindArguments(bucket, arg) - is Pair<*, *> -> bindArguments(bucket, arg) - else -> bindArguments(bucket, arg) + is Map<*, *> -> bindArguments(adaptor, arg) + is Pair<*, *> -> bindArguments(adaptor, arg) + else -> bindArguments(adaptor, arg) } } - return function.call(bucket) + return function.call(adaptor) } } From a9d061a43ec9784f5e0b5d4473c313de28147a72 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:38:41 +0900 Subject: [PATCH 15/21] =?UTF-8?q?KFunctionForCall=E3=81=AE=E5=88=9D?= =?UTF-8?q?=E6=9C=9F=E5=8C=96=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt b/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt index 871990d..33d2772 100644 --- a/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt @@ -20,11 +20,11 @@ class PlainKMapper private constructor( parameterNameConverter: (String) -> String ) { constructor(function: KFunction, parameterNameConverter: (String) -> String = { it }) : this( - KFunctionForCall(function), parameterNameConverter + KFunctionForCall(function, parameterNameConverter), parameterNameConverter ) constructor(clazz: KClass, parameterNameConverter: (String) -> String = { it }) : this( - clazz.toKConstructor(), parameterNameConverter + clazz.toKConstructor(parameterNameConverter), parameterNameConverter ) private val parameterMap: Map> = function.parameters From 82cb293c3c7cb9cc1b35a120943dfce466039d24 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:48:42 +0900 Subject: [PATCH 16/21] =?UTF-8?q?=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=81=AE=E7=94=9F=E6=88=90=E6=96=B9=E5=BC=8F=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit コンストラクタで処理が完結するようになったため、newInstanceメソッドは削除 --- .../com/mapk/kmapper/PlainParameterForMap.kt | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/PlainParameterForMap.kt b/src/main/kotlin/com/mapk/kmapper/PlainParameterForMap.kt index cc934e0..eab051e 100644 --- a/src/main/kotlin/com/mapk/kmapper/PlainParameterForMap.kt +++ b/src/main/kotlin/com/mapk/kmapper/PlainParameterForMap.kt @@ -1,16 +1,17 @@ package com.mapk.kmapper import com.mapk.core.EnumMapper +import com.mapk.core.ValueParameter import kotlin.reflect.KClass import kotlin.reflect.KFunction -import kotlin.reflect.KParameter import kotlin.reflect.full.isSuperclassOf -internal class PlainParameterForMap private constructor( - val param: KParameter, - private val clazz: KClass, +internal class PlainParameterForMap( + param: ValueParameter, private val parameterNameConverter: (String) -> String ) { + private val clazz: KClass = param.requiredClazz + private val javaClazz: Class by lazy { clazz.java } @@ -38,10 +39,4 @@ internal class PlainParameterForMap private constructor( else -> PlainKMapper(clazz, parameterNameConverter).map(value, PARAMETER_DUMMY) } } - - companion object { - fun newInstance(param: KParameter, parameterNameConverter: (String) -> String): PlainParameterForMap<*> { - return PlainParameterForMap(param, param.type.classifier as KClass<*>, parameterNameConverter) - } - } } From 0435be3b08be29ae980beca6d46197b06fd509d8 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:49:07 +0900 Subject: [PATCH 17/21] =?UTF-8?q?=E3=83=91=E3=83=A9=E3=83=A1=E3=83=BC?= =?UTF-8?q?=E3=82=BF=E3=81=AE=E7=94=9F=E6=88=90=E6=96=B9=E5=BC=8F=E3=82=92?= =?UTF-8?q?=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt b/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt index 33d2772..c72c74c 100644 --- a/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt @@ -27,12 +27,9 @@ class PlainKMapper private constructor( clazz.toKConstructor(parameterNameConverter), parameterNameConverter ) - private val parameterMap: Map> = function.parameters - .filter { it.kind != KParameter.Kind.INSTANCE && !it.isUseDefaultArgument() } - .associate { - (parameterNameConverter(it.getAliasOrName()!!)) to - PlainParameterForMap.newInstance(it, parameterNameConverter) - } + private val parameterMap: Map> = function.requiredParameters.associate { + it.name to PlainParameterForMap(it, parameterNameConverter) + } private fun bindArguments(argumentBucket: ArgumentBucket, src: Any) { src::class.memberProperties.forEach outer@{ property -> From fa1f27156f3659eaf3ab0dcf9c5df6b0e88d5576 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Wed, 6 May 2020 05:49:42 +0900 Subject: [PATCH 18/21] =?UTF-8?q?ArgumentAdaptor=E3=82=92=E5=88=A9?= =?UTF-8?q?=E7=94=A8=E3=81=97=E3=81=A6=E3=83=90=E3=82=A4=E3=83=B3=E3=83=89?= =?UTF-8?q?=E3=81=99=E3=82=8B=E5=BD=A2=E5=BC=8F=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/PlainKMapper.kt | 56 +++++++++---------- 1 file changed, 28 insertions(+), 28 deletions(-) diff --git a/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt b/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt index c72c74c..b1ab323 100644 --- a/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt +++ b/src/main/kotlin/com/mapk/kmapper/PlainKMapper.kt @@ -2,15 +2,12 @@ package com.mapk.kmapper import com.mapk.annotations.KGetterAlias import com.mapk.annotations.KGetterIgnore -import com.mapk.core.ArgumentBucket +import com.mapk.core.ArgumentAdaptor import com.mapk.core.KFunctionForCall -import com.mapk.core.getAliasOrName -import com.mapk.core.isUseDefaultArgument import com.mapk.core.toKConstructor import java.lang.reflect.Method import kotlin.reflect.KClass import kotlin.reflect.KFunction -import kotlin.reflect.KParameter import kotlin.reflect.KVisibility import kotlin.reflect.full.memberProperties import kotlin.reflect.jvm.javaGetter @@ -31,7 +28,7 @@ class PlainKMapper private constructor( it.name to PlainParameterForMap(it, parameterNameConverter) } - private fun bindArguments(argumentBucket: ArgumentBucket, src: Any) { + private fun bindArguments(argumentAdaptor: ArgumentAdaptor, src: Any) { src::class.memberProperties.forEach outer@{ property -> // propertyが公開されていない場合は処理を行わない if (property.visibility != KVisibility.PUBLIC) return@outer @@ -45,66 +42,69 @@ class PlainKMapper private constructor( if (it is KGetterIgnore) return@outer // ignoreされている場合は処理を行わない if (it is KGetterAlias) alias = it.value } + alias = alias ?: property.name - parameterMap[alias ?: property.name]?.let { + parameterMap[alias!!]?.let { // javaGetterを呼び出す方が高速 javaGetter.isAccessible = true - argumentBucket.putIfAbsent(it.param, javaGetter.invoke(src)?.let { value -> it.mapObject(value) }) + argumentAdaptor.putIfAbsent(alias!!, javaGetter.invoke(src)?.let { value -> it.mapObject(value) }) // 終了判定 - if (argumentBucket.isInitialized) return + if (argumentAdaptor.isFullInitialized()) return } } } - private fun bindArguments(argumentBucket: ArgumentBucket, src: Map<*, *>) { + private fun bindArguments(argumentAdaptor: ArgumentAdaptor, src: Map<*, *>) { src.forEach { (key, value) -> parameterMap[key]?.let { param -> // 取得した内容がnullでなければ適切にmapする - argumentBucket.putIfAbsent(param.param, value?.let { param.mapObject(value) }) + argumentAdaptor.putIfAbsent(key as String, value?.let { param.mapObject(value) }) // 終了判定 - if (argumentBucket.isInitialized) return + if (argumentAdaptor.isFullInitialized()) return } } } - private fun bindArguments(argumentBucket: ArgumentBucket, srcPair: Pair<*, *>) { - parameterMap[srcPair.first.toString()]?.let { - argumentBucket.putIfAbsent(it.param, srcPair.second?.let { value -> it.mapObject(value) }) + private fun bindArguments(argumentBucket: ArgumentAdaptor, srcPair: Pair<*, *>) { + val key = srcPair.first.toString() + + parameterMap[key]?.let { + argumentBucket.putIfAbsent(key, srcPair.second?.let { value -> it.mapObject(value) }) } } fun map(srcMap: Map): T { - val bucket: ArgumentBucket = function.getArgumentBucket() - bindArguments(bucket, srcMap) + val adaptor = function.getArgumentAdaptor() + bindArguments(adaptor, srcMap) - return function.call(bucket) + return function.call(adaptor) } fun map(srcPair: Pair): T { - val bucket: ArgumentBucket = function.getArgumentBucket() - bindArguments(bucket, srcPair) + val adaptor = function.getArgumentAdaptor() + bindArguments(adaptor, srcPair) - return function.call(bucket) + return function.call(adaptor) } fun map(src: Any): T { - val bucket: ArgumentBucket = function.getArgumentBucket() - bindArguments(bucket, src) + val adaptor = function.getArgumentAdaptor() + bindArguments(adaptor, src) - return function.call(bucket) + return function.call(adaptor) } fun map(vararg args: Any): T { - val bucket: ArgumentBucket = function.getArgumentBucket() + val adaptor = function.getArgumentAdaptor() listOf(*args).forEach { arg -> when (arg) { - is Map<*, *> -> bindArguments(bucket, arg) - is Pair<*, *> -> bindArguments(bucket, arg) - else -> bindArguments(bucket, arg) + is Map<*, *> -> bindArguments(adaptor, arg) + is Pair<*, *> -> bindArguments(adaptor, arg) + else -> bindArguments(adaptor, arg) } } - return function.call(bucket) + return function.call(adaptor) } } From c9766be29cba6061883448f840f82d6192b71a24 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sat, 9 May 2020 05:48:24 +0900 Subject: [PATCH 19/21] =?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 2ed2a7c..c938fa4 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.11") + api("com.github.ProjectMapK:Shared:0.12") // https://mvnrepository.com/artifact/org.junit.jupiter/junit-jupiter testImplementation(group = "org.junit.jupiter", name = "junit-jupiter", version = "5.6.2") { From 22393dea496fd072dc402c4d63d367be8d8a1791 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sat, 9 May 2020 05:49:37 +0900 Subject: [PATCH 20/21] =?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 c938fa4..feb3af9 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } group = "com.mapk" -version = "0.25" +version = "0.26" java { sourceCompatibility = JavaVersion.VERSION_1_8 From a2336c06637241a123adb01e8da9a60847791fcb Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sat, 9 May 2020 05:56:58 +0900 Subject: [PATCH 21/21] =?UTF-8?q?KParameterFlatten=E3=81=AE=E3=83=86?= =?UTF-8?q?=E3=82=B9=E3=83=88=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/mapk/kmapper/KParameterFlattenTest.kt | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 src/test/kotlin/com/mapk/kmapper/KParameterFlattenTest.kt diff --git a/src/test/kotlin/com/mapk/kmapper/KParameterFlattenTest.kt b/src/test/kotlin/com/mapk/kmapper/KParameterFlattenTest.kt new file mode 100644 index 0000000..844fd0c --- /dev/null +++ b/src/test/kotlin/com/mapk/kmapper/KParameterFlattenTest.kt @@ -0,0 +1,39 @@ +package com.mapk.kmapper + +import com.mapk.annotations.KParameterFlatten +import java.time.LocalDateTime +import org.junit.jupiter.api.Assertions.assertEquals +import org.junit.jupiter.api.DisplayName +import org.junit.jupiter.api.Test + +@DisplayName("KParameterFlattenテスト") +class KParameterFlattenTest { + data class InnerDst(val fooFoo: Int, val barBar: String) + data class Dst(@KParameterFlatten val bazBaz: InnerDst, val quxQux: LocalDateTime) + + private val expected = Dst(InnerDst(1, "str"), LocalDateTime.MIN) + + data class Src(val bazBazFooFoo: Int, val bazBazBarBar: String, val quxQux: LocalDateTime, val quuxQuux: Boolean) + private val src = Src(1, "str", LocalDateTime.MIN, false) + + @Test + @DisplayName("BoundKMapper") + fun boundKMapperTest() { + val result = BoundKMapper(::Dst, Src::class).map(src) + assertEquals(expected, result) + } + + @Test + @DisplayName("KMapper") + fun kMapperTest() { + val result = KMapper(::Dst).map(src) + assertEquals(expected, result) + } + + @Test + @DisplayName("PlainKMapper") + fun plainKMapperTest() { + val result = PlainKMapper(::Dst).map(src) + assertEquals(expected, result) + } +}