From db9352e832f7c64cb95de015dd6e752b49c87f4b Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 23 May 2021 07:46:12 +0900 Subject: [PATCH 01/10] optimize getting hasRequiredMarker process on CorrespondingAccessor --- .../kotlin/KotlinAnnotationIntrospector.kt | 41 ++++++++----------- 1 file changed, 16 insertions(+), 25 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index 588ed2f09..6f8b45605 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -13,7 +13,6 @@ import java.lang.reflect.Field import java.lang.reflect.Method import kotlin.reflect.KFunction import kotlin.reflect.KMutableProperty1 -import kotlin.reflect.KProperty1 import kotlin.reflect.KType import kotlin.reflect.full.createType import kotlin.reflect.full.declaredMemberProperties @@ -100,17 +99,7 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon private fun AnnotatedMethod.hasRequiredMarker(): Boolean? { // This could be a setter or a getter of a class property or // a setter-like/getter-like method. - val paramGetter = this.getCorrespondingGetter() - if (paramGetter != null) { - val byAnnotation = paramGetter.javaGetter?.isRequiredByAnnotation() - return requiredAnnotationOrNullability(byAnnotation, paramGetter.returnType.isRequired()) - } - - val paramSetter = this.getCorrespondingSetter() - if (paramSetter != null) { - val byAnnotation = paramSetter.javaMethod?.isRequiredByAnnotation() - return requiredAnnotationOrNullability(byAnnotation, paramSetter.isMethodParameterRequired(0)) - } + this.getFromCorrespondingAccessor()?.let { return it } // Is the member method a regular method of the data class or val method = this.member.kotlinFunction @@ -132,21 +121,23 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon private fun KFunction<*>.isSetterLike(): Boolean = parameters.size == 2 && returnType == Unit::class.createType() + private fun AnnotatedMethod.getFromCorrespondingAccessor(): Boolean? { + member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty1 -> + kProperty1.javaGetter + ?.takeIf { it == this.member } + ?.let { + val byAnnotation = it.isRequiredByAnnotation() + return requiredAnnotationOrNullability(byAnnotation, kProperty1.returnType.isRequired()) + } - private fun AnnotatedMethod.getCorrespondingGetter(): KProperty1? = - member.declaringClass.kotlin.declaredMemberProperties.find { - it.getter.javaMethod == this.member - } - - @Suppress("UNCHECKED_CAST") - private fun AnnotatedMethod.getCorrespondingSetter(): KMutableProperty1.Setter? { - val mutableProperty = member.declaringClass.kotlin.declaredMemberProperties.find { - when (it) { - is KMutableProperty1 -> it.javaSetter == this.member - else -> false - } + (kProperty1 as? KMutableProperty1)?.javaSetter + ?.takeIf { it == this.member } + ?.let { + val byAnnotation = it.isRequiredByAnnotation() + return requiredAnnotationOrNullability(byAnnotation, kProperty1.setter.isMethodParameterRequired(0)) + } } - return (mutableProperty as? KMutableProperty1)?.setter + return null } private fun AnnotatedParameter.hasRequiredMarker(): Boolean? { From eb0ebaed24b05a727163a5bd791d220b85ee3017 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 23 May 2021 07:50:17 +0900 Subject: [PATCH 02/10] kotlinize --- .../kotlin/KotlinAnnotationIntrospector.kt | 27 +++++++------------ 1 file changed, 10 insertions(+), 17 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index 6f8b45605..d1d222136 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -96,27 +96,20 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon return (this.annotations.firstOrNull { it.annotationClass.java == JsonProperty::class.java } as? JsonProperty)?.required } - private fun AnnotatedMethod.hasRequiredMarker(): Boolean? { - // This could be a setter or a getter of a class property or - // a setter-like/getter-like method. - this.getFromCorrespondingAccessor()?.let { return it } - - // Is the member method a regular method of the data class or - val method = this.member.kotlinFunction - if (method != null) { + // This could be a setter or a getter of a class property or + // a setter-like/getter-like method. + private fun AnnotatedMethod.hasRequiredMarker(): Boolean? = this.getFromCorrespondingAccessor() + ?: this.member.kotlinFunction?.let { method -> // Is the member method a regular method of the data class or val byAnnotation = method.javaMethod?.isRequiredByAnnotation() - if (method.isGetterLike()) { - return requiredAnnotationOrNullability(byAnnotation, method.returnType.isRequired()) - } - - if (method.isSetterLike()) { - return requiredAnnotationOrNullability(byAnnotation, method.isMethodParameterRequired(0)) + when { + method.isGetterLike() -> + requiredAnnotationOrNullability(byAnnotation, method.returnType.isRequired()) + method.isSetterLike() -> + requiredAnnotationOrNullability(byAnnotation, method.isMethodParameterRequired(0)) + else -> null } } - return null - } - private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1 private fun KFunction<*>.isSetterLike(): Boolean = parameters.size == 2 && returnType == Unit::class.createType() From d44db98dd3fc6d8c5a7eb4da819d829431285b50 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 23 May 2021 11:33:33 +0900 Subject: [PATCH 03/10] Fixed the order of definitions to the order in which they are used --- .../jackson/module/kotlin/KotlinAnnotationIntrospector.kt | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index d1d222136..7110758be 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -110,10 +110,6 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon } } - private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1 - private fun KFunction<*>.isSetterLike(): Boolean = - parameters.size == 2 && returnType == Unit::class.createType() - private fun AnnotatedMethod.getFromCorrespondingAccessor(): Boolean? { member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty1 -> kProperty1.javaGetter @@ -133,6 +129,10 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon return null } + private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1 + private fun KFunction<*>.isSetterLike(): Boolean = + parameters.size == 2 && returnType == Unit::class.createType() + private fun AnnotatedParameter.hasRequiredMarker(): Boolean? { val member = this.member val byAnnotation = this.getAnnotation(JsonProperty::class.java)?.required From c2b68ba66f1967cdd488d41986f92df82c2a27c6 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 23 May 2021 11:36:37 +0900 Subject: [PATCH 04/10] fix method name --- .../jackson/module/kotlin/KotlinAnnotationIntrospector.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index 7110758be..e62281ca1 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -98,7 +98,7 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon // This could be a setter or a getter of a class property or // a setter-like/getter-like method. - private fun AnnotatedMethod.hasRequiredMarker(): Boolean? = this.getFromCorrespondingAccessor() + private fun AnnotatedMethod.hasRequiredMarker(): Boolean? = this.getRequiredMarkerFromCorrespondingAccessor() ?: this.member.kotlinFunction?.let { method -> // Is the member method a regular method of the data class or val byAnnotation = method.javaMethod?.isRequiredByAnnotation() when { @@ -110,7 +110,7 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon } } - private fun AnnotatedMethod.getFromCorrespondingAccessor(): Boolean? { + private fun AnnotatedMethod.getRequiredMarkerFromCorrespondingAccessor(): Boolean? { member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty1 -> kProperty1.javaGetter ?.takeIf { it == this.member } From 5fff4463ab7904b2f0dcf1d8a9ff6752d2a24bb8 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 23 May 2021 11:40:31 +0900 Subject: [PATCH 05/10] split to method --- .../kotlin/KotlinAnnotationIntrospector.kt | 21 ++++++++++--------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index e62281ca1..3506c3c64 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -99,16 +99,7 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon // This could be a setter or a getter of a class property or // a setter-like/getter-like method. private fun AnnotatedMethod.hasRequiredMarker(): Boolean? = this.getRequiredMarkerFromCorrespondingAccessor() - ?: this.member.kotlinFunction?.let { method -> // Is the member method a regular method of the data class or - val byAnnotation = method.javaMethod?.isRequiredByAnnotation() - when { - method.isGetterLike() -> - requiredAnnotationOrNullability(byAnnotation, method.returnType.isRequired()) - method.isSetterLike() -> - requiredAnnotationOrNullability(byAnnotation, method.isMethodParameterRequired(0)) - else -> null - } - } + ?: this.member.kotlinFunction?.getRequiredMarkerFromAccessorLikeMethod() private fun AnnotatedMethod.getRequiredMarkerFromCorrespondingAccessor(): Boolean? { member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty1 -> @@ -129,6 +120,16 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon return null } + // Is the member method a regular method of the data class or + private fun KFunction<*>.getRequiredMarkerFromAccessorLikeMethod(): Boolean? { + val byAnnotation = this.javaMethod?.isRequiredByAnnotation() + return when { + this.isGetterLike() -> requiredAnnotationOrNullability(byAnnotation, this.returnType.isRequired()) + this.isSetterLike() -> requiredAnnotationOrNullability(byAnnotation, this.isMethodParameterRequired(0)) + else -> null + } + } + private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1 private fun KFunction<*>.isSetterLike(): Boolean = parameters.size == 2 && returnType == Unit::class.createType() From ff09bc18d563e3cbf14644106bcc0fc2b4fc7385 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 23 May 2021 11:55:17 +0900 Subject: [PATCH 06/10] cache Unit::class.createType() --- .../jackson/module/kotlin/KotlinAnnotationIntrospector.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index 3506c3c64..409c26873 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -131,8 +131,7 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon } private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1 - private fun KFunction<*>.isSetterLike(): Boolean = - parameters.size == 2 && returnType == Unit::class.createType() + private fun KFunction<*>.isSetterLike(): Boolean = parameters.size == 2 && returnType == UNIT_TYPE private fun AnnotatedParameter.hasRequiredMarker(): Boolean? { val member = this.member @@ -170,4 +169,7 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon private fun KType.isRequired(): Boolean = !isMarkedNullable + companion object { + val UNIT_TYPE: KType = Unit::class.createType() + } } From ca15dedce724dc511defd734e25e6c07e40b1333 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 23 May 2021 12:52:12 +0900 Subject: [PATCH 07/10] optimize for nullability --- .../module/kotlin/KotlinAnnotationIntrospector.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index 409c26873..6db295902 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -99,7 +99,7 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon // This could be a setter or a getter of a class property or // a setter-like/getter-like method. private fun AnnotatedMethod.hasRequiredMarker(): Boolean? = this.getRequiredMarkerFromCorrespondingAccessor() - ?: this.member.kotlinFunction?.getRequiredMarkerFromAccessorLikeMethod() + ?: this.member.getRequiredMarkerFromAccessorLikeMethod() private fun AnnotatedMethod.getRequiredMarkerFromCorrespondingAccessor(): Boolean? { member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty1 -> @@ -121,11 +121,11 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon } // Is the member method a regular method of the data class or - private fun KFunction<*>.getRequiredMarkerFromAccessorLikeMethod(): Boolean? { - val byAnnotation = this.javaMethod?.isRequiredByAnnotation() + private fun Method.getRequiredMarkerFromAccessorLikeMethod(): Boolean? = this.kotlinFunction?.let { method -> + val byAnnotation = this.isRequiredByAnnotation() return when { - this.isGetterLike() -> requiredAnnotationOrNullability(byAnnotation, this.returnType.isRequired()) - this.isSetterLike() -> requiredAnnotationOrNullability(byAnnotation, this.isMethodParameterRequired(0)) + method.isGetterLike() -> requiredAnnotationOrNullability(byAnnotation, method.returnType.isRequired()) + method.isSetterLike() -> requiredAnnotationOrNullability(byAnnotation, method.isMethodParameterRequired(0)) else -> null } } From 26737663062d0e5c4f67a8ddd5fc8096b77cd0ad Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 30 May 2021 03:44:25 +0900 Subject: [PATCH 08/10] fix name --- .../module/kotlin/KotlinAnnotationIntrospector.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index 6db295902..0fb8879c3 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -102,19 +102,19 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon ?: this.member.getRequiredMarkerFromAccessorLikeMethod() private fun AnnotatedMethod.getRequiredMarkerFromCorrespondingAccessor(): Boolean? { - member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty1 -> - kProperty1.javaGetter + member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty -> + kProperty.javaGetter ?.takeIf { it == this.member } ?.let { val byAnnotation = it.isRequiredByAnnotation() - return requiredAnnotationOrNullability(byAnnotation, kProperty1.returnType.isRequired()) + return requiredAnnotationOrNullability(byAnnotation, kProperty.returnType.isRequired()) } - (kProperty1 as? KMutableProperty1)?.javaSetter + (kProperty as? KMutableProperty1)?.javaSetter ?.takeIf { it == this.member } ?.let { val byAnnotation = it.isRequiredByAnnotation() - return requiredAnnotationOrNullability(byAnnotation, kProperty1.setter.isMethodParameterRequired(0)) + return requiredAnnotationOrNullability(byAnnotation, kProperty.setter.isMethodParameterRequired(0)) } } return null From 64a748c6abf5c411812edd1672172ba4c876e8c1 Mon Sep 17 00:00:00 2001 From: wrongwrong Date: Sun, 30 May 2021 03:49:43 +0900 Subject: [PATCH 09/10] simplification --- .../kotlin/KotlinAnnotationIntrospector.kt | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt index 0fb8879c3..918c91d8b 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt @@ -13,6 +13,7 @@ import java.lang.reflect.Field import java.lang.reflect.Method import kotlin.reflect.KFunction import kotlin.reflect.KMutableProperty1 +import kotlin.reflect.KProperty1 import kotlin.reflect.KType import kotlin.reflect.full.createType import kotlin.reflect.full.declaredMemberProperties @@ -96,6 +97,10 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon return (this.annotations.firstOrNull { it.annotationClass.java == JsonProperty::class.java } as? JsonProperty)?.required } + // Since Kotlin's property has the same Type for each field, getter, and setter, + // nullability can be determined from the returnType of KProperty. + private fun KProperty1<*, *>.isRequiredByNullability() = returnType.isRequired() + // This could be a setter or a getter of a class property or // a setter-like/getter-like method. private fun AnnotatedMethod.hasRequiredMarker(): Boolean? = this.getRequiredMarkerFromCorrespondingAccessor() @@ -103,19 +108,11 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon private fun AnnotatedMethod.getRequiredMarkerFromCorrespondingAccessor(): Boolean? { member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty -> - kProperty.javaGetter - ?.takeIf { it == this.member } - ?.let { - val byAnnotation = it.isRequiredByAnnotation() - return requiredAnnotationOrNullability(byAnnotation, kProperty.returnType.isRequired()) - } - - (kProperty as? KMutableProperty1)?.javaSetter - ?.takeIf { it == this.member } - ?.let { - val byAnnotation = it.isRequiredByAnnotation() - return requiredAnnotationOrNullability(byAnnotation, kProperty.setter.isMethodParameterRequired(0)) - } + if (kProperty.javaGetter == this.member || (kProperty as? KMutableProperty1)?.javaSetter == this.member) { + val byAnnotation = this.member.isRequiredByAnnotation() + val byNullability = kProperty.isRequiredByNullability() + return requiredAnnotationOrNullability(byAnnotation, byNullability) + } } return null } From 653f6725ac18708cab3fe699ff5ba649679fe107 Mon Sep 17 00:00:00 2001 From: Drew Stephens Date: Mon, 18 Oct 2021 09:40:19 -0400 Subject: [PATCH 10/10] Add credit --- release-notes/CREDITS-2.x | 1 + 1 file changed, 1 insertion(+) diff --git a/release-notes/CREDITS-2.x b/release-notes/CREDITS-2.x index b1d899edc..d0216d754 100644 --- a/release-notes/CREDITS-2.x +++ b/release-notes/CREDITS-2.x @@ -15,6 +15,7 @@ Contributors: wrongwrong (k163377@github) * #456: Refactor KNAI.findImplicitPropertyName() +* #449: Refactor AnnotatedMethod.hasRequiredMarker() (2.13.NEXT) Dmitri Domanine (novtor@github)