CodeSniffer снифф для генерации графиков зависимостей для кода PHP?
ЦЕЛЬ: Я заинтересован в создании описания формата DOT зависимостей классов в программе PHP.
IDEA: Нетрудно написать CodeSniffer "sniff", который может обнаруживать (и отправлять записи DOT) следующие шаблоны в исходном коде PHP:
class SomeClassName extends BasicClassName { // SomeClassName refers to BasicClassName
...
new OtherClassName(); // SomeClassName refers to OtherClassName
ThisClassName::some_method(); // SomeClassName refers to ThisClassName
ThatClassName::$some_member; // SomeClassName refers to ThatClassName
RandomClassName::some_constant; // SomeClassName refers to RandomClassName
...
}
Но я не нашел ни одного опубликованного сниффа, который бы испускал эту информацию (и любые другие шаблоны, указывающие на "реальные" отношения зависимости класса, которые я, возможно, пропустил).
ПРИМЕЧАНИЕ: мне совершенно безразличны операторы PHP include() и require() ( поведение которых, я не уверен, даже четко определено). Для целей этого вопроса давайте предположим, что все разрешения классов PHP обрабатываются с помощью автозагрузки, и что мы собираемся использовать только статический анализ кода для построения диаграммы зависимостей классов.
РЕДАКТИРОВАТЬ: К сожалению, я не вижу общего способа справиться со следующим:
class ThatClassName {
...
function generateClassName() {
// something too complicated to analyze statically...
}
function foo() {
$name = $this->generateClassName();
$instance = new $name; // ThatClassName refers to ... what?
...
}
...
}
Но, конечно, можно было бы представить этот сценарий в графе зависимостей, показав ThatClassName с зависимостью от метода generateClassName() - возможно, показанного с помощью скобок, чтобы сделать имя метода легко отличимым от имени класса. И, вероятно, было бы неплохо создать соглашение, согласно которому любой метод, который генерирует имя класса динамически, должен содержать аннотацию (в связанном комментарии), которая указывает каждое имя класса, которое может быть сгенерировано - эти "документированные динамические зависимости" затем может быть автоматически включен в граф зависимостей.
2 ответа
Я написал инструмент для этого: PhpDependencyAnalysis.
Это расширяемый статический анализ кода для объектно-ориентированных PHP-проектов (>= 5.3.3) на основе пространств имен. Он создает графики зависимостей на настраиваемых уровнях, например, на уровне пакета или на уровне класса. Таким образом, в общем случае можно объявлять зависимости, но также можно выполнять обнаружение нарушений между уровнями в многоуровневой архитектуре в соответствии с принципами разделения интересов, закона деметрии и ациклических зависимостей. Вы также можете изменить формат вывода на DOT.
Просто проверьте PhpDependencyAnalysis на GitHub.
Это не совсем то, для чего предназначен PHP_CodeSniffer; особенно потому, что сниффы не должны выводить данные или записывать в файлы. Но, конечно же, ничто не мешает вам делать это в воздухе. В конце концов, это всего лишь код PHP, и ему не нужно сообщать об ошибках или предупреждениях.
Я не сталкивался с какими-либо нюхами, которые делают что-то, как вы описываете, поэтому я думаю, что вам придется написать новый.
Если вы хотите создать новый снифф, я бы рекомендовал начать с абстрактного сниффа. Это позволяет вам искать токены T_NEW и T_DOUBLE_COLON внутри токенов T_CLASS. Вот пример.
Или, если вы также хотите посмотреть на глобальные функции и другой код вне классов, вы можете просто найти токены T_NEW и T_DOUBLE_COLON внутри обычного сниффа
Если вы не знаете, с чего начать, или вам нужна помощь в написании сниффа, свяжитесь со мной, и я могу помочь написать это с вами. Мне просто нужно знать, какой вывод вы хотите для каждого найденного случая, или я могу просто использовать что-то простое. Если вы хотите руку, мой электронный адрес: gsherwood at squiz dot net