diff options
Diffstat (limited to 'java/dagger/internal/codegen/writing/ComponentBindingExpressions.java')
-rw-r--r-- | java/dagger/internal/codegen/writing/ComponentBindingExpressions.java | 76 |
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()); - } } |