nextras / orm-phpstan

PHPStan extension for Nextras Orm
https://nextras.org/orm
MIT License
11 stars 6 forks source link

Mapper::toCollection() breaks PHPStan #17

Closed stpnkcrk closed 4 years ago

stpnkcrk commented 4 years ago

PHPStan 0.12.40 Nextras\Orm 4.0-RC1 Nextras\Orm-PHPStan dev-master

This makes PHPStan with active nextras/orm-phpstan extension to freeze when analysing the file.

<?php declare(strict_types=1);

namespace App\Model\System;

use Nextras\Orm\Collection\ICollection;
use Nextras\Orm\Mapper\Mapper;

final class LogMapper extends Mapper
{
    public function findAllWithTranslatedIps(): ICollection
    {
        return $this->toCollection(
            $this->builder()->addSelect('inet6_ntoa([ip]) as [ip]')
        );
    }
}

The issue persists even with just $this->builder() suggesting error isn't in the custom select part.

hrach commented 4 years ago

Well, the issue here is we try to guess the name of repository. What is FQN name of LogsRepository?

stpnkcrk commented 4 years ago

App\Model\System\Log (Entity) App\Model\System\LogMapper App\Model\System\LogRepository

stpnkcrk commented 4 years ago

It seems it's failing on $mapperClass = \get_parent_class($mapperClass); in the MapperMethodReturnTypeExtension.php as that returns false on my machine and therefore it falls into infinite loop.

$mapperClass = $mapper->getClassName();
do {
    /** @phpstan-var class-string<\Nextras\Orm\Repository\Repository> $repositoryClass */
    $repositoryClass = \str_replace('Mapper', 'Repository', $mapperClass);
    $mapperClass = \get_parent_class($mapperClass);
    assert(is_string($mapperClass));
} while (!\class_exists($repositoryClass) && $mapperClass !== DbalMapper::class);

$repositoryClass is recognised correctly as App\Model\System\LogRepository.

hrach commented 4 years ago

What is your definition of LogRepository? What does it extend?

stpnkcrk commented 4 years ago
<?php declare(strict_types=1);

namespace App\Model\System;

use Nextras\Orm\Collection\ICollection;
use Nextras\Orm\Repository\Repository;

/**
 * @method ICollection|Log[] findAllWithTranslatedIps()
 */
final class LogRepository extends Repository
{
    public static function getEntityClassNames(): array
    {
        return [Log::class];
    }
}
stpnkcrk commented 4 years ago

nextras-orm-phpstan-failing-demo.zip

hrach commented 4 years ago

I somehow know where the bug is, will try to fix asap. Thanks for reporting.

hrach commented 4 years ago

Fixed https://github.com/nextras/orm-phpstan/commit/c7a64f8897d6dce40b762a18bebae5e415edc3c8

stpnkcrk commented 4 years ago

Thank you very much!!!