Repository: JetBrains/kotlin
File: plugins/kotlinx-serialization/testData/boxIr/delegatedProperty.kt (Kotlin)

Code before:

@Serializable
data class SimpleDTO(
    val realProp: Int,
) {
    @Transient
    private val additionalProperties: Map<String, Int> = mapOf("delegatedProp" to 123)
    @Transient
    val delegatedProp: Int? by additionalProperties
}

// optimized properties must also work
// https://kotlinlang.org/docs/whatsnew1720.html#more-optimized-cases-of-delegated-properties
// A named object:
object NamedObject {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String = "test-string"
}

@Serializable
data class DelegatedByObjectProperty(
    val realProp: Int
) {
    val delegatedProp: String by NamedObject
}

// A final val property with a backing field and a default getter in the same module:
val impl: ReadOnlyProperty<Any?, String> = object : ReadOnlyProperty<Any?, String> {
    override operator fun getValue(thisRef: Any?, property: KProperty<*>): String = "test-string"
}

@Serializable
class DelegatedByFinalVal(
    val realProp: Int
) {
    val delegatedProp: String by impl
}

// delegated by this
@Serializable
class DelegatedByThis(val realProp: Int) {
    operator fun getValue(thisRef: Any?, property: KProperty<*>) = "test-string"

    val delegatedProp by this
}

fun box(): String {
    val simpleDTO = SimpleDTO(123)
    val simpleDTOJsonStr = Json.encodeToString(simpleDTO)
    val simpleDTODecoded = Json.decodeFromString<SimpleDTO>(simpleDTOJsonStr)
    if (simpleDTOJsonStr != """{"realProp":123}""") return simpleDTOJsonStr
    if (simpleDTODecoded.delegatedProp != simpleDTO.delegatedProp) return "SimpleDTO Delegate is incorrect!"

Review comment (performance):
I see you've added more test-cases for optimized properties, which is good. However, I also suggested that you make sure that even non-optimized delegated properties are still working correctly. Fortunately, it is easy to do so: just change `val` here to `var` and synthetic `delegatedProp$delegate` will appear in `DelegatedByFinalVal` - without breaking the test. (don't forget to rename the class itself though, as it will be no longer ByFinalVal)

Code after:

@Serializable
data class SimpleDTO(
    val realProp: Int,
) {
    @Transient
    private val additionalProperties: Map<String, Int> = mapOf("delegatedProp" to 123)
    val delegatedProp: Int? by additionalProperties
}

// optimized properties must also work
// https://kotlinlang.org/docs/whatsnew1720.html#more-optimized-cases-of-delegated-properties
// A named object:
object NamedObject {
    operator fun getValue(thisRef: Any?, property: KProperty<*>): String = "test-string"
}

@Serializable
data class DelegatedByObjectProperty(
    val realProp: Int
) {
    val delegatedProp: String by NamedObject
}

// A final val property with a backing field and a default getter in the same module:
val impl: ReadOnlyProperty<Any?, String> = object : ReadOnlyProperty<Any?, String> {
    override operator fun getValue(thisRef: Any?, property: KProperty<*>): String = "test-string"
}

@Serializable
class DelegatedByFinalVal(
    val realProp: Int
) {
    val delegatedProp: String by impl
}

// A var property with a backing field and a default getter in the same module:
var implvar: ReadWriteProperty<Any?, String> = object : ReadWriteProperty<Any?, String> {
    private var value = "test-string"
    override operator fun getValue(thisRef: Any?, property: KProperty<*>): String = value
    override operator fun setValue(
        thisRef: Any?,
        property: KProperty<*>,
        value: String) { this.value = value }
}

@Serializable
class DelegatedByVar(
    val realProp: Int
) {
    var delegatedProp: String by implvar