• 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.auto.common.MoreTypes.asTypeElement;
20 import static dagger.internal.codegen.base.Keys.isValidImplicitProvisionKey;
21 import static dagger.internal.codegen.binding.InjectionAnnotations.injectedConstructors;
22 import static dagger.internal.codegen.validation.BindingElementValidator.AllowsMultibindings.NO_MULTIBINDINGS;
23 import static dagger.internal.codegen.validation.BindingElementValidator.AllowsScoping.NO_SCOPING;
24 import static dagger.internal.codegen.validation.BindingMethodValidator.Abstractness.MUST_BE_ABSTRACT;
25 import static dagger.internal.codegen.validation.BindingMethodValidator.ExceptionSuperclass.NO_EXCEPTIONS;
26 
27 import com.google.common.collect.ImmutableSet;
28 import dagger.BindsOptionalOf;
29 import dagger.Module;
30 import dagger.internal.codegen.binding.InjectionAnnotations;
31 import dagger.internal.codegen.kotlin.KotlinMetadataUtil;
32 import dagger.internal.codegen.langmodel.DaggerElements;
33 import dagger.internal.codegen.langmodel.DaggerTypes;
34 import dagger.producers.ProducerModule;
35 import javax.inject.Inject;
36 import javax.lang.model.element.ExecutableElement;
37 import javax.lang.model.type.TypeMirror;
38 
39 /** A validator for {@link BindsOptionalOf} methods. */
40 final class BindsOptionalOfMethodValidator extends BindingMethodValidator {
41 
42   private final DaggerTypes types;
43   private final InjectionAnnotations injectionAnnotations;
44 
45   @Inject
BindsOptionalOfMethodValidator( DaggerElements elements, DaggerTypes types, KotlinMetadataUtil kotlinMetadataUtil, DependencyRequestValidator dependencyRequestValidator, InjectionAnnotations injectionAnnotations)46   BindsOptionalOfMethodValidator(
47       DaggerElements elements,
48       DaggerTypes types,
49       KotlinMetadataUtil kotlinMetadataUtil,
50       DependencyRequestValidator dependencyRequestValidator,
51       InjectionAnnotations injectionAnnotations) {
52     super(
53         elements,
54         types,
55         kotlinMetadataUtil,
56         BindsOptionalOf.class,
57         ImmutableSet.of(Module.class, ProducerModule.class),
58         dependencyRequestValidator,
59         MUST_BE_ABSTRACT,
60         NO_EXCEPTIONS,
61         NO_MULTIBINDINGS,
62         NO_SCOPING,
63         injectionAnnotations);
64     this.types = types;
65     this.injectionAnnotations = injectionAnnotations;
66   }
67 
68 
69   @Override
elementValidator(ExecutableElement element)70   protected ElementValidator elementValidator(ExecutableElement element) {
71     return new Validator(element);
72   }
73 
74   private class Validator extends MethodValidator {
Validator(ExecutableElement element)75     Validator(ExecutableElement element) {
76       super(element);
77     }
78 
79     @Override
checkKeyType(TypeMirror keyType)80     protected void checkKeyType(TypeMirror keyType) {
81       super.checkKeyType(keyType);
82       if (isValidImplicitProvisionKey(
83               injectionAnnotations.getQualifiers(element).stream().findFirst(), keyType, types)
84           && !injectedConstructors(asTypeElement(keyType)).isEmpty()) {
85         report.addError(
86             "@BindsOptionalOf methods cannot return unqualified types that have an @Inject-"
87                 + "annotated constructor because those are always present");
88       }
89     }
90 
91     @Override
checkParameters()92     protected void checkParameters() {
93       if (!element.getParameters().isEmpty()) {
94         report.addError("@BindsOptionalOf methods cannot have parameters");
95       }
96     }
97   }
98 }
99