Skip to content

Commit 630df45

Browse files
committed
Add test cases for Kotlin private constructor instantiation edge cases.
This commit adds two test cases to demonstrate a bug in Kotlin constructor resolution when dealing with private constructors. The first test case shows the failure scenario where a private constructor without default parameter values causes a runtime exception. The second test case demonstrates that adding default parameter values to the private constructor doesn't display the same issue. The bug seems to occur because the code incorrectly assumes that private constructors always generate synthetic parameters for both the default mask and the DefaultConstructorMarker. However, when a private primary constructor has no default parameter values, the Kotlin compiler only generates the DefaultConstructorMarker variant, not the mask parameter. References #3389 Signed-off-by: Edward Poot <edwardmp@gmail.com>
1 parent 1228d09 commit 630df45

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

src/test/kotlin/org/springframework/data/mapping/model/InlineClasses.kt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import java.time.LocalDate
2020

2121
/**
2222
* @author Mark Paluch
23+
* @author Edward Poot
2324
*/
2425
@JvmInline
2526
value class MyValueClass(val id: String)
@@ -46,6 +47,10 @@ data class WithMyValueClass(val id: MyValueClass) {
4647
// ---------
4748
}
4849

50+
data class WithMyValueClassPrivateConstructor private constructor(val id: MyValueClass)
51+
52+
data class WithMyValueClassPrivateConstructorAndDefaultValue private constructor(val id: MyValueClass = MyValueClass("id"))
53+
4954
@JvmInline
5055
value class MyNullableValueClass(val id: String? = "id")
5156

src/test/kotlin/org/springframework/data/mapping/model/KotlinClassGeneratingEntityInstantiatorUnitTests.kt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import kotlin.reflect.KClass
3030
*
3131
* @author Mark Paluch
3232
* @author Sebastien Deleuze
33+
* @author Edward Poot
3334
*/
3435
@Suppress("UNCHECKED_CAST")
3536
class KotlinClassGeneratingEntityInstantiatorUnitTests {
@@ -189,6 +190,24 @@ class KotlinClassGeneratingEntityInstantiatorUnitTests {
189190
assertThat(instance.id.id).isEqualTo("hello")
190191
}
191192

193+
@Test // GH-3389
194+
fun `should use private default constructor for types using value class`() {
195+
196+
every { provider.getParameterValue<String>(any()) } returns "hello"
197+
val instance = construct(WithMyValueClassPrivateConstructor::class)
198+
199+
assertThat(instance.id.id).isEqualTo("hello")
200+
}
201+
202+
@Test // GH-3389
203+
fun `should use private default constructor for types using value class with default value`() {
204+
205+
every { provider.getParameterValue<String>(any()) } returns "hello"
206+
val instance = construct(WithMyValueClassPrivateConstructorAndDefaultValue::class)
207+
208+
assertThat(instance.id.id).isEqualTo("hello")
209+
}
210+
192211
@Test
193212
fun `should use default constructor for types using nullable value class`() {
194213

0 commit comments

Comments
 (0)