Reputation: 714
In our project, we sometimes have to have some warnings suppressed (e.g. "WeakerAccess" might be suppressed as project is also used as a lib in another project, or "expression is always false" for instanceof
a checked exception that is thrown from a lib that masks the fact of throwing that exception).
On the other hand, it's not good to just add a suppression, as it might be unclear why is it there. So, I'd like to add a checkstyler rule that would only allow SuppressWarnings annotation if there is a comment nearby. That should be enough for people to start adding explanations.
But I can't find a way to do that. There is this block:
<module name="SuppressWarnings">
<property name="format"
value="^unchecked$|^unused$"/>
<property name="tokens"
value="
CLASS_DEF,INTERFACE_DEF,ENUM_DEF,
ANNOTATION_DEF,ANNOTATION_FIELD_DEF,
ENUM_CONSTANT_DEF,METHOD_DEF,CTOR_DEF
"/>
</module>
and some stuff about special comments to turn off checkstyler for a line, but it is just another suppress warnings thing that would need an explanation as well... But is there a way to say that suppression is OK if there is any comment nearby (on a line before or on the same line)?
Upvotes: 0
Views: 2045
Reputation: 2201
I recommend using 2 checks in unison. Use SuppressWarningsCheck to flag the methods you want documented and display an error message that says it is a violation because it is not documented. Then use SuppressWithNearbyCommentFilter to suppress violations of the other check when documentation is added. For the filter to work, the documentation must start with a specific text so it doesn't falsely suppress SuppressWarnings that don't really have a documentation.
Example:
$ cat TestClass.java
public class TestClass {
//SuppressWarnings: this is my reason for the suppression
@SuppressWarnings("unchecked")
void method() {
}
//this is just a comment and not a reason
@SuppressWarnings("unused")
void method2() {
}
@SuppressWarnings("unused")
void noComment() {
}
}
$ cat TestConfig.xml
<?xml version="1.0"?>
<!DOCTYPE module PUBLIC
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
"http://www.puppycrawl.com/dtds/configuration_1_3.dtd">
<module name="Checker">
<property name="charset" value="UTF-8"/>
<module name="TreeWalker">
<module name="SuppressWarnings">
<property name="format" value="^(unchecked|unused)$"/>
<message key="suppressed.warning.not.allowed"
value="The warning ''{0}'' cannot be suppressed at this location unless a comment is given for the reason for the suppression." />
<property name="tokens" value="CLASS_DEF,INTERFACE_DEF,ENUM_DEF,ANNOTATION_DEF,ANNOTATION_FIELD_DEF,ENUM_CONSTANT_DEF,METHOD_DEF,CTOR_DEF"/>
</module>
<module name="SuppressWithNearbyCommentFilter">
<property name="commentFormat"
value="SuppressWarnings: .{10,}"/>
<property name="checkFormat" value="SuppressWarnings"/>
<property name="influenceFormat" value="3"/>
</module>
</module>
</module>
$ java -jar checkstyle-8.18-all.jar -c TestConfig.xml TestClass.java
Starting audit...
[ERROR] TestClass.java:8:23: The warning 'unused' cannot be suppressed at this location unless a comment is given for the reason for the suppression. [SuppressWarnings]
[ERROR] TestClass.java:12:23: The warning 'unused' cannot be suppressed at this location unless a comment is given for the reason for the suppression. [SuppressWarnings]
Audit done.
Checkstyle ends with 2 errors.
You'll notice there are 2 violations but 3 SuppressWarnings. The first example shows how to correctly suppress that there is no documentation. The 2nd shows just a comment but not a documentation on the suppression, and the 3rd shows no comment at all.
<property name="format" value="^(unchecked|unused)$"/>
This specifies only documentation will be required for unchecked and unused suppressions. If you want documentation for all types but those 2, I recommend the expression "^((?!unchecked|unused).)*$"
.
Upvotes: 1