Для інструментів статичного аналізу я часто використовую CPD, PMD , FindBugs та Checkstyle .
CPD - це інструмент "Детектор копіювання / вставки" PMD. Я використовував PMD деякий час, перш ніж помітив посилання "Пошук дублюючого коду" на веб-сторінці PMD .
Я хотів би зазначити, що іноді ці інструменти можуть бути розширені за межами набору правил "поза коробкою". І не лише тому, що вони з відкритим кодом, щоб ви могли їх переписати. Деякі з цих інструментів поставляються із додатками чи "гачками", які дозволяють розширити їх. Наприклад, PMD поставляється з інструментом "конструктор", який дозволяє створювати нові правила. Також Checkstyle має перевірку DescendantToken, яка має властивості, що дозволяють істотно налаштувати.
Я інтегрую ці інструменти у збірку на основі мурашок . Ви можете перейти за посиланням, щоб побачити мою коментовану конфігурацію.
Окрім простої інтеграції в збірку, мені здається корисним налаштувати інструменти, щоб дещо «інтегруватися» в пару інших способів. А саме, повідомляти про рівномірність генерації та попередження попередження. Я хотів би додати ці аспекти до цієї дискусії (яка, мабуть, має також тег "статичний аналіз"): як люди налаштовують ці інструменти для створення "уніфікованого" рішення? (Я задав це питання окремо тут )
По-перше, для попереджувальних звітів я перетворюю вихід, щоб кожне попередження мало простий формат:
/absolute-path/filename:line-number:column-number: warning(tool-name): message
Це часто називається "формат Emacs", але навіть якщо ви не використовуєте Emacs, це розумний формат для гомогенізації звітів. Наприклад:
/project/src/com/example/Foo.java:425:9: warning(Checkstyle):Missing a Javadoc comment.
Мої перетворення формату попередження виконуються моїм сценарієм Ant з фільтром Ant .
Друга «інтеграція», яку я роблю, - це попередження придушення. За замовчуванням кожен інструмент підтримує коментарі або примітку (або обидва), які ви можете помістити у свій код, щоб заглушити попередження, яке ви хочете ігнорувати. Але ці різні запити щодо придушення попередження не мають послідовного вигляду, який здається дещо дурним. Коли ви придушуєте попередження, ви придушуєте попередження, то чому б не завжди писати " SuppressWarning?"
Наприклад, конфігурація за замовчуванням PMD пригнічує генерацію попереджень у рядках коду з рядком " NOPMD" в коментарі. Також PMD підтримує @SuppressWarningsанотацію Java . Я налаштовую PMD використовувати коментарі, що містять " SuppressWarning(PMD." замість того, NOPMDщоб придушення PMD виглядали однаково. Я заповнюю конкретне правило, яке порушується при використанні придушення стилю коментарів:
// SuppressWarnings(PMD.PreserveStackTrace) justification: (false positive) exceptions are chained
Тільки SuppressWarnings(PMD.частина " " є важливою для коментаря, але вона відповідає підтримці PMD для @SuppressWarningпримітки, яка розпізнає окремі порушення правил за назвою:
@SuppressWarnings("PMD.CompareObjectsWithEquals") // justification: identity comparision intended
Аналогічно, Checkstyle пригнічує генерацію попереджень між парами коментарів (не підтримується анотація). За замовчуванням коментарі для вимкнення та ввімкнення Checkstyle містять рядки CHECKSTYLE:OFFта CHECKSTYLE:ONвідповідно. Зміна цієї конфігурації (за допомогою "SuppressionCommentFilter" Checkstyle) для використання рядків " BEGIN SuppressWarnings(CheckStyle." і " END SuppressWarnings(CheckStyle." робить елементи управління схожішими на PMD:
// BEGIN SuppressWarnings(Checkstyle.HiddenField) justification: "Effective Java," 2nd ed., Bloch, Item 2
// END SuppressWarnings(Checkstyle.HiddenField)
Що стосується коментарів Checkstyle, то особливе порушення перевірки ( HiddenField) є суттєвим, оскільки кожна перевірка має власну " BEGIN/END" пару коментарів.
FindBugs також підтримує придушення покоління попередження з @SuppressWarningsанотацією, тому не потрібно додаткової конфігурації для досягнення певного рівня однаковості з іншими інструментами. На жаль, Findbugs повинен підтримувати користувацьку @SuppressWarningsанотацію, оскільки вбудована @SuppressWarningsанотація на Java має SOURCEполітику збереження, яка недостатньо сильна, щоб зберегти примітку у файлі класу, де її потребує FindBugs. Я повністю кваліфікуюча подання попереджень FindBugs, щоб уникнути зіткнення з @SuppressWarningsанотацією Java :
@edu.umd.cs.findbugs.annotations.SuppressWarnings("UWF_FIELD_NOT_INITIALIZED_IN_CONSTRUCTOR")
Ці методи дозволяють речі виглядати досить послідовно в різних інструментах. Зауважте, що наявність кожного придушення попередження містить рядок " SuppressWarnings" дозволяє легко запустити простий пошук, щоб знайти всі екземпляри всіх інструментів протягом усієї бази коду.