Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dead Code Detector Laravel Package

shipmonk/dead-code-detector

PHPStan extension that finds unused PHP code: dead methods, properties, constants, enum cases, cycles, and transitive “dead-tested” members. Supports popular frameworks like Symfony and can auto-remove dead code. Configurable detection and usage providers.

View on GitHub
Deep Wiki
Context7
1.2.1

Fixes:

  • Fix crash on array callable with unknown part, since PHPStan 2.1.54 (#373, @alfredbez)
1.2.0

New features:

  • Nette: support constructor calls of DIC services (#369, @spaze)
    • requires neon/neon to be installed
    • enable via:
parameters:
    shipmonkDeadCode:
        usageProviders:
            nette:
                containerNeonPaths:
                    - app/config/services.neon

Improvements:

  • Symfony: expose public members of #[AsTwigComponent] classes to templates (#366)
  • Laravel: add missing FormRequest methods (#370, @JeftaAtSiip)
1.1.3

Fixes:

  • Treat array_column() string keys as property reads (#362)
1.1.2

Fixes:

  • Symfony: mark constructor of #[AsEventListener] host class as used (#356)
  • export-ignore useless archive files (#355)
1.1.1

Fixes:

  • Symfony: skip services not instantiated by the DIC (#348)
  • Blade: mitigate heavy RAM usage (#349)
    • skip view data members declared in vendor (#350)
    • deduplicate view-data usages across call sites (#352)
1.1.0

New features:

  • Laravel: Blade view data support (#333)
    • Marks public members of objects passed to views via view(), View::make()/first(), response()->view(), ->with() as used
    • View composers/creators via View::composer()/View::creator(), including 'Class@method' syntax
  • Symfony forms data_class mapping (#334)
    • Marks accessor methods (get*/set*/is*/has*/can*/add*/remove*), public properties, and __construct on data classes as used
    • Detects data_class from OptionsResolver, AbstractController::createForm(), FormFactoryInterface::create() and related methods
  • Detect property reads via native operations (#332)
    • (array) cast, get_object_vars(), get_mangled_object_vars(), json_encode(), serialize()
    • Respects JsonSerializable, __serialize(), Serializable

Improvements:

  • Symfony:
    • Resolve string tags in #[AutowireIterator]/#[AutowireLocator] via DIC XML (#336)
      • String tags (e.g. 'app.handler') are now mapped to concrete classes, fixing false positives on defaultIndexMethod/defaultPriorityMethod
      • shipmonkDeadCode.usageProviders.symfony.containerXmlPaths must be set up
    • Support #[AsTwigComponent(template: new FromMethod(...))] (#341)
    • Symfony: support #[MapInput] in console commands (#340)
    • Mark enum cases as used in invokable command parameters (#343)
  • Doctrine:
    • Add missing #[PostRemove] lifecycle callback detection (#337)
    • Add ToolEvents to listener heuristic (#342)
  • PHPUnit:
    • Add cross-class [@dataProvider](https://github.com/dataProvider) annotation recognition (#338)
1.0.0

Stable version!

  • Detection of all dead members is implemented and stable!
    • Dead methods, constants, enum cases and properties
  • Thus, no more BC breaks in extension points are expected
  • It took ~4 years of development

Performance improvements

  • Result cache offloaded to own cache (#319)
    • Analysis reusing cache:
      • up to ~40% less memory
      • up to ~40% faster
    • Result cache size: decreased by ~55%

New features:

  • Fully new Laravel support (#294)
    • Route registration — Route::get(), post(), put(), patch(), delete(), any(), match(), resource(), apiResource()
      • Callable array syntax: [Controller::class, 'method']
      • Legacy string syntax: 'Controller@method'
      • Invokable controllers: Controller::class
    • Event listeners — Event::listen(), Event::subscribe()
    • Auto-discovered event listeners — classes with handle* methods whose first parameter has a class type
    • Scheduled jobs — Schedule::job()
    • Gate definitions — Gate::define() (callable + invokable), Gate::policy()
    • Policy resolution — $this->authorize() calls resolve policy class via Laravel's namespace convention (Models\Policies\)
    • Console commands — __construct, handle on Illuminate\Console\Command subclasses
    • Jobs — __construct, handle, failed, middleware, retryUntil, uniqueId, tags, backoff, uniqueVia, displayName on ShouldQueue / Dispatchable classes
    • Service providers — __construct, register, boot
    • Middleware — handle, terminate, __construct (detected by first parameter type Illuminate\Http\Request)
    • Notifications — via, toMail, toArray, toDatabase, toBroadcast, toVonage, toSlack
    • Form requests — authorize, rules, messages, attributes, prepareForValidation, passedValidation, failedValidation, failedAuthorization
    • Policies — before, viewAny, view, create, update, delete, restore, forceDelete (heuristic via \Policies\ namespace + Policy suffix)
    • Mailables — build, content, envelope, attachments, headers
    • Broadcast events — broadcastWith, broadcastAs, broadcastWhen
    • JSON resources — paginationInformation
    • Notifiable routing — routeNotificationFor* methods
    • Eloquent features:
      • Model methods — constructor, boot, booted, casts, newFactory
      • Query scopes — scope* methods
      • Relationships — methods returning Illuminate\Database\Eloquent\Relations\*
      • Attribute accessors — methods returning Illuminate\Database\Eloquent\Casts\Attribute
      • Legacy accessors/mutators — get*Attribute() / set*Attribute()
      • Observers — Model::observe() calls + #[ObservedBy] attribute (all observer event methods)
      • Factories — definition, configure
      • Seeders — run
      • Migrations — up, down
  • Symfony improvements
    • #[Autoconfigure(constructor:, calls:)], #[AutowireCallable], #[TaggedIterator], #[TaggedLocator], #[Required] on properties, #[AsSchedule], #[AsCronTask], #[AsPeriodicTask], !php/enum references in config yamls (#317)
    • Allow explicit containerXmlPaths configuration - no need for phpstan/phpstan-doctrine for DIC calls analysis (#325)
    • Symfony UX support: #[AsTwigComponent]/#[AsLiveComponent] (constructor, mount()), #[LiveProp], #[LiveAction], #[LiveListener], lifecycle hooks (#329)
  • Reflection improvements
    • support member constructors like new ReflectionMethod(Class, 'method') (#313)

Dependencies:

  • Requires PHP ^8.1 (was ^7.4) (#296)
  • Requires phpstan/phpstan ^2.1.41, (was ^2.1.23) (#297)
0.15.1

Fixes:

  • Fix false-positive for self-referencing property access in property hooks (#311)
0.15.0

New features:

  • Dead properties detection (#277, #281, #291)
    • Never read and never written properties are detected
  • Property hooks full support (#281)
    • Now part of transitivity chain detection (both read & write)
  • Twig supports template parameters (#275)
    • Including transitively referenced ones
    • Supports:
      • Params passed to $controller->render('my.twig', ['param' => $viewModel]),
      • Params returned from #[Template] controller methods
      • Params rendered via Twig\Environment::render() and similar
  • Symfony:
    • AutowireLocator to support defaultPriorityMethod (#286, @alcohol)
    • Support #[Interact] attribute for commands (#288, @mjanser)
  • Nette tester
    • test* methods, setUp/tearDown, [@dataProvider](https://github.com/dataProvider) (#299)

Improvements:

  • Solution to partial analysis false positives over inline ignores (#292)
  • ApiPhpDocUsageProvider: only count phpdocs within analysed files (#284)

Breaking changes:

  • All dead members are detected by default (#301)
    • You can rollback to previous setup via:
parameters:
    shipmonkDeadCode:
        detect:
            deadEnumCases: false
            deadProperties:
                neverRead: false
                neverWritten: false
0.14.1

Fixes:

  • Fix infinite run for huge unused subtrees while groupping errors (#282)
0.14.0

New features:

  • Support PHP 8.5 features (#269)
  • Support phpbench entrypoints (#262, @simPod)
  • Support behat entrypoints (#267, @devbanana)
  • Support stream_wrapper_register magic (#266)

Improvements

  • All filepaths are now resolved relative to config file they reside (same as native PHPStan configs) (#219)
    • usageProviders.symfony.configDir
    • usageExcluders.tests.devPaths

Dependencies

  • phpstan/phpstan now requires ^2.1.23 (was ^2.1.12) (#254)

Breaking changes

  • All classes are final (#237)
0.13.5

Improvements:

  • Symfony & Doctrine (#258):
    • Support #[AsDoctrineListener]
    • Support #[AutoconfigureTag('doctrine.event_listener')]
0.13.4

Fixes:

  • Fix disabling dead methods detection (#257)
0.13.3

Improvements:

  • Symfony:
    • Support #[AsTransitionListenerWorkflow] and other Event listener attributes (#248, by @S1ructure)
    • Support #[AsMessageHandler] attribute (#247, by @S1ructure)
0.13.2

Fixes

  • Property hooks partial support; fix crash & false positives (#244)
0.13.1

Improvements

  • Symfony: support anonymous services in DIC (#238)
  • Support [@api](https://github.com/api) over enums and enum cases (#240)
  • Debug output not to report mixed over mixed usages caused by ReflectionClass<object>::getMethods() etc. (#241)
0.13.0

New features:

  • Detect dead enum cases (#197); off by default, enable by:
parameters:
    shipmonkDeadCode:
        detect:
            deadEnumCases: true

Fixes

  • Fix false positive when [@final](https://github.com/final) class is inherited (#233)
  • Fix debug output for overridden built-in methods (#234)

Breaking changes:

  • ClassMemberRef is now generic, you may need to update phpdocs of those
  • ClassConstantRef constructor now requires TrinaryLogic $isEnumCase argument

Dependencies

  • phpstan/phpstan now requires ^2.1.12 (was ^2.1.9)
0.12.4

Fixes:

  • Detect also overriden vendor constants (#225)
0.12.3

Fixes:

  • Fix false positive with interface parent (#221)
0.12.2

Fixes

  • tests excluder not to exclude mixed usages in tests (#214)
  • Fix usageProviders.symfony.configDir wiring (#216)
0.12.1

Improvements:

  • PHPUnit: support #[DataProviderExternal] (#212)
0.12.0

New features:

0.11.1

Fixes:

  • Fix custom devPaths config for tests excluder (#202)
  • Fix detection of absolute paths in composer.json for tests excluder (#203)
  • Drop provided usage class existence validation (#201)
0.11.0

New features

  • Support unknown member names like $foo->$unknown() (#189)
    • Such call marks all methods of $foo as used (including possible descendants, ancestors, traits, ...)
  • Reflection provider:
    • Usages like ReflectionClass->getMethods() now mark alive also methods of descendants (#189)
    • Support calls over unbounded ReflectionClass<object> (#193)
      • e.g. $anyObjectReflection->getMethod('foo') marks all foo methods of all types as alive
      • Can be disabled with usageOverMixed excluder
  • New Twig provider:
    • Support #[AsTwigFilter], #[AsTwigFunction], #[AsTwigTest] and new TwigFilter(..., callback) counterparts (#194, @zacharylund)

Fixes:

  • Fix origin file reference for traits (#190)
  • Report dead method line at its name (#192)
  • Fix mixed calls diagnostics when custom excluder is used (#196)

Breaking changes:

- #[Deprecated] // [@phpstan-ignore](https://github.com/phpstan-ignore) shipmonk.deadMethod
- public function someMethod(): void
+ #[Deprecated]
+ public function someMethod(): void // [@phpstan-ignore](https://github.com/phpstan-ignore) shipmonk.deadMethod
0.10.2

Improvements:

  • Symfony:
  • Doctrine:
    • detect repositoryMethod in #[UniqueEntity] (#184)

Fixes:

  • Autoremove: fix removal of transitively dead constants (#183)
0.10.1

Improvements

  • Debug: Changing references not to invalidate result cache (#169)
  • Autoremove: warn about kept excluded usages (#175)
 • Removed method UserFacade::deadMethod
   ! Excluded usage at tests/User/UserFacadeTest.php:241 left intact
  • Improve descendant detection for const fetches (#176)

Dependencies

  • phpstan/phpstan now requires ^2.1.9 (was ^2.1.7) (#169)
0.10.0

New features:

  • Allow debugging of usages (#165, #172):
parameters:
    shipmonkDeadCode:
        debug:
            usagesOf:
                - App\User\Entity\Address::__construct

with -vvv outputs e.g.:

App\User\Entity\Address::__construct
|
| Marked as alive by:
| entry virtual usage from ShipMonk\PHPStan\DeadCode\Provider\SymfonyUsageProvider (Route method via #[Route] attribute)
|   calls App\User\RegisterUserController::__invoke:36 
|     calls App\User\UserFacade::registerUser:142
|       calls App\User\Entity\Address::__construct
|
| Found 2 usages:
|  • src/User/UserFacade.php:142
|  • tests/User/Entity/AddressTest.php:64 - excluded by tests excluder
  • Improved possible descendant detection (#151)
    • e.g. new Foo->method() does not mark method as used on Foo children anymore

Improvements:

  • Skip private constructors only when those have zero params (#159)
  • Reduce result cache size (#168)
  • Support Symfony's defaultIndexMethod on AutowireLocator/AutowireIterator attribute (#161, @ruudk)

Dependencies

  • Requires phpstan/phpstan ^2.1.7 (was ^2.0.0) (#151)

Breaking changes

  • ClassMemberUsage now requires UsageOrigin, not optionally ClassMethodRef (#165)
  • UsageOriginDetector was removed (#165)
    • use either UsageOrigin::createRegular or UsageOrigin::createVirtual
  • Virtual usages emitted by ReflectionBasedMemberUsageProvider now require note (#171)
    • true => VirtualUsageData::withNote('why considered used')
    • false => null
  • parameter trackMixedAccess was replaced with excluder (#167)
parameters:
    shipmonkDeadCode:
-         trackMixedAccess: false
+         usageExcluders:
+           usageOverMixed:
+               enabled: true
0.9.2

Fixes:

  • TestsUsageExcluder: fix path normalization for phar files (#155)
0.9.1

Fixes

  • TestsUsageExcluder: normalize provided paths (#149)
0.9.0

New features:

  • Members used only in tests can be reported as dead (#139)
parameters:
    shipmonkDeadCode:
        usageExcluders:
            tests:
                enabled: true # off by default
  • Custom usage exclusions (#139)
    • via MemberUsageExcluder interface

Fixes:

  • Fix false positives in indirect usage edgecases (#141)
  • Fix transitive member reported repeatedly in a dead group when called multiple times (#143)
  • Fix usage of symbols not available on PHP 7.4 (#145)
  • Dead cycle representative error is ignorable now (no longer picked randomly) (#144)
0.8.1

Fixes:

  • Symfony: fix DIC filepath for phpstan-symfony 2.0.2 (#138)
0.8.0

New features

  • Symfony:
    • detect constants used in config yamls via !php const Foo\Bar::BAZ (#131)
    • detect methods called by DIC, e.g. factory: [Acme\SerializerFactory, create] (#128)

Fixes

  • Reflection:
    • support accessing members present only on descendants (#134)
    • proper transitivity detection (#135)
  • Fix missing parts of vendor class hierarchy (#136)
0.7.0

New features:

  • Full dead class constant detection support (#113)
    • Transitive detection (e.g. constant fetched in dead method is dead)
    • Usages over mixed (e.g. $unknown::CONST)
    • Auto-removal (via --error-format removeDeadCode)
    • Trait constants (available since PHP 8.2)
    • constant function (e.g. constant('PDO::ATTR_ERRMODE'))
    • customizable (e.g. you can extract !php/const Foo::BAR usages from your yamls)
  • AST-based usage providers (#117)
    • Just implement MemberUsageProvider
    • Allows to emit member usages based on e.g. methods calls
    • Handy for command buses, event systems, serializers and more
  • Detect reflection usages (#120)
    • e.g. $reflectionClass->getMethod('foo') marks foo method as used

Improvements:

  • Symfony & Doctrine: improve usage provider extendability (#121)
  • Symfony: precise detection of EventSubscriberInterface::getSubscribedEvents (#122)
  • Doctrine: precise detection of Doctrine\Common\EventSubscriber::getSubscribedEvents (#127)

Breaking changes:

  • Renames (to fit constant usages and AST-based providers):
# classes & methods
- `ShipMonk\PHPStan\DeadCode\Provider\MethodEntrypointProvider::getEntrypoints(): list<ReflectionMethod>` 
+ `ShipMonk\PHPStan\DeadCode\Provider\MemberUsageProvider::getUsages(): list<ClassMemberUsage>`

- `ShipMonk\PHPStan\DeadCode\Provider\SimpleMethodEntrypointProvider::isEntrypointMethod(): bool`
+ `ShipMonk\PHPStan\DeadCode\Provider\ReflectionBasedMemberUsageProvider::shouldMarkMethodAsUsed(): bool`

# neon config params
- `parameters.shipmonkDeadCode.entrypoints` 
+ `parameters.shipmonkDeadCode.usageProviders`

- `parameters.shipmonkDeadCode.trackCallsOnMixed` 
+ `parameters.shipmonkDeadCode.trackMixedAccess`

# neon service tag 
- `shipmonk.deadCode.entrypointProvider`
+ `shipmonk.deadCode.memberUsageProvider`
0.6.0

Dependencies

  • requires phpstan/phpstan 2.0
0.5.1

Fixes:

  • Disable mixed calls diagnosis for trackMixedCalls: false (#109)
0.5.0

New features

  • Ability to automatically remove dead code (#103)
    • via vendor/bin/phpstan analyse --error-format removeDeadCode
  • Support calls over mixed (#105)
    • e.g. $unknownClass->method()

Dependencies

  • requires phpstan/phpstan 1.11.7 (was 1.11.0) (#107)
0.4.0

Major changes:

  • Dead cycles detection (#99)
    • Also, all transitively dead methods are reported within the first run:
 ------ ------------------------------------------------------------------------
  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

New features:

  • phpunit: support data providers in children classes (#97)
  • symfony: support #[AsCommand], #[AsController], Bundle children (#89)
  • doctrine: support EntityRepository constructor (#90)

Fixes:

  • vendor: properly detect vendor-originating methods (#101)
0.3.0

Major changes:

  • Performance boost ~20% (#74, #79)
  • EntrypointProvider interface changed (#74)
    • Just extend SimpleMethodEntrypointProvider for easy transition

New features

  • Support dead __clone methods (#80)

Fixes

  • Fix many trait related edgecases (#70, #75, #76, #78)
  • Fix missing nette provider in config (#81)
0.2.1

Fixes

  • Fix invalid file reported for non-overridden dead trait methods (#67)
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
babenkoivan/elastic-client
innmind/static-analysis
innmind/coding-standard
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata
splash/openapi
splash/scopes
splash/toolkit
testo/output-teamcity