Support revisit full binding graph from validation plugins.
RELNOTES=n/a
PiperOrigin-RevId: 504878700
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/BindingGraphValidationModule.java b/java/dagger/internal/codegen/bindinggraphvalidation/BindingGraphValidationModule.java
index 2df35e8..7e32bec 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/BindingGraphValidationModule.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/BindingGraphValidationModule.java
@@ -21,6 +21,7 @@
import dagger.Provides;
import dagger.internal.codegen.compileroption.CompilerOptions;
import dagger.internal.codegen.validation.Validation;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.BindingGraphPlugin;
/** Binds the set of {@link BindingGraphPlugin}s used to implement Dagger validation. */
@@ -29,7 +30,7 @@
@Provides
@Validation
- static ImmutableSet<BindingGraphPlugin> providePlugins(
+ static ImmutableSet<ValidationBindingGraphPlugin> providePlugins(
CompositeBindingGraphPlugin.Factory factory,
CompilerOptions compilerOptions,
DependencyCycleValidator validation1,
@@ -43,18 +44,19 @@
ProvisionDependencyOnProducerBindingValidator validation9,
SetMultibindingValidator validation10,
SubcomponentFactoryMethodValidator validation11) {
- ImmutableSet<BindingGraphPlugin> plugins = ImmutableSet.of(
- validation1,
- validation2,
- validation3,
- validation4,
- validation5,
- validation6,
- validation7,
- validation8,
- validation9,
- validation10,
- validation11);
+ ImmutableSet<ValidationBindingGraphPlugin> plugins =
+ ImmutableSet.of(
+ validation1,
+ validation2,
+ validation3,
+ validation4,
+ validation5,
+ validation6,
+ validation7,
+ validation8,
+ validation9,
+ validation10,
+ validation11);
if (compilerOptions.experimentalDaggerErrorMessages()) {
return ImmutableSet.of(factory.create(plugins));
} else {
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/CompositeBindingGraphPlugin.java b/java/dagger/internal/codegen/bindinggraphvalidation/CompositeBindingGraphPlugin.java
index cb1668a..a328158 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/CompositeBindingGraphPlugin.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/CompositeBindingGraphPlugin.java
@@ -30,6 +30,7 @@
import dagger.assisted.AssistedFactory;
import dagger.assisted.AssistedInject;
import dagger.internal.codegen.validation.DiagnosticMessageGenerator;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.ChildFactoryMethodEdge;
import dagger.spi.model.BindingGraph.ComponentNode;
@@ -38,27 +39,29 @@
import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DaggerProcessingEnv;
import dagger.spi.model.DiagnosticReporter;
+import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import javax.tools.Diagnostic;
/**
- * Combines many {@link BindingGraphPlugin} implementations. This helps reduce spam by combining
- * all of the messages that are reported on the root component.
+ * Combines many {@link BindingGraphPlugin} implementations. This helps reduce spam by combining all
+ * of the messages that are reported on the root component.
*/
-final class CompositeBindingGraphPlugin implements BindingGraphPlugin {
+final class CompositeBindingGraphPlugin extends ValidationBindingGraphPlugin {
@AssistedFactory
interface Factory {
- CompositeBindingGraphPlugin create(ImmutableSet<BindingGraphPlugin> plugins);
+ CompositeBindingGraphPlugin create(ImmutableSet<ValidationBindingGraphPlugin> plugins);
}
- private final ImmutableSet<BindingGraphPlugin> plugins;
+ private final ImmutableSet<ValidationBindingGraphPlugin> plugins;
private final DiagnosticMessageGenerator.Factory messageGeneratorFactory;
+ private final Map<ComponentNode, String> errorMessages = new HashMap<>();
@AssistedInject
CompositeBindingGraphPlugin(
- @Assisted ImmutableSet<BindingGraphPlugin> plugins,
+ @Assisted ImmutableSet<ValidationBindingGraphPlugin> plugins,
DiagnosticMessageGenerator.Factory messageGeneratorFactory) {
this.plugins = plugins;
this.messageGeneratorFactory = messageGeneratorFactory;
@@ -68,10 +71,38 @@
public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
AggregatingDiagnosticReporter aggregatingDiagnosticReporter = new AggregatingDiagnosticReporter(
bindingGraph, diagnosticReporter, messageGeneratorFactory.create(bindingGraph));
- plugins.forEach(plugin -> {
- aggregatingDiagnosticReporter.setCurrentPlugin(plugin.pluginName());
- plugin.visitGraph(bindingGraph, aggregatingDiagnosticReporter);
- });
+ plugins.forEach(
+ plugin -> {
+ aggregatingDiagnosticReporter.setCurrentPlugin(plugin.pluginName());
+ plugin.visitGraph(bindingGraph, aggregatingDiagnosticReporter);
+ if (plugin.visitFullGraphRequested(bindingGraph)) {
+ requestVisitFullGraph(bindingGraph);
+ }
+ });
+ if (visitFullGraphRequested(bindingGraph)) {
+ errorMessages.put(
+ bindingGraph.rootComponentNode(), aggregatingDiagnosticReporter.getMessage());
+ } else {
+ aggregatingDiagnosticReporter.report();
+ }
+ }
+
+ @Override
+ public void revisitFullGraph(
+ BindingGraph prunedGraph, BindingGraph fullGraph, DiagnosticReporter diagnosticReporter) {
+ AggregatingDiagnosticReporter aggregatingDiagnosticReporter =
+ new AggregatingDiagnosticReporter(
+ fullGraph,
+ diagnosticReporter,
+ errorMessages.get(prunedGraph.rootComponentNode()),
+ messageGeneratorFactory.create(fullGraph));
+ plugins.stream()
+ .filter(plugin -> plugin.visitFullGraphRequested(prunedGraph))
+ .forEach(
+ plugin -> {
+ aggregatingDiagnosticReporter.setCurrentPlugin(plugin.pluginName());
+ plugin.revisitFullGraph(prunedGraph, fullGraph, aggregatingDiagnosticReporter);
+ });
aggregatingDiagnosticReporter.report();
}
@@ -118,6 +149,17 @@
this.messageGenerator = messageGenerator;
}
+ AggregatingDiagnosticReporter(
+ BindingGraph graph,
+ DiagnosticReporter delegate,
+ String baseMessage,
+ DiagnosticMessageGenerator messageGenerator) {
+ this.graph = graph;
+ this.delegate = delegate;
+ this.messageGenerator = messageGenerator;
+ this.messageBuilder.append(baseMessage);
+ }
+
/** Sets the currently running aggregated plugin. Used to add a diagnostic prefix. */
void setCurrentPlugin(String pluginName) {
currentPluginName = pluginName;
@@ -133,6 +175,10 @@
}
}
+ String getMessage() {
+ return messageBuilder.toString();
+ }
+
@Override
public void reportComponent(Diagnostic.Kind diagnosticKind, ComponentNode componentNode,
String message) {
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java
index f2cb90b..f42f7ad 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/DependencyCycleValidator.java
@@ -44,12 +44,12 @@
import dagger.internal.codegen.base.OptionalType;
import dagger.internal.codegen.binding.DependencyRequestFormatter;
import dagger.internal.codegen.javapoet.TypeNames;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.ComponentNode;
import dagger.spi.model.BindingGraph.DependencyEdge;
import dagger.spi.model.BindingGraph.Node;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.BindingKind;
import dagger.spi.model.DependencyRequest;
import dagger.spi.model.DiagnosticReporter;
@@ -61,7 +61,7 @@
import javax.inject.Inject;
/** Reports errors for dependency cycles. */
-final class DependencyCycleValidator implements BindingGraphPlugin {
+final class DependencyCycleValidator extends ValidationBindingGraphPlugin {
private final DependencyRequestFormatter dependencyRequestFormatter;
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/DependsOnProductionExecutorValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/DependsOnProductionExecutorValidator.java
index 1d44133..4bdff69 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/DependsOnProductionExecutorValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/DependsOnProductionExecutorValidator.java
@@ -21,10 +21,10 @@
import dagger.internal.codegen.binding.KeyFactory;
import dagger.internal.codegen.compileroption.CompilerOptions;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.MaybeBinding;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DiagnosticReporter;
import dagger.spi.model.Key;
import javax.inject.Inject;
@@ -33,7 +33,7 @@
* Reports an error on all bindings that depend explicitly on the {@code @Production Executor} key.
*/
// TODO(dpb,beder): Validate this during @Inject/@Provides/@Produces validation.
-final class DependsOnProductionExecutorValidator implements BindingGraphPlugin {
+final class DependsOnProductionExecutorValidator extends ValidationBindingGraphPlugin {
private final CompilerOptions compilerOptions;
private final KeyFactory keyFactory;
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/DuplicateBindingsValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/DuplicateBindingsValidator.java
index 286fa7f..2b11f17 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/DuplicateBindingsValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/DuplicateBindingsValidator.java
@@ -44,10 +44,10 @@
import dagger.internal.codegen.binding.BindingNode;
import dagger.internal.codegen.binding.MultibindingDeclaration;
import dagger.internal.codegen.compileroption.CompilerOptions;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.ComponentNode;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.BindingKind;
import dagger.spi.model.ComponentPath;
import dagger.spi.model.DaggerElement;
@@ -63,7 +63,7 @@
import javax.tools.Diagnostic.Kind;
/** Reports errors for conflicting bindings with the same key. */
-final class DuplicateBindingsValidator implements BindingGraphPlugin {
+final class DuplicateBindingsValidator extends ValidationBindingGraphPlugin {
private static final Comparator<Binding> BY_LENGTH_OF_COMPONENT_PATH =
comparing(binding -> binding.componentPath().components().size());
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/IncompatiblyScopedBindingsValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/IncompatiblyScopedBindingsValidator.java
index b9cf89c..3643870 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/IncompatiblyScopedBindingsValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/IncompatiblyScopedBindingsValidator.java
@@ -30,10 +30,10 @@
import dagger.internal.codegen.binding.MethodSignatureFormatter;
import dagger.internal.codegen.compileroption.CompilerOptions;
import dagger.internal.codegen.validation.DiagnosticMessageGenerator;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.ComponentNode;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DiagnosticReporter;
import java.util.Optional;
import java.util.Set;
@@ -44,7 +44,7 @@
* Reports an error for any component that uses bindings with scopes that are not assigned to the
* component.
*/
-final class IncompatiblyScopedBindingsValidator implements BindingGraphPlugin {
+final class IncompatiblyScopedBindingsValidator extends ValidationBindingGraphPlugin {
private final MethodSignatureFormatter methodSignatureFormatter;
private final CompilerOptions compilerOptions;
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/InjectBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/InjectBindingValidator.java
index ece8bbe..ae153a0 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/InjectBindingValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/InjectBindingValidator.java
@@ -19,16 +19,16 @@
import static dagger.spi.model.BindingKind.INJECTION;
import dagger.internal.codegen.validation.InjectValidator;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.internal.codegen.validation.ValidationReport;
import dagger.internal.codegen.validation.ValidationReport.Item;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DiagnosticReporter;
import javax.inject.Inject;
/** Validates bindings from {@code @Inject}-annotated constructors. */
-final class InjectBindingValidator implements BindingGraphPlugin {
+final class InjectBindingValidator extends ValidationBindingGraphPlugin {
private final InjectValidator injectValidator;
@Inject
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/MapMultibindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/MapMultibindingValidator.java
index cef4a9b..0698bef 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/MapMultibindingValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/MapMultibindingValidator.java
@@ -37,9 +37,9 @@
import dagger.internal.codegen.binding.ContributionBinding;
import dagger.internal.codegen.binding.KeyFactory;
import dagger.internal.codegen.javapoet.TypeNames;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DiagnosticReporter;
import dagger.spi.model.Key;
import java.util.Set;
@@ -49,7 +49,7 @@
* Reports an error for any map binding with either more than one contribution with the same map key
* or contributions with inconsistent map key annotation types.
*/
-final class MapMultibindingValidator implements BindingGraphPlugin {
+final class MapMultibindingValidator extends ValidationBindingGraphPlugin {
private final BindingDeclarationFormatter bindingDeclarationFormatter;
private final KeyFactory keyFactory;
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java
index fdcccf9..eb0ef6c 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/MissingBindingValidator.java
@@ -31,6 +31,7 @@
import dagger.internal.codegen.binding.DependencyRequestFormatter;
import dagger.internal.codegen.binding.InjectBindingRegistry;
import dagger.internal.codegen.validation.DiagnosticMessageGenerator;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.ComponentNode;
@@ -38,7 +39,6 @@
import dagger.spi.model.BindingGraph.Edge;
import dagger.spi.model.BindingGraph.MissingBinding;
import dagger.spi.model.BindingGraph.Node;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.ComponentPath;
import dagger.spi.model.DiagnosticReporter;
import dagger.spi.model.Key;
@@ -47,7 +47,7 @@
import javax.inject.Inject;
/** Reports errors for missing bindings. */
-final class MissingBindingValidator implements BindingGraphPlugin {
+final class MissingBindingValidator extends ValidationBindingGraphPlugin {
private final InjectBindingRegistry injectBindingRegistry;
private final DependencyRequestFormatter dependencyRequestFormatter;
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/NullableBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/NullableBindingValidator.java
index 4130fe9..bbc026e 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/NullableBindingValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/NullableBindingValidator.java
@@ -24,10 +24,10 @@
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import dagger.internal.codegen.compileroption.CompilerOptions;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.DependencyEdge;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DiagnosticReporter;
import javax.inject.Inject;
@@ -35,7 +35,7 @@
* Reports errors or warnings (depending on the {@code -Adagger.nullableValidation} value) for each
* non-nullable dependency request that is satisfied by a nullable binding.
*/
-final class NullableBindingValidator implements BindingGraphPlugin {
+final class NullableBindingValidator extends ValidationBindingGraphPlugin {
private final CompilerOptions compilerOptions;
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/ProvisionDependencyOnProducerBindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/ProvisionDependencyOnProducerBindingValidator.java
index 53904a7..7ad0e9f 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/ProvisionDependencyOnProducerBindingValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/ProvisionDependencyOnProducerBindingValidator.java
@@ -22,11 +22,11 @@
import static dagger.internal.codegen.extension.DaggerStreams.instancesOf;
import static javax.tools.Diagnostic.Kind.ERROR;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.DependencyEdge;
import dagger.spi.model.BindingGraph.Node;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DiagnosticReporter;
import java.util.stream.Stream;
import javax.inject.Inject;
@@ -36,7 +36,7 @@
* binding.
*/
// TODO(b/29509141): Clarify the error.
-final class ProvisionDependencyOnProducerBindingValidator implements BindingGraphPlugin {
+final class ProvisionDependencyOnProducerBindingValidator extends ValidationBindingGraphPlugin {
@Inject
ProvisionDependencyOnProducerBindingValidator() {}
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidator.java
index 1f79f87..6b7de40 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/SetMultibindingValidator.java
@@ -25,15 +25,15 @@
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.google.common.collect.Multimap;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.Binding;
import dagger.spi.model.BindingGraph;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DiagnosticReporter;
import dagger.spi.model.Key;
import javax.inject.Inject;
/** Validates that there are not multiple set binding contributions to the same binding. */
-final class SetMultibindingValidator implements BindingGraphPlugin {
+final class SetMultibindingValidator extends ValidationBindingGraphPlugin {
@Inject
SetMultibindingValidator() {
diff --git a/java/dagger/internal/codegen/bindinggraphvalidation/SubcomponentFactoryMethodValidator.java b/java/dagger/internal/codegen/bindinggraphvalidation/SubcomponentFactoryMethodValidator.java
index e41c84b..1ecff19 100644
--- a/java/dagger/internal/codegen/bindinggraphvalidation/SubcomponentFactoryMethodValidator.java
+++ b/java/dagger/internal/codegen/bindinggraphvalidation/SubcomponentFactoryMethodValidator.java
@@ -31,10 +31,10 @@
import com.google.common.collect.Sets.SetView;
import dagger.internal.codegen.base.Util;
import dagger.internal.codegen.binding.ComponentNodeImpl;
+import dagger.internal.codegen.validation.ValidationBindingGraphPlugin;
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraph.ChildFactoryMethodEdge;
import dagger.spi.model.BindingGraph.ComponentNode;
-import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DiagnosticReporter;
import java.util.HashMap;
import java.util.Map;
@@ -43,7 +43,7 @@
import javax.inject.Inject;
/** Reports an error if a subcomponent factory method is missing required modules. */
-final class SubcomponentFactoryMethodValidator implements BindingGraphPlugin {
+final class SubcomponentFactoryMethodValidator extends ValidationBindingGraphPlugin {
private final Map<ComponentNode, Set<XTypeElement>> inheritedModulesCache = new HashMap<>();
diff --git a/java/dagger/internal/codegen/processingstep/BUILD b/java/dagger/internal/codegen/processingstep/BUILD
index 6eda2b4..97d79af 100644
--- a/java/dagger/internal/codegen/processingstep/BUILD
+++ b/java/dagger/internal/codegen/processingstep/BUILD
@@ -34,6 +34,7 @@
"//java/dagger/internal/codegen/validation",
"//java/dagger/internal/codegen/writing",
"//java/dagger/internal/codegen/xprocessing",
+ "//java/dagger/spi",
"//third_party/java/auto:common",
"//third_party/java/error_prone:annotations",
"//third_party/java/guava/base",
diff --git a/java/dagger/internal/codegen/processingstep/ComponentProcessingStep.java b/java/dagger/internal/codegen/processingstep/ComponentProcessingStep.java
index fe83d8c..bac8d21 100644
--- a/java/dagger/internal/codegen/processingstep/ComponentProcessingStep.java
+++ b/java/dagger/internal/codegen/processingstep/ComponentProcessingStep.java
@@ -26,8 +26,9 @@
import androidx.room.compiler.processing.XMessager;
import androidx.room.compiler.processing.XTypeElement;
import com.google.auto.common.BasicAnnotationProcessor.ProcessingStep;
+import com.google.common.base.Supplier;
+import com.google.common.base.Suppliers;
import com.google.common.collect.ImmutableSet;
-import com.google.errorprone.annotations.CanIgnoreReturnValue;
import com.squareup.javapoet.ClassName;
import dagger.internal.codegen.base.SourceFileGenerator;
import dagger.internal.codegen.binding.BindingGraph;
@@ -103,11 +104,19 @@
if (!isValid(componentDescriptor)) {
return;
}
- if (!validateFullBindingGraph(componentDescriptor)) {
- return;
+
+ Supplier<dagger.spi.model.BindingGraph> fullBindingGraphSupplier =
+ Suppliers.memoize(
+ () -> bindingGraphFactory.create(componentDescriptor, true).topLevelBindingGraph());
+ if (bindingGraphValidator.shouldDoFullBindingGraphValidation(component)) {
+ if (!bindingGraphValidator.isValid(fullBindingGraphSupplier.get())) {
+ return;
+ }
}
+
BindingGraph bindingGraph = bindingGraphFactory.create(componentDescriptor, false);
- if (bindingGraphValidator.isValid(bindingGraph.topLevelBindingGraph())) {
+ if (bindingGraphValidator.isValid(
+ bindingGraph.topLevelBindingGraph(), fullBindingGraphSupplier)) {
generateComponent(bindingGraph);
}
}
@@ -116,10 +125,14 @@
if (!isComponentValid(subcomponent)) {
return;
}
+ // TODO(dpb): ComponentDescriptorValidator for subcomponents, as we do for root components.
ComponentDescriptor subcomponentDescriptor =
componentDescriptorFactory.subcomponentDescriptor(subcomponent);
- // TODO(dpb): ComponentDescriptorValidator for subcomponents, as we do for root components.
- validateFullBindingGraph(subcomponentDescriptor);
+ if (!bindingGraphValidator.shouldDoFullBindingGraphValidation(subcomponent)) {
+ return;
+ }
+ BindingGraph fullBindingGraph = bindingGraphFactory.create(subcomponentDescriptor, true);
+ boolean isValid = bindingGraphValidator.isValid(fullBindingGraph.topLevelBindingGraph());
}
private void generateComponent(BindingGraph bindingGraph) {
@@ -136,16 +149,6 @@
return report.isClean();
}
- @CanIgnoreReturnValue
- private boolean validateFullBindingGraph(ComponentDescriptor componentDescriptor) {
- if (!bindingGraphValidator.shouldDoFullBindingGraphValidation(
- componentDescriptor.typeElement())) {
- return true;
- }
- BindingGraph fullBindingGraph = bindingGraphFactory.create(componentDescriptor, true);
- return bindingGraphValidator.isValid(fullBindingGraph.topLevelBindingGraph());
- }
-
private boolean isValid(ComponentDescriptor componentDescriptor) {
ValidationReport componentDescriptorReport =
componentDescriptorValidator.validate(componentDescriptor);
diff --git a/java/dagger/internal/codegen/validation/BindingGraphValidator.java b/java/dagger/internal/codegen/validation/BindingGraphValidator.java
index 09477d8..d20fe99 100644
--- a/java/dagger/internal/codegen/validation/BindingGraphValidator.java
+++ b/java/dagger/internal/codegen/validation/BindingGraphValidator.java
@@ -17,6 +17,8 @@
package dagger.internal.codegen.validation;
import androidx.room.compiler.processing.XTypeElement;
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
import dagger.internal.codegen.compileroption.CompilerOptions;
import dagger.internal.codegen.compileroption.ValidationType;
import dagger.spi.model.BindingGraph;
@@ -51,17 +53,23 @@
}
/** Returns {@code true} if no errors are reported for {@code graph}. */
- public boolean isValid(BindingGraph graph) {
- return visitValidationPlugins(graph) && visitExternalPlugins(graph);
+ public boolean isValid(BindingGraph fullGraph) {
+ return visitValidationPlugins(Optional.absent(), () -> fullGraph)
+ && visitExternalPlugins(fullGraph);
+ }
+
+ public boolean isValid(BindingGraph prunedGraph, Supplier<BindingGraph> fullGraphSupplier) {
+ return visitValidationPlugins(Optional.of(prunedGraph), fullGraphSupplier)
+ && visitExternalPlugins(prunedGraph);
}
/** Returns {@code true} if validation plugins report no errors. */
- private boolean visitValidationPlugins(BindingGraph graph) {
- if (graph.isFullBindingGraph() && !requiresFullBindingGraphValidation()) {
+ private boolean visitValidationPlugins(
+ Optional<BindingGraph> prunedGraph, Supplier<BindingGraph> fullGraphSupplier) {
+ if (!prunedGraph.isPresent() && !requiresFullBindingGraphValidation()) {
return true;
}
-
- return validationPlugins.visit(graph);
+ return validationPlugins.visit(prunedGraph, fullGraphSupplier);
}
/** Returns {@code true} if external plugins report no errors. */
diff --git a/java/dagger/internal/codegen/validation/ValidationBindingGraphPlugin.java b/java/dagger/internal/codegen/validation/ValidationBindingGraphPlugin.java
new file mode 100644
index 0000000..e431069
--- /dev/null
+++ b/java/dagger/internal/codegen/validation/ValidationBindingGraphPlugin.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Dagger Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package dagger.internal.codegen.validation;
+
+import com.google.common.base.Preconditions;
+import dagger.spi.model.BindingGraph;
+import dagger.spi.model.BindingGraph.ComponentNode;
+import dagger.spi.model.BindingGraphPlugin;
+import dagger.spi.model.DiagnosticReporter;
+import java.util.HashSet;
+import java.util.Set;
+
+/** BindingGraphPlugin that allows rerun visitGraph on full binding graph. */
+public abstract class ValidationBindingGraphPlugin implements BindingGraphPlugin {
+ private final Set<ComponentNode> visitFullGraphRequested = new HashSet<>();
+
+ public final boolean visitFullGraphRequested(BindingGraph graph) {
+ return visitFullGraphRequested.contains(graph.rootComponentNode());
+ }
+
+ /**
+ * Request revisit full binding graph for the given pruned graph.
+ *
+ * <p>If called from revisitFullGraph then no-op.
+ */
+ public final void requestVisitFullGraph(BindingGraph graph) {
+ Preconditions.checkState(
+ !graph.isFullBindingGraph(), "Cannot request revisit full graph when visiting full graph.");
+ visitFullGraphRequested.add(graph.rootComponentNode());
+ }
+
+ public void revisitFullGraph(
+ BindingGraph prunedGraph, BindingGraph fullGraph, DiagnosticReporter diagReporter) {}
+}
diff --git a/java/dagger/internal/codegen/validation/ValidationBindingGraphPlugins.java b/java/dagger/internal/codegen/validation/ValidationBindingGraphPlugins.java
index a283b99..9e2bbf4 100644
--- a/java/dagger/internal/codegen/validation/ValidationBindingGraphPlugins.java
+++ b/java/dagger/internal/codegen/validation/ValidationBindingGraphPlugins.java
@@ -20,6 +20,8 @@
import static javax.tools.Diagnostic.Kind.ERROR;
import androidx.room.compiler.processing.XProcessingEnv;
+import com.google.common.base.Optional;
+import com.google.common.base.Supplier;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Maps;
@@ -30,13 +32,15 @@
import dagger.spi.model.BindingGraph;
import dagger.spi.model.BindingGraphPlugin;
import dagger.spi.model.DaggerProcessingEnv;
+import java.util.ArrayList;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.inject.Inject;
/** Initializes {@link BindingGraphPlugin}s. */
public final class ValidationBindingGraphPlugins {
- private final ImmutableSet<BindingGraphPlugin> plugins;
+ private final ImmutableSet<ValidationBindingGraphPlugin> plugins;
private final DiagnosticReporterFactory diagnosticReporterFactory;
private final XProcessingEnv processingEnv;
private final CompilerOptions compilerOptions;
@@ -44,7 +48,7 @@
@Inject
ValidationBindingGraphPlugins(
- @Validation ImmutableSet<BindingGraphPlugin> plugins,
+ @Validation ImmutableSet<ValidationBindingGraphPlugin> plugins,
DiagnosticReporterFactory diagnosticReporterFactory,
XProcessingEnv processingEnv,
CompilerOptions compilerOptions,
@@ -79,25 +83,43 @@
}
/** Returns {@code false} if any of the plugins reported an error. */
- boolean visit(BindingGraph graph) {
- boolean errorsAsWarnings =
- graph.isFullBindingGraph()
- && compilerOptions.fullBindingGraphValidationType().equals(ValidationType.WARNING);
+ boolean visit(Optional<BindingGraph> prunedGraph, Supplier<BindingGraph> fullGraphSupplier) {
+ BindingGraph graph = prunedGraph.isPresent() ? prunedGraph.get() : fullGraphSupplier.get();
boolean isClean = true;
- for (BindingGraphPlugin plugin : plugins) {
- DiagnosticReporterImpl reporter =
- errorsAsWarnings
- ? diagnosticReporterFactory.reporterWithErrorAsWarnings(graph, plugin.pluginName())
- : diagnosticReporterFactory.reporter(graph, plugin.pluginName());
+ List<ValidationBindingGraphPlugin> rerunPlugins = new ArrayList<>();
+ for (ValidationBindingGraphPlugin plugin : plugins) {
+ DiagnosticReporterImpl reporter = createReporter(plugin.pluginName(), graph);
plugin.visitGraph(graph, reporter);
+ if (plugin.visitFullGraphRequested(graph)) {
+ rerunPlugins.add(plugin);
+ }
if (reporter.reportedDiagnosticKinds().contains(ERROR)) {
isClean = false;
}
}
+ if (!rerunPlugins.isEmpty()) {
+ BindingGraph fullGraph = fullGraphSupplier.get();
+ for (ValidationBindingGraphPlugin plugin : rerunPlugins) {
+ DiagnosticReporterImpl reporter = createReporter(plugin.pluginName(), fullGraph);
+ plugin.revisitFullGraph(prunedGraph.get(), fullGraph, reporter);
+ if (reporter.reportedDiagnosticKinds().contains(ERROR)) {
+ isClean = false;
+ }
+ }
+ }
return isClean;
}
+ private DiagnosticReporterImpl createReporter(String pluginName, BindingGraph graph) {
+ boolean errorsAsWarnings =
+ graph.isFullBindingGraph()
+ && compilerOptions.fullBindingGraphValidationType().equals(ValidationType.WARNING);
+ return errorsAsWarnings
+ ? diagnosticReporterFactory.reporterWithErrorAsWarnings(graph, pluginName)
+ : diagnosticReporterFactory.reporter(graph, pluginName);
+ }
+
public void endPlugins() {
plugins.forEach(BindingGraphPlugin::onPluginEnd);
}