phpstan / phpstan-doctrine

Doctrine extensions for PHPStan
MIT License
595 stars 97 forks source link

ORM\Column with enumType but missing type causes internal error #509

Open jspetrak opened 10 months ago

jspetrak commented 10 months ago

``Consider having a BackendEnum class FooEnum. The entity class has following property declaration:

#[ORM\Column(name: 'type', nullable: false, enumType: FooEnum::class)]
private FooEnum type;

When running PHPStan analysis, it fails with following stacktrace.

Internal error: Internal error: Call to a member function getName() on null while analysing file

     Post the following stack trace to https://github.com/phpstan/phpstan/issues/new?template=Bug_report.yaml:

     ##

     vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\DefaultTypedFieldMapper.php(65)

     #0

     vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php(1594):

     Doctrine\ORM\Mapping\DefaultTypedFieldMapper->validateAndComplete()

     #1

     vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php(1644):

     Doctrine\ORM\Mapping\ClassMetadataInfo->validateAndCompleteTypedFieldMapping()

     #2

     vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataInfo.php(2723):

     Doctrine\ORM\Mapping\ClassMetadataInfo->validateAndCompleteFieldMapping()

     #3

     vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\Driver\AttributeDriver.php(369):

     Doctrine\ORM\Mapping\ClassMetadataInfo->mapField()

     #4

     vendor\phpstan\phpstan-doctrine\src\Doctrine\Mapping\MappingDriverChain.php(31):

     Doctrine\ORM\Mapping\Driver\AttributeDriver->loadMetadataForClass()

     #5

     vendor\doctrine\orm\lib\Doctrine\ORM\Mapping\ClassMetadataFactory.php(149):

     PHPStan\Doctrine\Mapping\MappingDriverChain->loadMetadataForClass()

     #6

     vendor\doctrine\persistence\src\Persistence\Mapping\AbstractClassMetadataFactory.php(343):

     Doctrine\ORM\Mapping\ClassMetadataFactory->doLoadMetadata()

     #7

     vendor\doctrine\persistence\src\Persistence\Mapping\AbstractClassMetadataFactory.php(225):

     Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->loadMetadata()

     #8

     vendor\phpstan\phpstan-doctrine\src\Type\Doctrine\ObjectMetadataResolver.php(129):

     Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->getMetadataFor()

     #9

     vendor\phpstan\phpstan-doctrine\src\Rules\Doctrine\ORM\PropertiesExtension.php(27):

     PHPStan\Type\Doctrine\ObjectMetadataResolver->getClassMetadata()

     #10

     vendor/phpstan/phpstan/phpstan.phar/src/Rules/DeadCode/UnusedPrivatePropertyRule.php(100):

     PHPStan\Rules\Doctrine\ORM\PropertiesExtension->isAlwaysRead()

     #11

     vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(107):

     PHPStan\Rules\DeadCode\UnusedPrivatePropertyRule->processNode()

     #12

     vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(670):

     PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}()

     #13

     vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(402):

     PHPStan\Analyser\NodeScopeResolver->processStmtNode()

     #14

     vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(641):

     PHPStan\Analyser\NodeScopeResolver->processStmtNodes()

     #15

     vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(371):

     PHPStan\Analyser\NodeScopeResolver->processStmtNode()

     #16

     vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(166):

     PHPStan\Analyser\NodeScopeResolver->processNodes()

     #17

     vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(132):

     PHPStan\Analyser\FileAnalyser->analyseFile()

     #18

     vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):
     PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}()

     #19

     vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(117):

     _PHPStan_39fe102d2\Evenement\EventEmitter->emit()

     #20

     vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):
     _PHPStan_39fe102d2\Clue\React\NDJson\Decoder->handleData()

     #21

     vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62):

     _PHPStan_39fe102d2\Evenement\EventEmitter->emit()

     #22

     vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):
     _PHPStan_39fe102d2\React\Stream\Util::_PHPStan_39fe102d2\React\Stream\{closure}()

     #23

     vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154):

     _PHPStan_39fe102d2\Evenement\EventEmitter->emit()

     #24

     vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201):

     _PHPStan_39fe102d2\React\Stream\DuplexResourceStream->handleData()

     #25

     vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173):

     _PHPStan_39fe102d2\React\EventLoop\StreamSelectLoop->waitForStreamActivity()

     #26

     vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(98):

     _PHPStan_39fe102d2\React\EventLoop\StreamSelectLoop->run()

     #27

     vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259):

     PHPStan\Command\WorkerCommand->execute()

     #28

     vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(870):

     _PHPStan_39fe102d2\Symfony\Component\Console\Command\Command->run()

     #29

     vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(261):

     _PHPStan_39fe102d2\Symfony\Component\Console\Application->doRunCommand()

     #30

     vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157):

     _PHPStan_39fe102d2\Symfony\Component\Console\Application->doRun()

     #31

     vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(124):

     _PHPStan_39fe102d2\Symfony\Component\Console\Application->run()

     #32

     vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(125):

     _PHPStan_39fe102d2\{closure}()

     #33 vendor\phpstan\phpstan\phpstan(8): require('...')

     #34 vendor\bin\phpstan(119): include('...')

     #35 {main}

     Child process error (exit code 1):

When type is added to the annotation, PHPStan analysis completes successfully.

#[ORM\Column(name: 'type', 'type': string, nullable: false, enumType: FooEnum::class)]
private FooEnum type;
stof commented 2 months ago

As this error happens inside doctrine/orm, please provide the info about which version of doctrine/orm is used.

reading the code of Doctrine\ORM\Mapping\DefaultTypedFieldMapper in the latest 2.x and 3.x version, it seems impossible for it to call getName on null on line 65 as there is a condition `$type instanceof \ReflectionNamedType around that code. Maybe an older version had a bug.