Skip to content

Commit 158f783

Browse files
authored
Merge pull request #16 from ProjectMapK/ser-only-property
Serialize only Kotlin property.
2 parents a8323d3 + bf2abce commit 158f783

File tree

6 files changed

+62
-42
lines changed

6 files changed

+62
-42
lines changed

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

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -177,13 +177,11 @@ internal class KotlinAnnotationIntrospector(
177177
private fun Method.getRequiredMarkerFromAccessorLikeMethod(): Boolean? = this.kotlinFunction?.let { method ->
178178
val byAnnotation = this.isRequiredByAnnotation()
179179
return when {
180-
method.isGetterLike() -> requiredAnnotationOrNullability(byAnnotation, method.returnType.isRequired())
181180
method.isSetterLike() -> requiredAnnotationOrNullability(byAnnotation, method.isMethodParameterRequired(0))
182181
else -> null
183182
}
184183
}
185184

186-
private fun KFunction<*>.isGetterLike(): Boolean = parameters.size == 1
187185
private fun KFunction<*>.isSetterLike(): Boolean = parameters.size == 2 && returnType == UNIT_TYPE
188186

189187
private fun AnnotatedParameter.hasRequiredMarker(): Boolean? {
@@ -220,8 +218,6 @@ internal class KotlinAnnotationIntrospector(
220218
!(isPrimitive && !context.isEnabled(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES))
221219
}
222220

223-
private fun KType.isRequired(): Boolean = !isMarkedNullable
224-
225221
companion object {
226222
val UNIT_TYPE: KType = Unit::class.createType()
227223
}

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

Lines changed: 27 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,17 @@ package com.fasterxml.jackson.module.kotlin
22

33
import com.fasterxml.jackson.annotation.JsonCreator
44
import com.fasterxml.jackson.annotation.JsonProperty
5-
import com.fasterxml.jackson.databind.PropertyName
6-
import com.fasterxml.jackson.databind.cfg.MapperConfig
75
import com.fasterxml.jackson.databind.introspect.Annotated
86
import com.fasterxml.jackson.databind.introspect.AnnotatedConstructor
97
import com.fasterxml.jackson.databind.introspect.AnnotatedField
108
import com.fasterxml.jackson.databind.introspect.AnnotatedMember
119
import com.fasterxml.jackson.databind.introspect.AnnotatedMethod
1210
import com.fasterxml.jackson.databind.introspect.AnnotatedParameter
1311
import com.fasterxml.jackson.databind.introspect.NopAnnotationIntrospector
14-
import com.fasterxml.jackson.databind.util.BeanUtil
12+
import kotlinx.metadata.jvm.fieldSignature
13+
import kotlinx.metadata.jvm.getterSignature
1514
import java.lang.reflect.Constructor
1615
import java.lang.reflect.Method
17-
import java.util.Locale
1816
import kotlin.reflect.KClass
1917
import kotlin.reflect.KFunction
2018
import kotlin.reflect.KParameter
@@ -30,35 +28,35 @@ import kotlin.reflect.jvm.kotlinFunction
3028
internal class KotlinNamesAnnotationIntrospector(val module: KotlinModule, val cache: ReflectionCache, val ignoredClassesForImplyingJsonCreator: Set<KClass<*>>) : NopAnnotationIntrospector() {
3129
// since 2.4
3230
override fun findImplicitPropertyName(member: AnnotatedMember): String? = when (member) {
33-
is AnnotatedMethod -> if (member.name.contains('-') && member.parameterCount == 0) {
34-
when {
35-
member.name.startsWith("get") -> member.name.substringAfter("get")
36-
member.name.startsWith("is") -> member.name.substringAfter("is")
37-
else -> null
38-
}?.replaceFirstChar { it.lowercase(Locale.getDefault()) }?.substringBefore('-')
39-
} else null
31+
is AnnotatedMethod -> member.annotated.declaringClass.toKmClass()?.let { kmClass ->
32+
val methodSignature = member.annotated.toSignature()
33+
34+
kmClass.properties.find { it.getterSignature == methodSignature }?.name
35+
}
36+
is AnnotatedField -> member.annotated.declaringClass.toKmClass()?.let { kmClass ->
37+
val fieldSignature = member.annotated.toSignature()
38+
39+
kmClass.properties.find { it.fieldSignature == fieldSignature }?.name
40+
}
4041
is AnnotatedParameter -> findKotlinParameterName(member)
4142
else -> null
4243
}
4344

44-
// since 2.11: support Kotlin's way of handling "isXxx" backed properties where
45-
// logical property name needs to remain "isXxx" and not become "xxx" as with Java Beans
46-
// (see https://kotlinlang.org/docs/reference/java-to-kotlin-interop.html and
47-
// https://github.com/FasterXML/jackson-databind/issues/2527
48-
// for details)
49-
override fun findRenameByField(
50-
config: MapperConfig<*>,
51-
field: AnnotatedField,
52-
implName: PropertyName
53-
): PropertyName? {
54-
val origSimple = implName.simpleName
55-
if (field.declaringClass.isKotlinClass() && origSimple.startsWith("is")) {
56-
val mangledName: String? = BeanUtil.stdManglePropertyName(origSimple, 2)
57-
if ((mangledName != null) && !mangledName.equals(origSimple)) {
58-
return PropertyName.construct(mangledName)
59-
}
60-
}
61-
return null
45+
// If it is not a property on Kotlin, it is not used to serialization
46+
override fun findPropertyAccess(ann: Annotated): JsonProperty.Access? = when (ann) {
47+
is AnnotatedMethod ->
48+
ann.annotated
49+
.takeIf { it.parameters.isEmpty() } // Ignore target is only getter
50+
?.let { method ->
51+
method.declaringClass.toKmClass()?.let { kmClass ->
52+
val methodSignature = method.toSignature()
53+
54+
JsonProperty.Access.WRITE_ONLY.takeIf {
55+
kmClass.properties.none { it.getterSignature == methodSignature }
56+
}
57+
}
58+
}
59+
else -> null
6260
}
6361

6462
@Suppress("UNCHECKED_CAST")
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.fasterxml.jackson.module.kotlin._integration.ser
2+
3+
import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
4+
import org.junit.jupiter.api.Assertions.assertEquals
5+
import org.junit.jupiter.api.Test
6+
7+
class PropertySerializeTest {
8+
data class Src(
9+
// Serialized by property name in Kotlin even when not following getter naming conventions
10+
@get:JvmName("renamed") val fooFoo: Int,
11+
// https://github.com/FasterXML/jackson-module-kotlin/issues/600
12+
val isBar: Boolean,
13+
val bar: String,
14+
// https://github.com/FasterXML/jackson-module-kotlin/pull/451
15+
@Suppress("PropertyName") val `baz-baz`: String,
16+
// https://github.com/FasterXML/jackson-module-kotlin/issues/503
17+
val nQux: Int
18+
) {
19+
// Ignored because it is not a Kotlin property
20+
fun getZzz(): Int = -1
21+
}
22+
23+
@Test
24+
fun test() {
25+
assertEquals(
26+
"""{"fooFoo":0,"isBar":true,"bar":"bar","baz-baz":"baz-baz","nQux":1}""",
27+
jacksonObjectMapper().writeValueAsString(Src(0, true, "bar", "baz-baz", 1))
28+
)
29+
}
30+
}

src/test/kotlin/com/fasterxml/jackson/module/kotlin/_ported/test/PropertyRequirednessTests.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ class TestPropertyRequiredness {
4141
"c".isOptionalForDeserializationOf(testClass, mapper)
4242
"d".isOptionalForDeserializationOf(testClass, mapper)
4343

44-
"e".isRequiredForSerializationOf(testClass, mapper)
44+
"e".isOptionalForSerializationOf(testClass, mapper)
4545
"f".isOptionalForSerializationOf(testClass, mapper)
4646

4747
"g".isRequiredForDeserializationOf(testClass, mapper)

src/test/kotlin/com/fasterxml/jackson/module/kotlin/_ported/test/github/Github464.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ class Github464 {
3333
abstract class AbstractGetter<T> {
3434
abstract val qux: T
3535

36-
fun <T> getPlugh() = qux
36+
val plugh: T get() = qux
3737
}
3838
interface IGetter<T> {
3939
val quux: T
4040

41-
fun <T> getXyzzy() = quux
41+
val xyzzy: T get() = quux
4242
}
4343

4444
class Poko(

src/test/kotlin/com/fasterxml/jackson/module/kotlin/_ported/test/github/failing/Github340.kt

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package com.fasterxml.jackson.module.kotlin._ported.test.github.failing
22

33
import com.fasterxml.jackson.databind.ObjectMapper
4-
import com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException
5-
import com.fasterxml.jackson.module.kotlin._ported.test.expectFailure
64
import com.fasterxml.jackson.module.kotlin.kotlinModule
75
import com.fasterxml.jackson.module.kotlin.readValue
86
import org.junit.jupiter.api.Assertions.assertEquals
@@ -21,10 +19,8 @@ class OwnerRequestTest {
2119

2220
@Test
2321
fun testDeserHit340() {
24-
expectFailure<UnrecognizedPropertyException>("GitHub #340 has been fixed!") {
25-
val value: IsField = jackson.readValue(json)
26-
assertEquals("Got a foo", value.foo)
27-
}
22+
val value: IsField = jackson.readValue(json)
23+
assertEquals("Got a foo", value.foo)
2824
}
2925

3026
@Test

0 commit comments

Comments
 (0)