evant / kotlin-inject

Dependency injection lib for kotlin
Apache License 2.0
1.29k stars 60 forks source link

Ksp code generation fails on Jvm/Desktop after updating Kotlin to 1.9.20 & Ksp to 1.9.20-1.0.14 #316

Open mr3y-the-programmer opened 1 year ago

mr3y-the-programmer commented 1 year ago

After I bumped kotlin version to 1.9.20 & ksp as well in a project where I'm using kotlin-inject, I can't compile the desktop app anymore due to this error:

[ksp] java.lang.IllegalArgumentException: Error type '<ERROR TYPE>' is not resolvable in the current round of processing.
    at com.squareup.kotlinpoet.ksp.KsTypesKt.toTypeName(KsTypes.kt:61)
    at com.squareup.kotlinpoet.ksp.KsTypesKt.toTypeName(KsTypes.kt:182)
    at com.squareup.kotlinpoet.ksp.KsTypesKt.toTypeName(KsTypes.kt:167)
    at com.squareup.kotlinpoet.ksp.KsTypesKt.toTypeName(KsTypes.kt:66)
    at com.squareup.kotlinpoet.ksp.KsTypesKt.toTypeName(KsTypes.kt:182)
    at com.squareup.kotlinpoet.ksp.KsTypesKt.toTypeName$default(KsTypes.kt:179)
    at me.tatarka.kotlin.ast.KSAstType.toString(KSAst.kt:455)
    at java.base/java.lang.String.valueOf(String.java:4220)
    at java.base/java.lang.StringBuilder.append(StringBuilder.java:173)
    at me.tatarka.inject.compiler.TypeKey.toString(TypeKey.kt:25)
    at java.base/java.lang.StringConcatHelper.stringOf(StringConcatHelper.java:453)
    at java.base/java.lang.StringConcatHelper.simpleConcat(StringConcatHelper.java:408)
    at me.tatarka.inject.compiler.TypeResultResolver.cannotFind(TypeResultResolver.kt:560)
    at me.tatarka.inject.compiler.TypeResultResolver.resolveParamsLegacy(TypeResultResolver.kt:164)
    at me.tatarka.inject.compiler.TypeResultResolver.resolveParams(TypeResultResolver.kt:70)
    at me.tatarka.inject.compiler.TypeResultResolver.access$resolveParams(TypeResultResolver.kt:17)
    at me.tatarka.inject.compiler.TypeResultResolver$Constructor$1.invoke(TypeResultResolver.kt:452)
    at me.tatarka.inject.compiler.TypeResultResolver$Constructor$1.invoke(TypeResultResolver.kt:448)
    at me.tatarka.inject.compiler.TypeResultResolver$withCycleDetection$result$1.invoke(TypeResultResolver.kt:537)
    at me.tatarka.inject.compiler.TypeResultResolver$withCycleDetection$result$1.invoke(TypeResultResolver.kt:535)
    at me.tatarka.inject.compiler.CycleDetector.check(CycleDetector.kt:53)
    at me.tatarka.inject.compiler.TypeResultResolver.withCycleDetection(TypeResultResolver.kt:535)
    at me.tatarka.inject.compiler.TypeResultResolver.Constructor(TypeResultResolver.kt:448)
    at me.tatarka.inject.compiler.TypeResultResolver.constructor(TypeResultResolver.kt:379)
    at me.tatarka.inject.compiler.TypeResultResolver.findType(TypeResultResolver.kt:236)
    at me.tatarka.inject.compiler.TypeResultResolver.resolveOrNull(TypeResultResolver.kt:49)
    at me.tatarka.inject.compiler.TypeResultResolver.resolve(TypeResultResolver.kt:39)
    at me.tatarka.inject.compiler.TypeResultResolver.Scoped(TypeResultResolver.kt:440)
    at me.tatarka.inject.compiler.TypeResultResolver.constructor(TypeResultResolver.kt:371)
    at me.tatarka.inject.compiler.TypeResultResolver.findType(TypeResultResolver.kt:236)
    at me.tatarka.inject.compiler.TypeResultResolver.resolveOrNull(TypeResultResolver.kt:49)
    at me.tatarka.inject.compiler.TypeResultResolver.resolve(TypeResultResolver.kt:39)
    at me.tatarka.inject.compiler.TypeResultResolver.access$resolve(TypeResultResolver.kt:17)
    at me.tatarka.inject.compiler.TypeResultResolver$Provider$result$1.invoke(TypeResultResolver.kt:396)
    at me.tatarka.inject.compiler.TypeResultResolver$Provider$result$1.invoke(TypeResultResolver.kt:3[95](https://github.com/mr3y-the-programmer/Ludi/actions/runs/6790259011/job/18459283096?pr=60#step:7:96))
    at me.tatarka.inject.compiler.TypeResultResolver$withCycleDetection$result$1.invoke(TypeResultResolver.kt:537)
    at me.tatarka.inject.compiler.TypeResultResolver$withCycleDetection$result$1.invoke(TypeResultResolver.kt:535)
    at me.tatarka.inject.compiler.CycleDetector.check(CycleDetector.kt:53)
    at me.tatarka.inject.compiler.TypeResultResolver.withCycleDetection(TypeResultResolver.kt:535)
    at me.tatarka.inject.compiler.TypeResultResolver.Provider(TypeResultResolver.kt:395)
    at me.tatarka.inject.compiler.TypeResultResolver.resolveAll(TypeResultResolver.kt:30)
    at me.tatarka.inject.compiler.InjectGenerator.generateInjectComponent(InjectGenerator.kt:140)
    at me.tatarka.inject.compiler.InjectGenerator.generate(InjectGenerator.kt:60)
    at me.tatarka.inject.compiler.ksp.InjectProcessor.process(InjectProcessor.kt:64)
    at me.tatarka.inject.compiler.ksp.InjectProcessor.process(InjectProcessor.kt:52)
    at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:305)
    at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension$doAnalysis$8$1.invoke(KotlinSymbolProcessingExtension.kt:303)
    at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.handleException(KotlinSymbolProcessingExtension.kt:409)
    at com.google.devtools.ksp.AbstractKotlinSymbolProcessingExtension.doAnalysis(KotlinSymbolProcessingExtension.kt:303)
    at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(TopDownAnalyzerFacadeForJVM.kt:112)
    at org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration$default(TopDownAnalyzerFacadeForJVM.kt:77)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:256)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler$analyze$1.invoke(KotlinToJVMBytecodeCompiler.kt:247)
    at org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport.analyzeAndReport(AnalyzerWithCompilerReport.kt:115)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.analyze(KotlinToJVMBytecodeCompiler.kt:247)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli(KotlinToJVMBytecodeCompiler.kt:87)
    at org.jetbrains.kotlin.cli.jvm.compiler.KotlinToJVMBytecodeCompiler.compileModules$cli$default(KotlinToJVMBytecodeCompiler.kt:43)
    at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:165)
    at org.jetbrains.kotlin.cli.jvm.K2JVMCompiler.doExecute(K2JVMCompiler.kt:50)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:104)
    at org.jetbrains.kotlin.cli.common.CLICompiler.execImpl(CLICompiler.kt:48)
    at org.jetbrains.kotlin.cli.common.CLITool.exec(CLITool.kt:101)
    at org.jetbrains.kotlin.daemon.CompileServiceImpl.compile(CompileServiceImpl.kt:1523)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:568)
    at java.rmi/sun.rmi.server.UnicastServerRef.dispatch(UnicastServerRef.java:360)
    at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:200)
    at java.rmi/sun.rmi.transport.Transport$1.run(Transport.java:197)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:712)
    at java.rmi/sun.rmi.transport.Transport.serviceCall(Transport.java:1[96](https://github.com/mr3y-the-programmer/Ludi/actions/runs/6790259011/job/18459283096?pr=60#step:7:97))
    at java.rmi/sun.rmi.transport.tcp.TCPTransport.handleMessages(TCPTransport.java:587)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(TCPTransport.java:828)
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.lambda$run$0(TCPTransport.java:705)
    at java.base/java.security.AccessController.doPrivileged(AccessController.java:3[99](https://github.com/mr3y-the-programmer/Ludi/actions/runs/6790259011/job/18459283096?pr=60#step:7:100))
    at java.rmi/sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(TCPTransport.java:704)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:[113](https://github.com/mr3y-the-programmer/Ludi/actions/runs/6790259011/job/18459283096?pr=60#step:7:114)6)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635)
    at java.base/java.lang.Thread.run(Thread.java:840)

At first look, Seems like it is Kotlinpoet's fault but I'm not sure.

evant commented 1 year ago

Seems to be a change in ksp where it's returning an error type where it was resolved before. Either a bug in ksp or this project, if you could narrow it down to a sample that would be super helpful

mr3y-the-programmer commented 1 year ago

I'm having a hard time isolating the bug into its own small sample, but here is the project https://github.com/mr3y-the-programmer/Ludi/pull/60 that is reproducing the bug. reproducing the error is fairly simple, just clone the repository, checkout bump_kotlin_version branch, run .\gradlew :shared:kspKotlinDesktop and you should see the error.

mr3y-the-programmer commented 1 year ago

FYI, if you downgraded KSP version to 1.9.10-1.0.13, kspKotlinDesktop completes successfully with no issues. version 1.9.20-RC2-1.0.13 is the first one that can reproduce the bug, this commit seems to be the culprit.

evant commented 9 months ago

Finally got around to looking at this, it's failing to resolve types generated by wire. You can get around this by wrapping those types when providing them, ex:

@JvmInline
value class UserFavoriteGamesDataStore(val value: DataStore<UserFavouriteGame>)

interface DataStoreComponent {
    @Provides
    @Singleton
    fun provideFavouriteGamesDataStore(dataStoreParentDir: Path): UserFavoriteGamesDataStore {
        ...
    }
 }

Will work on better error messages for unresolved types, but I don't know if there's a good solution to making those types resolvable as wire is a gradle plugin and ksp doesn't know about it. This is similar to https://github.com/evant/kotlin-inject/issues/155

mr3y-the-programmer commented 9 months ago

Thanks for your effort, will try this workaround.

dave08 commented 7 months ago

I seem to be getting the same error when trying to inject a Map<String, Foo<*>>... even if I wrap it in a value class or a data class... I'm on Kotlin 1.9.22/23 with corresponding latest ksp version and kotlinInject 0.6.3

dave08 commented 7 months ago

Nope, it was an error in my code, that I didn't use <*> in all of the occurences of the use of that base class. But that's a funny error for this kind of problem...