phpstan/phpstan-doctrine

Why is `@extend` for ServiceEntityRepository necessary?

MaxValEh opened this issue · 3 comments

when using phpstan-doctrine i get the following Error:
Class App\Repository\LoginUserRepository extends generic class Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository but does not specify its types: TEntityClass

i can solve this by adding the following annotation to the class:
@extends \Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository<LoginUser>

Without phpstan-doctrine phpstan produces the following error:
PHPDoc tag @extends contains generic type Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository<App\Entity\LoginUser> but class Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository is not generic.

I tend to agree that ServiceEntityRepository is a generic class because you can use it with any Entity.

Why is the annotation necessary though?

Calling the parent constructor already seems to describes everything.

use App\Entity\Person;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;

/**
 * @extends \Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository<Person>
 */
class PersonRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Person::class);
    }
}

using php 7.4.14, phpstan/phpstan 0.12.80, phpstan/phpstan-doctrine 0.12.32

Hi, make sure to read this guide on generics: https://phpstan.org/blog/generics-in-php-using-phpdocs

The annotation is necessary because PHPStan needs to see what's TEntityClass in context of Doctrine\ORM\EntityRepository, see the stub here: https://github.com/phpstan/phpstan-doctrine/blob/master/stubs/EntityRepository.stub

PHPStan simply doesn't read that from the constructor contents because it'd be inefficient and would slow down the analysis a lot.

Thank you for your explanation!

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.