javaintellij-ideaannotationscode-inspectionstructural-search

How to find top level not annotated classes in IntelliJ IDEA


Motivation: Every class/interface/annotation/enum has to be annotated by @SomeAnnotation. However we want this annotation to be only at the top level classes and not at the inner ones.

The goal is to create a structural inspection which warns developers that they forgot to annotate the classes. How can I specify the structural search/replace to find all such top level structures missing the @SomeAnnotation?


Solution

  • Something like this should work:

    @$Annotation$ // min: 0, max: 0, text/regexp: SomeAnnotation
    class $C$ {} // min: 1, max: 1
    
    // Complete Match - Script text: 
    if (C instanceof com.intellij.psi.PsiIdentifier) C = C.parent
    C.containingClass == null && !(C instanceof com.intellij.psi.PsiAnonymousClass)
    

    First line of the script is necessary for IntelliJ IDEA 14. The C in the script references $C$ in the pattern.

    Replacement template:

    @SomeAnnotation
    class $C$ {}
    

    Full template for importing (using the Import Template from Clipboard under the tool button in the dialog):

    <replaceConfiguration name="Method calls" text="@$Annotation$&#10;class $C$ {}" recursive="false" caseInsensitive="true" type="JAVA" pattern_context="default" reformatAccordingToStyle="false" shortenFQN="false" replacement="@SomeAnnotation&#10;class $C$ {}">
      <constraint name="__context__" script="&quot;if (C instanceof com.intellij.psi.PsiIdentifier) C = C.parent &#10;C.containingClass == null &amp;&amp; !(C instanceof com.intellij.psi.PsiAnonymousClass)&quot;" within="" contains="" />
      <constraint name="Annotation" regexp="SomeAnnotation" minCount="0" maxCount="0" within="" contains="" />
      <constraint name="C" within="" contains="" />
    </replaceConfiguration>