• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
21 import com.squareup.javapoet.ClassName;
22 import com.squareup.javapoet.CodeBlock;
23 import dagger.internal.codegen.binding.BindingRequest;
24 import dagger.internal.codegen.binding.ComponentDescriptor.ComponentMethodDescriptor;
25 import dagger.internal.codegen.binding.ContributionBinding;
26 import dagger.internal.codegen.javapoet.Expression;
27 import dagger.internal.codegen.langmodel.DaggerTypes;
28 import javax.lang.model.type.TypeMirror;
29 
30 /**
31  * A binding expression that implements and uses a component method.
32  *
33  * <p>Dependents of this binding expression will just call the component method.
34  */
35 final class ComponentMethodBindingExpression extends MethodBindingExpression {
36   private final ComponentImplementation componentImplementation;
37   private final ComponentMethodDescriptor componentMethod;
38 
ComponentMethodBindingExpression( BindingRequest request, ContributionBinding binding, MethodImplementationStrategy methodImplementationStrategy, BindingExpression wrappedBindingExpression, ComponentImplementation componentImplementation, ComponentMethodDescriptor componentMethod, DaggerTypes types)39   ComponentMethodBindingExpression(
40       BindingRequest request,
41       ContributionBinding binding,
42       MethodImplementationStrategy methodImplementationStrategy,
43       BindingExpression wrappedBindingExpression,
44       ComponentImplementation componentImplementation,
45       ComponentMethodDescriptor componentMethod,
46       DaggerTypes types) {
47     super(
48         request,
49         binding,
50         methodImplementationStrategy,
51         wrappedBindingExpression,
52         componentImplementation,
53         types);
54     this.componentImplementation = checkNotNull(componentImplementation);
55     this.componentMethod = checkNotNull(componentMethod);
56   }
57 
58   @Override
getComponentMethodImplementation( ComponentMethodDescriptor componentMethod, ComponentImplementation component)59   protected CodeBlock getComponentMethodImplementation(
60       ComponentMethodDescriptor componentMethod, ComponentImplementation component) {
61     // There could be several methods on the component for the same request key and kind.
62     // Only one should use the BindingMethodImplementation; the others can delegate that one. So
63     // use methodImplementation.body() only if componentMethod equals the method for this instance.
64 
65     // Separately, the method might be defined on a supertype that is also a supertype of some
66     // parent component. In that case, the same ComponentMethodDescriptor will be used to add a CMBE
67     // for the parent and the child. Only the parent's should use the BindingMethodImplementation;
68     // the child's can delegate to the parent. So use methodImplementation.body() only if
69     // componentName equals the component for this instance.
70     return componentMethod.equals(this.componentMethod) && component.equals(componentImplementation)
71         ? methodBodyForComponentMethod(componentMethod)
72         : super.getComponentMethodImplementation(componentMethod, component);
73   }
74 
75   @Override
getDependencyExpression(ClassName requestingClass)76   Expression getDependencyExpression(ClassName requestingClass) {
77     // If a component method returns a primitive, update the expression's type which might be boxed.
78     Expression expression = super.getDependencyExpression(requestingClass);
79     TypeMirror methodReturnType = componentMethod.methodElement().getReturnType();
80     return methodReturnType.getKind().isPrimitive()
81         ? Expression.create(methodReturnType, expression.codeBlock())
82         : expression;
83   }
84 
85   @Override
addMethod()86   protected void addMethod() {}
87 
88   @Override
methodName()89   protected String methodName() {
90     return componentMethod.methodElement().getSimpleName().toString();
91   }
92 }
93