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

Prototype support for kotlin-inject #1197

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft

Prototype support for kotlin-inject #1197

wants to merge 17 commits into from

Conversation

ZacSweers
Copy link
Collaborator

@ZacSweers ZacSweers commented Feb 12, 2024

This adds code gen support for @evant's https://github.com/evant/kotlin-inject

Adapting from @joshafeinberg's prior prototyping in https://github.com/joshafeinberg/CircuitKotlinInject

This works by introducing an @MergeCircuitComponent annotation that can be used on a scoped "circuit component" interface that code gen then processes and generates a kotlin-inject-compatible component impl for, aggregating bound UI and presenter factories within the module.

Pros: multiplatform!
Cons: aggregating processor, no cross-module hinting like anvil and hilt do

Example

// Given an existing app component
@Component
abstract class AppComponent {
  // ...
}

// Write a merged circuit component that extends from it
// The generic type is the parent component
// The argument is the scope key
@MergeCircuitComponent(AppScope::class)
abstract class AppScopeCircuitComponent(@Component appComponent: AppComponent) : CircuitComponent

// Usage
val appComponent = AppComponent::class.create()
val circuitComponent = AppScopeCircuitComponent::class.create(appComponent)
val circuit = circuitComponent.newBuilder().build()

Everything else works the same before as far as using @CircuitInject.

TODO

  • Docs
  • Tests
  • API improvements
    • Should we make a separate runtime for the CircuitComponent and new annotations?
    • Can we further abstract the code gen mode specifics from the Circuit processor? Currently we do custom handling for assisted types
  • Inexplicable, generated code doesn't seem able to smart-cast data object types to their type when passing it as an assisted param

@ZacSweers
Copy link
Collaborator Author

ZacSweers commented Feb 12, 2024

Thinking it might be better to leave the parent component to the class itself

// Write a merged circuit component that extends from it
// The argument is the scope key
// Primary constructor params are just copied to the generated impl and passed up
@MergeCircuitComponent(AppScope::class)
abstract class AppScopeCircuitComponent(@Component val parent: AppComponent) : CircuitComponent

@ZacSweers
Copy link
Collaborator Author

I'm not sure this has wheels until evant/kotlin-inject#351 is available. I'm also not able to figure out a way to get past this hurdle of deferring generation until kotlin-inject runs 🤔. I suspect there may be a problem with both plugins deferring.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant