I am trying to create a rule for checkstyle, that will prevent writing inline annotations usage, like this:
@Entity MyClass someEntity;
@Foo(a="B") public void bar(Baz baz) {
}
but will not prevent thinks like that:
public void bar(@Param Baz baz) {
}
Is there any way to achieve that?
Most of this answer was inspired by Checkstyle’s “Writing Checks” article. Most of the work is done in
AnnotationSameLineCheck.AnnotationSameLineCheck.java
This Java file was inspired by the “Visitor In Action” section of the “Writing Checks” article.
getDefaultTokensdefines which parts (a.k.a. tokens) of a Java file we’re interested in. Out first one might think that we’d be interested inTokenTypes.ANNOTATION, but this is not the case. We’re not interested inTokenTypes.ANNOTATIONbecause we don’t want to inspect all annotations; we actually want to disregardTokenTypes.PARAMETER_DEF.What are we interested in then? We’re actually interested in those parts of a Java file that can be annotated (i.e., the class definition
TokenTypes.CLASS_DEF, method definitionsTokenTypes.METHOD_DEF, etc.). Conveniently, Checkstyle’s API has a method that can tell us if a token is annotated. That method isAnnotationUtility.containsAnnotation, which is used invisitToken.The algorithm used to determine if an annotation is on the same line as other parts of a Java file is as follows:
This algorithm is found in
visitToken.checks.xml
This XML file was inspired by the “Integrate Your Check” section of the “Writing Checks” article. It is used by Checkstyle to specify which checks to perform on a set of Java files. Note that
AnnotationSameLineCheckis fully qualified (i.e., its package is specified in the name).checks.xmlis mentioned in thebuild.xmlfile.build.xml
This Ant build file was inspired by Checkstyle’s “Ant Task” article. Using Ant is only one way to execute Checkstyle. Using the command line is another option.
AnnotationClass.java
One can use the following class to test
AnnotationSameLineCheck. It is mentioned in thebuild.xmlfile. Note the testing of interface, class, enum, member-variable, method, parameter, and local-variable declarations.