public class AnnotationLocationCheck extends AbstractCheck
Attention: Annotations among modifiers are ignored (looks like false-negative) as there might be a problem with annotations for return types.
public @Nullable Long getStartTimeOrNull() { ... }.
Such annotations are better to keep close to type. Due to limitations, Checkstyle can not examine the target of an annotation.
Example:
@Override @Nullable public String getNameIfPresent() { ... }
The check has the following options:
Example to allow single parameterless annotation on the same line:
@Override public int hashCode() { ... }
Use the following configuration:
<module name="AnnotationLocation"> <property name="allowSamelineMultipleAnnotations" value="false"/> <property name="allowSamelineSingleParameterlessAnnotation" value="true"/> <property name="allowSamelineParameterizedAnnotation" value="false" /> </module>
Example to allow multiple parameterized annotations on the same line:
@SuppressWarnings("deprecation") @Mock DataLoader loader;
Use the following configuration:
<module name="AnnotationLocation"> <property name="allowSamelineMultipleAnnotations" value="true"/> <property name="allowSamelineSingleParameterlessAnnotation" value="true"/> <property name="allowSamelineParameterizedAnnotation" value="true" /> </module>
Example to allow multiple parameterless annotations on the same line:
@Partial @Mock DataLoader loader;
Use the following configuration:
<module name="AnnotationLocation"> <property name="allowSamelineMultipleAnnotations" value="true"/> <property name="allowSamelineSingleParameterlessAnnotation" value="true"/> <property name="allowSamelineParameterizedAnnotation" value="false" /> </module>
The following example demonstrates how the check validates annotation of method parameters, catch parameters, foreach, for-loop variable definitions.
Configuration:
<module name="AnnotationLocation"> <property name="allowSamelineMultipleAnnotations" value="false"/> <property name="allowSamelineSingleParameterlessAnnotation" value="false"/> <property name="allowSamelineParameterizedAnnotation" value="false" /> <property name="tokens" value="VARIABLE_DEF, PARAMETER_DEF"/> </module>
Code example
...
public void test(@MyAnnotation String s) { // OK
...
for (@MyAnnotation char c : s.toCharArray()) { ... } // OK
...
try { ... }
catch (@MyAnnotation Exception ex) { ... } // OK
...
for (@MyAnnotation int i = 0; i < 10; i++) { ... } // OK
...
MathOperation c = (@MyAnnotation int a, @MyAnnotation int b) -> a + b; // OK
...
}
Modifier and Type | Field and Description |
---|---|
private boolean |
allowSamelineMultipleAnnotations
If true, it allows annotation to be located on the same line as
target element.
|
private boolean |
allowSamelineParameterizedAnnotation
If true, it allows parameterized annotation to be located on the same line as
target element.
|
private boolean |
allowSamelineSingleParameterlessAnnotation
If true, it allows single prameterless annotation to be located on the same line as
target element.
|
static java.lang.String |
MSG_KEY_ANNOTATION_LOCATION
A key is pointing to the warning message text in "messages.properties"
file.
|
static java.lang.String |
MSG_KEY_ANNOTATION_LOCATION_ALONE
A key is pointing to the warning message text in "messages.properties"
file.
|
private static int[] |
SINGLELINE_ANNOTATION_PARENTS
Array of single line annotation parents.
|
Constructor and Description |
---|
AnnotationLocationCheck() |
Modifier and Type | Method and Description |
---|---|
private void |
checkAnnotations(DetailAST modifierNode,
int correctIndentation)
Checks annotations positions in code:
1) Checks whether the annotations locations are correct.
|
int[] |
getAcceptableTokens()
The configurable token set.
|
private static java.lang.String |
getAnnotationName(DetailAST annotation)
Returns the name of the given annotation.
|
int[] |
getDefaultTokens()
Returns the default token a check is interested in.
|
private static int |
getExpectedAnnotationIndentation(DetailAST modifierNode)
Returns an expected annotation indentation.
|
int[] |
getRequiredTokens()
The tokens that this check must be registered for.
|
private static boolean |
hasAnnotations(DetailAST modifierNode)
Checks whether a given modifier node has an annotation.
|
private static boolean |
hasNodeAfter(DetailAST annotation)
Checks whether an annotation node has any node after on the same line.
|
private static boolean |
hasNodeBefore(DetailAST annotation)
Checks whether an annotation node has any node before on the same line.
|
private static boolean |
hasNodeBeside(DetailAST annotation)
Checks whether an annotation node has any node before or after on the same line.
|
static boolean |
isAllowedPosition(DetailAST annotation,
int... allowedPositions)
Checks whether position of annotation is allowed.
|
private boolean |
isCorrectLocation(DetailAST annotation,
boolean hasParams)
Checks whether an annotation has a correct location.
|
private static boolean |
isInSpecificCodeBlock(DetailAST node,
int blockType)
Checks whether the scope of a node is restricted to a specific code block.
|
private static boolean |
isParameterized(DetailAST annotation)
Checks whether an annotation has parameters.
|
void |
setAllowSamelineMultipleAnnotations(boolean allow)
Sets if allow annotation to be located on the same line as
target element.
|
void |
setAllowSamelineParameterizedAnnotation(boolean allow)
Sets if allow parameterized annotation to be located on the same line as
target element.
|
void |
setAllowSamelineSingleParameterlessAnnotation(boolean allow)
Sets if allow same line single parameterless annotation.
|
void |
visitToken(DetailAST ast)
Called to process a token.
|
beginTree, destroy, finishTree, getClassLoader, getFileContents, getLine, getLines, getTabWidth, getTokenNames, init, isCommentNodesRequired, leaveToken, log, log, setClassLoader, setFileContents, setMessages, setTabWidth, setTokens
getCustomMessages, getId, getMessageBundle, getSeverity, getSeverityLevel, log, setId, setSeverity
configure, contextualize, finishLocalSetup, getConfiguration, setupChild
public static final java.lang.String MSG_KEY_ANNOTATION_LOCATION_ALONE
public static final java.lang.String MSG_KEY_ANNOTATION_LOCATION
private static final int[] SINGLELINE_ANNOTATION_PARENTS
private boolean allowSamelineSingleParameterlessAnnotation
private boolean allowSamelineParameterizedAnnotation
private boolean allowSamelineMultipleAnnotations
public final void setAllowSamelineSingleParameterlessAnnotation(boolean allow)
allow
- User's value of allowSamelineSingleParameterlessAnnotation.public final void setAllowSamelineParameterizedAnnotation(boolean allow)
allow
- User's value of allowSamelineParameterizedAnnotation.public final void setAllowSamelineMultipleAnnotations(boolean allow)
allow
- User's value of allowSamelineMultipleAnnotations.public int[] getDefaultTokens()
AbstractCheck
getDefaultTokens
in class AbstractCheck
TokenTypes
public int[] getAcceptableTokens()
AbstractCheck
getAcceptableTokens
in class AbstractCheck
TokenTypes
public int[] getRequiredTokens()
AbstractCheck
getRequiredTokens
in class AbstractCheck
TokenTypes
public void visitToken(DetailAST ast)
AbstractCheck
visitToken
in class AbstractCheck
ast
- the token to processprivate static boolean hasAnnotations(DetailAST modifierNode)
modifierNode
- modifier node.private static int getExpectedAnnotationIndentation(DetailAST modifierNode)
modifierNode
- modifier node.private void checkAnnotations(DetailAST modifierNode, int correctIndentation)
modifierNode
- modifiers node.correctIndentation
- correct indentation of the annotation.private static boolean isParameterized(DetailAST annotation)
annotation
- annotation node.private static java.lang.String getAnnotationName(DetailAST annotation)
annotation
- annotation node.private boolean isCorrectLocation(DetailAST annotation, boolean hasParams)
allowSamelineMultipleAnnotations
is set to true.
The method also:
1) checks parameterized annotation location considering
the value of allowSamelineParameterizedAnnotation
;
2) checks parameterless annotation location considering
the value of allowSamelineSingleParameterlessAnnotation
;
3) checks annotation location considering the elements
of SINGLELINE_ANNOTATION_PARENTS
;annotation
- annotation node.hasParams
- whether an annotation has parameters.private static boolean hasNodeBefore(DetailAST annotation)
annotation
- annotation node.private static boolean hasNodeBeside(DetailAST annotation)
annotation
- annotation node.private static boolean hasNodeAfter(DetailAST annotation)
annotation
- annotation node.public static boolean isAllowedPosition(DetailAST annotation, int... allowedPositions)
annotation
- annotation token.allowedPositions
- an array of allowed annotation positions.private static boolean isInSpecificCodeBlock(DetailAST node, int blockType)
node
- node.blockType
- block type.