Add an Expression type, which is a tuple of a CodeBlock and the type that it represents. This will help implementing BindingExpressions for @Binds methods, in particular for the following case:
@Binds Foo to(FooImpl impl);
where Foo is public but FooImpl is not, nor is it in the same package as the component. If FooImpl is scoped, a rawtypes Provider will be used. Before this change, the BindingExpression for Foo had no way of knowing if the FooImpl it was receiving was in fact a FooImpl or an Object from the perspective of the compiler.
This should also hopefully simplify some of the logic in SimpleMethodBindingExpression and InjectionMethods where casting is needed.
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=170374236
diff --git a/java/dagger/internal/codegen/ComponentBindingExpressions.java b/java/dagger/internal/codegen/ComponentBindingExpressions.java
index b490765..7bb9312 100644
--- a/java/dagger/internal/codegen/ComponentBindingExpressions.java
+++ b/java/dagger/internal/codegen/ComponentBindingExpressions.java
@@ -18,16 +18,14 @@
import static dagger.internal.codegen.Accessibility.isRawTypeAccessible;
import static dagger.internal.codegen.Accessibility.isTypeAccessibleFrom;
-import static dagger.internal.codegen.TypeNames.rawTypeName;
import com.google.common.collect.FluentIterable;
import com.google.common.collect.ImmutableList;
import com.squareup.javapoet.ClassName;
-import com.squareup.javapoet.CodeBlock;
-import com.squareup.javapoet.TypeName;
import java.util.HashMap;
import java.util.Map;
import javax.lang.model.type.TypeMirror;
+import javax.lang.model.util.Types;
/** A central repository of code expressions used to access any binding available to a component. */
final class ComponentBindingExpressions {
@@ -41,14 +39,16 @@
* component; the second contains the bindings owned by its parent; and so on.
*/
private final ImmutableList<Map<BindingKey, BindingExpression>> bindingExpressionsMaps;
+ private final Types types;
private ComponentBindingExpressions(
- ImmutableList<Map<BindingKey, BindingExpression>> bindingExpressionsMaps) {
+ ImmutableList<Map<BindingKey, BindingExpression>> bindingExpressionsMaps, Types types) {
this.bindingExpressionsMaps = bindingExpressionsMaps;
+ this.types = types;
}
- ComponentBindingExpressions() {
- this(ImmutableList.of(newBindingExpressionMap()));
+ ComponentBindingExpressions(Types types) {
+ this(ImmutableList.of(newBindingExpressionMap()), types);
}
/**
@@ -59,9 +59,21 @@
* @throws IllegalStateException if there is no binding expression that satisfies the dependency
* request
*/
- CodeBlock getDependencyExpression(DependencyRequest request, ClassName requestingClass) {
- return getBindingExpression(request.bindingKey())
- .getDependencyExpression(request.kind(), requestingClass);
+ Expression getDependencyExpression(
+ BindingKey bindingKey, DependencyRequest.Kind requestKind, ClassName requestingClass) {
+ return getBindingExpression(bindingKey).getDependencyExpression(requestKind, requestingClass);
+ }
+
+ /**
+ * Returns an expression that evaluates to the value of a dependency request for a binding owned
+ * by this component or an ancestor.
+ *
+ * @param requestingClass the class that will contain the expression
+ * @throws IllegalStateException if there is no binding expression that satisfies the dependency
+ * request
+ */
+ Expression getDependencyExpression(DependencyRequest request, ClassName requestingClass) {
+ return getDependencyExpression(request.bindingKey(), request.kind(), requestingClass);
}
/**
@@ -72,10 +84,12 @@
* @throws IllegalStateException if there is no binding expression that satisfies the dependency
* request
*/
- CodeBlock getDependencyExpression(
+ Expression getDependencyExpression(
FrameworkDependency frameworkDependency, ClassName requestingClass) {
- return getBindingExpression(frameworkDependency.bindingKey())
- .getDependencyExpression(frameworkDependency.dependencyRequestKind(), requestingClass);
+ return getDependencyExpression(
+ frameworkDependency.bindingKey(),
+ frameworkDependency.dependencyRequestKind(),
+ requestingClass);
}
/**
@@ -89,18 +103,18 @@
* @param requestingClass the class that will contain the expression
*/
// TODO(b/64024402) Merge with getDependencyExpression(DependencyRequest, ClassName) if possible.
- CodeBlock getDependencyArgumentExpression(
+ Expression getDependencyArgumentExpression(
DependencyRequest dependencyRequest, ClassName requestingClass) {
- CodeBlock.Builder argument = CodeBlock.builder();
TypeMirror dependencyType = dependencyRequest.key().type();
+ Expression dependencyExpression = getDependencyExpression(dependencyRequest, requestingClass);
+
if (!isTypeAccessibleFrom(dependencyType, requestingClass.packageName())
&& isRawTypeAccessible(dependencyType, requestingClass.packageName())) {
- argument.add("($T) ", rawTypeName(TypeName.get(dependencyType)));
+ return dependencyExpression.castTo(types.erasure(dependencyType));
}
- argument.add(getDependencyExpression(dependencyRequest, requestingClass));
- return argument.build();
+ return dependencyExpression;
}
private BindingExpression getBindingExpression(BindingKey bindingKey) {
@@ -125,7 +139,8 @@
*/
ComponentBindingExpressions forChildComponent() {
return new ComponentBindingExpressions(
- FluentIterable.of(newBindingExpressionMap()).append(bindingExpressionsMaps).toList());
+ FluentIterable.of(newBindingExpressionMap()).append(bindingExpressionsMaps).toList(),
+ types);
}
private static Map<BindingKey, BindingExpression> newBindingExpressionMap() {