• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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