101 lines
4.7 KiB
Java
101 lines
4.7 KiB
Java
/*
|
|
* Copyright (C) 2015 The Dagger Authors.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package dagger.internal.codegen.writing;
|
|
|
|
import static com.google.common.base.Preconditions.checkNotNull;
|
|
import static com.squareup.javapoet.MethodSpec.methodBuilder;
|
|
import static com.squareup.javapoet.TypeSpec.anonymousClassBuilder;
|
|
import static dagger.internal.codegen.javapoet.TypeNames.dependencyMethodProducerOf;
|
|
import static dagger.internal.codegen.javapoet.TypeNames.listenableFutureOf;
|
|
import static javax.lang.model.element.Modifier.FINAL;
|
|
import static javax.lang.model.element.Modifier.PRIVATE;
|
|
import static javax.lang.model.element.Modifier.PUBLIC;
|
|
|
|
import com.squareup.javapoet.ClassName;
|
|
import com.squareup.javapoet.CodeBlock;
|
|
import com.squareup.javapoet.FieldSpec;
|
|
import com.squareup.javapoet.TypeName;
|
|
import dagger.internal.codegen.binding.BindingGraph;
|
|
import dagger.internal.codegen.binding.ComponentRequirement;
|
|
import dagger.internal.codegen.binding.ContributionBinding;
|
|
import dagger.internal.codegen.writing.FrameworkFieldInitializer.FrameworkInstanceCreationExpression;
|
|
|
|
/**
|
|
* A {@link dagger.producers.Producer} creation expression for a production method on a production
|
|
* component's {@linkplain dagger.producers.ProductionComponent#dependencies()} dependency} that
|
|
* returns a {@link com.google.common.util.concurrent.ListenableFuture}.
|
|
*/
|
|
// TODO(dpb): Resolve with DependencyMethodProviderCreationExpression.
|
|
final class DependencyMethodProducerCreationExpression
|
|
implements FrameworkInstanceCreationExpression {
|
|
private final ContributionBinding binding;
|
|
private final ComponentImplementation componentImplementation;
|
|
private final ComponentRequirementExpressions componentRequirementExpressions;
|
|
private final BindingGraph graph;
|
|
|
|
DependencyMethodProducerCreationExpression(
|
|
ContributionBinding binding,
|
|
ComponentImplementation componentImplementation,
|
|
ComponentRequirementExpressions componentRequirementExpressions,
|
|
BindingGraph graph) {
|
|
this.binding = checkNotNull(binding);
|
|
this.componentImplementation = checkNotNull(componentImplementation);
|
|
this.componentRequirementExpressions = checkNotNull(componentRequirementExpressions);
|
|
this.graph = checkNotNull(graph);
|
|
}
|
|
|
|
@Override
|
|
public CodeBlock creationExpression() {
|
|
ComponentRequirement dependency =
|
|
graph.componentDescriptor().getDependencyThatDefinesMethod(binding.bindingElement().get());
|
|
FieldSpec dependencyField =
|
|
FieldSpec.builder(
|
|
ClassName.get(dependency.typeElement()), dependency.variableName(), PRIVATE, FINAL)
|
|
.initializer(
|
|
componentRequirementExpressions.getExpressionDuringInitialization(
|
|
dependency,
|
|
// This isn't a real class name, but we want the requesting class for the
|
|
// expression to *not* be the same class as the component implementation,
|
|
// because it isn't... it's an anonymous inner class.
|
|
// TODO(cgdecker): If we didn't use an anonymous inner class here but instead
|
|
// generated a named nested class as with
|
|
// DependencyMethodProviderCreationExpression, we wouldn't need to deal with
|
|
// this and might be able to avoid potentially creating an extra field in the
|
|
// component?
|
|
componentImplementation.name().nestedClass("Anonymous")))
|
|
.build();
|
|
// TODO(b/70395982): Explore using a private static type instead of an anonymous class.
|
|
TypeName keyType = TypeName.get(binding.key().type());
|
|
return CodeBlock.of(
|
|
"$L",
|
|
anonymousClassBuilder("")
|
|
.superclass(dependencyMethodProducerOf(keyType))
|
|
.addField(dependencyField)
|
|
.addMethod(
|
|
methodBuilder("callDependencyMethod")
|
|
.addAnnotation(Override.class)
|
|
.addModifiers(PUBLIC)
|
|
.returns(listenableFutureOf(keyType))
|
|
.addStatement(
|
|
"return $N.$L()",
|
|
dependencyField,
|
|
binding.bindingElement().get().getSimpleName())
|
|
.build())
|
|
.build());
|
|
}
|
|
}
|