diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java index 61e270b0603..f2117171a67 100644 --- a/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java +++ b/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java @@ -44,7 +44,7 @@ import dagger.internal.codegen.model.BindingGraph; import dagger.internal.codegen.model.BindingGraph.DependencyEdge; import dagger.internal.codegen.model.BindingGraph.MissingBinding; -import dagger.internal.codegen.model.DaggerAnnotation; +import dagger.internal.codegen.model.DaggerType; import dagger.internal.codegen.model.DiagnosticReporter; import dagger.internal.codegen.model.Key; import dagger.internal.codegen.validation.DiagnosticMessageGenerator; @@ -53,8 +53,6 @@ import java.util.ArrayDeque; import java.util.Deque; import java.util.Iterator; -import java.util.List; -import java.util.Optional; import javax.inject.Inject; /** Reports errors for missing bindings. */ @@ -114,17 +112,21 @@ private void reportMissingBinding( private static ImmutableSet getSimilarTypeBindings( BindingGraph graph, Key missingBindingKey) { - XType missingBindingType = missingBindingKey.type().xprocessing(); - Optional missingBindingQualifier = missingBindingKey.qualifier(); - ImmutableList flatMissingBindingType = flattenBindingType(missingBindingType); + ImmutableList flatMissingBindingType = flattenBindingType(missingBindingKey.type()); if (flatMissingBindingType.size() <= 1) { return ImmutableSet.of(); } return graph.bindings().stream() - .filter( - binding -> - binding.key().qualifier().equals(missingBindingQualifier) - && isSimilarType(binding.key().type().xprocessing(), flatMissingBindingType)) + // Filter out multibinding contributions (users can't request these directly). + .filter(binding -> binding.key().multibindingContributionIdentifier().isEmpty()) + // Filter out keys with the exact same type (those are reported elsewhere). + .filter(binding -> !binding.key().type().equals(missingBindingKey.type())) + // Filter out keys with different qualifiers. + // TODO(bcorso): We should consider allowing keys with different qualifiers here, as that + // could actually be helpful when users forget a qualifier annotation on the request. + .filter(binding -> binding.key().qualifier().equals(missingBindingKey.qualifier())) + // Filter out keys that don't have a similar type (i.e. same type if ignoring wildcards). + .filter(binding -> isSimilarType(binding.key().type(), flatMissingBindingType)) .collect(toImmutableSet()); } @@ -132,11 +134,11 @@ && isSimilarType(binding.key().type().xprocessing(), flatMissingBindingType)) * Unwraps a parameterized type to a list of TypeNames. e.g. {@code Map>} to {@code * [Map, Foo, List, Bar]}. */ - private static ImmutableList flattenBindingType(XType type) { + private static ImmutableList flattenBindingType(DaggerType type) { return ImmutableList.copyOf(new TypeDfsIterator(type)); } - private static boolean isSimilarType(XType type, List flatTypeNames) { + private static boolean isSimilarType(DaggerType type, ImmutableList flatTypeNames) { return Iterators.elementsEqual(flatTypeNames.iterator(), new TypeDfsIterator(type)); } @@ -261,8 +263,8 @@ private boolean typeHasInjectionSites(Key key) { private static class TypeDfsIterator implements Iterator { final Deque stack = new ArrayDeque<>(); - TypeDfsIterator(XType root) { - stack.push(root); + TypeDfsIterator(DaggerType root) { + stack.push(root.xprocessing()); } @Override diff --git a/javatests/dagger/internal/codegen/MissingBindingValidationTest.java b/javatests/dagger/internal/codegen/MissingBindingValidationTest.java index 360fb8fcd77..4910011df8f 100644 --- a/javatests/dagger/internal/codegen/MissingBindingValidationTest.java +++ b/javatests/dagger/internal/codegen/MissingBindingValidationTest.java @@ -1460,12 +1460,6 @@ public void requestWildcardTypeWithNonWildcardTypeBindingProvided_failsWithMissi "Note: A similar binding is provided in the following other components:", " Set is provided at:", " [MyComponent] Dagger-generated binding for Set", - // TODO(b/360278200): Remove multibinding contributions from this list. - " Set TestModule#provideBars is provided at:", - " [MyComponent] TestModule.provideBars()", - // TODO(b/360278200): Remove this as it's already listed above. - " Set is provided at:", - " [Child] ChildModule.provideBar()", JVM_SUPPRESS_WILDCARDS_MESSAGE, "", "======================")) @@ -1539,9 +1533,6 @@ public void requestWildcardTypeWithNonWildcardTypeBindingProvided_failsWithMissi "Note: A similar binding is provided in the following other components:", " Set is provided at:", " [MyComponent] Dagger-generated binding for Set", - // TODO(b/360278200): Remove multibinding contributions from this list. - " Set TestModule#provideBars is provided at:", - " [MyComponent] TestModule.provideBars()", JVM_SUPPRESS_WILDCARDS_MESSAGE, "", "======================")) @@ -1618,9 +1609,6 @@ public void injectWildcardTypeWithNonWildcardTypeBindingProvided_failsWithMissin "Note: A similar binding is provided in the following other components:", " Set is provided at:", " [MyComponent] Dagger-generated binding for Set", - // TODO(b/360278200): Remove multibinding contributions from this list. - " Set TestModule#provideBars is provided at:", - " [MyComponent] TestModule.provideBars()", JVM_SUPPRESS_WILDCARDS_MESSAGE, "", "======================"))