Для инструментов статического анализа я часто использую CPD, PMD , FindBugs и Checkstyle .
CPD - это инструмент PMD «Детектор копирования / вставки». Некоторое время я использовал PMD, прежде чем заметил ссылку «Поиск повторяющегося кода» на веб-странице PMD .
Я хотел бы отметить, что эти инструменты иногда могут быть расширены за пределы их «нестандартного» набора правил. И не только потому, что у них открытый исходный код, так что вы можете их переписать. Некоторые из этих инструментов поставляются с приложениями или «крючками», которые позволяют их расширять. Например, PMD поставляется с инструментом «конструктор», который позволяет создавать новые правила. Кроме того, в Checkstyle есть проверка DescendantToken, которая имеет свойства, допускающие существенную настройку.
Я интегрирую эти инструменты в сборку на основе Ant . Вы можете перейти по ссылке, чтобы увидеть мою прокомментированную конфигурацию.
В дополнение к простой интеграции в сборку, я считаю полезным настроить инструменты так, чтобы они были несколько «интегрированы» несколькими другими способами. А именно: формирование отчетов и единообразие подавления предупреждений. Я хотел бы добавить эти аспекты в это обсуждение (которое, вероятно, также должно иметь тег «static-analysis»): как люди настраивают эти инструменты для создания «унифицированного» решения? (Я задал этот вопрос отдельно здесь )
Во-первых, для отчетов с предупреждениями я преобразовываю вывод так, чтобы каждое предупреждение имело простой формат:
/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
соответственно. Изменение этой конфигурации (с помощью Checkstyle's "SuppressionCommentFilter") для использования строк " 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
», это упрощает выполнение простого поиска для поиска всех экземпляров всех инструментов по всей базе кода.