Skip to content

πŸ’€ PHP unused code detection via PHPStan extension. Detects dead cycles, supports libs like Symfony, Doctrine, PHPUnit etc. Can automatically remove dead PHP code. Able to detect dead code used only in tests.

Notifications You must be signed in to change notification settings

shipmonk-rnd/dead-code-detector

Repository files navigation

Dead code detector

PHPStan rules to find dead code in your project.

Installation:

composer require --dev shipmonk/dead-code-detector

Use official extension-installer or just load the rules:

includes:
    - vendor/shipmonk/dead-code-detector/rules.neon

Supported libraries

  • Any overridden method that originates in vendor is not reported as dead
  • We also support many magic calls in following libraries:

Symfony:

  • constructor calls for DIC services!
  • AsEventListener attribute
  • Required attribute
  • Route attributes
  • onKernelResponse, onKernelRequest, etc

Doctrine:

  • AsEntityListener attribute
  • Doctrine\ORM\Events::* events
  • Doctrine\Common\EventSubscriber methods
  • lifecycle event attributes PreFlush, PostLoad, ...

PHPUnit:

  • data provider methods
  • testXxx methods
  • annotations like @test, @before, @afterClass etc
  • attributes like #[Test], #[Before], #[AfterClass] etc

PHPStan:

  • constructor calls for DIC services (rules, extensions, ...)

Nette:

  • handleXxx, renderXxx, actionXxx, injectXxx, createComponentXxx
  • SmartObject magic calls for @property annotations

All those libraries are autoenabled when found within your composer dependencies. If you want to force enable/disable some of them, you can:

# phpstan.neon.dist
parameters:
    shipmonkDeadCode:
        entrypoints:
            phpunit:
                enabled: true

Customization:

  • If your application does some magic calls unknown to this library, you can implement your own entrypoint provider.
  • Just tag it with shipmonk.deadCode.entrypointProvider and implement ShipMonk\PHPStan\DeadCode\Provider\EntrypointProvider
# phpstan.neon.dist
services:
    -
        class: App\MyEntrypointProvider
        tags:
            - shipmonk.deadCode.entrypointProvider
use ReflectionMethod;
use ShipMonk\PHPStan\DeadCode\Provider\EntrypointProvider;

class MyEntrypointProvider implements EntrypointProvider
{

    public function isEntrypoint(ReflectionMethod $method): bool
    {
        return $method->getDeclaringClass()->implementsInterface(ApiOutput::class));
    }
}

Comparison with tomasvotruba/unused-public

  • You can see detailed comparison PR
  • Basically, their analysis is less precise and less flexible. Mainly:
    • It cannot detect dead constructors
    • It does not properly detect calls within inheritance hierarchy
    • It does not offer any custom adjustments of used methods
    • It has almost no built-it library extensions
    • It ignores trait methods
    • Is lacks many minor features like class-string calls, dynamic method calls, array callbacks, nullsafe call chains etc

Limitations:

  • Only method calls are detected so far
    • Including static methods, trait methods, interface methods, first class callables, etc.
    • Any calls on mixed types are not detected, e.g. $unknownClass->method()
    • Anonymous classes are ignored (PHPStan limitation)
    • Does not check magic methods (__get, __set etc)
    • Call-graph not implemented so far
      • No transitive check is performed (dead method called only from dead method)
      • No dead cycles are detected (e.g. dead method calling itself)

Contributing

  • Check your code by composer check
  • Autofix coding-style by composer fix:cs
  • All functionality must be tested

Supported PHP versions

  • PHP 7.4 - 8.3

About

πŸ’€ PHP unused code detection via PHPStan extension. Detects dead cycles, supports libs like Symfony, Doctrine, PHPUnit etc. Can automatically remove dead PHP code. Able to detect dead code used only in tests.

Topics

Resources

Stars

Watchers

Forks

Languages