Remove unreachable nodes (from the root component node) from the binding graph model.

When bindings are copied down into child graphs because they transitively depend on local multibindings or optional bindings, the parent-owned binding is still there. If that parent-owned binding is not reachable from its component, it doesn't need to be in the graph because it will never be used. So remove all nodes that are not reachable from the root component.

RELNOTES=n/a

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=208475694
diff --git a/java/dagger/internal/codegen/BindingGraphConverter.java b/java/dagger/internal/codegen/BindingGraphConverter.java
index 533f434..c8bca97 100644
--- a/java/dagger/internal/codegen/BindingGraphConverter.java
+++ b/java/dagger/internal/codegen/BindingGraphConverter.java
@@ -17,6 +17,7 @@
 package dagger.internal.codegen;
 
 import static com.google.auto.common.MoreTypes.asTypeElement;
+import static dagger.internal.codegen.DaggerGraphs.unreachableNodes;
 import static dagger.internal.codegen.DaggerStreams.instancesOf;
 import static dagger.internal.codegen.DaggerStreams.presentValues;
 import static dagger.internal.codegen.DaggerStreams.toImmutableSet;
@@ -28,6 +29,7 @@
 import com.google.common.collect.ImmutableSet;
 import com.google.common.collect.Iterables;
 import com.google.common.graph.MutableNetwork;
+import com.google.common.graph.Network;
 import com.google.common.graph.NetworkBuilder;
 import dagger.internal.codegen.ComponentDescriptor.ComponentMethodDescriptor;
 import dagger.model.BindingGraph.BindingNode;
@@ -63,9 +65,26 @@
   dagger.model.BindingGraph convert(BindingGraph rootGraph) {
     Traverser traverser = new Traverser(rootGraph);
     traverser.traverseComponents();
+
+    // When bindings are copied down into child graphs because they transitively depend on local
+    // multibindings or optional bindings, the parent-owned binding is still there. If that
+    // parent-owned binding is not reachable from its component, it doesn't need to be in the graph
+    // because it will never be used. So remove all nodes that are not reachable from the root
+    // component.
+    unreachableNodes(traverser.network.asGraph(), rootComponentNode(traverser.network))
+        .forEach(traverser.network::removeNode);
+
     return BindingGraphProxies.bindingGraph(traverser.network);
   }
 
+  // TODO(dpb): Example of BindingGraph logic applied to derived networks.
+  private ComponentNode rootComponentNode(Network<Node, Edge> network) {
+    return (ComponentNode)
+        Iterables.find(
+            network.nodes(),
+            node -> node instanceof ComponentNode && node.componentPath().atRoot());
+  }
+
   private final class Traverser extends ComponentTreeTraverser {
 
     private final MutableNetwork<Node, Edge> network =
diff --git a/java/dagger/internal/codegen/DaggerGraphs.java b/java/dagger/internal/codegen/DaggerGraphs.java
index f0471da..e9f3842 100644
--- a/java/dagger/internal/codegen/DaggerGraphs.java
+++ b/java/dagger/internal/codegen/DaggerGraphs.java
@@ -16,9 +16,14 @@
 
 package dagger.internal.codegen;
 
+import static com.google.common.collect.Sets.difference;
+import static com.google.common.graph.Graphs.reachableNodes;
+
 import com.google.common.collect.ImmutableList;
 import com.google.common.collect.ImmutableSet;
+import com.google.common.graph.Graph;
 import com.google.common.graph.SuccessorsFunction;
+import dagger.model.BindingGraph.Node;
 import java.util.ArrayDeque;
 import java.util.HashMap;
 import java.util.Map;
@@ -85,5 +90,10 @@
     return ImmutableList.of();
   }
 
+  /** Returns the nodes in a graph that are not reachable from a node. */
+  static ImmutableSet<Node> unreachableNodes(Graph<Node> graph, Node node) {
+    return ImmutableSet.copyOf(difference(graph.nodes(), reachableNodes(graph, node)));
+  }
+
   private DaggerGraphs() {}
 }