Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Build fails with multi module android project with Kotlin 2.0.0 #388

Open
julioromano opened this issue May 22, 2024 · 8 comments
Open

Build fails with multi module android project with Kotlin 2.0.0 #388

julioromano opened this issue May 22, 2024 · 8 comments
Labels
bug Something isn't working

Comments

@julioromano
Copy link

Repro project: https://github.com/julioromano/kotlin-inject-bug-repro-1
It's got 2 commit, the 1st commit builds fine, the second triggers the error.

e: [ksp] Cannot find an @Inject constructor or provider for: Function1<kotlin.Function1<kotlin.Long, kotlin.Unit>, kotlin.Unit>
com.example.foo.TrendingNavigation(trendingScreen: Function1<kotlin.Function1<kotlin.Long, kotlin.Unit>, kotlin.Unit>)

The difference between the commits is that some code has been moved out from the app module to an external one.

Slack convo: https://kotlinlang.slack.com/archives/C0255B8KX7W/p1716363571041319

@evant evant added the bug Something isn't working label May 22, 2024
@eygraber
Copy link
Contributor

I tried that project with 0.7.0 and #349 and it still doesn't work.

The issue seems to be that KSP in app is looking for the signature of TrendingScreen before it has been transformed by the Compose compiler, i.e. @Composable ((id: Long) -> Unit) -> Unit is seen as

Function1<Function1<Long, Unit>, Unit>

However, looking at TrendingNavigation.class, the Compose compiler has transformed it into:

Function3<Function1<Long, Unit>, Composer, Integer, Unit>

I'm not sure if this is an issue in kotlin-inject, KSP, or Compose.

@eygraber
Copy link
Contributor

Hmm maybe that's not it, because the first commit where it works sees the type the same way.

The first commit fails on 0.7.0-SNAPSHOT though, because it needs to use @Assisted. I don't know much about how function injection works, but I think there were some changes made there so maybe it is related to that.

@eygraber
Copy link
Contributor

Did some more digging, and it looks like in the working case, the TrendingScreen typealias is maintained, but in the broken case it is not a typealias, but is already resolved.

@eygraber
Copy link
Contributor

And looks like it's this issue in KSP - google/ksp#1849

@julioromano
Copy link
Author

Interestingly enough I get a very similar failure when setting ksp.useKSP2=true even with the 1st commit.

e: [ksp] Cannot find an @Inject constructor or provider for: Function1<kotlin.Long, kotlin.Unit>
/Users/julionb/Develop/marco/kotlin-inject-bug-repro-1/app/src/main/java/com/example/myapplication/TrendingNavigation.kt:18: TrendingScreen(trendingViewModel: Function0<com.example.myapplication.TrendingViewModel>, navToDetail: Function1<kotlin.Long, kotlin.Unit>): Unit
/Users/julionb/Develop/marco/kotlin-inject-bug-repro-1/app/src/main/java/com/example/myapplication/TrendingNavigation.kt:10: com.example.myapplication.TrendingNavigation(trendingScreen: com.example.myapplication.TrendingScreen)
/Users/julionb/Develop/marco/kotlin-inject-bug-repro-1/app/src/main/java/com/example/myapplication/ApplicationComponent.kt:11: trendingNavigation: com.example.myapplication.TrendingNavigation

@eygraber
Copy link
Contributor

OK probably not related to that issue. I filed a new one - google/ksp#1921

@julioromano
Copy link
Author

FYI: As a workaround I had to inject composables through wrapper classes instead of using type aliases.

typealias TrendingScreen = @Composable ((id: Long) -> Unit) -> Unit

@Inject
@Composable
fun TrendingScreen(
    trendingViewModel: () -> TrendingViewModel,
    navToDetail: (id: Long) -> Unit,
) {
    val vm = remember { trendingViewModel() }
    Text(text = "I'm just a placeholder")
}

becomes

public class TrendingScreen @Inject constructor(
  private val trendingViewModel: () -> TrendingViewModel,
) {
  @Composable
  public fun Composable(navToDetail: (id: Long) -> Unit) {
    val vm = viewModel { trendingViewModel() }
    Text(text = "I'm just a placeholder")
  }
}

@eygraber
Copy link
Contributor

Looks like this is fixed in newer versions of KSP / Kotlin.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants