checkstyle запретить аннотацию SuppressWarnings, если рядом нет комментария

В нашем проекте нам иногда приходится подавлять некоторые предупреждения (например, "WeakerAccess" может быть подавлен, так как проект также используется как библиотека в другом проекте, или "выражение всегда ложно" для instanceof проверенное исключение, которое выдается из библиотеки, которая маскирует факт создания этого исключения).

С другой стороны, нехорошо просто добавлять подавление, так как может быть неясно, почему оно там. Итак, я хотел бы добавить правило checkstyler, которое будет разрешать аннотацию SuppressWarnings, только если рядом есть комментарий. Этого должно быть достаточно, чтобы люди начали добавлять объяснения.

Но я не могу найти способ сделать это. Есть этот блок:

<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>

и кое-что о специальных комментариях, чтобы отключить checkstyler для строки, но это просто еще одна вещь для подавления предупреждений, которая также нуждается в объяснении... Но есть ли способ сказать, что подавление в порядке, если рядом есть какой-либо комментарий (на линии до или на той же линии)?

1 ответ

Решение

Я рекомендую использовать 2 чека в унисон. Используйте SuppressWarningsCheck, чтобы пометить методы, которые вы хотите документировать, и отобразить сообщение об ошибке, в котором говорится, что это нарушение, поскольку оно не документировано. Затем используйте SuppressWithNearbyCommentFilter для подавления нарушений другой проверки при добавлении документации. Чтобы фильтр работал, документация должна начинаться с определенного текста, чтобы он не ложно подавлял SuppressWarnings, которые на самом деле не имеют документации.

Пример:

$ 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.

Вы заметите, что есть 2 нарушения, но 3 SuppressWarnings. Первый пример показывает, как правильно подавить отсутствие документации. 2-й показывает только комментарий, но не документацию по подавлению, а 3-й показывает вообще никакого комментария.

<property name="format" value="^(unchecked|unused)$"/>

Это указывает, что для непроверенных и неиспользуемых подавлений потребуется только документация. Если вы хотите документацию для всех типов, кроме этих 2, я рекомендую выражение "^((?!unchecked|unused).)*$",

Другие вопросы по тегам