Bagaimana cara menonaktifkan aturan gaya pemeriksaan tertentu untuk baris kode tertentu?

183

Saya memiliki aturan validasi checkstyle yang dikonfigurasi dalam proyek saya, yang melarang untuk mendefinisikan metode kelas dengan lebih dari 3 parameter input. Aturan berfungsi dengan baik untuk kelas saya , tetapi kadang-kadang saya harus memperluas kelas pihak ketiga, yang tidak mematuhi aturan khusus ini.

Apakah ada kemungkinan untuk menginstruksikan "checkstyle" bahwa metode tertentu harus diabaikan dalam hati?

BTW, saya berakhir dengan pembungkus saya sendiri checkstyle: qulice.com (lihat Kontrol Ketat Kualitas Kode Java )

yegor256
sumber

Jawaban:

291

Lihatlah penggunaan supressionCommentFilter di http://checkstyle.sourceforge.net/config_filters.html#SuppressionCommentFilter . Anda harus menambahkan modul ke checkstyle.xml Anda

<module name="SuppressionCommentFilter"/>

dan itu dapat dikonfigurasi. Dengan demikian Anda dapat menambahkan komentar ke kode Anda untuk mematikan checkstyle (di berbagai level) dan kemudian kembali lagi melalui penggunaan komentar dalam kode Anda. Misalnya

//CHECKSTYLE:OFF
public void someMethod(String arg1, String arg2, String arg3, String arg4) {
//CHECKSTYLE:ON

Atau bahkan lebih baik, gunakan versi yang lebih tweak ini:

<module name="SuppressionCommentFilter">
    <property name="offCommentFormat" value="CHECKSTYLE.OFF\: ([\w\|]+)"/>
    <property name="onCommentFormat" value="CHECKSTYLE.ON\: ([\w\|]+)"/>
    <property name="checkFormat" value="$1"/>
</module>

yang memungkinkan Anda untuk mematikan pemeriksaan khusus untuk baris kode tertentu:

//CHECKSTYLE.OFF: IllegalCatch - Much more readable than catching 7 exceptions
catch (Exception e)
//CHECKSTYLE.ON: IllegalCatch

* Catatan: Anda juga harus menambahkan FileContentsHolder:

<module name="FileContentsHolder"/>

Lihat juga

<module name="SuppressionFilter">
    <property name="file" value="docs/suppressions.xml"/>
</module>

di bawah SuppressionFilterbagian pada halaman yang sama, yang memungkinkan Anda untuk mematikan cek individu untuk sumber daya pola yang cocok.

Jadi, jika ada di checkstyle.xml Anda:

<module name="ParameterNumber">
   <property name="id" value="maxParameterNumber"/>
   <property name="max" value="3"/>
   <property name="tokens" value="METHOD_DEF"/>
</module>

Anda dapat mematikannya di file xml penindasan Anda dengan:

<suppress id="maxParameterNumber" files="YourCode.java"/>

Metode lain, sekarang tersedia di Checkstyle 5.7 adalah untuk menekan pelanggaran melalui @SuppressWarningsanotasi java. Untuk melakukan ini, Anda perlu menambahkan dua modul baru ( SuppressWarningsFilterdan SuppressWarningsHolder) di file konfigurasi Anda:

<module name="Checker">
   ...
   <module name="SuppressWarningsFilter" />
   <module name="TreeWalker">
       ...
       <module name="SuppressWarningsHolder" />
   </module>
</module> 

Kemudian, dalam kode Anda, Anda dapat melakukan hal berikut:

@SuppressWarnings("checkstyle:methodlength")
public void someLongMethod() throws Exception {

atau, untuk banyak penindasan:

@SuppressWarnings({"checkstyle:executablestatementcount", "checkstyle:methodlength"})
public void someLongMethod() throws Exception {

NB:checkstyle: Awalan " " adalah opsional (tetapi disarankan). Menurut dokumen nama parameter harus dalam huruf kecil semua, tetapi praktek menunjukkan setiap kasus berfungsi.

Chris Knight
sumber
7
Ingatlah untuk menambahkan FileContentsHolder di TreeWalter. Lihat stackoverflow.com/a/5764666/480483
djjeck
2
jika Anda menggunakan //CHECKSTYLE.OFF: dan kemudian lupa untuk menyalakannya lagi, apakah akan tetap diperiksa hanya dalam file yang berisi //CHECKSTYLE.OFF: atau semua file yang diproses selanjutnya juga?
Roland
1
@Roland, tetap tidak aktif hanya selama durasi kelas tes itu.
Chris Knight
1
"nama parameter harus dalam huruf kecil semua." @SuppressWarnings("checkstyle:VariableDeclarationUsageDistance")bekerja dengan baik bagi saya sebagai setara dengan huruf kecil.
Anders Rabo Thorbeck
2
Sejak checkstyle 8.1 yang SuppressionCommentFilter harus berada di bawah TreeWalker, dan FileContentHoldertidak diperlukan (tersedia) lagi.
avandeursen
70

Jika Anda lebih suka menggunakan anotasi untuk membungkam secara selektif aturan, ini sekarang mungkin menggunakan @SuppressWarningsanotasi, dimulai dengan Checkstyle 5.7 (dan didukung oleh Plugin Checkstyle Maven 2.12+).

Pertama, di Anda checkstyle.xml, tambahkan SuppressWarningsHoldermodul ke TreeWalker:

<module name="TreeWalker">
    <!-- Make the @SuppressWarnings annotations available to Checkstyle -->
    <module name="SuppressWarningsHolder" />
</module>

Selanjutnya, aktifkan yang SuppressWarningsFilterada (sebagai saudara kandung TreeWalker):

<!-- Filter out Checkstyle warnings that have been suppressed with the @SuppressWarnings annotation -->
<module name="SuppressWarningsFilter" />

<module name="TreeWalker">
...

Sekarang Anda dapat membuat anotasi misalnya metode yang ingin Anda kecualikan dari aturan Checkstyle tertentu:

@SuppressWarnings("checkstyle:methodlength")
@Override
public boolean equals(Object obj) {
    // very long auto-generated equals() method
}

The checkstyle:awalan dalam argumen untuk @SuppressWarningsopsional, tapi saya seperti itu sebagai pengingat di mana peringatan ini berasal. Nama aturan harus huruf kecil.

Terakhir, jika Anda menggunakan Eclipse, itu akan mengeluh tentang argumen yang tidak diketahui:

@SuppressWarnings tidak didukung ("checkstyle: methodlength")

Anda dapat menonaktifkan peringatan Eclipse ini di preferensi jika Anda suka:

Preferences:
  Java
  --> Compiler
  --> Errors/Warnings
  --> Annotations
  --> Unhandled token in '@SuppressWarnings': set to 'Ignore'
Henrik Heimbuerger
sumber
2
Saya mencalonkan ini sebagai jawaban yang dicentang, karena saya pikir ini adalah solusi yang paling sesuai untuk kebanyakan kasus.
avandeursen
33

Yang juga berfungsi dengan baik adalah SuppressWithNearbyCommentFilter yang menggunakan komentar individu untuk menekan acara audit.

Sebagai contoh

// CHECKSTYLE IGNORE check FOR NEXT 1 LINES
public void onClick(View view) { ... }

Untuk mengonfigurasikan filter sehingga PERIKSA PERKEMBANGAN periksa UNTUK BERIKUTNYA var LINES menghindari memicu audit untuk pemeriksaan yang diberikan untuk baris saat ini dan baris var berikutnya (untuk total var + 1 baris):

<module name="SuppressWithNearbyCommentFilter">
    <property name="commentFormat" value="CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINES"/>
    <property name="checkFormat" value="$1"/>
    <property name="influenceFormat" value="$2"/>
</module>

http://checkstyle.sourceforge.net/config.html

Akos Cz
sumber
Saya akan mengubah regex CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINES?yang akan membuat perintah abaikan lebih mudah dibaca. (Anda dapat menggunakan "PERIKSA PERIKSA LEBIH LANJUT UNTUK NEXT 1 LINE" dan "PERIKSA PERIKSA SELANJUTNYA UNTUK NEXT 3 LINES").
Matt3o12
@ matt3o12 CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINEjuga berfungsi untuk saya (cocok dengan keduanya linedan lines).
Slava Semushin
3

Setiap jawaban yang mengacu pada SuppressWarningsFilter tidak memiliki detail penting. Anda hanya dapat menggunakan id semua-huruf kecil jika itu didefinisikan seperti itu di checkstyle-config.xml Anda. Jika tidak, Anda harus menggunakan nama modul asli.

Misalnya, jika di checkstyle-config.xml saya, saya punya:

<module name="NoWhitespaceBefore"/>

Saya tidak bisa menggunakan:

@SuppressWarnings({"nowhitespacebefore"})

Namun saya harus menggunakan:

@SuppressWarnings({"NoWhitespaceBefore"})

Agar sintaks pertama berfungsi, checkstyle-config.xml harus memiliki:

<module name="NoWhitespaceBefore">
  <property name="id" value="nowhitespacebefore"/>
</module>

Inilah yang berhasil bagi saya, setidaknya dalam versi CheckStyle 6.17.

Joao Baltazar
sumber
1

Saya mengalami kesulitan dengan jawaban di atas, berpotensi karena saya mengatur peringatan checkStyle menjadi kesalahan. Apa yang berhasil adalah SuppressionFilter: http://checkstyle.sourceforge.net/config_filters.html#SuppressionFilter

Kelemahan dari ini adalah bahwa rentang baris disimpan dalam file suppresssions.xml terpisah, sehingga pengembang yang tidak terbiasa mungkin tidak segera membuat koneksi.

Saltymule
sumber
Terima kasih, itu satu-satunya yang bekerja untuk saya juga
jonathanrz
1
<module name="Checker">
    <module name="SuppressionCommentFilter"/>
    <module name="TreeWalker">
        <module name="FileContentsHolder"/>
    </module>
</module>

Untuk mengonfigurasi filter untuk menekan acara audit antara komentar yang berisi baris BEGIN GENERATED CODE dan komentar yang berisi baris END GENERATED CODE:

<module name="SuppressionCommentFilter">
  <property name="offCommentFormat" value="BEGIN GENERATED CODE"/>
  <property name="onCommentFormat" value="END GENERATED CODE"/>
</module>

//BEGIN GENERATED CODE
@Override
public boolean equals(Object obj) { ... } // No violation events will be reported

@Override
public int hashCode() { ... } // No violation events will be reported
//END GENERATED CODE

Lihat lebih lanjut

Roberto
sumber
0

Anda dapat mencoba https://checkstyle.sourceforge.io/config_filters.html#SuppressionXpathFilter

Anda dapat mengonfigurasinya sebagai:


<module name="SuppressionXpathFilter">
  <property name="file" value="config/suppressions-xpath.xml"/>
  <property name="optional" value="false"/>
</module>
        

Hasilkan penindasan Xpath menggunakan CLI dengan opsi -g dan tentukan output menggunakan switch -o.

https://checkstyle.sourceforge.io/cmdline.html#Command_line_usage

Berikut ini cuplikan semut yang akan membantu Anda mengatur generasi otomatis penindasan Checkstyle Anda:


<target name="checkstyleg">
    <move file="suppressions-xpath.xml"
      tofile="suppressions-xpath.xml.bak"
      preservelastmodified="true"
      force="true"
      failonerror="false"
      verbose="true"/>
    <fileset dir="${basedir}"
                    id="javasrcs">
    <include name="**/*.java" />
    </fileset>
    <pathconvert property="sources"
                            refid="javasrcs"
                            pathsep=" " />
    <loadfile property="cs.cp"
                        srcFile="../${cs.classpath.file}" />
    <java classname="${cs.main.class}"
                logError="true">
    <arg line="-c ../${cs.config} -p ${cs.properties} -o ${ant.project.name}-xpath.xml -g ${sources}" />
    <classpath>
        <pathelement path="${cs.cp}" />
        <pathelement path="${java.class.path}" />
    </classpath>
</java>
<condition property="file.is.empty" else="false">
     <length file="${ant.project.name}-xpath.xml" when="equal" length="0" />
   </condition>
   <if>
     <equals arg1="${file.is.empty}" arg2="false"/>
     <then>
     <move file="${ant.project.name}-xpath.xml"
      tofile="suppressions-xpath.xml"
      preservelastmodified="true"
      force="true"
      failonerror="true"
  verbose="true"/>
   </then>
</if>
    </target>

The suppressions-xpath.xml ditentukan sebagai sumber penindasan Xpath dalam konfigurasi aturan Checkstyle. Dalam cuplikan di atas, saya memuat classpath Checkstyle dari file cs.cp ke properti. Anda dapat memilih untuk menentukan classpath secara langsung.

Atau Anda dapat menggunakan asyik dalam Maven (atau Ant) untuk melakukan hal yang sama:


import java.nio.file.Files
import java.nio.file.StandardCopyOption  
import java.nio.file.Paths

def backupSuppressions() {
  def supprFileName = 
      project.properties["checkstyle.suppressionsFile"]
  def suppr = Paths.get(supprFileName)
  def target = null
  if (Files.exists(suppr)) {
    def supprBak = Paths.get(supprFileName + ".bak")
    target = Files.move(suppr, supprBak,
        StandardCopyOption.REPLACE_EXISTING)
    println "Backed up " + supprFileName
  }
  return target
}

def renameSuppressions() {
  def supprFileName = 
      project.properties["checkstyle.suppressionsFile"]
  def suppr = Paths.get(project.name + "-xpath.xml")
  def target = null
  if (Files.exists(suppr)) {
    def supprNew = Paths.get(supprFileName)
    target = Files.move(suppr, supprNew)
    println "Renamed " + suppr + " to " + supprFileName
  }
  return target
}

def getClassPath(classLoader, sb) {
  classLoader.getURLs().each {url->
     sb.append("${url.getFile().toString()}:")
  }
  if (classLoader.parent) {
     getClassPath(classLoader.parent, sb)
  }
  return sb.toString()
}

backupSuppressions()

def cp = getClassPath(this.class.classLoader, 
    new StringBuilder())
def csMainClass = 
      project.properties["cs.main.class"]
def csRules = 
      project.properties["checkstyle.rules"]
def csProps = 
      project.properties["checkstyle.properties"]

String[] args = ["java", "-cp", cp,
    csMainClass,
    "-c", csRules,
"-p", csProps,
"-o", project.name + "-xpath.xml",
"-g", "src"]

ProcessBuilder pb = new ProcessBuilder(args)
pb = pb.inheritIO()
Process proc = pb.start()
proc.waitFor()

renameSuppressions()

Satu-satunya kelemahan dengan menggunakan penindasan Xpath --- selain cek itu tidak mendukung --- adalah jika Anda memiliki kode seperti berikut:

package cstests;

@SuppressWarnings("PMD")
public interface TestMagicNumber {
  static byte[] getAsciiRotator() {
    byte[] rotation = new byte[95 * 2];
    for (byte i = ' '; i <= '~'; i++) {
      rotation[i - ' '] = i;
      rotation[i + 95 - ' '] = i;
    }
    return rotation;
  }
}

Penindasan Xpath yang dihasilkan dalam kasus ini tidak dicerna oleh Checkstyle dan pemeriksa gagal dengan pengecualian:

<suppress-xpath
       files="TestMagicNumber.java"
       checks="MagicNumberCheck"
       query="/INTERFACE_DEF[./IDENT[@text='TestMagicNumber']]/OBJBLOCK/METHOD_DEF[./IDENT[@text='getAsciiRotator']]/SLIST/LITERAL_FOR/SLIST/EXPR/ASSIGN[./IDENT[@text='i']]/INDEX_OP[./IDENT[@text='rotation']]/EXPR/MINUS[./CHAR_LITERAL[@text='' '']]/PLUS[./IDENT[@text='i']]/NUM_INT[@text='95']"/>

Menghasilkan penindasan Xpath direkomendasikan ketika Anda telah memperbaiki semua pelanggaran lainnya dan ingin menekan sisanya. Itu tidak akan memungkinkan Anda untuk memilih contoh spesifik dalam kode untuk ditekan. Anda dapat, bagaimanapun, memilih dan memilih penindasan dari file yang dihasilkan untuk melakukan hal itu.

Untuk menentukan aturan tertentu, file atau pesan kesalahan, SuppressionXpathSingleFilter akan lebih cocok.

https://checkstyle.sourceforge.io/config_filters.html#SuppressionXpathSingleFilter

fernal73
sumber