phpstan/phpstan-webmozart-assert

`Assert::implementsInterface($foo, <Type>)` is incorrectly being translated to `assert($foo instanceof <Type>)`

Ocramius opened this issue · 5 comments

Assert::implementsInterface() works on object|string, not just object, so it should be translated to something like assert($foo instanceof $type || in_array($interface, \class_implements($value))) (see https://3v4l.org/VdIbR).

Not sure what the correct translation (understood by PHPStan) would be.

For reference, this is the current implementation:

'implementsInterface' => function (Scope $scope, Arg $expr, Arg $class): ?\PhpParser\Node\Expr {
$classType = $scope->getType($class->value);
if (!$classType instanceof ConstantStringType) {
return null;
}
return new \PhpParser\Node\Expr\Instanceof_(
$expr->value,
new \PhpParser\Node\Name($classType->getValue())
);
},

Can you tell me some real-world examples of implementsInterface usages? I've seen examples where both arguments are literal strings which doesn't seem very useful.

Currently finding it in something like:

class MyThingFactory
{
    public function make(string $thing)
    {
        Assert::implementsInterface($thing, SomeDto::class);

        // use $thing static API here
    }
}

Note that this is completely removable if I use something like:

class MyThingFactory
{
    /**
     * @template T of SomeDto
     * @param class-string<T> $thing
     */
    public function make(string $thing)
    {
        Assert::implementsInterface($thing, SomeDto::class);

        // use $thing static API here
    }
}

Not sure if that's understood by the tooling yet though

Can you tell me some real-world examples of implementsInterface usages? I've seen examples where both arguments are literal strings which doesn't seem very useful.

This leads to weird hacks in real projects:
https://github.com/phpDocumentor/ReflectionDocBlock/blob/master/src/DocBlock/StandardTagFactory.php#L177

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.