• 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;
18 
19 import static dagger.internal.codegen.DaggerStreams.instancesOf;
20 import static javax.tools.Diagnostic.Kind.ERROR;
21 
22 import dagger.model.BindingGraph;
23 import dagger.model.BindingGraph.MaybeBinding;
24 import dagger.model.Key;
25 import dagger.spi.BindingGraphPlugin;
26 import dagger.spi.DiagnosticReporter;
27 import javax.inject.Inject;
28 
29 /**
30  * Reports an error on all bindings that depend explicitly on the {@code @Production Executor} key.
31  */
32 // TODO(dpb,beder): Validate this during @Inject/@Provides/@Produces validation.
33 final class DependsOnProductionExecutorValidator implements BindingGraphPlugin {
34   private final CompilerOptions compilerOptions;
35   private final KeyFactory keyFactory;
36 
37   @Inject
DependsOnProductionExecutorValidator(CompilerOptions compilerOptions, KeyFactory keyFactory)38   DependsOnProductionExecutorValidator(CompilerOptions compilerOptions, KeyFactory keyFactory) {
39     this.compilerOptions = compilerOptions;
40     this.keyFactory = keyFactory;
41   }
42 
43   @Override
pluginName()44   public String pluginName() {
45     return "Dagger/DependsOnProductionExecutor";
46   }
47 
48   @Override
visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter)49   public void visitGraph(BindingGraph bindingGraph, DiagnosticReporter diagnosticReporter) {
50     if (!compilerOptions.usesProducers()) {
51       return;
52     }
53 
54     Key productionImplementationExecutorKey = keyFactory.forProductionImplementationExecutor();
55     Key productionExecutorKey = keyFactory.forProductionExecutor();
56 
57     bindingGraph.network().nodes().stream()
58         .flatMap(instancesOf(MaybeBinding.class))
59         .filter(node -> node.key().equals(productionExecutorKey))
60         .flatMap(productionExecutor -> bindingGraph.requestingBindings(productionExecutor).stream())
61         .filter(binding -> !binding.key().equals(productionImplementationExecutorKey))
62         .forEach(binding -> reportError(diagnosticReporter, binding));
63   }
64 
reportError(DiagnosticReporter diagnosticReporter, dagger.model.Binding binding)65   private void reportError(DiagnosticReporter diagnosticReporter, dagger.model.Binding binding) {
66     diagnosticReporter.reportBinding(
67         ERROR, binding, "%s may not depend on the production executor", binding.key());
68   }
69 }
70