@Override public void visitGraph(BindingGraph graph, DiagnosticReporter diagnosticReporter) { for (Binding binding : graph.bindings()) { if (isDispatchingAndroidInjector(binding)) { validateMapKeyUniqueness(binding, graph, diagnosticReporter); } } }
private ImmutableSet<ContributionBinding> mapBindingContributions( dagger.model.Binding binding, BindingGraph bindingGraph) { checkArgument(binding.kind().equals(MULTIBOUND_MAP)); return bindingGraph.requestedBindings(binding).stream() .map(b -> (BindingNode) b) .map(b -> (ContributionBinding) b.delegate()) .collect(toImmutableSet()); }
private ImmutableList<Node> shortestPathToCycleFromAnEntryPoint( Cycle<Node> cycle, BindingGraph bindingGraph) { Node someCycleNode = cycle.nodes().asList().get(0); ComponentNode componentContainingCycle = bindingGraph.componentNode(someCycleNode.componentPath()).get(); ImmutableList<Node> pathToCycle = shortestPath(bindingGraph.network(), componentContainingCycle, someCycleNode); return subpathToCycle(pathToCycle, cycle); }
@Override public void visitGraph(BindingGraph graph, DiagnosticReporter diagnosticReporter) { if (graph.isModuleBindingGraph() || graph.isPartialBindingGraph()) { return; // Don't report missing bindings when validating a module or a partial binding graph } graph .missingBindings() .forEach(missingBinding -> reportMissingBinding(missingBinding, graph, diagnosticReporter)); }
@Override public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) { if (bindingGraph.isModuleBindingGraph() || bindingGraph.isPartialBindingGraph()) { // We don't know all the modules that might be owned by the child until we know the root. return; } bindingGraph.network().edges().stream() .flatMap(instancesOf(ChildFactoryMethodEdge.class)) .forEach( edge -> { ImmutableSet<TypeElement> missingModules = findMissingModules(edge, bindingGraph); if (!missingModules.isEmpty()) { reportMissingModuleParameters( edge, missingModules, bindingGraph, diagnosticReporter); } }); }
@Override public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) { ImmutableSetMultimap.Builder<ComponentNode, dagger.model.Binding> incompatibleBindings = ImmutableSetMultimap.builder(); for (dagger.model.Binding binding : bindingGraph.bindings()) { binding .scope() .filter(scope -> !scope.isReusable()) .ifPresent( scope -> { ComponentNode componentNode = bindingGraph.componentNode(binding.componentPath()).get(); if (!componentNode.scopes().contains(scope)) { // @Inject bindings in module binding graphs will appear at the properly scoped // ancestor component, so ignore them here. if (binding.kind().equals(INJECTION) && bindingGraph.isModuleBindingGraph()) { return; } incompatibleBindings.put(componentNode, binding); } }); } Multimaps.asMap(incompatibleBindings.build()) .forEach( (componentNode, bindings) -> report(componentNode, bindings, bindingGraph, diagnosticReporter)); }
private DependencyEdge chooseDependencyEdgeConnecting( Node source, Node target, BindingGraph bindingGraph) { return bindingGraph.network().edgesConnecting(source, target).stream() .flatMap(instancesOf(DependencyEdge.class)) .findFirst() .get(); }
private ImmutableSet<TypeElement> findMissingModules( ChildFactoryMethodEdge edge, BindingGraph graph) { ImmutableSet<TypeElement> factoryMethodParameters = subgraphFactoryMethodParameters(edge, graph); ComponentNode child = (ComponentNode) graph.network().incidentNodes(edge).target(); SetView<TypeElement> modulesOwnedByChild = ownedModules(child, graph); return graph.bindings().stream() // bindings owned by child .filter(binding -> binding.componentPath().equals(child.componentPath())) // that require a module instance .filter(binding -> binding.requiresModuleInstance()) .map(binding -> binding.contributingModule().get()) .distinct() // module owned by child .filter(module -> modulesOwnedByChild.contains(module)) // module not in the method parameters .filter(module -> !factoryMethodParameters.contains(module)) // module doesn't have an accessible no-arg constructor .filter(moduleType -> !componentCanMakeNewInstances(moduleType)) .collect(toImmutableSet()); }
/** Returns the subgraph containing only {@link DependencyEdge}s that would not break a cycle. */ // TODO(dpb): Return a network containing only Binding nodes. private ImmutableNetwork<Node, DependencyEdge> nonCycleBreakingDependencyGraph( BindingGraph bindingGraph) { MutableNetwork<Node, DependencyEdge> dependencyNetwork = NetworkBuilder.from(bindingGraph.network()) .expectedNodeCount(bindingGraph.network().nodes().size()) .expectedEdgeCount(bindingGraph.dependencyEdges().size()) .build(); bindingGraph.dependencyEdges().stream() .filter(edge -> !breaksCycle(edge, bindingGraph)) .forEach( edge -> { EndpointPair<Node> endpoints = bindingGraph.network().incidentNodes(edge); dependencyNetwork.addEdge(endpoints.source(), endpoints.target(), edge); }); return ImmutableNetwork.copyOf(dependencyNetwork); }
@Override public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) { if (!compilerOptions.usesProducers()) { return; } Key productionImplementationExecutorKey = keyFactory.forProductionImplementationExecutor(); Key productionExecutorKey = keyFactory.forProductionExecutor(); bindingGraph.network().nodes().stream() .flatMap(instancesOf(MaybeBinding.class)) .filter(node -> node.key().equals(productionExecutorKey)) .flatMap(productionExecutor -> bindingGraph.requestingBindings(productionExecutor).stream()) .filter(binding -> !binding.key().equals(productionImplementationExecutorKey)) .forEach(binding -> reportError(diagnosticReporter, binding)); }
if (bindingGraph.isModuleBindingGraph()) { diagnosticReporter.reportComponent( ERROR, bindingGraph.componentNode(cycle.nodes().asList().get(0).componentPath()).get(), errorMessage(cycle, bindingGraph)); return;
DiagnosticInfo(DependencyEdge dependencyEdge) { requests = ImmutableSet.of(dependencyEdge); ImmutableList.Builder<DependencyEdge> dependencyTraceBuilder = ImmutableList.builder(); dependencyTraceBuilder.add(dependencyEdge); if (dependencyEdge.isEntryPoint()) { entryPoints = ImmutableSet.of(dependencyEdge); } else { // It's not an entry point, so it's part of a binding dagger.model.Binding binding = (dagger.model.Binding) source(dependencyEdge); entryPoints = graph.entryPointEdgesDependingOnBinding(binding); dependencyTraceBuilder.addAll(dependencyTrace(binding, entryPoints)); } dependencyTrace = dependencyTraceBuilder.build(); }
private Function<ComponentNode, Set<TypeElement>> uncachedInheritedModules(BindingGraph graph) { return componentNode -> componentNode.componentPath().atRoot() ? ImmutableSet.of() : graph .componentNode(componentNode.componentPath().parent()) .map(parent -> union(ownedModules(parent, graph), inheritedModules(parent, graph))) .get(); }
new StringBuilder(componentNode.componentPath().currentComponent().getQualifiedName()); if (bindingGraph.isModuleBindingGraph() && componentNode.componentPath().atRoot()) {
/** Returns the dependencies on {@code binding}. */ // TODO(dpb): Move to BindingGraph. private Stream<DependencyEdge> incomingDependencies( dagger.model.Binding binding, BindingGraph bindingGraph) { return bindingGraph.network().inEdges(binding).stream() .flatMap(instancesOf(DependencyEdge.class)); }
DiagnosticInfo(MaybeBinding binding) { entryPoints = graph.entryPointEdgesDependingOnBinding(binding); requests = requests(binding); dependencyTrace = dependencyTrace(binding, entryPoints); }
private ImmutableList<dagger.model.Binding> nullableBindings(BindingGraph bindingGraph) { return bindingGraph.bindings().stream() .filter(binding -> binding.isNullable()) .collect(toImmutableList()); }
private ImmutableSet<BindingDeclaration> declarations( BindingGraph graph, dagger.model.Binding binding) { ImmutableSet.Builder<BindingDeclaration> declarations = ImmutableSet.builder(); BindingNode bindingNode = (BindingNode) binding; bindingNode.associatedDeclarations().forEach(declarations::add); if (bindingDeclarationFormatter.canFormat(bindingNode.delegate())) { declarations.add(bindingNode.delegate()); } else { graph.requestedBindings(binding).stream() .flatMap(requestedBinding -> declarations(graph, requestedBinding).stream()) .forEach(declarations::add); } return declarations.build(); }
private boolean allIncomingDependenciesCanUseProduction( MissingBinding missingBinding, BindingGraph graph) { return graph.network().inEdges(missingBinding).stream() .flatMap(instancesOf(DependencyEdge.class)) .allMatch(edge -> dependencyCanBeProduction(edge, graph)); }
private Stream<DependencyEdge> provisionDependenciesOnProductionBindings( BindingGraph bindingGraph) { return bindingGraph.bindings().stream() .filter(binding -> binding.isProduction()) .flatMap(binding -> incomingDependencies(binding, bindingGraph)) .filter(edge -> !dependencyCanUseProduction(edge, bindingGraph)); }