Class SFProcessor

  • All Implemented Interfaces:
    javax.annotation.processing.Processor

    public class SFProcessor
    extends javax.annotation.processing.AbstractProcessor
    SFProcessor - Documentation.

    Processes the @StaticFunctional Annotation so that javac will properly handle it.




    • Field Summary

      • Fields inherited from class javax.annotation.processing.AbstractProcessor

        processingEnv
    • Constructor Summary

      Constructors 
      Constructor
      SFProcessor()  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method
      java.util.Set<String> getSupportedAnnotationTypes()
      javax.lang.model.SourceVersion getSupportedSourceVersion()
      void init​(javax.annotation.processing.ProcessingEnvironment env)
      boolean process​(java.util.Set<? extends javax.lang.model.element.TypeElement> set, javax.annotation.processing.RoundEnvironment roundEnv)
      • Methods inherited from class javax.annotation.processing.AbstractProcessor

        getCompletions, getSupportedOptions, isInitialized
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Method Detail

      • init

        public void init​(javax.annotation.processing.ProcessingEnvironment env)
        Specified by:
        init in interface javax.annotation.processing.Processor
        Overrides:
        init in class javax.annotation.processing.AbstractProcessor
        Code:
        Exact Method Body:
        1
         messager = env.getMessager();
        
      • process

        public boolean process​
                    (java.util.Set<? extends javax.lang.model.element.TypeElement> set,
                     javax.annotation.processing.RoundEnvironment roundEnv)
        
        This implements the processing for the Annotation @StaticFunctional. It does a lot of validity checks on the parameter input.
        Specified by:
        process in interface javax.annotation.processing.Processor
        Specified by:
        process in class javax.annotation.processing.AbstractProcessor
        Code:
        Exact Method Body:
          1
          2
          3
          4
          5
          6
          7
          8
          9
         10
         11
         12
         13
         14
         15
         16
         17
         18
         19
         20
         21
         22
         23
         24
         25
         26
         27
         28
         29
         30
         31
         32
         33
         34
         35
         36
         37
         38
         39
         40
         41
         42
         43
         44
         45
         46
         47
         48
         49
         50
         51
         52
         53
         54
         55
         56
         57
         58
         59
         60
         61
         62
         63
         64
         65
         66
         67
         68
         69
         70
         71
         72
         73
         74
         75
         76
         77
         78
         79
         80
         81
         82
         83
         84
         85
         86
         87
         88
         89
         90
         91
         92
         93
         94
         95
         96
         97
         98
         99
        100
        101
        102
        103
        104
        105
        106
        107
        108
        109
        110
        111
        112
        113
        114
        115
        116
        117
         boolean errors = false;
        
         for (Element ciet : roundEnv.getElementsAnnotatedWith(StaticFunctional.class))
         {
             ElementKind k = ciet.getKind();
        
             if ((k != ElementKind.CLASS) && (k != ElementKind.INTERFACE))
             {
                 messager.printMessage(
                     Diagnostic.Kind.ERROR, LOCATION(ciet) +
                     "\tOnly classes and interfaces can be annotated with @" +
                     StaticFunctional.class.getSimpleName() + '\n' +
                     ciet.toString() + " is neither of these, it is of kind: " + k.toString()
                 );
        
                 errors = true;
                 continue;
             }
        
             Vector<String> excused = new Vector<>();
             Vector<Excuse> excuses = new Vector<>();
        
             Counter errorCount = new Counter();
        
             for (AnnotationMirror am : ciet.getAnnotationMirrors())
        
                 if (am.getAnnotationType().toString().equals
                     ("Torello.HTML.Tools.JavaDoc.StaticFunctional"))
        
                     am.getElementValues().forEach((ExecutableElement ee, AnnotationValue av) ->
                     {
                         if (ee.toString().equals("Excused()"))
                         {
                             Matcher m = EXCUSED.matcher(av.toString());
                             while (m.find()) excused.add(StringParse.ifQuotesStripQuotes(m.group(1)));
                         }
                         else if (ee.toString().equals("Excuses()"))
                         {
                             Matcher m = EXCUSES.matcher(av.toString());
                             while (m.find()) excuses.add(Excuse.valueOf(m.group(1)));
                         }
                         else
                         {
                             ERR(ciet, ee, av);
                             errorCount.addOne();
                         }
                     });
        
             if (errorCount.size() > 0) errors = true;
        
             if (excuses.size() != excused.size()) messager.printMessage(
                 Diagnostic.Kind.ERROR, LOCATION(ciet) +
                 "\tYou have passed " + excused.size() + " excused field name(s), and " +
                 excuses.size() + " explanation(s) for those non-final field(s).\n\tThe two " +
                 "optional array-parameters to the annotation @StaticFunctional, if used, must " +
                 "be parallel-arrays, and therefore these array-lengths must be equal."
             );
        
             for (String ex : excused) checkJavaIdentifier(ciet, ex);
        
             int constructorCount = 0;
        
             for (Element e : ciet.getEnclosedElements())
             {
                 Set<Modifier> modifiers = e.getModifiers();
        
                 switch (e.getKind())
                 {
                     case METHOD : 
                         if (! modifiers.contains(Modifier.STATIC))
                             errors |= ERR(ElementKind.METHOD, Modifier.STATIC, ciet, e);
                         break;
        
                     case FIELD :
                         boolean isExcused = excused.contains(e.getSimpleName().toString());
        
                         if (! modifiers.contains(Modifier.STATIC))
                             errors |= ERR(ElementKind.FIELD, Modifier.STATIC, ciet, e);
        
                         if (! modifiers.contains(Modifier.FINAL))
                         {
                             if (! isExcused)
                                 errors |= ERR(ElementKind.FIELD, Modifier.FINAL, ciet, e);
                         }
                         else
                             if (isExcused) WARN_EXCUSED_AND_FINAL(ciet, e);
        
                         if (isExcused) excused.remove(e.getSimpleName().toString());
        
                         break;
        
                     case CONSTRUCTOR :
                         constructorCount++;
                         if (! modifiers.contains(Modifier.PRIVATE))
                             errors |= ERR(ElementKind.CONSTRUCTOR, Modifier.PRIVATE, ciet, e);
                         break;
                 } // switch-statement
             }
        
             if (excused.size() > 0) messager.printMessage(
                 Diagnostic.Kind.ERROR, LOCATION(ciet) +
                 "\tThere were fields listed as excused and non-final, but those fields were " +
                 "not actually members of the " + ciet.getKind().toString().toLowerCase() + "." +
                 "\n\tUn-Resolved Excused Feild-Names: " +
                 StrCSV.toCSV(excused, s -> "\"" + s + "\"", false, null)
             );
        
             if (constructorCount > 1) messager.printMessage(
                 Diagnostic.Kind.ERROR, LOCATION(ciet) +
                 "\tThere are " + constructorCount + " constructors.  There should be exactly 1."
             );
        
             errors |= (constructorCount > 1);
        
         } // for-loop
        
         return errors;
        
      • getSupportedAnnotationTypes

        public java.util.Set<java.lang.String> getSupportedAnnotationTypes()
        Method required by AbstractProcessor
        Specified by:
        getSupportedAnnotationTypes in interface javax.annotation.processing.Processor
        Overrides:
        getSupportedAnnotationTypes in class javax.annotation.processing.AbstractProcessor
        Returns:
        the set of annotations supported by this processor
        Code:
        Exact Method Body:
        1
        2
        3
        4
         TreeSet<String> ret = new TreeSet<>();
        
         ret.add(StaticFunctional.class.getCanonicalName());
         return ret;
        
      • getSupportedSourceVersion

        public javax.lang.model.SourceVersion getSupportedSourceVersion()
        Method required by AbstractProcessor
        Specified by:
        getSupportedSourceVersion in interface javax.annotation.processing.Processor
        Overrides:
        getSupportedSourceVersion in class javax.annotation.processing.AbstractProcessor
        Returns:
        the Java version supported
        Code:
        Exact Method Body:
        1
         return SourceVersion.latestSupported();