From 8bb23d24b73bb8481c40e9aabd18b046923ba6ee Mon Sep 17 00:00:00 2001 From: Donghyeon Kim Date: Fri, 4 Aug 2023 03:06:43 +0900 Subject: [PATCH 1/2] Support for value classes resolve: #199 --- .../KotlinNamesAnnotationIntrospector.kt | 4 ++-- .../module/kotlin/ReflectJvmMapping.kt | 16 ++++++++++++++ .../jackson/module/kotlin/ReflectionCache.kt | 2 +- .../module/kotlin/test/ValueClassTest.kt | 21 +++++++++++++++++++ 4 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectJvmMapping.kt create mode 100644 src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/ValueClassTest.kt diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt index 858ceb7e..9260e4e2 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/KotlinNamesAnnotationIntrospector.kt @@ -127,11 +127,11 @@ internal class KotlinNamesAnnotationIntrospector( if (member is Constructor<*>) { val ctor = (member as Constructor) val ctorParmCount = ctor.parameterTypes.size - val ktorParmCount = try { ctor.kotlinFunction?.parameters?.size ?: 0 } + val ktorParmCount = try { ctor.kotlinCtor?.parameters?.size ?: 0 } catch (ex: KotlinReflectionInternalError) { 0 } catch (ex: UnsupportedOperationException) { 0 } if (ktorParmCount > 0 && ktorParmCount == ctorParmCount) { - ctor.kotlinFunction?.parameters?.get(param.index)?.name + ctor.kotlinCtor?.parameters?.get(param.index)?.name } else { null } diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectJvmMapping.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectJvmMapping.kt new file mode 100644 index 00000000..3ba84d71 --- /dev/null +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectJvmMapping.kt @@ -0,0 +1,16 @@ +package com.fasterxml.jackson.module.kotlin + +import java.lang.reflect.Constructor +import kotlin.reflect.KFunction +import kotlin.reflect.jvm.javaConstructor + +val Constructor.kotlinCtor: KFunction? + get() { + val kotlinClass = declaringClass.kotlin + return if (kotlinClass.isValue) { + val parameterTypes = this.parameters.map { p -> p.type } + kotlinClass.constructors.firstOrNull { it.parameters.map { p -> p.type.erasedType() } == parameterTypes } + } else { + kotlinClass.constructors.firstOrNull { it.javaConstructor == this } + } + } diff --git a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt index dbcb6b17..9dcf14d1 100644 --- a/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt +++ b/src/main/kotlin/com/fasterxml/jackson/module/kotlin/ReflectionCache.kt @@ -58,7 +58,7 @@ internal class ReflectionCache(reflectionCacheSize: Int) : Serializable { LRUMap(0, reflectionCacheSize) fun kotlinFromJava(key: Constructor): KFunction? = javaConstructorToKotlin.get(key) - ?: key.kotlinFunction?.let { javaConstructorToKotlin.putIfAbsent(key, it) ?: it } + ?: key.kotlinCtor?.let { javaConstructorToKotlin.putIfAbsent(key, it) ?: it } fun kotlinFromJava(key: Method): KFunction<*>? = javaMethodToKotlin.get(key) ?: key.kotlinFunction?.let { javaMethodToKotlin.putIfAbsent(key, it) ?: it } diff --git a/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/ValueClassTest.kt b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/ValueClassTest.kt new file mode 100644 index 00000000..43712069 --- /dev/null +++ b/src/test/kotlin/com/fasterxml/jackson/module/kotlin/test/ValueClassTest.kt @@ -0,0 +1,21 @@ +package com.fasterxml.jackson.module.kotlin.test + +import com.fasterxml.jackson.databind.ObjectMapper +import com.fasterxml.jackson.module.kotlin.kotlinModule +import org.junit.Assert +import org.junit.Test + +class ValueClassTest { + @JvmInline + value class TestClass(val foo: List) + + @Test + fun `test value class`() { + val mapper = createMapper() + Assert.assertEquals(listOf(1, 2), mapper.readValue("""{"foo": [1,2]}""", TestClass::class.java).foo) + } + + private fun createMapper(): ObjectMapper { + return ObjectMapper().registerModule(kotlinModule()) + } +} From 0e29756c793eed7f8b47dce9538dfad8eaefd687 Mon Sep 17 00:00:00 2001 From: Donghyeon Kim Date: Fri, 4 Aug 2023 03:08:15 +0900 Subject: [PATCH 2/2] [Temp] Use jackson-databind snapshot version https://github.com/wplong11/jackson-databind/commit/570ed132022fbff8ff741921ecb97d4321545e9e --- pom.xml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 0ef4d293..4b813410 100644 --- a/pom.xml +++ b/pom.xml @@ -81,8 +81,9 @@ - com.fasterxml.jackson.core + com.github.wplong11 jackson-databind + revert-1005-SNAPSHOT @@ -253,5 +254,9 @@ true + + jitpack.io + https://jitpack.io +