google / ksp

Kotlin Symbol Processing API
https://github.com/google/ksp
Apache License 2.0
2.83k stars 265 forks source link

[KMP] Properties from dependencies incorrectly return false from hasBackingField on native #1875

Open danysantiago opened 5 months ago

danysantiago commented 5 months ago

Given a two module KMP project targeting native with a KSP processor, when inspecting the declaration of a dependency, the declaration properties report that they have no backing field when in fact they do. Only happens when the declaration comes from a dependency.

For example, given the library source:

// library/nativeMain/kotlin/src/dany/TestEntity.kt

package dany

data class TestEntity(val id: Long)

and consumer module:

// consumer/nativeMain/kotlin/src/Foo.kt

interface Foo

and KSP processor applied to :consumer:

class TestProcessor(val env: SymbolProcessorEnvironment) : SymbolProcessor {

    override fun process(resolver: Resolver): List<KSAnnotated> {
        val testEntityDeclaration = resolver.getClassDeclarationByName("dany.TestEntity")
        requireNotNull(testEntityDeclaration)
        testEntityDeclaration.getAllProperties().forEach {
            env.logger.info("Found property: $it")
            env.logger.info("hasBackingField: ${it.hasBackingField}")
        }
        return emptyList()
    }
}

the KSP logs will contain:

> Task :consumer:kspKotlinMacosX64
i: [ksp] loaded provider(s): [TestProcessorProvider]
i: [ksp] Found property: id
i: [ksp] hasBackingField: false

This was originally reported in the Room KMP project here: https://issuetracker.google.com/338842136

neetopia commented 5 months ago

In JVM implementation KSP reads from bytecode to determine if a property have a backing field, which is impossible in other platforms. To address this, this information needs to be populated into the metadata of klib.

neetopia commented 5 months ago

pending upstream: https://youtrack.jetbrains.com/issue/KT-59526/Store-annotation-default-values-in-metadata-on-JVM