Pentru instrumentele de analiză statică folosesc adesea CPD, PMD , FindBugs și Checkstyle .
CPD este instrumentul PMD "Copy / Paste Detector". Folosesc PMD puțin timp înainte de a observa link-ul "Găsirea codului duplicat" pagina web PMD .
Aș dori să subliniez că uneori aceste instrumente pot fi extinse dincolo de setul de reguli "out-of-the-box". Și nu doar pentru că sunt sursă deschisă pentru a le putea rescrie. Unele dintre aceste instrumente vin cu aplicații sau "cârlige" care le permit să fie extinse. De exemplu, PMD vine cu instrumentul "designer" care vă permite să creați noi reguli. De asemenea, Checkstyle are controlul DescendantToken care are proprietăți care permit personalizarea substanțială.
Eu integrez aceste instrumente cu un constructor bazat pe Ant . Puteți să urmați linkul pentru a vedea configurația mea comentată.
În plus față de integrarea simplă în construcție, mi se pare util să configurez instrumentele să fie oarecum "integrate" în câteva alte moduri. Anume, generarea de rapoarte și uniformitatea suprimării avertismentelor. Aș dori să adaug aceste aspecte la această discuție (care ar trebui probabil să aibă și eticheta "analiză statică"): cum sunt oamenii configurând aceste instrumente pentru a crea o soluție "unificată"? (Am pus această întrebare separat aici )
În primul rând, pentru rapoartele de avertizare, eu transform de ieșire, astfel încât fiecare avertisment are format simplu:
/absolute-path/filename:line-number:column-number: warning(tool-name): message
Acest lucru este adesea numit "format Emacs", dar chiar dacă nu utilizați Emacs, este un format rezonabil pentru omogenizarea rapoartelor. De exemplu:
/project/src/com/example/Foo.java:425:9: warning(Checkstyle):Missing a Javadoc comment.
Formatele mele de transformare de avertizare sunt efectuate de scriptul meu Ant cu Ant filtru .
A doua "integrare" pe care o fac este pentru suprimarea avertismentelor. În mod prestabilit, fiecare instrument acceptă comentarii sau o adnotare (sau ambele) pe care le puteți plasa în codul dvs. pentru a tăcea un avertisment pe care doriți să îl ignorați. Dar aceste cereri diferite de suprimare a avertismentului nu au un aspect consistent care pare oarecum prostie. Când suprimați un avertisment, reprimați un avertisment, de ce să nu scrieți întotdeauna " SuppressWarning
?"
De exemplu, configurația implicită a PMD suprimă generarea de avertizare pe liniile de cod cu un șir " NOPMD
" într-un comentariu. De asemenea, PMD acceptă adnotarea @SuppressWarnings
a Java. Confirmați PMD să utilizeze comentariile care conțin SuppressWarning (PMD.
"în loc de NOPMD
), astfel încât suprimările PMD să arate la fel. suprimarea stilului:
// SuppressWarnings(PMD.PreserveStackTrace) justification: (false positive) exceptions are chained
Numai partea " SuppressWarnings (PMD.
" este semnificativă pentru un comentariu, dar este compatibilă cu suportul PMD pentru adnotarea @SuppressWarning
@SuppressWarnings("PMD.CompareObjectsWithEquals") // justification: identity comparision intended
Similarly, Checkstyle suppresses warning generation between pairs of comments (no annotation support is provided). By default, comments to turn Checkstyle off and on contain the strings CHECKSTYLE:OFF
and CHECKSTYLE:ON
, respectively. Changing this configuration (with Checkstyle's "SuppressionCommentFilter") to use the strings "BEGIN SuppressWarnings(CheckStyle.
" and "END SuppressWarnings(CheckStyle.
" makes the controls look more like PMD:
// BEGIN SuppressWarnings(Checkstyle.HiddenField) justification: "Effective Java," 2nd ed., Bloch, Item 2
// END SuppressWarnings(Checkstyle.HiddenField)
Cu comentariile Checkstyle, violarea specială a verificării ( HiddenField
) este semnificativă, deoarece fiecare cec are propria pereche de comentarii BEGIN / END
".
FindBugs suportă, de asemenea, suprimarea generațiilor de avertizare cu o adnotare @SuppressWarnings
, astfel încât nu este necesară o altă configurație pentru a atinge un anumit nivel de uniformitate cu alte instrumente. Din păcate, Findbugs trebuie să suporte o adnotare personalizată @SuppressWarnings
, deoarece adnotarea Java @SuppressWarnings
încorporată are o politică de păstrare SOURCE
care nu este puternică suficient pentru a păstra adnotarea în fișierul de clasă unde FindBugs are nevoie de ea. Calificăm pe deplin calculele de avertizare FindBugs pentru a evita contracararea cu adnotarea @SuppressWarnings
a Java:
@edu.umd.cs.findbugs.annotations.SuppressWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
Aceste tehnici fac ca lucrurile să pară în mod rezonabil consecvente între instrumente. Rețineți că dacă fiecare suprimare a avertismentelor conține șirul " SuppressWarnings
" este ușor să executați o căutare simplă pentru a găsi toate instanțele pentru toate uneltele de pe o bază de cod întregă.