11package com.fasterxml.jackson.module.kotlin
22
33import com.fasterxml.jackson.annotation.JsonProperty
4+ import com.fasterxml.jackson.annotation.JsonSetter
5+ import com.fasterxml.jackson.annotation.Nulls
46import com.fasterxml.jackson.databind.JavaType
57import com.fasterxml.jackson.databind.cfg.MapperConfig
68import com.fasterxml.jackson.databind.introspect.Annotated
@@ -12,8 +14,10 @@ import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector
1214import com.fasterxml.jackson.databind.introspect.PotentialCreator
1315import java.lang.reflect.Constructor
1416import java.util.Locale
17+ import kotlin.collections.getOrNull
1518import kotlin.reflect.KClass
1619import kotlin.reflect.KFunction
20+ import kotlin.reflect.KParameter
1721import kotlin.reflect.full.hasAnnotation
1822import kotlin.reflect.full.memberProperties
1923import kotlin.reflect.full.primaryConstructor
@@ -22,6 +26,7 @@ import kotlin.reflect.jvm.javaType
2226
2327internal class KotlinNamesAnnotationIntrospector (
2428 private val cache : ReflectionCache ,
29+ private val strictNullChecks : Boolean ,
2530 private val kotlinPropertyNameAsImplicitName : Boolean
2631) : NopAnnotationIntrospector() {
2732 private fun getterNameFromJava (member : AnnotatedMethod ): String? {
@@ -81,6 +86,18 @@ internal class KotlinNamesAnnotationIntrospector(
8186 ?.let { config.constructType(it) }
8287 } ? : baseType
8388
89+ override fun findSetterInfo (ann : Annotated ): JsonSetter .Value = ann.takeIf { strictNullChecks }
90+ ?.let { _ ->
91+ findKotlinParameter(ann)?.let { param ->
92+ if (param.requireStrictNullCheck(ann.type)) {
93+ JsonSetter .Value .forContentNulls(Nulls .FAIL )
94+ } else {
95+ null
96+ }
97+ }
98+ }
99+ ? : super .findSetterInfo(ann)
100+
84101 override fun findDefaultCreator (
85102 config : MapperConfig <* >,
86103 valueClass : AnnotatedClass ,
@@ -109,6 +126,13 @@ internal class KotlinNamesAnnotationIntrospector(
109126 ?.let { cache.findKotlinParameter(it) }
110127}
111128
129+ private fun KParameter.markedNonNullAt (index : Int ) = type.arguments.getOrNull(index)?.type?.isMarkedNullable == false
130+
131+ private fun KParameter.requireStrictNullCheck (type : JavaType ): Boolean =
132+ ((type.isArrayType || type.isCollectionLikeType) && this .markedNonNullAt(0 )) ||
133+ (type.isMapLikeType && this .markedNonNullAt(1 ))
134+
135+
112136// If it is not a Kotlin class or an Enum, Creator is not used
113137private fun AnnotatedClass.creatableKotlinClass (): KClass <* >? = annotated
114138 .takeIf { it.isKotlinClass() && ! it.isEnum }
0 commit comments