W przypadku narzędzi do analizy statycznej często używam CPD, PMD , FindBugs i Checkstyle .
CPD to narzędzie PMD „Copy / Paste Detector”. Używałem PMD przez jakiś czas, zanim zauważyłem łącze „Finding Duplicated Code” na stronie internetowej PMD .
Chciałbym zaznaczyć, że czasami narzędzia te mogą wykraczać poza ich „gotowy do użycia” zestaw reguł. I to nie tylko dlatego, że są open source, więc możesz je przepisać. Niektóre z tych narzędzi są dostarczane z aplikacjami lub „haczykami”, które umożliwiają ich rozszerzenie. Na przykład PMD zawiera narzędzie „projektant”, które umożliwia tworzenie nowych reguł. Ponadto Checkstyle ma kontrolę DescendantToken, która ma właściwości, które umożliwiają znaczne dostosowanie.
Integruję te narzędzia z kompilacją opartą na Ant . Możesz kliknąć link, aby zobaczyć moją skomentowaną konfigurację.
Oprócz prostej integracji z kompilacją, uważam, że pomocne jest skonfigurowanie narzędzi tak, aby były nieco „zintegrowane” na kilka innych sposobów. Mianowicie generowanie raportów i jednorodność tłumienia ostrzeżeń. Chciałbym dodać te aspekty do tej dyskusji (która prawdopodobnie powinna mieć również tag „static-analysis”): jak ludzie konfigurują te narzędzia, aby stworzyć „ujednolicone” rozwiązanie? (Zadałem to pytanie osobno tutaj )
Po pierwsze, w przypadku raportów ostrzegawczych przekształcam dane wyjściowe, tak aby każde ostrzeżenie miało prosty format:
/absolute-path/filename:line-number:column-number: warning(tool-name): message
Jest to często nazywane „formatem Emacsa”, ale nawet jeśli nie używasz Emacsa, jest to rozsądny format do ujednolicania raportów. Na przykład:
/project/src/com/example/Foo.java:425:9: warning(Checkstyle):Missing a Javadoc comment.
Moje transformacje formatu ostrzegawczego są wykonywane przez mój skrypt Ant z łańcuchami filtrów Ant .
Druga „integracja”, którą robię, to tłumienie ostrzeżeń. Domyślnie każde narzędzie obsługuje komentarze lub adnotacje (lub obie), które można umieścić w kodzie, aby wyciszyć ostrzeżenie, które chcesz zignorować. Ale te różne prośby o stłumienie ostrzeżeń nie mają spójnego wyglądu, co wydaje się nieco głupie. Kiedy tłumisz ostrzeżenie, tłumisz ostrzeżenie, więc dlaczego nie zawsze pisać „ SuppressWarning
?”
Na przykład, domyślna konfiguracja PMD blokuje generowanie ostrzeżeń w wierszach kodu z ciągiem znaków „ NOPMD
” w komentarzu. PMD obsługuje również @SuppressWarnings
adnotacje w języku Java . Skonfigurowałem PMD tak, aby używał komentarzy zawierających „ SuppressWarning(PMD.
” zamiast NOPMD
tak, aby blokady PMD wyglądały podobnie. Wypełniam konkretną regułę, która jest naruszana podczas korzystania z pomijania stylu komentarzy:
// SuppressWarnings(PMD.PreserveStackTrace) justification: (false positive) exceptions are chained
Tylko część „ SuppressWarnings(PMD.
” ma znaczenie dla komentarza, ale jest zgodna z obsługą przez PMD @SuppressWarning
adnotacji, która rozpoznaje poszczególne naruszenia reguł po nazwie:
@SuppressWarnings("PMD.CompareObjectsWithEquals") // justification: identity comparision intended
Podobnie, Checkstyle wyłącza generowanie ostrzeżeń między parami komentarzy (brak obsługi adnotacji). Domyślnie komentarze wyłączające i włączające Checkstyle zawierają odpowiednio łańcuchy CHECKSTYLE:OFF
i CHECKSTYLE:ON
. Zmiana tej konfiguracji (za pomocą funkcji „SuppressionCommentFilter” firmy Checkstyle) w celu użycia ciągów „ BEGIN SuppressWarnings(CheckStyle.
” i „ END SuppressWarnings(CheckStyle.
” powoduje, że kontrolki wyglądają bardziej jak PMD:
// BEGIN SuppressWarnings(Checkstyle.HiddenField) justification: "Effective Java," 2nd ed., Bloch, Item 2
// END SuppressWarnings(Checkstyle.HiddenField)
W przypadku komentarzy typu Checkstyle, szczególne naruszenie kontroli ( HiddenField
) jest istotne, ponieważ każdy " BEGIN/END
" test ma swoją własną parę komentarzy.
FindBugs obsługuje również pomijanie generowania ostrzeżeń z @SuppressWarnings
adnotacją, więc nie jest wymagana dalsza konfiguracja, aby osiągnąć pewien poziom ujednolicenia z innymi narzędziami. Niestety, Findbugs musi obsługiwać niestandardową @SuppressWarnings
adnotację, ponieważ wbudowana @SuppressWarnings
adnotacja Java ma SOURCE
politykę przechowywania, która nie jest wystarczająco silna, aby zachować adnotację w pliku klasy, w którym FindBugs tego potrzebuje. W pełni kwalifikuję blokady ostrzeżeń FindBugs, aby uniknąć kolizji z @SuppressWarnings
adnotacją Java :
@edu.umd.cs.findbugs.annotations.SuppressWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
Te techniki sprawiają, że rzeczy wyglądają na dość spójne we wszystkich narzędziach. Należy zauważyć, że umieszczenie każdego pomijania ostrzeżenia w postaci ciągu „ SuppressWarnings
” ułatwia przeprowadzenie prostego wyszukiwania w celu znalezienia wszystkich wystąpień wszystkich narzędzi w całej bazie kodu.