• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 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 static com.google.common.collect.Iterables.getOnlyElement;
20 import static dagger.internal.codegen.base.ComponentAnnotation.anyComponentAnnotation;
21 import static dagger.internal.codegen.base.ModuleAnnotation.moduleAnnotation;
22 import static dagger.internal.codegen.xprocessing.XMethodElements.getEnclosingTypeElement;
23 
24 import androidx.room.compiler.processing.XMethodElement;
25 import androidx.room.compiler.processing.XType;
26 import androidx.room.compiler.processing.XTypeElement;
27 import androidx.room.compiler.processing.XVariableElement;
28 import dagger.internal.codegen.base.DaggerSuperficialValidation;
29 import dagger.internal.codegen.base.ModuleAnnotation;
30 import dagger.internal.codegen.binding.InjectionAnnotations;
31 import java.util.List;
32 import java.util.Optional;
33 import javax.inject.Inject;
34 
35 /** Validates {@link BindsInstance} usages on builder methods. */
36 public final class BindsInstanceMethodValidator
37     extends BindsInstanceElementValidator<XMethodElement> {
38   private final DaggerSuperficialValidation superficialValidation;
39 
40   @Inject
BindsInstanceMethodValidator( InjectionAnnotations injectionAnnotations, DaggerSuperficialValidation superficialValidation)41   BindsInstanceMethodValidator(
42       InjectionAnnotations injectionAnnotations,
43       DaggerSuperficialValidation superficialValidation) {
44     super(injectionAnnotations);
45     this.superficialValidation = superficialValidation;
46   }
47 
48   @Override
elementValidator(XMethodElement method)49   protected ElementValidator elementValidator(XMethodElement method) {
50     return new Validator(method);
51   }
52 
53   private class Validator extends ElementValidator {
54     private final XMethodElement method;
55 
Validator(XMethodElement method)56     Validator(XMethodElement method) {
57       super(method);
58       this.method = method;
59     }
60 
61     @Override
checkAdditionalProperties()62     protected void checkAdditionalProperties() {
63       if (!method.isAbstract()) {
64         report.addError("@BindsInstance methods must be abstract");
65       }
66       if (method.getParameters().size() != 1) {
67         report.addError(
68             "@BindsInstance methods should have exactly one parameter for the bound type");
69       }
70       XTypeElement enclosingTypeElement = getEnclosingTypeElement(method);
71       moduleAnnotation(enclosingTypeElement, superficialValidation)
72           .ifPresent(moduleAnnotation -> report.addError(didYouMeanBinds(moduleAnnotation)));
73       anyComponentAnnotation(enclosingTypeElement, superficialValidation)
74           .ifPresent(
75               componentAnnotation ->
76                   report.addError(
77                       String.format(
78                           "@BindsInstance methods should not be included in @%1$ss. "
79                               + "Did you mean to put it in a @%1$s.Builder?",
80                           componentAnnotation.simpleName())));
81     }
82 
83     @Override
bindingElementType()84     protected Optional<XType> bindingElementType() {
85       List<? extends XVariableElement> parameters = method.getParameters();
86       return parameters.size() == 1
87           ? Optional.of(getOnlyElement(parameters).getType())
88           : Optional.empty();
89     }
90   }
91 
didYouMeanBinds(ModuleAnnotation moduleAnnotation)92   private static String didYouMeanBinds(ModuleAnnotation moduleAnnotation) {
93     return String.format(
94         "@BindsInstance methods should not be included in @%ss. Did you mean @Binds?",
95         moduleAnnotation.simpleName());
96   }
97 }
98