diff options
author | Brad Corso <bcorso@google.com> | 2023-12-07 11:46:49 -0800 |
---|---|---|
committer | Dagger Team <dagger-dev+copybara@google.com> | 2023-12-07 11:52:47 -0800 |
commit | f4b45197f95133f286860674467b74506aefc79c (patch) | |
tree | eb91f8b2e12a12a1e15142465dba3e689cdf5756 | |
parent | eb9a034572a0749f0af5017369bd8d87b65500eb (diff) | |
download | dagger2-f4b45197f95133f286860674467b74506aefc79c.tar.gz |
Internal changes
RELNOTES=N/A
PiperOrigin-RevId: 588861836
3 files changed, 59 insertions, 38 deletions
diff --git a/java/dagger/internal/codegen/base/TarjanSCCs.java b/java/dagger/internal/codegen/base/TarjanSCCs.java index ab9a0fdae..b089333b0 100644 --- a/java/dagger/internal/codegen/base/TarjanSCCs.java +++ b/java/dagger/internal/codegen/base/TarjanSCCs.java @@ -20,6 +20,7 @@ import static com.google.common.base.Preconditions.checkState; import static java.lang.Math.min; import com.google.common.collect.ImmutableCollection; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableSet; import com.google.common.collect.Maps; import com.google.common.collect.Sets; @@ -39,7 +40,7 @@ import java.util.Set; public final class TarjanSCCs { /** Returns the set of strongly connected components in reverse topological order. */ - public static <NodeT> ImmutableSet<ImmutableSet<NodeT>> compute( + public static <NodeT> ImmutableList<ImmutableSet<NodeT>> compute( ImmutableCollection<NodeT> nodes, SuccessorsFunction<NodeT> successorsFunction) { return new TarjanSCC<>(nodes, successorsFunction).compute(); } @@ -62,14 +63,14 @@ public final class TarjanSCCs { this.lowLinks = Maps.newHashMapWithExpectedSize(nodes.size()); } - private ImmutableSet<ImmutableSet<NodeT>> compute() { + private ImmutableList<ImmutableSet<NodeT>> compute() { checkState(indexes.isEmpty(), "TarjanSCC#compute() can only be called once per instance!"); for (NodeT node : nodes) { if (!indexes.containsKey(node)) { stronglyConnect(node); } } - return ImmutableSet.copyOf(stronglyConnectedComponents); + return ImmutableList.copyOf(stronglyConnectedComponents); } private void stronglyConnect(NodeT node) { diff --git a/java/dagger/internal/codegen/binding/BindingGraph.java b/java/dagger/internal/codegen/binding/BindingGraph.java index 092f8ff9a..0090b3d2a 100644 --- a/java/dagger/internal/codegen/binding/BindingGraph.java +++ b/java/dagger/internal/codegen/binding/BindingGraph.java @@ -149,7 +149,7 @@ public abstract class BindingGraph { /** Returns the set of strongly connected nodes in this graph in reverse topological order. */ @Memoized - public ImmutableSet<ImmutableSet<Node>> stronglyConnectedNodes() { + public ImmutableList<ImmutableSet<Node>> stronglyConnectedNodes() { return TarjanSCCs.<Node>compute( ImmutableSet.copyOf(network().nodes()), // NetworkBuilder does not have a stable successor order, so we have to roll our own diff --git a/java/dagger/internal/codegen/binding/BindingGraphFactory.java b/java/dagger/internal/codegen/binding/BindingGraphFactory.java index 72eb17d80..941001044 100644 --- a/java/dagger/internal/codegen/binding/BindingGraphFactory.java +++ b/java/dagger/internal/codegen/binding/BindingGraphFactory.java @@ -648,8 +648,7 @@ public final class BindingGraphFactory implements ClearableCache { * ResolvedBindings#owningComponent(ContributionBinding)}. */ private XTypeElement getOwningComponent(Key requestKey, ContributionBinding binding) { - if (isResolvedInParent(requestKey, binding) - && !new RequiresResolutionChecker().requiresResolution(binding)) { + if (isResolvedInParent(requestKey, binding) && !requiresResolution(binding)) { ResolvedBindings parentResolvedBindings = parentResolver.get().resolvedContributionBindings.get(requestKey); return parentResolvedBindings.owningComponent(binding); @@ -876,7 +875,7 @@ public final class BindingGraphFactory implements ClearableCache { previouslyResolvedBindings.bindings().stream() .anyMatch(binding -> binding.kind() == BindingKind.ASSISTED_INJECTION); if (!isAssistedInjectionBinding - && !new RequiresResolutionChecker().requiresResolution(key) + && !requiresResolution(key) && getLocalExplicitBindings(key).isEmpty()) { /* Cache the inherited parent component's bindings in case resolving at the parent found * bindings in some component between this one and the previously-resolved one. */ @@ -921,7 +920,15 @@ public final class BindingGraphFactory implements ClearableCache { return resolvedMembersInjectionBindings.get(key); } - private final class RequiresResolutionChecker { + private boolean requiresResolution(Key key) { + return new LegacyRequiresResolutionChecker().requiresResolution(key); + } + + private boolean requiresResolution(Binding binding) { + return new LegacyRequiresResolutionChecker().requiresResolution(binding); + } + + private final class LegacyRequiresResolutionChecker { private final Set<Object> cycleChecker = new HashSet<>(); /** @@ -969,9 +976,7 @@ public final class BindingGraphFactory implements ClearableCache { Resolver.this, key); ResolvedBindings previouslyResolvedBindings = getPreviouslyResolvedBindings(key).get(); - if (hasLocalMultibindingContributions(key) - || hasLocalOptionalBindingContribution(previouslyResolvedBindings) - ) { + if (hasLocalBindings(previouslyResolvedBindings)) { return true; } @@ -995,35 +1000,50 @@ public final class BindingGraphFactory implements ClearableCache { } return false; } + } - /** - * Returns {@code true} if there is at least one multibinding contribution declared within - * this component's modules that matches the key. - */ - private boolean hasLocalMultibindingContributions(Key requestKey) { - return keysMatchingRequest(requestKey) - .stream() - .anyMatch(key -> !getLocalExplicitMultibindings(key).isEmpty()); - } + private boolean hasLocalBindings(Binding binding) { + return hasLocalMultibindingContributions(binding.key()) + || hasLocalOptionalBindingContribution( + binding.key(), ImmutableSet.of((ContributionBinding) binding)); + } - /** - * Returns {@code true} if there is a contribution in this component for an {@code - * Optional<Foo>} key that has not been contributed in a parent. - */ - private boolean hasLocalOptionalBindingContribution(ResolvedBindings resolvedBindings) { - if (resolvedBindings - .contributionBindings() - .stream() - .map(ContributionBinding::kind) - .anyMatch(isEqual(OPTIONAL))) { - return !getLocalExplicitBindings(keyFactory.unwrapOptional(resolvedBindings.key()).get()) - .isEmpty(); - } else { - // If a parent contributes a @Provides Optional<Foo> binding and a child has a - // @BindsOptionalOf Foo method, the two should conflict, even if there is no binding for - // Foo on its own - return !getOptionalBindingDeclarations(resolvedBindings.key()).isEmpty(); - } + private boolean hasLocalBindings(ResolvedBindings resolvedBindings) { + return hasLocalMultibindingContributions(resolvedBindings.key()) + || hasLocalOptionalBindingContribution(resolvedBindings); + } + + /** + * Returns {@code true} if there is at least one multibinding contribution declared within + * this component's modules that matches the key. + */ + private boolean hasLocalMultibindingContributions(Key requestKey) { + return keysMatchingRequest(requestKey) + .stream() + .anyMatch(key -> !getLocalExplicitMultibindings(key).isEmpty()); + } + + /** + * Returns {@code true} if there is a contribution in this component for an {@code + * Optional<Foo>} key that has not been contributed in a parent. + */ + private boolean hasLocalOptionalBindingContribution(ResolvedBindings resolvedBindings) { + return hasLocalOptionalBindingContribution( + resolvedBindings.key(), resolvedBindings.contributionBindings()); + } + + private boolean hasLocalOptionalBindingContribution( + Key key, ImmutableSet<ContributionBinding> previousContributionBindings) { + if (previousContributionBindings.stream() + .map(ContributionBinding::kind) + .anyMatch(isEqual(OPTIONAL))) { + return !getLocalExplicitBindings(keyFactory.unwrapOptional(key).get()) + .isEmpty(); + } else { + // If a parent contributes a @Provides Optional<Foo> binding and a child has a + // @BindsOptionalOf Foo method, the two should conflict, even if there is no binding for + // Foo on its own + return !getOptionalBindingDeclarations(key).isEmpty(); } } } |