private void reportError(DiagnosticReporter diagnosticReporter, dagger.model.Binding binding) { diagnosticReporter.reportBinding( ERROR, binding, "%s may not depend on the production executor", binding.key()); } }
private String dependencyErrorMessage( DependencyEdge dependencyOnProduction, BindingGraph bindingGraph) { return String.format( "%s is a provision, which cannot depend on a production.", bindingRequestingDependency(dependencyOnProduction, bindingGraph).key()); } }
private boolean isDispatchingAndroidInjector(Binding binding) { Key key = binding.key(); return MoreTypes.isTypeOf(DispatchingAndroidInjector.class, key.type()) && !key.qualifier().isPresent(); }
private void checkForDuplicateMapKeys( dagger.model.Binding multiboundMapBinding, ImmutableSet<ContributionBinding> contributions, DiagnosticReporter diagnosticReporter) { ImmutableSetMultimap<Object, ContributionBinding> contributionsByMapKey = ImmutableSetMultimap.copyOf(Multimaps.index(contributions, ContributionBinding::mapKey)); for (Set<ContributionBinding> contributionsForOneMapKey : Multimaps.asMap(contributionsByMapKey).values()) { if (contributionsForOneMapKey.size() > 1) { diagnosticReporter.reportBinding( ERROR, multiboundMapBinding, duplicateMapKeyErrorMessage(contributionsForOneMapKey, multiboundMapBinding.key())); } } }
private void checkForInconsistentMapKeyAnnotationTypes( dagger.model.Binding multiboundMapBinding, ImmutableSet<ContributionBinding> contributions, DiagnosticReporter diagnosticReporter) { ImmutableSetMultimap<Equivalence.Wrapper<DeclaredType>, ContributionBinding> contributionsByMapKeyAnnotationType = indexByMapKeyAnnotationType(contributions); if (contributionsByMapKeyAnnotationType.keySet().size() > 1) { diagnosticReporter.reportBinding( ERROR, multiboundMapBinding, inconsistentMapKeyAnnotationTypesErrorMessage( contributionsByMapKeyAnnotationType, multiboundMapBinding.key())); } }
private void reportExplicitBindingConflictsWithInject( ImmutableSetMultimap<BindingElement, Binding> duplicateBindings, DiagnosticReporter diagnosticReporter, Kind diagnosticKind) { Binding injectBinding = rootmostBindingWithKind(k -> k.equals(INJECTION), duplicateBindings.values()); Binding explicitBinding = rootmostBindingWithKind(k -> !k.equals(INJECTION), duplicateBindings.values()); StringBuilder message = new StringBuilder() .append(explicitBinding.key()) .append(" is bound multiple times:") .append(formatWithComponentPath(injectBinding)) .append(formatWithComponentPath(explicitBinding)) .append( "\nThis condition was never validated before, and will soon be an error. " + "See https://google.github.io/dagger/conflicting-inject."); diagnosticReporter.reportBinding(diagnosticKind, explicitBinding, message.toString()); }
@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)); }
/** * Returns a stream of the dependencies of {@code binding} that have a key type of {@code Map<K, * Provider<AndroidInjector.Factory<?>>}. */ private Stream<Binding> injectorMapDependencies(Binding binding, BindingGraph graph) { return graph.requestedBindings(binding).stream() .filter(requestedBinding -> requestedBinding.kind().equals(BindingKind.MULTIBOUND_MAP)) .filter( requestedBinding -> { TypeMirror valueType = MoreTypes.asDeclared(requestedBinding.key().type()).getTypeArguments().get(1); if (!MoreTypes.isTypeOf(Provider.class, valueType) || !valueType.getKind().equals(TypeKind.DECLARED)) { return false; } TypeMirror providedType = MoreTypes.asDeclared(valueType).getTypeArguments().get(0); return MoreTypes.isTypeOf(AndroidInjector.Factory.class, providedType); }); }
private void reportDuplicateBindings( ImmutableSetMultimap<BindingElement, Binding> duplicateBindings, BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) { if (explicitBindingConfictsWithInject(duplicateBindings.keySet())) { compilerOptions .explicitBindingConflictsWithInjectValidationType() .diagnosticKind() .ifPresent( diagnosticKind -> reportExplicitBindingConflictsWithInject( duplicateBindings, diagnosticReporter, diagnosticKind)); return; } ImmutableSet<Binding> bindings = ImmutableSet.copyOf(duplicateBindings.values()); Binding oneBinding = bindings.asList().get(0); diagnosticReporter.reportBinding( ERROR, oneBinding, Iterables.any(bindings, binding -> binding.kind().isMultibinding()) ? incompatibleBindingsMessage(oneBinding.key(), bindings, bindingGraph) : duplicateBindingMessage(oneBinding.key(), bindings, bindingGraph)); }
@Override public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) { for (dagger.model.Binding binding : nullableBindings(bindingGraph)) { for (DependencyEdge dependencyEdge : nonNullableDependencies(bindingGraph, binding)) { diagnosticReporter.reportDependency( compilerOptions.nullableValidationKind(), dependencyEdge, nullableToNonNullable( binding.key().toString(), binding.toString())); // binding.toString() will include the @Nullable } } }
private void validateInjectionBinding( dagger.model.Binding node, DiagnosticReporter diagnosticReporter) { ValidationReport<TypeElement> typeReport = injectValidator.validateType(MoreTypes.asTypeElement(node.key().type())); for (Item item : typeReport.allItems()) { diagnosticReporter.reportBinding(item.kind(), node, item.message()); } } }