Add support for Kotlin value classes in BeanUtils

This commit adds support for Kotlin value classes annotated
with @JvmInline to BeanUtils#findPrimaryConstructor.

This is only the first step, more refinements are expected
to be needed to achieve a comprehensive support of Kotlin
values classes in Spring Framework.

Closes gh-28638
This commit is contained in:
Sébastien Deleuze
2023-08-09 10:26:25 +02:00
parent dd76ed7a0a
commit 88c2a25f12
2 changed files with 65 additions and 1 deletions

View File

@@ -90,6 +90,45 @@ class BeanUtilsKotlinTests {
BeanUtils.instantiateClass(PrivateClass::class.java.getDeclaredConstructor())
}
@Test
fun `Instantiate value class`() {
val constructor = BeanUtils.findPrimaryConstructor(ValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = "Hello value class!"
val instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(ValueClass(value))
}
@Test
fun `Instantiate value class with multiple constructors`() {
val constructor = BeanUtils.findPrimaryConstructor(ValueClassWithMultipleConstructors::class.java)!!
assertThat(constructor).isNotNull()
val value = "Hello value class!"
val instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(ValueClassWithMultipleConstructors(value))
}
@Test
fun `Instantiate class with value class parameter`() {
val constructor = BeanUtils.findPrimaryConstructor(OneConstructorWithValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = ValueClass("Hello value class!")
val instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(OneConstructorWithValueClass(value))
}
@Test
fun `Instantiate class with nullable value class parameter`() {
val constructor = BeanUtils.findPrimaryConstructor(OneConstructorWithNullableValueClass::class.java)!!
assertThat(constructor).isNotNull()
val value = ValueClass("Hello value class!")
var instance = BeanUtils.instantiateClass(constructor, value)
assertThat(instance).isEqualTo(OneConstructorWithNullableValueClass(value))
instance = BeanUtils.instantiateClass(constructor, null)
assertThat(instance).isEqualTo(OneConstructorWithNullableValueClass(null))
}
class Foo(val param1: String, val param2: Int)
class Bar(val param1: String, val param2: Int = 12)
@@ -128,4 +167,17 @@ class BeanUtilsKotlinTests {
private class PrivateClass
@JvmInline
value class ValueClass(private val value: String)
@JvmInline
value class ValueClassWithMultipleConstructors(private val value: String) {
constructor() : this("Fail")
constructor(part1: String, part2: String) : this("Fail")
}
data class OneConstructorWithValueClass(val value: ValueClass)
data class OneConstructorWithNullableValueClass(val value: ValueClass?)
}