aboutsummaryrefslogtreecommitdiff
path: root/java/dagger/internal/codegen/binding/BindingGraph.java
diff options
context:
space:
mode:
Diffstat (limited to 'java/dagger/internal/codegen/binding/BindingGraph.java')
-rw-r--r--java/dagger/internal/codegen/binding/BindingGraph.java72
1 files changed, 39 insertions, 33 deletions
diff --git a/java/dagger/internal/codegen/binding/BindingGraph.java b/java/dagger/internal/codegen/binding/BindingGraph.java
index 8dfe74f5f..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
@@ -212,14 +212,7 @@ public abstract class BindingGraph {
// particular BindingNode.
Map<Key, BindingNode> contributionBindings = new LinkedHashMap<>();
Map<Key, BindingNode> membersInjectionBindings = new LinkedHashMap<>();
-
- // Construct the maps of the ContributionBindings and MembersInjectionBindings by iterating
- // bindings from this component and then from each successive parent. If a binding exists in
- // multple components, this order ensures that the child-most binding is always chosen first.
- Stream.iterate(componentNode.componentPath(), ComponentPath::parent)
- // Stream.iterate is inifinte stream so we need limit it to the known size of the path.
- .limit(componentNode.componentPath().components().size())
- .flatMap(path -> topLevelBindingGraph.bindingsByComponent().get(path).stream())
+ topLevelBindingGraph.bindingsByComponent().get(componentNode.componentPath())
.forEach(
bindingNode -> {
if (bindingNode.delegate() instanceof ContributionBinding) {
@@ -233,16 +226,19 @@ public abstract class BindingGraph {
BindingGraph bindingGraph = new AutoValue_BindingGraph(componentNode, topLevelBindingGraph);
- ImmutableSet<ModuleDescriptor> modules =
- ((ComponentNodeImpl) componentNode).componentDescriptor().modules();
+ ImmutableSet<XTypeElement> modules =
+ ((ComponentNodeImpl) componentNode).componentDescriptor().modules().stream()
+ .map(ModuleDescriptor::moduleElement)
+ .collect(toImmutableSet());
- ImmutableSet<ModuleDescriptor> inheritedModules =
+ ImmutableSet<XTypeElement> inheritedModules =
parent.isPresent()
? Sets.union(parent.get().ownedModules, parent.get().inheritedModules).immutableCopy()
: ImmutableSet.of();
// Set these fields directly on the instance rather than passing these in as input to the
// AutoValue to prevent exposing this data outside of the class.
+ bindingGraph.parent = parent;
bindingGraph.inheritedModules = inheritedModules;
bindingGraph.ownedModules = Sets.difference(modules, inheritedModules).immutableCopy();
bindingGraph.contributionBindings = ImmutableMap.copyOf(contributionBindings);
@@ -257,10 +253,11 @@ public abstract class BindingGraph {
return bindingGraph;
}
+ private Optional<BindingGraph> parent;
private ImmutableMap<Key, BindingNode> contributionBindings;
private ImmutableMap<Key, BindingNode> membersInjectionBindings;
- private ImmutableSet<ModuleDescriptor> inheritedModules;
- private ImmutableSet<ModuleDescriptor> ownedModules;
+ private ImmutableSet<XTypeElement> inheritedModules;
+ private ImmutableSet<XTypeElement> ownedModules;
private ImmutableSet<XTypeElement> bindingModules;
BindingGraph() {}
@@ -287,9 +284,7 @@ public abstract class BindingGraph {
*/
public final Optional<Binding> localContributionBinding(Key key) {
return contributionBindings.containsKey(key)
- ? Optional.of(contributionBindings.get(key))
- .filter(bindingNode -> bindingNode.componentPath().equals(componentPath()))
- .map(BindingNode::delegate)
+ ? Optional.of(contributionBindings.get(key).delegate())
: Optional.empty();
}
@@ -299,15 +294,18 @@ public abstract class BindingGraph {
*/
public final Optional<Binding> localMembersInjectionBinding(Key key) {
return membersInjectionBindings.containsKey(key)
- ? Optional.of(membersInjectionBindings.get(key))
- .filter(bindingNode -> bindingNode.componentPath().equals(componentPath()))
- .map(BindingNode::delegate)
+ ? Optional.of(membersInjectionBindings.get(key).delegate())
: Optional.empty();
}
/** Returns the {@link ContributionBinding} for the given {@link Key}. */
public final ContributionBinding contributionBinding(Key key) {
- return (ContributionBinding) contributionBindings.get(key).delegate();
+ if (contributionBindings.containsKey(key)) {
+ return (ContributionBinding) contributionBindings.get(key).delegate();
+ } else if (parent.isPresent()) {
+ return parent.get().contributionBinding(key);
+ }
+ throw new AssertionError("Contribution binding not found for key: " + key);
}
/**
@@ -315,9 +313,12 @@ public abstract class BindingGraph {
* Optional#empty()} if one does not exist.
*/
public final Optional<MembersInjectionBinding> membersInjectionBinding(Key key) {
- return membersInjectionBindings.containsKey(key)
- ? Optional.of((MembersInjectionBinding) membersInjectionBindings.get(key).delegate())
- : Optional.empty();
+ if (membersInjectionBindings.containsKey(key)) {
+ return Optional.of((MembersInjectionBinding) membersInjectionBindings.get(key).delegate());
+ } else if (parent.isPresent()) {
+ return parent.get().membersInjectionBinding(key);
+ }
+ return Optional.empty();
}
/** Returns the {@link XTypeElement} for the component this graph represents. */
@@ -334,9 +335,7 @@ public abstract class BindingGraph {
* ancestors.
*/
public final ImmutableSet<XTypeElement> ownedModuleTypes() {
- return ownedModules.stream()
- .map(ModuleDescriptor::moduleElement)
- .collect(toImmutableSet());
+ return ownedModules;
}
/**
@@ -394,7 +393,7 @@ public abstract class BindingGraph {
ImmutableSet<XTypeElement> requiredModules =
stream(Traverser.forTree(BindingGraph::subgraphs).depthFirstPostOrder(this))
.flatMap(graph -> graph.bindingModules.stream())
- .filter(ownedModuleTypes()::contains)
+ .filter(ownedModules::contains)
.collect(toImmutableSet());
ImmutableSet.Builder<ComponentRequirement> requirements = ImmutableSet.builder();
componentDescriptor().requirements().stream()
@@ -433,11 +432,18 @@ public abstract class BindingGraph {
return topLevelBindingGraph().bindingsByComponent().get(componentPath());
}
- @Memoized
+ // TODO(bcorso): This method can be costly. Consider removing this method and inlining it into its
+ // only usage, BindingGraphJsonGenerator.
public ImmutableSet<BindingNode> bindingNodes() {
- return ImmutableSet.<BindingNode>builder()
- .addAll(contributionBindings.values())
- .addAll(membersInjectionBindings.values())
- .build();
+ // Construct the set of bindings by iterating bindings from this component and then from each
+ // successive parent. If a binding exists in multiple components, this order ensures that the
+ // child-most binding is always chosen first.
+ Map<Key, BindingNode> bindings = new LinkedHashMap<>();
+ Stream.iterate(componentPath(), ComponentPath::parent)
+ // Stream.iterate() is infinite stream so we need limit it to the known size of the path.
+ .limit(componentPath().components().size())
+ .flatMap(path -> topLevelBindingGraph().bindingsByComponent().get(path).stream())
+ .forEach(bindingNode -> bindings.putIfAbsent(bindingNode.key(), bindingNode));
+ return ImmutableSet.copyOf(bindings.values());
}
}