Skip to content

File tree

2 files changed

+27
-1
lines changed

2 files changed

+27
-1
lines changed

src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinModule.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,9 @@ class KotlinModule private constructor(
125125
nullIsSameAsDefault,
126126
useJavaDurationConversion
127127
))
128-
context.appendAnnotationIntrospector(KotlinNamesAnnotationIntrospector(cache, kotlinPropertyNameAsImplicitName))
128+
context.appendAnnotationIntrospector(
129+
KotlinNamesAnnotationIntrospector(cache, newStrictNullChecks, kotlinPropertyNameAsImplicitName)
130+
)
129131

130132
context.addDeserializers(KotlinDeserializers(cache, useJavaDurationConversion))
131133
context.addKeyDeserializers(KotlinKeyDeserializers)

src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.fasterxml.jackson.module.kotlin
22

33
import com.fasterxml.jackson.annotation.JsonProperty
4+
import com.fasterxml.jackson.annotation.JsonSetter
5+
import com.fasterxml.jackson.annotation.Nulls
46
import com.fasterxml.jackson.databind.JavaType
57
import com.fasterxml.jackson.databind.cfg.MapperConfig
68
import com.fasterxml.jackson.databind.introspect.Annotated
@@ -12,8 +14,10 @@ import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector
1214
import com.fasterxml.jackson.databind.introspect.PotentialCreator
1315
import java.lang.reflect.Constructor
1416
import java.util.Locale
17+
import kotlin.collections.getOrNull
1518
import kotlin.reflect.KClass
1619
import kotlin.reflect.KFunction
20+
import kotlin.reflect.KParameter
1721
import kotlin.reflect.full.hasAnnotation
1822
import kotlin.reflect.full.memberProperties
1923
import kotlin.reflect.full.primaryConstructor
@@ -22,6 +26,7 @@ import kotlin.reflect.jvm.javaType
2226

2327
internal 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
113137
private fun AnnotatedClass.creatableKotlinClass(): KClass<*>? = annotated
114138
.takeIf { it.isKotlinClass() && !it.isEnum }

0 commit comments

Comments
 (0)