Skip to content

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

Open
TomasVotruba wants to merge 1 commit into
mainfrom
tv-keep-private-methods-using-reflection
Open

[DeadCode] Keep private method called via self::class static call#8098
TomasVotruba wants to merge 1 commit 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
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.

1 participant