Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CodeSniffer sniff for generating dependency graphs for PHP code?

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.

like image 985
Peter Avatar asked Oct 06 '22 00:10

Peter


1 Answers

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

like image 130
Greg Sherwood Avatar answered Oct 10 '22 02:10

Greg Sherwood