class Impl : AppGraph { private val repositoryProvider = DoubleCheck.provider(ProvideApiMetroFactory.create(this)) override val val repository: Repository get() = Repository(repositoryProvider()) } }
@DefaultBinding<FragmentCreator <*> > interface FragmentCreator<T : Fragment> { // Generated in FIR abstract class DefaultBindingMirror { // Generated in IR abstract fun defaultBinding() : FragmentCreator <*> } }
class MainActivity { @Inject lateinit var id: String // FIR class MetroMembersInjector : MembersInjector<MainActivity> { // IR private val id: Provider<String> = ... // FIR companion object { // IR fun injectId(@Assisted instance: MainActivity, id_: String) { instance.id = id } } } }
@Inject class Repository(api: Api) { // FIR class MetroFactory : Factory<Repository> { // FIR override fun invoke() : Repository // FIR companion object } }
@Inject class Repository(api: Api) { // FIR class MetroFactory : Factory<Repository> { // IR private val api = ... // FIR override fun invoke() : Repository { // IR return Repository(api()) } // FIR companion object { // IR fun create( ... ) = ... // IR fun newInstance( ... ) = ... } } }
val graphs: List<GraphToProcess> val syntheticGraphs: List<GraphToProcess> val allGraphs get() = graphs + syntheticGraphs } data class GraphToProcess( val declaration: IrClass, val dependencyGraphAnno: IrConstructorCall, val graphImpl: IrClass, val scopes: Set<ClassId>, )
val graphs: List<GraphToProcess> val syntheticGraphs: List<GraphToProcess> val allGraphs get() = graphs + syntheticGraphs } data class GraphToProcess( val declaration: IrClass, val dependencyGraphAnno: IrConstructorCall, val graphImpl: IrClass, val scopes: Set<ClassId>, )
Merge contributions Process declarations (accessor roots, etc) Build BindingGraph - Collect bindings class ConstructorInjected class ObjectClass // @Provides class Provided // @Binds class Alias class AssistedFactory class BoundInstance // For default values class Absent // For @Includes class GraphDependency class Multibinding class MembersInjected class GraphExtension class GraphExtensionFactory // j.u.Optional interop, etc. class CustomWrapper
val missingBindings = populateGraph(roots) } fun populateGraph(roots) { // BFS from roots val queue = ArrayDeque<Binding>() val visited = HashSet<TypeKey>() while (queue.isNotEmpty()) { val next = queue.removeFirst() // Skipping code // Visit dependencies } } BindingLookup
val missingBindings = populateGraph(roots) } fun populateGraph(roots) { // BFS from roots val queue = ArrayDeque<Binding>() val visited = HashSet<TypeKey>() while (queue.isNotEmpty()) { val next = queue.removeFirst() // Skipping code // Visit dependencies } } BindingLookup
val missingBindings = populateGraph(roots) } fun populateGraph(roots) { // BFS from roots val queue = ArrayDeque<Binding>() val visited = HashSet<TypeKey>() while (queue.isNotEmpty()) { val next = queue.removeFirst() // Skipping code // Visit dependencies } } BindingLookup
val missingBindings = populateGraph(roots) } fun populateGraph(roots) { // BFS from roots val queue = ArrayDeque<Binding>() val visited = HashSet<TypeKey>() while (queue.isNotEmpty()) { val next = queue.removeFirst() // Skipping code // Visit dependencies } } BindingLookup Absent(MissingKey)
val missingBindings = populateGraph(roots) } fun populateGraph(roots) { // BFS from roots val queue = ArrayDeque<Binding>() val visited = HashSet<TypeKey>() while (queue.isNotEmpty()) { val next = queue.removeFirst() // Skipping code // Visit dependencies } } BindingLookup
IrGraphShardGenerator class Impl : HumongousAppGraph { val shard1 = Shard1(this) val shard2 = Shard2(this) class Shard1(parent: Impl) { // Dozens of f i elds } class Shard2(parent: Impl) { // Dozens of f i elds } }
class Impl : AppGraph { val apiProvider = DoubleCheck.provider(Api.MetroFactory.create()) val clockProvider = DoubleCheck.provider(Clock.MetroFactory.create()) val loggerProvider = DoubleCheck.provider(Logger.MetroFactory.create(clockProvider)) }