• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
18 
19 import static com.squareup.javapoet.MethodSpec.constructorBuilder;
20 import static dagger.internal.codegen.BindingRequest.bindingRequest;
21 import static dagger.model.RequestKind.INSTANCE;
22 import static javax.lang.model.element.Modifier.FINAL;
23 import static javax.lang.model.element.Modifier.PRIVATE;
24 
25 import com.squareup.javapoet.ClassName;
26 import com.squareup.javapoet.CodeBlock;
27 import com.squareup.javapoet.TypeName;
28 import com.squareup.javapoet.TypeSpec;
29 import dagger.internal.codegen.javapoet.Expression;
30 import dagger.internal.codegen.langmodel.DaggerTypes;
31 import dagger.model.Key;
32 import javax.inject.Provider;
33 import javax.lang.model.type.TypeMirror;
34 
35 /**
36  * Generates {@linkplain BindingExpression binding expressions} for a binding that is represented by
37  * an inner {@code SwitchingProvider} class.
38  */
39 final class InnerSwitchingProviders extends SwitchingProviders {
40   private final ComponentBindingExpressions componentBindingExpressions;
41   private final DaggerTypes types;
42 
InnerSwitchingProviders( ComponentImplementation componentImplementation, ComponentBindingExpressions componentBindingExpressions, DaggerTypes types)43   InnerSwitchingProviders(
44       ComponentImplementation componentImplementation,
45       ComponentBindingExpressions componentBindingExpressions,
46       DaggerTypes types) {
47     super(componentImplementation, types);
48     this.componentBindingExpressions = componentBindingExpressions;
49     this.types = types;
50   }
51 
52   /**
53    * Returns the binding expression for a binding that satisfies a {@link Provider} requests with a
54    * inner {@code SwitchingProvider} class.
55    */
newBindingExpression(ContributionBinding binding)56   BindingExpression newBindingExpression(ContributionBinding binding) {
57     return new BindingExpression() {
58       @Override
59       Expression getDependencyExpression(ClassName requestingClass) {
60         return getProviderExpression(new SwitchCase(binding, requestingClass));
61       }
62     };
63   }
64 
65   @Override
66   protected TypeSpec createSwitchingProviderType(TypeSpec.Builder builder) {
67     return builder
68         .addModifiers(PRIVATE, FINAL)
69         .addField(TypeName.INT, "id", PRIVATE, FINAL)
70         .addMethod(
71             constructorBuilder()
72                 .addParameter(TypeName.INT, "id")
73                 .addStatement("this.id = id")
74                 .build())
75         .build();
76   }
77 
78   private final class SwitchCase implements SwitchingProviders.SwitchCase {
79     private final ContributionBinding binding;
80     private final ClassName requestingClass;
81 
82     SwitchCase(ContributionBinding binding, ClassName requestingClass) {
83       this.binding = binding;
84       this.requestingClass = requestingClass;
85     }
86 
87     @Override
88     public Key key() {
89       return binding.key();
90     }
91 
92     @Override
93     public Expression getProviderExpression(ClassName switchingProviderClass, int switchId) {
94       TypeMirror instanceType = types.accessibleType(binding.contributedType(), requestingClass);
95       return Expression.create(
96           types.wrapType(instanceType, Provider.class),
97           CodeBlock.of("new $T<>($L)", switchingProviderClass, switchId));
98     }
99 
100     @Override
101     public Expression getReturnExpression(ClassName switchingProviderClass) {
102       return componentBindingExpressions.getDependencyExpression(
103           bindingRequest(binding.key(), INSTANCE), switchingProviderClass);
104     }
105   }
106 }
107