Closed bellatoris closed 2 years ago
I have the same issue, on 1.0-rc6 and 1.0-rc7. I did explore the code a little, and from what I can tell it seems like the nullability is swallowed in mutationInfo( )
.
The property and the returned MutationInfo do not have the same nullability.
Sadly I'm not sure whether I would be able to solve this issue. My first idea would be to check for nullability in mutationInfo and ensure that it is preserved, however I'm not sure what the implications for the other extensions would be.
I found this doing the following very basic approach:
// change test to have a nullable property
@Test
fun `mutate one property`() {
"""
|data class Person(val name: String, val age: Int?)
|
|val p1 = Person("Alex", 1)
|val p2 = p1.copy { age = age + 1 }
|val r = p2.age
""".evals("r" to 2)
}
// compare return value of mutationInfo with passed value
val mutationInfo: Sequence<Pair<KSPropertyDeclaration, MutationInfo<TypeName>>>
get() = properties.map { prop ->
prop to mutationInfo(prop.type.resolve()).also {
println("PROPVSMUTATIONINFO: ${prop.type} ${prop.typeName} ${prop.typeName.isNullable} | ${it.className} ${it.className.isNullable} | ${prop.type.resolve().isMarkedNullable}")
} }
// compare property.typeName and mutationInfo.className
internal fun FileCompilerScope.addMutableCopy() {
/* (...) */
primaryConstructor {
mutationInfo.forEach { (property, mutationInfo) ->
with(property) {
println("PROPERTY: ${this.typeName} ${this.typeName.isNullable}")
println("MUTATIONINFO: ${mutationInfo.className} ${mutationInfo.className.isNullable}")
addParameter(
name = baseName,
type = mutationInfo.className,
modifiers = parameterModifiers
)
as you can see the generated mutable data class does not reflect the nullability of fields of original data class.
so that
User.toMutable()
class can not be even compiled since this discrepancy of mutability.