Skip to content

Commit cf5a405

Browse files
authoredOct 18, 2021
Merge pull request #449 from k163377/optimize_instrospector
Optimize `KotlinAnnotationIntrospector#AnnotatedMethod.hasRequiredMarker` method.
2 parents de52ac5 + 653f672 commit cf5a405

File tree

2 files changed

+29
-44
lines changed

2 files changed

+29
-44
lines changed
 

‎release-notes/CREDITS-2.x

+1
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ Contributors:
1515

1616
wrongwrong (k163377@github)
1717
* #456: Refactor KNAI.findImplicitPropertyName()
18+
* #449: Refactor AnnotatedMethod.hasRequiredMarker()
1819
(2.13.NEXT)
1920

2021
Dmitri Domanine (novtor@github)

‎src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinAnnotationIntrospector.kt

+28-44
Original file line numberDiff line numberDiff line change
@@ -97,58 +97,39 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon
9797
return (this.annotations.firstOrNull { it.annotationClass.java == JsonProperty::class.java } as? JsonProperty)?.required
9898
}
9999

100-
private fun AnnotatedMethod.hasRequiredMarker(): Boolean? {
101-
// This could be a setter or a getter of a class property or
102-
// a setter-like/getter-like method.
103-
val paramGetter = this.getCorrespondingGetter()
104-
if (paramGetter != null) {
105-
val byAnnotation = paramGetter.javaGetter?.isRequiredByAnnotation()
106-
return requiredAnnotationOrNullability(byAnnotation, paramGetter.returnType.isRequired())
107-
}
108-
109-
val paramSetter = this.getCorrespondingSetter()
110-
if (paramSetter != null) {
111-
val byAnnotation = paramSetter.javaMethod?.isRequiredByAnnotation()
112-
return requiredAnnotationOrNullability(byAnnotation, paramSetter.isMethodParameterRequired(0))
113-
}
114-
115-
// Is the member method a regular method of the data class or
116-
val method = this.member.kotlinFunction
117-
if (method != null) {
118-
val byAnnotation = method.javaMethod?.isRequiredByAnnotation()
119-
if (method.isGetterLike()) {
120-
return requiredAnnotationOrNullability(byAnnotation, method.returnType.isRequired())
121-
}
122-
123-
if (method.isSetterLike()) {
124-
return requiredAnnotationOrNullability(byAnnotation, method.isMethodParameterRequired(0))
100+
// Since Kotlin's property has the same Type for each field, getter, and setter,
101+
// nullability can be determined from the returnType of KProperty.
102+
private fun KProperty1<*, *>.isRequiredByNullability() = returnType.isRequired()
103+
104+
// This could be a setter or a getter of a class property or
105+
// a setter-like/getter-like method.
106+
private fun AnnotatedMethod.hasRequiredMarker(): Boolean? = this.getRequiredMarkerFromCorrespondingAccessor()
107+
?: this.member.getRequiredMarkerFromAccessorLikeMethod()
108+
109+
private fun AnnotatedMethod.getRequiredMarkerFromCorrespondingAccessor(): Boolean? {
110+
member.declaringClass.kotlin.declaredMemberProperties.forEach { kProperty ->
111+
if (kProperty.javaGetter == this.member || (kProperty as? KMutableProperty1)?.javaSetter == this.member) {
112+
val byAnnotation = this.member.isRequiredByAnnotation()
113+
val byNullability = kProperty.isRequiredByNullability()
114+
return requiredAnnotationOrNullability(byAnnotation, byNullability)
125115
}
126116
}
127-
128117
return null
129118
}
130119

131-
private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1
132-
private fun KFunction<*>.isSetterLike(): Boolean =
133-
parameters.size == 2 && returnType == Unit::class.createType()
134-
135-
136-
private fun AnnotatedMethod.getCorrespondingGetter(): KProperty1<out Any, Any?>? =
137-
member.declaringClass.kotlin.declaredMemberProperties.find {
138-
it.getter.javaMethod == this.member
139-
}
140-
141-
@Suppress("UNCHECKED_CAST")
142-
private fun AnnotatedMethod.getCorrespondingSetter(): KMutableProperty1.Setter<out Any, Any?>? {
143-
val mutableProperty = member.declaringClass.kotlin.declaredMemberProperties.find {
144-
when (it) {
145-
is KMutableProperty1 -> it.javaSetter == this.member
146-
else -> false
147-
}
120+
// Is the member method a regular method of the data class or
121+
private fun Method.getRequiredMarkerFromAccessorLikeMethod(): Boolean? = this.kotlinFunction?.let { method ->
122+
val byAnnotation = this.isRequiredByAnnotation()
123+
return when {
124+
method.isGetterLike() -> requiredAnnotationOrNullability(byAnnotation, method.returnType.isRequired())
125+
method.isSetterLike() -> requiredAnnotationOrNullability(byAnnotation, method.isMethodParameterRequired(0))
126+
else -> null
148127
}
149-
return (mutableProperty as? KMutableProperty1<out Any, Any?>)?.setter
150128
}
151129

130+
private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1
131+
private fun KFunction<*>.isSetterLike(): Boolean = parameters.size == 2 && returnType == UNIT_TYPE
132+
152133
private fun AnnotatedParameter.hasRequiredMarker(): Boolean? {
153134
val member = this.member
154135
val byAnnotation = this.getAnnotation(JsonProperty::class.java)?.required
@@ -185,4 +166,7 @@ internal class KotlinAnnotationIntrospector(private val context: Module.SetupCon
185166

186167
private fun KType.isRequired(): Boolean = !isMarkedNullable
187168

169+
companion object {
170+
val UNIT_TYPE: KType = Unit::class.createType()
171+
}
188172
}

0 commit comments

Comments
 (0)
Please sign in to comment.