I'm trying out Kotlin 2.0 Beta 3 and it looks like...
# ksp
e
I'm trying out Kotlin 2.0 Beta 3 and it looks like generated KSP code is getting a lot of unresolved reference errors for types from my regular source set. Did the configuration change for 2.0?
This is a multiplatform project and it looks like it's failing only for Android source sets
t
Are those references made from some common source set, and the referred-to classes are either to-be-generated or resides in platform source sets?
e
I have a class Foo in the Android source set, and ksp generates a GeneratedFoo class based on it in the generated Android source set. GeneratedFoo references Foo, but with 2.0 Beta 3 there's an unresolved reference error to Foo in GeneratedFoo
Not sure if this is related, but in another project I'm seeing an issue where common code can't see generated code. It's not a typical setup. The module (
ksp-companion
) is empty, and adds a directory containing common test code (
common-companion
) to
kotlin.srcDir
for
commonTest
. A file in
common-companion
(
CompanionTest
) has code generated for it in
ksp-companion
but it can't see that code. You can repro this by running
./gradlew assemble
on the branch I linked above. This is a different scenario than my OP. I added it here in case they're related.
@Ting-Yuan Huang should I file an issue for this, or is it expected / I'm doing something wrong?
t
It's expected that common code cannot reference generated code in the compilation of platform code. Generated codes are treated as platform code and K2 explicitly disallow references from common to platform (you'll have to use expect/actual).
With regard to your original issue where generated code cannot reference common, yes, a bug report with reproduce case will be super helpful.
e
So with K2 it wouldn't be possible to generate common code anymore?
Oh maybe the latter issue is that the annotated code is in a common test source set and there isn't a configuration for kspCommonTestMetadata?
OK for the latter issue I think the project was misconfigured and now won't work in K2 because of what you mentioned about disallowing references from common to platform. I'm gonna look closer at the initial issue and if I can't figure anything out I'll file an issue
👍 1
What I got working with the latter issue was only with
ksp.useKSP2=false
(using Kotlin 2.0 Beta 3). However if I set
ksp.useKSP2=true
then it stops working because no common main code is generated.
Filed this for the first issue - https://github.com/google/ksp/issues/1723
🙏 1
a
I'm generating code with KSP. The generated code will be used in common/intermediate code. According to this thread, I understand that this is not allowed. Common/intermediate (= none-platform) code cannot reference generated code in the compilation of platform code. Generated codes are treated as platform code (you'll have to use expect/actual). I therefore implemented the proposed expect/actual solution. Everything works fine (see https://github.com/softappeal/yass2/blob/main/yass2-generate/src/jvmMain/kotlin/ksp/Generate.kt). For finding out if a
KSDeclaration
is in platform specific code I use the following code:
private val Platforms = setOf(
"jvm", // JVM
"js", // JavaScript
"wasmJs", "wasmWasi",// WebAssembly
"macosX64", "macosArm64", // macOS
"iosArm64", "iosX64", "iosSimulatorArm64", // iOS
"linuxX64", "linuxArm64", // Linux
"watchosArm64", "watchosX64", "watchosSimulatorArm64", "watchosDeviceArm64", // watchOS
"tvosArm64", "tvosX64", "tvosSimulatorArm64", // tvOS
"mingwX64", // Windows
)
private fun KSDeclaration.isPlatformCode(): Boolean { // TODO: is there a better solution?
val filePath = containingFile!!.filePath
Platforms.forEach { platform ->
if (filePath.contains("/${platform}Main/") || filePath.contains("/${platform}Test/")) return true
}
return false
}
internal fun KSDeclaration.actual() = if (isPlatformCode()) "" else "actual "
I believe/hope there must be a more elegant solution for
isPlatformCode().
Any ideas are welcome.