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