• 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 import static dagger.internal.codegen.langmodel.Accessibility.isTypeAccessibleFrom;
21 import static dagger.internal.codegen.xprocessing.XProcessingEnvs.wrapType;
22 
23 import androidx.room.compiler.processing.XProcessingEnv;
24 import androidx.room.compiler.processing.XType;
25 import com.squareup.javapoet.ClassName;
26 import dagger.internal.codegen.binding.ContributionBinding;
27 import dagger.internal.codegen.binding.FrameworkType;
28 import dagger.internal.codegen.javapoet.Expression;
29 import dagger.internal.codegen.javapoet.ExpressionType;
30 
31 /** A binding expression that uses a {@link FrameworkType} field. */
32 abstract class FrameworkInstanceRequestRepresentation extends RequestRepresentation {
33   private final ContributionBinding binding;
34   private final FrameworkInstanceSupplier frameworkInstanceSupplier;
35   private final XProcessingEnv processingEnv;
36 
FrameworkInstanceRequestRepresentation( ContributionBinding binding, FrameworkInstanceSupplier frameworkInstanceSupplier, XProcessingEnv processingEnv)37   FrameworkInstanceRequestRepresentation(
38       ContributionBinding binding,
39       FrameworkInstanceSupplier frameworkInstanceSupplier,
40       XProcessingEnv processingEnv) {
41     this.binding = checkNotNull(binding);
42     this.frameworkInstanceSupplier = checkNotNull(frameworkInstanceSupplier);
43     this.processingEnv = checkNotNull(processingEnv);
44   }
45 
46   /**
47    * The expression for the framework instance for this binding. The field will be initialized and
48    * added to the component the first time this method is invoked.
49    */
50   @Override
getDependencyExpression(ClassName requestingClass)51   Expression getDependencyExpression(ClassName requestingClass) {
52     MemberSelect memberSelect = frameworkInstanceSupplier.memberSelect();
53     XType expressionType =
54         wrapType(frameworkType().frameworkClassName(), binding.contributedType(), processingEnv);
55     return Expression.create(
56         isTypeAccessibleFrom(binding.contributedType(), requestingClass.packageName())
57                 || isInlinedFactoryCreation(memberSelect)
58             ? ExpressionType.create(expressionType)
59             : ExpressionType.createRawType(expressionType),
60         memberSelect.getExpressionFor(requestingClass));
61   }
62 
63   /** Returns the framework type for the binding. */
frameworkType()64   protected abstract FrameworkType frameworkType();
65 
66   /**
67    * Returns {@code true} if a factory is created inline each time it is requested. For example, in
68    * the initialization {@code this.fooProvider = Foo_Factory.create(Bar_Factory.create());}, {@code
69    * Bar_Factory} is considered to be inline.
70    *
71    * <p>This is used in {@link #getDependencyExpression(ClassName)} when determining the type of a
72    * factory. Normally if the {@link ContributionBinding#contributedType()} is not accessible from
73    * the component, the type of the expression will be a raw {@link javax.inject.Provider}. However,
74    * if the factory is created inline, even if contributed type is not accessible, javac will still
75    * be able to determine the type that is returned from the {@code Foo_Factory.create()} method.
76    */
isInlinedFactoryCreation(MemberSelect memberSelect)77   private static boolean isInlinedFactoryCreation(MemberSelect memberSelect) {
78     return memberSelect.staticMember();
79   }
80 }
81