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 javax.lang.model.element.ElementKind.METHOD; 20 import static javax.lang.model.element.Modifier.ABSTRACT; 21 import static javax.lang.model.type.TypeKind.DECLARED; 22 import static javax.lang.model.type.TypeKind.TYPEVAR; 23 24 import com.google.auto.common.MoreElements; 25 import dagger.internal.codegen.binding.InjectionAnnotations; 26 import java.util.Optional; 27 import javax.inject.Inject; 28 import javax.lang.model.element.Element; 29 import javax.lang.model.element.ExecutableElement; 30 import javax.lang.model.element.VariableElement; 31 import javax.lang.model.type.TypeKind; 32 import javax.lang.model.type.TypeMirror; 33 34 final class BindsInstanceParameterValidator extends BindsInstanceElementValidator<VariableElement> { 35 @Inject BindsInstanceParameterValidator(InjectionAnnotations injectionAnnotations)36 BindsInstanceParameterValidator(InjectionAnnotations injectionAnnotations) { 37 super(injectionAnnotations); 38 } 39 40 @Override elementValidator(VariableElement element)41 protected ElementValidator elementValidator(VariableElement element) { 42 return new Validator(element); 43 } 44 45 private class Validator extends ElementValidator { Validator(VariableElement element)46 Validator(VariableElement element) { 47 super(element); 48 } 49 50 @Override checkAdditionalProperties()51 protected void checkAdditionalProperties() { 52 Element enclosing = element.getEnclosingElement(); 53 if (!enclosing.getKind().equals(METHOD)) { 54 report.addError( 55 "@BindsInstance should only be applied to methods or parameters of methods"); 56 return; 57 } 58 59 ExecutableElement method = MoreElements.asExecutable(enclosing); 60 if (!method.getModifiers().contains(ABSTRACT)) { 61 report.addError("@BindsInstance parameters may only be used in abstract methods"); 62 } 63 64 TypeKind returnKind = method.getReturnType().getKind(); 65 if (!(returnKind.equals(DECLARED) || returnKind.equals(TYPEVAR))) { 66 report.addError( 67 "@BindsInstance parameters may not be used in methods with a void, array or primitive " 68 + "return type"); 69 } 70 } 71 72 @Override bindingElementType()73 protected Optional<TypeMirror> bindingElementType() { 74 return Optional.of(element.asType()); 75 } 76 } 77 } 78