Skip to content

ReadOnlyPropertyAssignRule does not respect additionalConstructors setting #6612

@IonBazan

Description

@IonBazan

Bug report

This was initially reported as phpstan/phpstan-phpunit#118 but after digging into PHPStan code, I found out that certain rules make use of additionalConstructors parameter which is correctly set to PHPUnit\Framework\TestCase::setUp in that plugin.

I believe ReadOnlyPropertyAssignRule should respect additionalConstructors parameter to resolve all methods that are allowed to set readonly properties instead of hardcoding to __construct and __unserialize:
https://github.com/phpstan/phpstan-src/blob/4dd6b692ef9224725764a6daec1b680c9eb84e03/src/Rules/Properties/ReadOnlyPropertyAssignRule.php#L70

I noticed there are 2 other rules that already use this functionality:
https://github.com/phpstan/phpstan-src/blob/44fd938c30de5ee87f41b9c97b3d79ec18a731fa/src/Rules/Properties/MissingReadOnlyPropertyAssignRule.php
and
https://github.com/phpstan/phpstan-src/blob/28bd563fbafe2f4a884a6e77bba0149df98a8b93/src/Rules/Properties/UninitializedPropertyRule.php

but the code responsible for caching additionalConstructors is duplicated. Perhaps we could extract it into some kind of helper?

Code snippet that reproduces the problem

class SubjectTest extends \PHPUnit\Framework\TestCase
{
    protected readonly Subject $subject;

    protected function setUp(): void
    {
        parent::setUp();

        $this->subject = new Subject('test');
    }
}

with config:

parameters:
	additionalConstructors:
		- PHPUnit\Framework\TestCase::setUp

triggers: Readonly property App\Tests\SubjectTest::$subject is assigned outside of the constructor.

Runnable example: https://phpstan.org/r/974f222b-dcfa-470b-8281-a4e2dab6a954

Expected output

No errors should be produced.

Did PHPStan help you today? Did it make you happy in any way?

PHPStan makes me happy every day - most of the time we don't even need to run any tests to find out that something is wrong which saves time and helps to eliminate both trivial and complex problems early before they reach production. Thank you so much ❤️

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions