1 /* 2 * Copyright (C) 2021 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.writing; 18 19 import com.squareup.javapoet.CodeBlock; 20 import dagger.internal.codegen.binding.ComponentRequirement; 21 import dagger.internal.codegen.binding.ContributionBinding; 22 import dagger.internal.codegen.binding.ProvisionBinding; 23 import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression; 24 import javax.inject.Inject; 25 26 /** 27 * A factory for creating unscoped creation expressions for a provision or production binding. 28 * 29 * <p>A creation expression is responsible for creating the factory for a given binding (e.g. by 30 * calling the generated factory create method, {@code Foo_Factory.create(...)}). Note that this 31 * class does not handle scoping of these factories (e.g. wrapping in {@code 32 * DoubleCheck.provider()}). 33 */ 34 final class UnscopedFrameworkInstanceCreationExpressionFactory { 35 private final ComponentImplementation componentImplementation; 36 private final ComponentRequirementExpressions componentRequirementExpressions; 37 private final AnonymousProviderCreationExpression.Factory 38 anonymousProviderCreationExpressionFactory; 39 private final DelegatingFrameworkInstanceCreationExpression.Factory 40 delegatingFrameworkInstanceCreationExpressionFactory; 41 private final DependencyMethodProducerCreationExpression.Factory 42 dependencyMethodProducerCreationExpressionFactory; 43 private final DependencyMethodProviderCreationExpression.Factory 44 dependencyMethodProviderCreationExpressionFactory; 45 private final InjectionOrProvisionProviderCreationExpression.Factory 46 injectionOrProvisionProviderCreationExpressionFactory; 47 private final MapFactoryCreationExpression.Factory mapFactoryCreationExpressionFactory; 48 private final MembersInjectorProviderCreationExpression.Factory 49 membersInjectorProviderCreationExpressionFactory; 50 private final OptionalFactoryInstanceCreationExpression.Factory 51 optionalFactoryInstanceCreationExpressionFactory; 52 private final ProducerCreationExpression.Factory producerCreationExpressionFactory; 53 private final SetFactoryCreationExpression.Factory setFactoryCreationExpressionFactory; 54 55 @Inject UnscopedFrameworkInstanceCreationExpressionFactory( ComponentImplementation componentImplementation, ComponentRequirementExpressions componentRequirementExpressions, AnonymousProviderCreationExpression.Factory anonymousProviderCreationExpressionFactory, DelegatingFrameworkInstanceCreationExpression.Factory delegatingFrameworkInstanceCreationExpressionFactory, DependencyMethodProducerCreationExpression.Factory dependencyMethodProducerCreationExpressionFactory, DependencyMethodProviderCreationExpression.Factory dependencyMethodProviderCreationExpressionFactory, InjectionOrProvisionProviderCreationExpression.Factory injectionOrProvisionProviderCreationExpressionFactory, MapFactoryCreationExpression.Factory mapFactoryCreationExpressionFactory, MembersInjectorProviderCreationExpression.Factory membersInjectorProviderCreationExpressionFactory, OptionalFactoryInstanceCreationExpression.Factory optionalFactoryInstanceCreationExpressionFactory, ProducerCreationExpression.Factory producerCreationExpressionFactory, SetFactoryCreationExpression.Factory setFactoryCreationExpressionFactory)56 UnscopedFrameworkInstanceCreationExpressionFactory( 57 ComponentImplementation componentImplementation, 58 ComponentRequirementExpressions componentRequirementExpressions, 59 AnonymousProviderCreationExpression.Factory anonymousProviderCreationExpressionFactory, 60 DelegatingFrameworkInstanceCreationExpression.Factory 61 delegatingFrameworkInstanceCreationExpressionFactory, 62 DependencyMethodProducerCreationExpression.Factory 63 dependencyMethodProducerCreationExpressionFactory, 64 DependencyMethodProviderCreationExpression.Factory 65 dependencyMethodProviderCreationExpressionFactory, 66 InjectionOrProvisionProviderCreationExpression.Factory 67 injectionOrProvisionProviderCreationExpressionFactory, 68 MapFactoryCreationExpression.Factory mapFactoryCreationExpressionFactory, 69 MembersInjectorProviderCreationExpression.Factory 70 membersInjectorProviderCreationExpressionFactory, 71 OptionalFactoryInstanceCreationExpression.Factory 72 optionalFactoryInstanceCreationExpressionFactory, 73 ProducerCreationExpression.Factory producerCreationExpressionFactory, 74 SetFactoryCreationExpression.Factory setFactoryCreationExpressionFactory) { 75 this.componentImplementation = componentImplementation; 76 this.componentRequirementExpressions = componentRequirementExpressions; 77 this.anonymousProviderCreationExpressionFactory = anonymousProviderCreationExpressionFactory; 78 this.delegatingFrameworkInstanceCreationExpressionFactory = 79 delegatingFrameworkInstanceCreationExpressionFactory; 80 this.dependencyMethodProducerCreationExpressionFactory = 81 dependencyMethodProducerCreationExpressionFactory; 82 this.dependencyMethodProviderCreationExpressionFactory = 83 dependencyMethodProviderCreationExpressionFactory; 84 this.injectionOrProvisionProviderCreationExpressionFactory = 85 injectionOrProvisionProviderCreationExpressionFactory; 86 this.mapFactoryCreationExpressionFactory = mapFactoryCreationExpressionFactory; 87 this.membersInjectorProviderCreationExpressionFactory = 88 membersInjectorProviderCreationExpressionFactory; 89 this.optionalFactoryInstanceCreationExpressionFactory = 90 optionalFactoryInstanceCreationExpressionFactory; 91 this.producerCreationExpressionFactory = producerCreationExpressionFactory; 92 this.setFactoryCreationExpressionFactory = setFactoryCreationExpressionFactory; 93 } 94 95 /** 96 * Returns an unscoped creation expression for a {@link javax.inject.Provider} for provision 97 * bindings or a {@link dagger.producers.Producer} for production bindings. 98 */ create(ContributionBinding binding)99 FrameworkInstanceCreationExpression create(ContributionBinding binding) { 100 switch (binding.kind()) { 101 case COMPONENT: 102 // The cast can be removed when we drop java 7 source support 103 return new InstanceFactoryCreationExpression( 104 () -> 105 CodeBlock.of( 106 "($T) $L", 107 binding.key().type().xprocessing().getTypeName(), 108 componentImplementation.componentFieldReference())); 109 110 case BOUND_INSTANCE: 111 return instanceFactoryCreationExpression( 112 binding, ComponentRequirement.forBoundInstance(binding)); 113 114 case COMPONENT_DEPENDENCY: 115 return instanceFactoryCreationExpression( 116 binding, ComponentRequirement.forDependency(binding.key().type().xprocessing())); 117 118 case COMPONENT_PROVISION: 119 return dependencyMethodProviderCreationExpressionFactory.create((ProvisionBinding) binding); 120 121 case SUBCOMPONENT_CREATOR: 122 return anonymousProviderCreationExpressionFactory.create(binding); 123 124 case ASSISTED_FACTORY: 125 case ASSISTED_INJECTION: 126 case INJECTION: 127 case PROVISION: 128 return injectionOrProvisionProviderCreationExpressionFactory.create(binding); 129 130 case COMPONENT_PRODUCTION: 131 return dependencyMethodProducerCreationExpressionFactory.create(binding); 132 133 case PRODUCTION: 134 return producerCreationExpressionFactory.create(binding); 135 136 case MULTIBOUND_SET: 137 return setFactoryCreationExpressionFactory.create(binding); 138 139 case MULTIBOUND_MAP: 140 return mapFactoryCreationExpressionFactory.create(binding); 141 142 case DELEGATE: 143 return delegatingFrameworkInstanceCreationExpressionFactory.create(binding); 144 145 case OPTIONAL: 146 return optionalFactoryInstanceCreationExpressionFactory.create(binding); 147 148 case MEMBERS_INJECTOR: 149 return membersInjectorProviderCreationExpressionFactory.create((ProvisionBinding) binding); 150 151 default: 152 throw new AssertionError(binding); 153 } 154 } 155 instanceFactoryCreationExpression( ContributionBinding binding, ComponentRequirement componentRequirement)156 private InstanceFactoryCreationExpression instanceFactoryCreationExpression( 157 ContributionBinding binding, ComponentRequirement componentRequirement) { 158 return new InstanceFactoryCreationExpression( 159 binding.isNullable(), 160 () -> 161 componentRequirementExpressions.getExpressionDuringInitialization( 162 componentRequirement, componentImplementation.name())); 163 } 164 } 165