Search code examples
static-analysisphpstan

PHPStan - change type of constructor parameter


When running PHPStan on my codebase I get the error:

Parameter #2 $credentials of class Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken constructor expects string, null given.

This is because the constructor's docblock only specifies a string as valid type. But when you check the eraseCredentials() method, it seems that null also is a valid value for $credentials.

Now I want to instruct PHPStan that the type of the $credentials parameter is string|null as opposed to string.

I think I would need an implementation of MethodsClassReflectionExtension to do that. But when I register this it does not seem to get called for the right class.

My current implementation:

class UsernamePasswordToken implements MethodsClassReflectionExtension
{
    public function hasMethod(ClassReflection $classReflection, string $methodName): bool
    {
        if ($classReflection->getName()===\Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken::class) {
            var_dump(__FILE__ . ':' . __LINE__ . ' :: ' . __METHOD__);die();
        }
        if ($methodName === '__construct' && $classReflection->getName() === UsernamePasswordTokenClass::class) {
            return true;
        }

        return false;
    }

    public function getMethod(ClassReflection $classReflection, string $methodName): MethodReflection
    {
        var_dump(__FILE__ . ':' . __LINE__ . ' :: ' . __METHOD__);die();
    }
}

What do I need to do to make PHPStan understand that the $credentials property accepts both string and null values?


Solution

  • Unfortunately you cannot use extensions to override information about existing method. There's currently no way to convince PHPStan that a method has a different signature than the one in the code.

    I'm a little bit confused by the reported error, because UsernamePasswordToken currently accepts mixed (meaning anything) as the type of $credentials. So your issue can go away just by upgrading Symfony (not sure to which version). And also I don't know what you mean by referencing the eraseCredentials method.

    If you need to solve a similar issue and the parameter documentation is wrong even in the recent version of your dependency, you have currently two options:

    1) Send a PR to the depedency that fixes their typehint or phpDoc. 2) Write a regexp for ignoreErrors (see README) that ignores this issue.

    In the future, there will be a third option. I'm planning to enable overriding 3rd party types by offering configuration options to do that.