1 package org.robolectric.annotation.processing.validator; 2 3 import javax.annotation.processing.Messager; 4 import javax.annotation.processing.ProcessingEnvironment; 5 import javax.lang.model.element.AnnotationMirror; 6 import javax.lang.model.element.AnnotationValue; 7 import javax.lang.model.element.Element; 8 import javax.lang.model.element.ElementVisitor; 9 import javax.lang.model.element.ExecutableElement; 10 import javax.lang.model.element.PackageElement; 11 import javax.lang.model.element.TypeElement; 12 import javax.lang.model.element.TypeParameterElement; 13 import javax.lang.model.element.VariableElement; 14 import javax.lang.model.util.AbstractElementVisitor6; 15 import javax.lang.model.util.Elements; 16 import javax.lang.model.util.Types; 17 import javax.tools.Diagnostic.Kind; 18 import org.robolectric.annotation.processing.Helpers; 19 import org.robolectric.annotation.processing.RobolectricModel; 20 21 /** 22 * Base class for validators. 23 */ 24 public abstract class Validator implements ElementVisitor<Void, Element> { 25 final protected RobolectricModel.Builder modelBuilder; 26 final protected Elements elements; 27 final protected Types types; 28 final protected Messager messager; 29 final protected TypeElement annotationType; 30 final protected Helpers helpers; 31 // This is the easiest way to do it because visit() is final in AbstractEV6 32 final ElementVisitor<Void, Element> visitorAdapter = new AbstractElementVisitor6<Void, Element>() { 33 34 @Override 35 public Void visitPackage(PackageElement e, Element p) { 36 return Validator.this.visitPackage(e, p); 37 } 38 39 @Override 40 public Void visitType(TypeElement e, Element p) { 41 return Validator.this.visitType(e, p); 42 } 43 44 @Override 45 public Void visitVariable(VariableElement e, Element p) { 46 return Validator.this.visitVariable(e, p); 47 } 48 49 @Override 50 public Void visitExecutable(ExecutableElement e, Element p) { 51 return Validator.this.visitExecutable(e, p); 52 } 53 54 @Override 55 public Void visitTypeParameter(TypeParameterElement e, Element p) { 56 return Validator.this.visitTypeParameter(e, p); 57 } 58 }; 59 protected Element currentElement; 60 protected AnnotationMirror currentAnnotation; 61 Validator(RobolectricModel.Builder modelBuilder, ProcessingEnvironment env, String annotationType)62 public Validator(RobolectricModel.Builder modelBuilder, ProcessingEnvironment env, String annotationType) { 63 this.modelBuilder = modelBuilder; 64 elements = env.getElementUtils(); 65 types = env.getTypeUtils(); 66 this.helpers = new Helpers(env); 67 messager = env.getMessager(); 68 // FIXME: Need to test case where type lookup fails 69 this.annotationType = elements.getTypeElement(annotationType); 70 } 71 getCurrentAnnotation()72 protected AnnotationMirror getCurrentAnnotation() { 73 if (currentAnnotation == null) { 74 currentAnnotation = Helpers.getAnnotationMirror(types, currentElement, annotationType); 75 } 76 return currentAnnotation; 77 } 78 message(Kind severity, String msg, AnnotationValue av)79 protected void message(Kind severity, String msg, AnnotationValue av) { 80 final AnnotationMirror am = getCurrentAnnotation(); 81 messager.printMessage(severity, msg, currentElement, am, av); 82 } 83 message(Kind severity, String msg)84 protected void message(Kind severity, String msg) { 85 final AnnotationMirror am = getCurrentAnnotation(); 86 messager.printMessage(severity, msg, currentElement, am); 87 } 88 error(String msg)89 protected void error(String msg) { 90 message(Kind.ERROR, msg); 91 } 92 error(String msg, AnnotationValue av)93 protected void error(String msg, AnnotationValue av) { 94 message(Kind.ERROR, msg, av); 95 } 96 init(Element e, Element p)97 public void init(Element e, Element p) { 98 currentElement = e; 99 currentAnnotation = null; 100 } 101 getAnnotationType()102 public TypeElement getAnnotationType() { 103 return annotationType; 104 } 105 106 @Override visit(Element e, Element p)107 public Void visit(Element e, Element p) { 108 init(e, p); 109 return visitorAdapter.visit(e, p); 110 } 111 112 @Override visit(Element e)113 public Void visit(Element e) { 114 return visit(e, null); 115 } 116 117 @Override visitPackage(PackageElement e, Element p)118 public Void visitPackage(PackageElement e, Element p) { 119 return null; 120 } 121 122 @Override visitType(TypeElement e, Element p)123 public Void visitType(TypeElement e, Element p) { 124 return null; 125 } 126 127 @Override visitVariable(VariableElement e, Element p)128 public Void visitVariable(VariableElement e, Element p) { 129 return null; 130 } 131 132 @Override visitExecutable(ExecutableElement e, Element p)133 public Void visitExecutable(ExecutableElement e, Element p) { 134 return null; 135 } 136 137 @Override visitTypeParameter(TypeParameterElement e, Element p)138 public Void visitTypeParameter(TypeParameterElement e, Element p) { 139 return null; 140 } 141 142 @Override visitUnknown(Element e, Element p)143 public Void visitUnknown(Element e, Element p) { 144 return null; 145 } 146 } 147