Skip to content

Support injecting top-level functions with context parameters #820

@alexvanyo

Description

@alexvanyo

Description

Right now, injecting a top-level function that has context parameters isn't allowed:

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions