Skip to content

[DeadCode] Keep private method called via self::class static call#8098

Merged
TomasVotruba merged 3 commits into
mainfrom
tv-keep-private-methods-using-reflection
Jun 30, 2026
Merged

[DeadCode] Keep private method called via self::class static call#8098
TomasVotruba merged 3 commits into
mainfrom
tv-keep-private-methods-using-reflection

Conversation

@TomasVotruba

@TomasVotruba TomasVotruba commented Jun 28, 2026

Copy link
Copy Markdown
Member

Why

RemoveUnusedPrivateMethodRector removes private methods that look unused to static analysis. But a private method invoked through a class-string static call is not seen by the usage analyzer, so it gets wrongly removed.

This pattern was found by scanning withSkip() across popular Rector configs - real projects disable the rule on files where private methods are called this way.

Code sample

final class SomeClass
{
    public function run(): object
    {
        return self::class::sampleClass();
    }

    private function sampleClass(): object
    {
        return new \stdClass();
    }
}

Before this PR, sampleClass() is removed (the self::class::sampleClass() call is invisible to the analyzer), breaking run(). After, it is kept.

Fix

resolveClassStringStaticCallNames() collects method names invoked via a ::class static call (self::class::x(), static::class::x(), Foo::class::x()) and skips removing them.

Tests

New keep-fixture keep_self_class_static_call.php.inc. ECS + PHPStan clean, all rule tests green.

A private method invoked through a class-string static call, e.g.
self::class::sampleClass(), is not detected by the usage analyzer and would
be wrongly removed. Keep such methods.
@TomasVotruba TomasVotruba force-pushed the tv-keep-private-methods-using-reflection branch from 0c30408 to 429255c Compare June 28, 2026 14:52
@TomasVotruba TomasVotruba changed the title [DeadCode] Skip private method removal in classes using reflection [DeadCode] Keep private method called via self::class static call Jun 28, 2026
@staabm

staabm commented Jun 29, 2026

Copy link
Copy Markdown
Contributor

PHPStan side fix in phpstan/phpstan-src#5953

@TomasVotruba

Copy link
Copy Markdown
Member Author

Nice work! It so WTF to me I forgot to merge this.

I'll link the fix in code, so we can remove this workaround. Thank you 👍

@TomasVotruba TomasVotruba enabled auto-merge (squash) June 30, 2026 15:11
@TomasVotruba TomasVotruba merged commit c9bf9cd into main Jun 30, 2026
65 checks passed
@TomasVotruba TomasVotruba deleted the tv-keep-private-methods-using-reflection branch June 30, 2026 15:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

2 participants