-
Notifications
You must be signed in to change notification settings - Fork 58
Description
Description
Right now, injecting a top-level function that has context parameters isn't allowed:
metro/compiler/src/main/kotlin/dev/zacsweers/metro/compiler/fir/checkers/FunctionInjectionChecker.kt
Line 50 in 1cf5ce6
| "Injected functions cannot have context parameters.", |
It seems reasonable to allow injecting the context parameters, while also allowing assisted injection of the context parameters as well.
Self-contained Reproducer
For a function like the following:
@Inject
@Composable
context(
@Assisted sharedTransitionScope: SharedTransitionScope
_: MyUiComponentClass,
)
fun App(
clock: Clock,
@Assisted modifier: Modifier = Modifier,
) {
// ...
}I would expect to be able to generate something like this:
@Inject
class AppClass(
private val clock: Clock,
private val myUiComponentClass: MyUiComponentClass,
) {
@Composable
context(sharedTransitionScope: SharedTransitionScope)
operator fun invoke(
modifier: Modifier = Modifier,
) = lambda(sharedTransitionScope, myUiComponentClass, clock, modifier)
companion object {
// Helper lambda to get an invocation of App without `AppClass` in scope
private val lambda:
@Composable context(
SharedTransitionScope,
MyUiComponentClass
) (Clock, Modifier) -> Unit = { clock, modifier ->
App(clock, modifier)
}
}
}Metro version
0.5.2
Context
With this support, the injected function could then be called like the following, where the AppClass is itself a context parameter:
@Composable
context(
_: SharedTransitionScope,
appClass: AppClass,
)
fun AppClass(
modifier: Modifier = Modifier,
) = appClass(modifier)Maybe this call-site could this be generated as well?
Or maybe this could optionally be generated if another annotation is present? Maybe that annotation could could help configure visibility?
Function injection as a whole is already opt-in, so maybe there's a more complete story to create there around visibility, overloads, receivers, and other considerations.