shipmonk-rnd / dead-code-detector

๐Ÿ’€ PHP unused code detection via PHPStan extension. Detects dead cycles, supports libs like Symfony, Doctrine, PHPUnit etc. Can automatically remove dead PHP code.
116 stars 6 forks source link
dead dead-code-removal php phpstan phpstan-extension phpstan-rules static-analysis unused-code

Dead code detector for PHP

PHPStan extension to find unused PHP code in your project with ease!

Summary:

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

Symfony:

Doctrine:

PHPUnit:

PHPStan:

Nette:

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:

# phpstan.neon.dist
services:
    -
        class: App\ApiOutputEntrypointProvider
        tags:
            - shipmonk.deadCode.entrypointProvider

use ReflectionMethod;
use ShipMonk\PHPStan\DeadCode\Provider\SimpleMethodEntrypointProvider;

class ApiOutputEntrypointProvider extends SimpleMethodEntrypointProvider
{

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

Dead cycles & transitively dead methods

 ------ ------------------------------------------------------------------------
  Line   src/App/Facade/UserFacade.php
 ------ ------------------------------------------------------------------------
  26     Unused App\Facade\UserFacade::updateUserAddress
         ๐Ÿชช  shipmonk.deadMethod
         ๐Ÿ’ก Thus App\Entity\User::updateAddress is transitively also unused
         ๐Ÿ’ก Thus App\Entity\Address::setPostalCode is transitively also unused
         ๐Ÿ’ก Thus App\Entity\Address::setCountry is transitively also unused
         ๐Ÿ’ก Thus App\Entity\Address::setStreet is transitively also unused
         ๐Ÿ’ก Thus App\Entity\Address::setZip is transitively also unused
 ------ ------------------------------------------------------------------------
parameters:
    shipmonkDeadCode:
        reportTransitivelyDeadMethodAsSeparateError: true

Automatic removal of dead code

vendor/bin/phpstan analyse --error-format removeDeadCode
class UserFacade
{
-    public function deadMethod(): void
-    {
-    }
}

Calls over unknown types

parameters:
    shipmonkDeadCode:
        trackCallsOnMixed: false
Found 2 methods called over unknown type:
 โ€ข setCountry, for example in App\Entity\User::updateAddress
 โ€ข setStreet, for example in App\Entity\User::updateAddress

Comparison with tomasvotruba/unused-public

Limitations:

Other problematic cases:

Constructors:

parameters:
    ignoreErrors:
        - '#^Unused .*?::__construct$#'

Private constructors:

Future scope:

Contributing

Supported PHP versions