1 /* 2 * Copyright (C) 2018 The Dagger Authors. 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package dagger.internal.codegen.validation; 18 19 import androidx.room.compiler.processing.XTypeElement; 20 import com.google.common.base.Optional; 21 import com.google.common.base.Supplier; 22 import dagger.internal.codegen.compileroption.CompilerOptions; 23 import dagger.internal.codegen.compileroption.ValidationType; 24 import dagger.internal.codegen.model.BindingGraph; 25 import javax.inject.Inject; 26 import javax.inject.Singleton; 27 28 /** Validates a {@link BindingGraph}. */ 29 @Singleton 30 public final class BindingGraphValidator { 31 private final ValidationBindingGraphPlugins validationPlugins; 32 private final ExternalBindingGraphPlugins externalPlugins; 33 private final CompilerOptions compilerOptions; 34 35 @Inject BindingGraphValidator( ValidationBindingGraphPlugins validationPlugins, ExternalBindingGraphPlugins externalPlugins, CompilerOptions compilerOptions)36 BindingGraphValidator( 37 ValidationBindingGraphPlugins validationPlugins, 38 ExternalBindingGraphPlugins externalPlugins, 39 CompilerOptions compilerOptions) { 40 this.validationPlugins = validationPlugins; 41 this.externalPlugins = externalPlugins; 42 this.compilerOptions = compilerOptions; 43 } 44 45 /** Returns {@code true} if validation or analysis is required on the full binding graph. */ shouldDoFullBindingGraphValidation(XTypeElement component)46 public boolean shouldDoFullBindingGraphValidation(XTypeElement component) { 47 return requiresFullBindingGraphValidation() 48 || compilerOptions.pluginsVisitFullBindingGraphs(component); 49 } 50 requiresFullBindingGraphValidation()51 private boolean requiresFullBindingGraphValidation() { 52 return !compilerOptions.fullBindingGraphValidationType().equals(ValidationType.NONE); 53 } 54 55 /** Returns {@code true} if no errors are reported for {@code graph}. */ isValid(BindingGraph fullGraph)56 public boolean isValid(BindingGraph fullGraph) { 57 return visitValidationPlugins(Optional.absent(), () -> fullGraph) 58 && visitExternalPlugins(fullGraph); 59 } 60 isValid(BindingGraph prunedGraph, Supplier<BindingGraph> fullGraphSupplier)61 public boolean isValid(BindingGraph prunedGraph, Supplier<BindingGraph> fullGraphSupplier) { 62 return visitValidationPlugins(Optional.of(prunedGraph), fullGraphSupplier) 63 && visitExternalPlugins(prunedGraph); 64 } 65 66 /** Returns {@code true} if validation plugins report no errors. */ visitValidationPlugins( Optional<BindingGraph> prunedGraph, Supplier<BindingGraph> fullGraphSupplier)67 private boolean visitValidationPlugins( 68 Optional<BindingGraph> prunedGraph, Supplier<BindingGraph> fullGraphSupplier) { 69 if (!prunedGraph.isPresent() && !requiresFullBindingGraphValidation()) { 70 return true; 71 } 72 return validationPlugins.visit(prunedGraph, fullGraphSupplier); 73 } 74 75 /** Returns {@code true} if external plugins report no errors. */ visitExternalPlugins(BindingGraph graph)76 private boolean visitExternalPlugins(BindingGraph graph) { 77 if (graph.isFullBindingGraph() 78 // TODO(b/135938915): Consider not visiting plugins if only 79 // fullBindingGraphValidation is enabled. 80 && !requiresFullBindingGraphValidation() 81 && !compilerOptions.pluginsVisitFullBindingGraphs( 82 graph.rootComponentNode().componentPath().currentComponent().xprocessing())) { 83 return true; 84 } 85 86 return externalPlugins.visit(graph); 87 } 88 } 89