Home | History | Annotate | Download | only in validator
      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