SuppressWithPlainTextCommentFilter

Since Checkstyle 8.6

Description

Filter SuppressWithPlainTextCommentFilter uses plain text to suppress audit events. The filter can be used only to suppress audit events received from the checks which implement FileSetCheck interface. In other words, the checks which have Checker as a parent module. The filter knows nothing about AST, it treats only plain text comments and extracts the information required for suppression from the plain text comments. Currently, the filter supports only single-line comments.

Please, be aware of the fact that, it is not recommended to use the filter for Java code anymore, however you still are able to use it to suppress audit events received from the checks which implement FileSetCheck interface.

Rationale: Sometimes there are legitimate reasons for violating a check. When this is a matter of the code in question and not personal preference, the best place to override the policy is in the code itself. Semi-structured comments can be associated with the check. This is sometimes superior to a separate suppressions file, which must be kept up-to-date as the source file is edited.

Note that the suppression comment should be put before the violation. You can use more than one suppression comment each on separate line.

Properties

name description type default value since
checkFormat Specify check pattern to suppress. Pattern ".*" 8.6
idFormat Specify check ID pattern to suppress. Pattern null 8.24
messageFormat Specify message pattern to suppress. Pattern null 8.6
offCommentFormat Specify comment pattern to trigger filter to begin suppression. Pattern "// CHECKSTYLE:OFF" 8.6
onCommentFormat Specify comment pattern to trigger filter to end suppression. Pattern "// CHECKSTYLE:ON" 8.6

Notes

Properties offCommentFormat and onCommentFormat must have equal paren counts.

SuppressionWithPlainTextCommentFilter can suppress Checks that have Treewalker or Checker as parent module.

Examples

To configure a filter to suppress audit events between a comment containing // CHECKSTYLE:OFF and a comment containing // CHECKSTYLE:ON (the default comments). Checker is configured to check only properties files using UniqueProperties check:


<module name="Checker">
  <property name="fileExtensions" value="properties"/>

  <module name="UniqueProperties"/>
  <module name="SuppressWithPlainTextCommentFilter"/>

</module>
        

Example:


# // CHECKSTYLE:OFF
# suppressed violation below
keyB=value1
keyB=value2
# // CHECKSTYLE:ON
# // violation below 'Duplicated property 'keyC' (2 occurrence(s)).'
keyC=value4
keyC=value5
        

To configure a filter to suppress audit events between a comment containing STOP CHECK and a comment containing RESUME CHECK. Checker is configured to check only properties files using UniqueProperties check:


<module name="Checker">
  <property name="fileExtensions" value="properties"/>

  <module name="UniqueProperties"/>

  <module name="SuppressWithPlainTextCommentFilter">
    <property name="offCommentFormat" value="STOP CHECK"/>
    <property name="onCommentFormat" value="RESUME CHECK"/>
  </module>

</module>
        

Example:


# STOP CHECK
# suppressed violation below
keyB=value1
keyB=value2
# RESUME CHECK
# // violation below 'Duplicated property 'keyC' (2 occurrence(s)).'
keyC=value4
keyC=value5
        

To configure a filter to suppress UniqueProperties check audit events between a comment containing STOP UNIQUE CHECK and a comment containing RESUME UNIQUE CHECK. Checker is configured to check only properties files using both UniqueProperties check and OrderedProperties check:


<module name="Checker">
  <property name="fileExtensions" value="properties"/>

  <module name="OrderedProperties"/>
  <module name="UniqueProperties"/>

  <module name="SuppressWithPlainTextCommentFilter">
    <property name="offCommentFormat" value="STOP UNIQUE CHECK"/>
    <property name="onCommentFormat" value="RESUME UNIQUE CHECK"/>
    <property name="checkFormat" value="UniquePropertiesCheck"/>
  </module>

</module>
        

Example:


# STOP UNIQUE CHECK
# (OrderedProperties check is still enabled)
# suppressed violation below
keyB=value1
keyB=value2
# // violation below 'Property key 'keyA' is not in the right order with previous property 'keyB.'
keyA=value3
# RESUME UNIQUE CHECK
# // violation below 'Duplicated property 'keyC' (2 occurrence(s)).'
keyC=value4
keyC=value5
        

To configure a filter to suppress audit events for the check mentioned in the comment CSOFF: regexp and CSON: regexp. Checker is configured to check only XML files using RegexpSingleline check to detect disallowed 'code' values for the 'type' parameter:


<module name="Checker">
  <property name="fileExtensions" value="xml"/>

  <module name="RegexpSingleline">
    <property name="format"
        value="param\s+name=&quot;type&quot;\s+value=&quot;code&quot;"/>
    <property name="message"
        value="Type code is not allowed. Use type raw instead."/>
  </module>

  <module name="SuppressWithPlainTextCommentFilter">
    <property name="offCommentFormat" value="CSOFF\: ([\w\|]+)"/>
    <property name="onCommentFormat" value="CSON\: ([\w\|]+)"/>
    <property name="checkFormat" value="$1"/>
  </module>

</module>
        

Example:


<project>
  <p>Examples:</p>
<!-- CSOFF: RegexpSinglelineCheck -->
  <macro name="example">
    <param name="path" value="Example3.java"/>
    <!-- suppressed violation below  -->
    <param name="type" value="code"/>
  </macro>
<!-- CSON: RegexpSinglelineCheck -->
  <macro name="example">
    <param name="path" value="Example4.sql"/>
    <param name="type" value="code"/>
    <!-- // violation above 'Type code is not allowed. Use type raw instead'
    -->
  </macro>
</project>
        

To configure a filter to suppress all audit events between a comment containing CSOFF: ALMOST_ALL and a comment containing CSON: ALMOST_ALL, except for the RegexpSingleline check. Checker is configured to check only XML files using RegexpSingleline check to detect disallowed 'code' values for the 'type' parameter:


<module name="Checker">
  <property name="fileExtensions" value="xml"/>

  <module name="RegexpSingleline">
    <property name="format"
        value="param\s+name=&quot;type&quot;\s+value=&quot;code&quot;"/>
    <property name="message"
        value="Type code is not allowed. Use type raw instead."/>
  </module>

  <module name="SuppressWithPlainTextCommentFilter">
    <property name="offCommentFormat" value="CSOFF\: ALMOST_ALL"/>
    <property name="onCommentFormat" value="CSON\: ALMOST_ALL"/>
    <property name="checkFormat" value="^((?!(RegexpSinglelineCheck)).)*$"/>
  </module>

</module>
        

Example:


<project>
  <p>Examples:</p>
<!-- CSOFF: ALMOST_ALL -->
  <macro name="example">
    <param name="path" value="Example3.sql"/>
    <param name="type" value="code"/>
    <!-- // violation above 'Type code is not allowed. Use type raw instead'
    (The RegexpSingleline check is explicitly excluded from suppressions.) -->
  </macro>
<!-- CSON: ALMOST_ALL -->
  <macro name="example">
    <param name="path" value="Example4.sql"/>
    <param name="type" value="code"/>
    <!-- // violation above 'Type code is not allowed. Use type raw instead'
    -->
  </macro>
</project>
        

To configure a filter to suppress audit events that match a specific message in the messageFormat (allowing suppression not only by the check's name but also by the message content, as the same check can report violations with different message formats) between a comment containing CSOFF and comment containing CSON. Checker is configured to check only XML files using RegexpSingleline check to detect disallowed 'code' and 'config' values for the 'type' parameter:


<module name="Checker">
  <property name="fileExtensions" value="xml"/>

  <module name="RegexpSingleline">
    <property name="format"
        value="param\s+name=&quot;type&quot;\s+value=&quot;code&quot;"/>
    <property name="message"
        value="Type code is not allowed. Use type raw instead."/>
  </module>

  <module name="RegexpSingleline">
    <property name="format"
        value="param\s+name=&quot;type&quot;\s+value=&quot;config&quot;"/>
    <property name="message" value="Type config is not allowed in this file."/>
  </module>

  <module name="SuppressWithPlainTextCommentFilter">
    <property name="offCommentFormat" value="CSOFF"/>
    <property name="onCommentFormat" value="CSON"/>
    <property name="checkFormat" value="RegexpSinglelineCheck"/>
    <property name="messageFormat"
        value="^Type code is not allowed. Use type raw instead.$"/>
  </module>
</module>
        

Example:


<project>
  <p>Examples:</p>
<!-- CSOFF -->
  <macro name="example">
    <param name="path" value="Example3.java"/>
    <param name="type" value="config"/>
    <!-- // violation above 'Type config is not allowed in this file'
    (Audit events with this message are not suppressed.) -->
  </macro>
  <macro name="example">
    <param name="path" value="Example4.java"/>
    <!-- suppressed violation below  -->
    <param name="type" value="code"/>
<!-- CSON -->
  </macro>
</project>
        

It is possible to specify the ID of checks, which can be used by the SuppressWithPlainTextCommentFilter to suppress audit events. The following examples show how to suppress audit events in code surrounded by CSOFF <ID> (reason) and CSON <ID>, where ID is the ID of the check you want to suppress.

Example of Checkstyle checks and SuppressWithPlainTextCommentFilter configuration - the checkFormat, set to '$1', indicates that the ID of the check is in the first group of offCommentFormat and onCommentFormat regular expressions. Checker is configured to check only XML files using RegexpSingleline check to detect disallowed 'code' and 'config' values for the 'type' parameter:


<module name="Checker">
  <property name="fileExtensions" value="xml"/>

  <module name="RegexpSingleline">
    <property name="id" value="typeCode"/>
    <property name="format"
        value="param\s+name=&quot;type&quot;\s+value=&quot;code&quot;"/>
    <property name="message"
        value="Type code is not allowed. Use type raw instead."/>
  </module>

  <module name="RegexpSingleline">
    <property name="id" value="typeConfig"/>
    <property name="format"
        value="param\s+name=&quot;type&quot;\s+value=&quot;config&quot;"/>
    <property name="message" value="Type config is not allowed in this file."/>
  </module>

  <module name="SuppressWithPlainTextCommentFilter">
    <property name="offCommentFormat" value="CSOFF (\w+) \(([\w\s]+)\)"/>
    <property name="onCommentFormat" value="CSON (\w+)"/>
    <property name="idFormat" value="$1"/>
  </module>

</module>
        

Example:


<project>
  <p>Examples:</p>
<!-- CSOFF typeCode (OK to use examples of type code here) -->
  <macro name="example">
    <param name="path" value="Example3.java"/>
    <param name="type" value="config"/>
    <!-- // violation above 'Type config is not allowed in this file'
    (Audit events from the check with id "typeConfig" are not suppressed) -->
  </macro>
  <macro name="example">
    <param name="path" value="Example4.sql"/>
    <!-- suppressed violation below  -->
    <param name="type" value="code"/>
<!-- CSON typeCode -->
  </macro>
</project>
        

Example of how to configure the check to suppress more than one check. Checker is configured to check only SQL files using RegexpSingleline check to detect usage of JOIN operations and LineLength check to detect lines exceeding 60 characters:


<module name="Checker">
  <property name="fileExtensions" value="sql"/>

  <module name="RegexpSingleline">
    <property name="format" value="^.*JOIN\s.+\s(ON|USING)$"/>
    <property name="message" value="Don't use JOIN, use sub-select instead."/>
  </module>

  <module name="LineLength">
    <property name="max" value="60"/>
  </module>

  <module name="SuppressWithPlainTextCommentFilter">
    <property name="offCommentFormat" value="CSOFF\: ([\w\|]+)"/>
    <property name="onCommentFormat" value="CSON\: ([\w\|]+)"/>
    <property name="checkFormat" value="$1"/>
  </module>

</module>
        

Example:


-- CSOFF: RegexpSinglelineCheck
-- CSOFF: LineLengthCheck
SELECT name, job_name
FROM users AS u
-- suppressed violation below (RegexpSinglelineCheck)
JOIN jobs AS j ON u.job_id = j.id
-- suppressed violation below (LineLengthCheck)
WHERE u.registration_date >= '2023-01-01' AND u.status = 'active';
        

This check is not limited to comments. It can match any symbols in the given file as offCommentFormat and onCommentFormat for suppression. The following example shows how to suppress violations within a text block for the LineLength check. Checker is configured to use LineLength check to detect lines exceeding the maximum length of 100 characters:


<module name="Checker">
  <module name="LineLength">
      <property name="max" value="100"/>
  </module>

  <module name="SuppressWithPlainTextCommentFilter">
    <property name="offCommentFormat" value='=\s+"""'/>
    <property name="onCommentFormat" value='^\s+""";'/>
  </module>

</module>
        

Example:


public class Example9 {

  // suppressed violation below, opening/closing quotes are 'offCommentFormat' and 'onCommentFormat'
  static final String LOCATION_CSV_SAMPLE = """
          locationId,label,regionId,regionLabel,vendorId,vendorLabel,address,address2,city,stateProvinceCode,zipCode,countryCode,latitude,longitude
          ST001,Station 001,ZONE1,Zone 1,CP1,Competitor 1,123 Street,Unit 2,Houston,TX,77033,US,29.761496813335178,-95.53049214204984
          ST002,Station 002,ZONE2,,CP2,,668 Street,Unit 23,San Jose,CA,95191,US,37.35102477242508,-121.9209934020318
          """;

  // violation below, 'Line is longer than 100 characters (found 183).'
  static final String SINGLE_LINE_SAMPLE = "locationId,label,regionId,regionLabel,vendorId,vendorLabel,address,address2,city,stateProvinceCode,zipCode,countryCode,latitude,longitude";
}
        

Example of Usage

Package

com.puppycrawl.tools.checkstyle.filters

Parent Module

Checker