CodeSniffer sniff for generating dependency graphs for PHP code?

拥有回忆 提交于 2019-12-10 17:56:43

问题


GOAL: I'm interested in generating a DOT Format description of the class dependencies in a PHP program.

IDEA: It shouldn't be hard to write a CodeSniffer "sniff" that can detect (and emit DOT records for) the following patterns in PHP source:

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
...
}

But I haven't found any published sniffs to emit this information (and any other patterns indicating a "real" class dependency relationship that I may have missed).

NOTE: I specifically do not care about PHP's include() and require() statements (whose behavior I'm not convinced is even well-defined). For the purposes of this question let's assume that all PHP class resolution is handled via autoloading, and that we're looking to use only static code analysis to build the class dependency diagram.

EDIT: Unfortunately, I see no general way to deal with the following:

class ThatClassName {
...
    function generateClassName() {
        // something too complicated to analyze statically...
    }

    function foo() {
        $name = $this->generateClassName();
        $instance = new $name; // ThatClassName refers to ... what?
        ...
    }
...
}

But of course it would be possible to represent this scenario in a dependency graph by showing ThatClassName with a dependency on the generateClassName() method - perhaps shown with parens to make the method name easily distinguishable from a class name. And it probably wouldn't be a bad idea to establish a convention whereby any method which generates a class name dynamically must contain an annotation (in the associated comment) which indicates every class name which might possibly be generated - these "documented dynamic dependencies" could then be automatically included in the dependency graph.


回答1:


This isn't really what PHP_CodeSniffer is designed to do; specifically because the sniffs are not supposed to output data or write to files. But, there is certainly nothing stopping you from doing this inside a sniff. It's just PHP code after all and it doesn't need to report any errors or warnings.

I haven't come across any sniffs that are doing anything like you describe, so I think you'd have to write a new one.

If you want to create a new sniff, I'd recommend starting with an abstract scope sniff. This allows you to look for T_NEW and T_DOUBLE_COLON tokens inside T_CLASS tokens. Here is an example.

Or, if you also want to look into global functions and other code outside classes, you can just look for T_NEW and T_DOUBLE_COLON tokens inside a regular sniff

If you're not sure how to get started or you just want some help writing the sniff, contact me and I can help write this with you. I'd just need to know what output you'd want for each case found, or I can just use something basic. If you want a hand, my email is: gsherwood at squiz dot net




回答2:


I wrote a tool for this: PhpDependencyAnalysis.

This is an extandable static code analysis for object-oriented PHP-Projects (>= 5.3.3) based on namespaces. It creates dependency graphs on customizable levels, e.g. on package-level or on class-level. Thus, it's usable to declare dependencies in general, but it's also usable to perform a detection of violations between layers in a tiered architecture according to compliance with Separation of Concerns, Law of Demeter and Acyclic Dependencies Principle. You can also change the output format to DOT.

Just check PhpDependencyAnalysis on GitHub.



来源:https://stackoverflow.com/questions/13337708/codesniffer-sniff-for-generating-dependency-graphs-for-php-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!