e.ultra.mutator.0.76.0.source-code.Cloner.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of mutator Show documentation
Show all versions of mutator Show documentation
"Make immutable objects mutable"
The newest version!
package de.peekandpoke.ultra.mutator
import kotlin.reflect.full.createInstance
import kotlin.reflect.full.declaredFunctions
import kotlin.reflect.full.memberProperties
import kotlin.reflect.full.primaryConstructor
import kotlin.reflect.jvm.javaField
object Cloner {
fun cloneDataClass(subject: T): T {
val cls = subject::class
val primaryCtr = cls.primaryConstructor
return when {
// Data class
cls.isData -> {
// TODO: cache the first part, where the information is gathered
// every data class has a primary constructor
val ctor = cls.primaryConstructor!!
// get all fields of the data class in the order as they appear in the primary constructor
val fields = ctor.parameters.map { param ->
val field = cls.memberProperties.first { it.name == param.name }.javaField!!
field.isAccessible = true
field.get(subject)
}
// invoke the copy() method with the values
val copy = cls.declaredFunctions.first { it.name == "copy" }
@Suppress("UNCHECKED_CAST", "Detekt:SpreadOperator")
copy.call(subject, *fields.toTypedArray()) as T
}
// No arg primary constructor
primaryCtr != null && primaryCtr.parameters.isEmpty() -> cls.createInstance()
// TODO: more specific exception
else -> throw CouldNotCloneException(
"Cannot clone type '${subject::class}'. It is not a data class and has no no-arg constructor!"
)
}
}
}