aboutsummaryrefslogtreecommitdiff
path: root/java/dagger/internal/codegen/writing/ComponentBindingExpressions.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/dagger/internal/codegen/writing/ComponentBindingExpressions.java')
-rw-r--r--java/dagger/internal/codegen/writing/ComponentBindingExpressions.java76
1 files changed, 45 insertions, 31 deletions
diff --git a/java/dagger/internal/codegen/writing/ComponentBindingExpressions.java b/java/dagger/internal/codegen/writing/ComponentBindingExpressions.java
index dc15c998b..5f1f0bdd8 100644
--- a/java/dagger/internal/codegen/writing/ComponentBindingExpressions.java
+++ b/java/dagger/internal/codegen/writing/ComponentBindingExpressions.java
@@ -212,14 +212,19 @@ public final class ComponentBindingExpressions {
public MethodSpec getComponentMethod(ComponentMethodDescriptor componentMethod) {
checkArgument(componentMethod.dependencyRequest().isPresent());
BindingRequest request = bindingRequest(componentMethod.dependencyRequest().get());
- return MethodSpec.overriding(
+ MethodSpec.Builder method =
+ MethodSpec.overriding(
componentMethod.methodElement(),
MoreTypes.asDeclared(graph.componentTypeElement().asType()),
- types)
- .addCode(
- getBindingExpression(request)
- .getComponentMethodImplementation(componentMethod, componentImplementation))
- .build();
+ types);
+ // Even though this is not used if the method is abstract, we need to invoke the binding
+ // expression in order for the side of effect of the method being added to the
+ // ComponentImplementation
+ CodeBlock methodBody =
+ getBindingExpression(request)
+ .getComponentMethodImplementation(componentMethod, componentImplementation);
+
+ return method.addCode(methodBody).build();
}
/** Returns the {@link BindingExpression} for the given {@link BindingRequest}. */
@@ -455,7 +460,8 @@ public final class ComponentBindingExpressions {
private BindingExpression providerBindingExpression(ContributionBinding binding) {
if (binding.kind().equals(DELEGATE) && !needsCaching(binding)) {
return new DelegateBindingExpression(binding, RequestKind.PROVIDER, this, types, elements);
- } else if (isFastInit()
+ } else if (compilerOptions.fastInit(
+ topLevelComponentImplementation.componentDescriptor().typeElement())
&& frameworkInstanceCreationExpression(binding).useInnerSwitchingProvider()
&& !(instanceBindingExpression(binding)
instanceof DerivedFromFrameworkInstanceBindingExpression)) {
@@ -487,27 +493,24 @@ public final class ComponentBindingExpressions {
/**
* Returns a binding expression for {@link RequestKind#INSTANCE} requests.
+ *
+ * <p>If there is a direct expression (not calling {@link Provider#get()}) we can use for an
+ * instance of this binding, return it, wrapped in a method if the binding {@linkplain
+ * #needsCaching(ContributionBinding) needs to be cached} or the expression has dependencies.
+ *
+ * <p>In fastInit mode, we can use direct expressions unless the binding needs to be cached.
*/
private BindingExpression instanceBindingExpression(ContributionBinding binding) {
Optional<BindingExpression> maybeDirectInstanceExpression =
unscopedDirectInstanceExpression(binding);
- if (maybeDirectInstanceExpression.isPresent()) {
- // If this is the case where we don't need to use Provider#get() because there's no caching
- // and it isn't an assisted factory, or because we're in fastInit mode (since fastInit avoids
- // using Providers), we can try to use the direct expression, possibly wrapped in a method
- // if necessary (e.g. it has dependencies).
- if ((!needsCaching(binding) && binding.kind() != BindingKind.ASSISTED_FACTORY)
- || isFastInit()) {
- BindingExpression directInstanceExpression = maybeDirectInstanceExpression.get();
- // While this can't require caching in default mode, if we're in fastInit mode and we need
- // caching we also need to wrap it in a method.
- return directInstanceExpression.requiresMethodEncapsulation() || needsCaching(binding)
- ? wrapInMethod(
- binding,
- bindingRequest(binding.key(), RequestKind.INSTANCE),
- directInstanceExpression)
- : directInstanceExpression;
- }
+ if (canUseDirectInstanceExpression(binding) && maybeDirectInstanceExpression.isPresent()) {
+ BindingExpression directInstanceExpression = maybeDirectInstanceExpression.get();
+ return directInstanceExpression.requiresMethodEncapsulation() || needsCaching(binding)
+ ? wrapInMethod(
+ binding,
+ bindingRequest(binding.key(), RequestKind.INSTANCE),
+ directInstanceExpression)
+ : directInstanceExpression;
}
return new DerivedFromFrameworkInstanceBindingExpression(
binding.key(), FrameworkType.PROVIDER, RequestKind.INSTANCE, this, types);
@@ -607,12 +610,27 @@ public final class ComponentBindingExpressions {
* MapFactory} or {@code SetFactory}.
*/
private boolean useStaticFactoryCreation(ContributionBinding binding) {
- return !isFastInit()
+ return !compilerOptions.fastInit(
+ topLevelComponentImplementation.componentDescriptor().typeElement())
|| binding.kind().equals(MULTIBOUND_MAP)
|| binding.kind().equals(MULTIBOUND_SET);
}
/**
+ * Returns {@code true} if we can use a direct (not {@code Provider.get()}) expression for this
+ * binding. If the binding doesn't {@linkplain #needsCaching(ContributionBinding) need to be
+ * cached} and the binding is not an {@link BindingKind.ASSISTED_FACTORY}, we can.
+ *
+ * <p>In fastInit mode, we can use a direct expression even if the binding {@linkplain
+ * #needsCaching(ContributionBinding) needs to be cached}.
+ */
+ private boolean canUseDirectInstanceExpression(ContributionBinding binding) {
+ return (!needsCaching(binding) && binding.kind() != BindingKind.ASSISTED_FACTORY)
+ || compilerOptions.fastInit(
+ topLevelComponentImplementation.componentDescriptor().typeElement());
+ }
+
+ /**
* Returns a binding expression that uses a given one as the body of a method that users call. If
* a component provision method matches it, it will be the method implemented. If it does not
* match a component provision method and the binding is modifiable, then a new public modifiable
@@ -672,7 +690,8 @@ public final class ComponentBindingExpressions {
private MethodImplementationStrategy methodImplementationStrategy(
ContributionBinding binding, BindingRequest request) {
- if (isFastInit()) {
+ if (compilerOptions.fastInit(
+ topLevelComponentImplementation.componentDescriptor().typeElement())) {
if (request.isRequestKind(RequestKind.PROVIDER)) {
return MethodImplementationStrategy.SINGLE_CHECK;
} else if (request.isRequestKind(RequestKind.INSTANCE) && needsCaching(binding)) {
@@ -699,9 +718,4 @@ public final class ComponentBindingExpressions {
}
return true;
}
-
- private boolean isFastInit() {
- return compilerOptions.fastInit(
- topLevelComponentImplementation.componentDescriptor().typeElement());
- }
}