google / ksp

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

K2: Generated platform code cannot see code from platform source set #1723

Open eygraber opened 9 months ago

eygraber commented 9 months ago

After updating Kotlin to 2.0.0-Beta3 and KSP to 2.0.0-Beta3-1.0.17 (with ksp.useKSP2 = false) I started seeing an issue where code generated from the android source set can't see code that is in the android source set:

android source set:

import android.content.ContentResolver
import android.content.Context
import android.content.SharedPreferences
import android.content.pm.PackageManager
import android.content.res.AssetManager
import android.content.res.Resources
import android.os.Looper
import me.tatarka.inject.annotations.Assisted
import me.tatarka.inject.annotations.Component
import me.tatarka.inject.annotations.Provides

@Component
public abstract class AndroidComponent(
  @get:Provides public val context: Context,
) {
  @Provides public fun assetManager(): AssetManager = context.assets
  @Provides public fun contentResolver(): ContentResolver = context.contentResolver
  @Provides public fun mainLooper(): Looper = context.mainLooper
  @Provides public fun packageManager(): PackageManager = context.packageManager
  @Provides public fun resources(): Resources = context.resources
  @Provides public fun sharedPreferences(@Assisted name: String): SharedPreferences =
    context.getSharedPreferences(
      name,
      Context.MODE_PRIVATE,
    )

  public companion object
}

generated code:

import android.content.Context

public fun AndroidComponent.Companion.create(context: Context): AndroidComponent =
    InjectAndroidComponent(context)

public class InjectAndroidComponent(
  context: Context,
) : AndroidComponent(context)

Errors:

> Task :di-components:compileDebugKotlinAndroid
e: file:///home/eli/workspace/di-components/build/generated/ksp/android/androidDebug/kotlin/com/eygraber/di/components/InjectAndroidComponent.kt:5:12 Unresolved reference 'AndroidComponent'.
e: file:///home/eli/workspace/di-components/build/generated/ksp/android/androidDebug/kotlin/com/eygraber/di/components/InjectAndroidComponent.kt:5:68 Unresolved reference 'AndroidComponent'.
e: file:///home/eli/workspace/di-components/build/generated/ksp/android/androidDebug/kotlin/com/eygraber/di/components/InjectAndroidComponent.kt:10:5 Unresolved reference 'AndroidComponent'.

I use the following to set up my KSP dependencies:

fun KotlinTarget.kspDependencies(block: KspDependencies.() -> Unit) {
  val configurationName = "ksp${targetName.capitalize()}"
  project.dependencies {
    object : KspDependencies {
      override fun ksp(dependencyNotation: Any) {
        add(configurationName, dependencyNotation)
      }
    }.block()
  }
}

fun KotlinMultiplatformExtension.kspDependenciesForAllTargets(block: KspDependencies.() -> Unit) {
  targets.configureEach {
    if(targetName != "metadata") {
      kspDependencies(block)
    }
  }
}
kalinjul commented 8 months ago

I'm experiencing the same problem with kotlin 2.0.0-Beta4 K2, ksp 2.0.0-Beta4-1.0.17. I'm using koin-annotations (ksp), which generates code that calls a constructor which in turn is only defined in the actual class. Compilation fails, because the compiler appearently does not see the actual class, even when it is in the same source set: compileDebugKotlinAndroid FAILED: Expected class 'expect class OnlineStatusCheckerModule : Any' does not have default constructor.

kalinjul commented 8 months ago

Could be a duplicate of https://github.com/google/ksp/issues/1651