1 /* 2 * Copyright (C) 2018 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.internal.codegen.componentgenerator; 18 19 import dagger.BindsInstance; 20 import dagger.Module; 21 import dagger.Provides; 22 import dagger.Subcomponent; 23 import dagger.internal.codegen.binding.BindingGraph; 24 import dagger.internal.codegen.compileroption.CompilerOptions; 25 import dagger.internal.codegen.writing.ComponentImplementation; 26 import dagger.internal.codegen.writing.ComponentImplementation.ChildComponentImplementationFactory; 27 import dagger.internal.codegen.writing.ComponentRequestRepresentations; 28 import dagger.internal.codegen.writing.ComponentRequirementExpressions; 29 import dagger.internal.codegen.writing.ComponentWrapperImplementation; 30 import dagger.internal.codegen.writing.GeneratedImplementation; 31 import dagger.internal.codegen.writing.ParentComponent; 32 import dagger.internal.codegen.writing.PerComponentImplementation; 33 import dagger.internal.codegen.writing.TopLevel; 34 import java.util.Optional; 35 import javax.inject.Provider; 36 37 /** 38 * A subcomponent that injects all objects that are responsible for creating a single {@link 39 * ComponentImplementation} instance. Each child {@link ComponentImplementation} will have its own 40 * instance of {@link CurrentImplementationSubcomponent}. 41 */ 42 @Subcomponent( 43 modules = CurrentImplementationSubcomponent.ChildComponentImplementationFactoryModule.class) 44 @PerComponentImplementation 45 // This only needs to be public because the type is referenced by generated component. 46 public interface CurrentImplementationSubcomponent { componentImplementation()47 ComponentImplementation componentImplementation(); 48 49 /** A module to bind the {@link ChildComponentImplementationFactory}. */ 50 @Module 51 interface ChildComponentImplementationFactoryModule { 52 @Provides provideChildComponentImplementationFactory( CurrentImplementationSubcomponent.Builder currentImplementationSubcomponentBuilder, Provider<ComponentImplementation> componentImplementation, Provider<ComponentRequestRepresentations> componentRequestRepresentations, Provider<ComponentRequirementExpressions> componentRequirementExpressions)53 static ChildComponentImplementationFactory provideChildComponentImplementationFactory( 54 CurrentImplementationSubcomponent.Builder currentImplementationSubcomponentBuilder, 55 Provider<ComponentImplementation> componentImplementation, 56 Provider<ComponentRequestRepresentations> componentRequestRepresentations, 57 Provider<ComponentRequirementExpressions> componentRequirementExpressions) { 58 return childGraph -> 59 currentImplementationSubcomponentBuilder 60 .bindingGraph(childGraph) 61 .parentImplementation(Optional.of(componentImplementation.get())) 62 .parentRequestRepresentations(Optional.of(componentRequestRepresentations.get())) 63 .parentRequirementExpressions(Optional.of(componentRequirementExpressions.get())) 64 .build() 65 .componentImplementation(); 66 } 67 68 @Provides 69 @TopLevel provideTopLevelImplementation( ComponentImplementation componentImplementation, ComponentWrapperImplementation componentWrapperImplementation, CompilerOptions compilerOptions)70 static GeneratedImplementation provideTopLevelImplementation( 71 ComponentImplementation componentImplementation, 72 ComponentWrapperImplementation componentWrapperImplementation, 73 CompilerOptions compilerOptions) { 74 return compilerOptions.generatedClassExtendsComponent() 75 ? componentImplementation.rootComponentImplementation().getComponentShard() 76 : componentWrapperImplementation; 77 } 78 } 79 80 /** Returns the builder for {@link CurrentImplementationSubcomponent}. */ 81 @Subcomponent.Builder 82 interface Builder { 83 @BindsInstance bindingGraph(BindingGraph bindingGraph)84 Builder bindingGraph(BindingGraph bindingGraph); 85 86 @BindsInstance parentImplementation( @arentComponent Optional<ComponentImplementation> parentImplementation)87 Builder parentImplementation( 88 @ParentComponent Optional<ComponentImplementation> parentImplementation); 89 90 @BindsInstance parentRequestRepresentations( @arentComponent Optional<ComponentRequestRepresentations> parentRequestRepresentations)91 Builder parentRequestRepresentations( 92 @ParentComponent Optional<ComponentRequestRepresentations> parentRequestRepresentations); 93 94 @BindsInstance parentRequirementExpressions( @arentComponent Optional<ComponentRequirementExpressions> parentRequirementExpressions)95 Builder parentRequirementExpressions( 96 @ParentComponent Optional<ComponentRequirementExpressions> parentRequirementExpressions); 97 build()98 CurrentImplementationSubcomponent build(); 99 } 100 } 101