Статистическому анализатору c необходимо знать, что означает код. Для скомпилированных языков значение кода часто зависит от того, как вызывается компилятор. Для C / C ++ это включает такие параметры, как -D
(определение макроса) и -I
(include path), поскольку первый часто контролирует поведение #ifdef
, а второй используется для поиска заголовков для сторонних библиотек. (среди прочего). Для Java команда компиляции включает опцию -classpath
, которая опять-таки определяет, как обнаруживаются сторонние зависимости. Другие скомпилированные языки похожи.
Важно найти правильные зависимости как потому, что это может повлиять на способ синтаксического анализа кода и его поведение. В качестве примера первого рассмотрим, что в Java выражение a.b.c.d.e.f
может означать много вещей, поскольку оператор .
используется как для навигации по иерархии пакетов, так и для разыменования объекта для доступа к полю. Если a
исходит из пути к классам, инструмент не может знать, что это значит, без проверки классов в этом пути к классам. В качестве примера последнего рассмотрим функцию в сторонней библиотеке, которая принимает ссылку на объект. Позволяет ли эта функция передавать ссылку null
? Если это не хорошо известная функция, о которой инструмент уже знает, то единственный способ сказать, что анализатор проверяет байт-код этой функции.
Теперь инструмент может просто попросить пользователя предоставить Информация компиляции непосредственно при вызове анализатора. Таков подход, например, clang-tidy
. Это концептуально просто, но поддерживать его сложно. В большом проекте может быть много наборов файлов, которые компилируются с различными параметрами, что затрудняет настройку. И, что еще хуже, не существует простого и общего способа гарантировать, что параметры, передаваемые в анализатор, и набор файлов для анализа будут синхронизированы c с реальной сборкой.
Следовательно, некоторые инструменты обеспечивают " монитор сборки », который может обернуть обычную сборку, проверяя все компиляции, которые он выполняет, и собирая набор исходных файлов для анализа и параметры, необходимые для их компиляции. Когда это закончится, можно начать основной анализ. При таком подходе ничто в обычной сборке не должно изменяться или поддерживаться с течением времени. Это не совсем без потенциальных проблем, однако. Инструменту может потребоваться сообщить, например, как называется исполняемый файл вашего компилятора (который может сильно различаться в сценарии кросс-компиляции ios), и вы должны убедиться, что нормальная сборка выполняет полную сборку из " чистое »состояние, в противном случае некоторые файлы могут быть пропущены.
Интерпретируемые языки обычно отличаются, потому что они часто имеют зависимости, заданные переменными среды, которые может видеть анализатор. Если это не так, анализатор обычно принимает дополнительные параметры конфигурации. Например, если исполняемый файл python
на PATH
не является тем, что будет использоваться для запуска анализируемых Python сценариев, анализатору обычно говорят эмулировать другой.
Tangent: At В конце вашего вопроса вы в шутку называете этот процесс «вмешательством». Фактически, эти инструменты очень стараются , а не , чтобы оказать какое-либо заметное влияние на нормальную сборку. В статье Несколько миллиардов строк кода позже (одним из авторов которой я являюсь) есть несколько забавных анекдотов неудач, чтобы быть прозрачными.