shipmonk / dead-code-detector
Dead code detector to find unused PHP code via PHPStan extension.
Installs: 10 743
Dependents: 4
Suggesters: 0
Security: 0
Stars: 61
Watchers: 4
Forks: 6
Open Issues: 9
Type:phpstan-extension
Requires
- php: ^7.4 || ^8.0
- phpstan/phpstan: ^1.11.0
Requires (Dev)
- doctrine/orm: ^2.19 || ^3.0
- editorconfig-checker/editorconfig-checker: ^10.3.0
- ergebnis/composer-normalize: ^2.28
- nette/application: ^3.1
- nette/component-model: ^3.0
- nette/utils: ^3.0 || ^4.0
- phpstan/phpstan-phpunit: ^1.1.1
- phpstan/phpstan-strict-rules: ^1.2.3
- phpstan/phpstan-symfony: ^1.4
- phpunit/phpunit: ^9.5.20
- shipmonk/composer-dependency-analyser: ^1.6
- shipmonk/name-collision-detector: ^2.0.0
- shipmonk/phpstan-rules: ^3.1
- slevomat/coding-standard: ^8.15.0
- symfony/contracts: ^2.5 || ^3.0
- symfony/event-dispatcher: ^5.4 || ^6.0 || ^7.0
- symfony/http-kernel: ^5.4 || ^6.0 || ^7.0
- symfony/routing: ^5.4 || ^6.0 || ^7.0
This package is auto-updated.
Last update: 2024-10-24 13:00:46 UTC
README
PHPStan extension to find unused PHP code in your project with ease!
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!
phpstan/phpstan-symfony
withcontainerXmlPath
must be used
#[AsEventListener]
attribute#[AsController]
attribute#[AsCommand]
attribute#[Required]
attribute#[Route]
attributesonKernelResponse
,onKernelRequest
, etc
Doctrine:
#[AsEntityListener]
attributeDoctrine\ORM\Events::*
eventsDoctrine\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 implementShipMonk\PHPStan\DeadCode\Provider\MethodEntrypointProvider
- You can simplify your implementation by extending
ShipMonk\PHPStan\DeadCode\Provider\SimpleMethodEntrypointProvider
# 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
- This library automatically detects dead cycles and transitively dead methods (methods that are only called from dead methods)
- By default, it reports only the first dead method in the subtree and the rest as a tip:
------ ------------------------------------------------------------------------
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
------ ------------------------------------------------------------------------
- If you want to report all dead methods individually, you can enable it in your
phpstan.neon.dist
:
parameters: shipmonkDeadCode: reportTransitivelyDeadMethodAsSeparateError: true
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 constructors, static methods, trait methods, interface methods, first class callables, clone, etc.
- Any calls on mixed types are not detected, e.g.
$unknownClass->method()
- Methods of anonymous classes are never reported as dead (PHPStan limitation)
- Most magic methods (e.g.
__get
,__set
etc) are never reported as dead
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