Jak wyłączyć określoną regułę stylu sprawdzania dla określonej linii kodu?

183

Mam Checkstyle regułę sprawdzania skonfigurowany w moim projekcie, który zakazuje zdefiniowanie metod klasy z więcej niż 3 parametrów wejściowych. Reguła działa dobrze dla moich klas, ale czasami muszę rozszerzać klasy stron trzecich, które nie przestrzegają tej konkretnej reguły.

Czy istnieje możliwość instruowania „stylu sprawdzania”, że pewną metodę należy po cichu zignorować?

BTW, skończyłem z własnym opakowaniem checkstyle: qulice.com (patrz Ścisła kontrola jakości kodu Java )

yegor256
źródło

Odpowiedzi:

291

Sprawdź użycie supressionCommentFilter na http://checkstyle.sourceforge.net/config_filters.html#SuppressionCommentFilter . Musisz dodać moduł do pliku checkstyle.xml

<module name="SuppressionCommentFilter"/>

i jest konfigurowalny. W ten sposób możesz dodawać komentarze do kodu, aby wyłączyć styl sprawdzania (na różnych poziomach), a następnie ponownie włączyć, używając komentarzy w kodzie. Na przykład

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

Lub jeszcze lepiej, użyj tej bardziej ulepszonej wersji:

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

co pozwala wyłączyć określone kontrole dla określonych wierszy kodu:

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

* Uwaga: musisz również dodać FileContentsHolder:

<module name="FileContentsHolder"/>

Zobacz też

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

w SuppressionFiltersekcji na tej samej stronie, która pozwala wyłączyć indywidualne sprawdzanie zasobów dopasowanych do wzorca.

Więc jeśli masz w pliku checkstyle.xml:

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

Możesz go wyłączyć w swoim pliku XML eliminacji za pomocą:

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

Inną metodą, obecnie dostępną w Checkstyle 5.7, jest tłumienie naruszeń za pomocą @SuppressWarningsadnotacji Java. Aby to zrobić, musisz dodać dwa nowe moduły ( SuppressWarningsFilteri SuppressWarningsHolder) do pliku konfiguracyjnego:

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

Następnie w kodzie możesz wykonać następujące czynności:

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

lub w przypadku wielokrotnego tłumienia:

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

NB:checkstyle: Prefiks „ ” jest opcjonalny (ale zalecany). Według dokumentacji nazwa parametru musi być pisana małymi literami, ale praktyka wskazuje, że każdy przypadek działa.

Chris Knight
źródło
7
Pamiętaj, aby dodać FileContentsHolder na TreeWalter. Zobacz stackoverflow.com/a/5764666/480483
djjeck
2
jeśli użyjesz, //CHECKSTYLE.OFF: a następnie zapomnisz włączyć go ponownie, czy pozostanie on zaznaczony tylko w pliku zawierającym //CHECKSTYLE.OFF: lub we wszystkich później przetworzonych plikach?
Roland
1
@Roland, pozostaje wyłączony tylko na czas trwania tej klasy testowej.
Chris Knight
1
„nazwa parametru musi być pisana małymi literami”. @SuppressWarnings("checkstyle:VariableDeclarationUsageDistance")działał dla mnie równie dobrze, jak odpowiednik małych liter.
Anders Rabo Thorbeck,
2
Od Checkstyle 8.1 SuppressionCommentFilter powinny być pod TreeWalker, a FileContentHoldernie jest to konieczne (dostępny) więcej.
avandeursen
70

Jeśli wolisz używać adnotacji do selektywnego wyciszania reguł, jest to teraz możliwe dzięki @SuppressWarningsadnotacji, zaczynając od Checkstyle 5.7 (i obsługiwanej przez Checkstyle Maven Plugin 2.12+).

Najpierw checkstyle.xmldodaj swój SuppressWarningsHoldermoduł do TreeWalker:

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

Następnie włącz SuppressWarningsFiltertam (jako rodzeństwo do TreeWalker):

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

<module name="TreeWalker">
...

Teraz możesz opisać np. Metodę, którą chcesz wykluczyć z określonej reguły Checkstyle:

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

checkstyle:Prefiks w argument @SuppressWarningsjest opcjonalny, ale lubię go jako przypomnienie, gdzie to ostrzeżenie pochodzi. Nazwa reguły musi być pisana małymi literami.

Wreszcie, jeśli używasz Eclipse, będzie narzekać na nieznany mu argument:

Nieobsługiwane @SuppressWarnings („checkstyle: methodlength”)

Możesz wyłączyć to ostrzeżenie Eclipse w preferencjach, jeśli chcesz:

Preferences:
  Java
  --> Compiler
  --> Errors/Warnings
  --> Annotations
  --> Unhandled token in '@SuppressWarnings': set to 'Ignore'
Henrik Heimbuerger
źródło
2
Określam to jako odpowiedź sprawdzoną, ponieważ uważam, że jest to rozwiązanie, które powinno najlepiej działać w większości przypadków.
avandeursen
33

Działa również dobrze SuppressWithNearbyCommentFilter, który używa indywidualnych komentarzy do tłumienia zdarzeń kontrolnych.

Na przykład

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

Aby skonfigurować filtr w taki sposób, aby sprawdzanie IGNORUJ KONTROLĘ STANOWI DLA NASTĘPNYCH LINII var unika uruchamiania jakichkolwiek audytów dla danej kontroli dla bieżącej linii i następnych linii var (w sumie var + 1 linii):

<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
źródło
Zmieniłbym wyrażenie regularne, dzięki CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINES?któremu komenda ignorowania będzie bardziej czytelna. (Będziesz mógł użyć opcji „Sprawdzanie IGNORE dla następnej linii 1” i „Sprawdzanie IGNORE dla następnej linii 3”).
Matt3o12
@ matt3o12 CHECKSTYLE IGNORE (\w+) FOR NEXT (\d+) LINErównież działa dla mnie (pasuje do obu linei lines).
Slava Semushin
3

W każdej odpowiedzi dotyczącej SuppressWarningsFilter brakuje ważnego szczegółu. Możesz używać tylko małych liter, jeśli jest on zdefiniowany jako taki w pliku checkstyle-config.xml. Jeśli nie, musisz użyć oryginalnej nazwy modułu.

Na przykład, jeśli w moim checkstyle-config.xml mam:

<module name="NoWhitespaceBefore"/>

Nie mogę użyć:

@SuppressWarnings({"nowhitespacebefore"})

Muszę jednak użyć:

@SuppressWarnings({"NoWhitespaceBefore"})

Aby pierwsza składnia zadziałała, plik checkstyle-config.xml powinien mieć:

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

To działało dla mnie, przynajmniej w wersji CheckStyle 6.17.

Joao Baltazar
źródło
1

Miałem trudności z powyższymi odpowiedziami, potencjalnie ponieważ ustawiłem ostrzeżenia checkStyle na błędy. To, co zadziałało, to SuppressionFilter: http://checkstyle.sourceforge.net/config_filters.html#SuppressionFilter

Wadą tego jest to, że zakres linii jest przechowywany w osobnym pliku suppresssions.xml, więc nieznany programista może nie od razu nawiązać połączenia.

Saltymule
źródło
Dziękuję, to była jedyna rzecz, która również działała dla mnie
jonathanrz
1
<module name="Checker">
    <module name="SuppressionCommentFilter"/>
    <module name="TreeWalker">
        <module name="FileContentsHolder"/>
    </module>
</module>

Aby skonfigurować filtr, aby pomijać zdarzenia kontrolne między komentarzem zawierającym wiersz POCZĄTEK KODU GENEROWANEGO a komentarzem zawierającym wiersz KONIEC KODU GENEROWANEGO:

<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

Zobacz więcej

Roberto
źródło
0

Możesz wypróbować https://checkstyle.sourceforge.io/config_filters.html#SuppressionXpathFilter

Generuj tłumienia Xpath przy użyciu interfejsu CLI z opcją -g. Następnie wybierz element tłumienia właściwy dla linii, którą chcesz pominąć. Zapisz to w pliku suppressions i określ ścieżkę do pliku w powyższym elemencie SuppressionXpathFilter.

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

Jeśli używasz mrówki, możesz odnieść się do tego postu jako zadania mrówki, które zostanie użyte do wygenerowania pliku Xpath z pomijaniem.

https://github.com/checkstyle/checkstyle/issues/6934#issuecomment-522289083

Sprawdź ten wątek na temat korzystania z filtra:

https://groups.google.com/forum/m/#!topic/checkstyle/F_f6R_Qk1EM

fernal73
źródło