1 /* 2 * Copyright (C) 2017 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 static com.google.common.base.Preconditions.checkNotNull; 20 import static com.google.common.base.Preconditions.checkState; 21 import static com.squareup.javapoet.MethodSpec.methodBuilder; 22 import static dagger.internal.codegen.binding.AssistedInjectionAnnotations.assistedParameterSpecs; 23 import static dagger.internal.codegen.writing.ComponentImplementation.MethodSpecKind.PRIVATE_METHOD; 24 import static javax.lang.model.element.Modifier.PRIVATE; 25 26 import com.google.common.collect.ImmutableList; 27 import com.squareup.javapoet.TypeName; 28 import dagger.internal.codegen.binding.BindingRequest; 29 import dagger.internal.codegen.binding.ContributionBinding; 30 import dagger.internal.codegen.compileroption.CompilerOptions; 31 import dagger.internal.codegen.langmodel.DaggerTypes; 32 import dagger.model.BindingKind; 33 34 /** 35 * A binding expression that wraps the dependency expressions in a private, no-arg method. 36 * 37 * <p>Dependents of this binding expression will just call the no-arg private method. 38 */ 39 final class PrivateMethodBindingExpression extends MethodBindingExpression { 40 private final ContributionBinding binding; 41 private final BindingRequest request; 42 private final ComponentImplementation componentImplementation; 43 private final CompilerOptions compilerOptions; 44 private final DaggerTypes types; 45 private String methodName; 46 PrivateMethodBindingExpression( BindingRequest request, ContributionBinding binding, MethodImplementationStrategy methodImplementationStrategy, BindingExpression wrappedBindingExpression, ComponentImplementation componentImplementation, DaggerTypes types, CompilerOptions compilerOptions)47 PrivateMethodBindingExpression( 48 BindingRequest request, 49 ContributionBinding binding, 50 MethodImplementationStrategy methodImplementationStrategy, 51 BindingExpression wrappedBindingExpression, 52 ComponentImplementation componentImplementation, 53 DaggerTypes types, 54 CompilerOptions compilerOptions) { 55 super( 56 request, 57 binding, 58 methodImplementationStrategy, 59 wrappedBindingExpression, 60 componentImplementation, 61 types); 62 this.binding = binding; 63 this.request = checkNotNull(request); 64 this.componentImplementation = checkNotNull(componentImplementation); 65 this.compilerOptions = checkNotNull(compilerOptions); 66 this.types = types; 67 } 68 69 @Override addMethod()70 protected void addMethod() { 71 if (methodName == null) { 72 // Have to set methodName field before implementing the method in order to handle recursion. 73 methodName = componentImplementation.getUniqueMethodName(request); 74 75 // TODO(bcorso): Fix the order that these generated methods are written to the component. 76 componentImplementation.addMethod( 77 PRIVATE_METHOD, 78 methodBuilder(methodName) 79 .addModifiers(PRIVATE) 80 .addParameters( 81 // Private methods for assisted injection take assisted parameters as input. 82 binding.kind() == BindingKind.ASSISTED_INJECTION 83 ? assistedParameterSpecs(binding, types) 84 : ImmutableList.of()) 85 .returns(TypeName.get(returnType())) 86 .addCode(methodBody()) 87 .build()); 88 } 89 } 90 91 @Override methodName()92 protected String methodName() { 93 checkState(methodName != null, "addMethod() must be called before methodName()"); 94 return methodName; 95 } 96 } 97