Use a raw framework class to avoid Java 7's poor type inference when scoping generic @Inject classes.
Fixes https://github.com/google/dagger/issues/671
-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=154187714
diff --git a/java/dagger/internal/codegen/AbstractComponentWriter.java b/java/dagger/internal/codegen/AbstractComponentWriter.java
index 8262d7a..97b89c9 100644
--- a/java/dagger/internal/codegen/AbstractComponentWriter.java
+++ b/java/dagger/internal/codegen/AbstractComponentWriter.java
@@ -34,6 +34,7 @@
import static dagger.internal.codegen.BindingKey.contribution;
import static dagger.internal.codegen.CodeBlocks.makeParametersCodeBlock;
import static dagger.internal.codegen.ContributionBinding.FactoryCreationStrategy.SINGLETON_INSTANCE;
+import static dagger.internal.codegen.ContributionBinding.Kind.INJECTION;
import static dagger.internal.codegen.ErrorMessages.CANNOT_RETURN_NULL_FROM_NON_NULLABLE_COMPONENT_METHOD;
import static dagger.internal.codegen.MapKeys.getMapKeyExpression;
import static dagger.internal.codegen.MemberSelect.emptyFrameworkMapFactory;
@@ -967,10 +968,7 @@
ImmutableList.of(
initializeDeferredDependencies(binding),
initializeMember(
- bindingKey,
- binding.scope().isPresent()
- ? decorateForScope(delegatingCodeBlock, binding.scope().get())
- : delegatingCodeBlock))));
+ bindingKey, decorateForScope(delegatingCodeBlock, binding.scope())))));
case SINGLETON_INSTANCE:
if (!binding.scope().isPresent()) {
return Optional.empty();
@@ -1201,9 +1199,16 @@
"$T.create($L)",
generatedClassNameForBinding(binding),
makeParametersCodeBlock(arguments));
- return binding.scope().isPresent()
- ? decorateForScope(factoryCreate, binding.scope().get())
- : factoryCreate;
+
+ // If scoping a parameterized factory for an @Inject class, Java 7 cannot always infer the
+ // type properly, so cast to a raw framework type before scoping.
+ if (binding.bindingKind().equals(INJECTION)
+ && binding.unresolved().isPresent()
+ && binding.scope().isPresent()) {
+ factoryCreate =
+ CodeBlock.of("($T) $L", binding.bindingType().frameworkClass(), factoryCreate);
+ }
+ return decorateForScope(factoryCreate, binding.scope());
}
case COMPONENT_PRODUCTION:
@@ -1278,7 +1283,11 @@
return graph.componentDescriptor().dependencyMethodIndex().get(binding.bindingElement().get());
}
- private CodeBlock decorateForScope(CodeBlock factoryCreate, Scope scope) {
+ private CodeBlock decorateForScope(CodeBlock factoryCreate, Optional<Scope> maybeScope) {
+ if (!maybeScope.isPresent()) {
+ return factoryCreate;
+ }
+ Scope scope = maybeScope.get();
if (requiresReleasableReferences(scope)) {
return CodeBlock.of(
"$T.create($L, $L)",
diff --git a/java/dagger/internal/codegen/ContributionBinding.java b/java/dagger/internal/codegen/ContributionBinding.java
index ee6edd7..b95f04a 100644
--- a/java/dagger/internal/codegen/ContributionBinding.java
+++ b/java/dagger/internal/codegen/ContributionBinding.java
@@ -226,7 +226,7 @@
/**
* The {@link TypeMirror type} for the {@code Factory<T>} or {@code Producer<T>} which is created
- * for this binding. Uses the binding's key, V in the came of {@code Map<K, FrameworkClass<V>>>},
+ * for this binding. Uses the binding's key, V in the case of {@code Map<K, FrameworkClass<V>>>},
* and E {@code Set<E>} for {@link dagger.multibindings.IntoSet @IntoSet} methods.
*/
final TypeMirror contributedType() {