phpstan / phpstan-doctrine

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

internal error on nested doctrine annotation #362

Closed dbu closed 2 years ago

dbu commented 2 years ago

Bug report

$ composer show "phpstan/*"

phpstan/extension-installer 1.1.0  Composer plugin for automatic installation of PHPStan extensions
phpstan/phpdoc-parser       1.7.0  PHPDoc parser with support for nullable, intersection and generic types
phpstan/phpstan             1.8.2  PHPStan - PHP Static Analysis Tool
phpstan/phpstan-doctrine    1.3.12 Doctrine extensions for PHPStan
phpstan/phpstan-phpunit     1.1.1  PHPUnit extensions and rules for PHPStan
phpstan/phpstan-symfony     1.2.9  Symfony Framework extensions and rules for PHPStan

$ php -v
PHP 7.4.29 (cli) (built: Apr 19 2022 00:46:05) ( NTS )

I have entities with doctrine annotations:

/**
 * @ORM\Entity(repositoryClass="Migros\Api\Price\Repository\DoctrinePriceRepository")
 * @ORM\Table(
 *     name="price",
 *     uniqueConstraints={
 *         @ORM\UniqueConstraint(name="price_id", columns={"product_id", "discount_id", "channel", "region", "store_id"})
 *     },
 *     indexes={
 *         @ORM\Index(name="index_price_discount_channel_region", columns={"discount_id", "channel", "region"}),
 *         @ORM\Index(name="index_parent_discount_id", columns={"parent_discount_id"}),
 *     },
 *     options={"collate": "utf8_bin", "charset": "utf8"},
 * )
 */
class Price {}

when i run phpstan, it chokes on a annotation parsing error:

Internal error: Internal error: [Syntax Error] Expected Doctrine\Common\Annotations\DocLexer::T_CLOSE_CURLY_BRACES, got '(' at position 178 in class Api\Price\Entity\Price. in file                                            
 /usr/src/app/src/Api/Price/Entity/Price.php   

we use the doctrine phpstan plugin. doctrine itself is happy with the annotations.

 #0 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(464): Doctrine\Common\Annotations\AnnotationException::syntaxError('Expected Doctri...')                                                     
 #1 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(416): Doctrine\Common\Annotations\DocParser->syntaxError('Doctrine\\Common...')                                                              
 #2 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1339): Doctrine\Common\Annotations\DocParser->match(102)                                                                                     
 #3 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1237): Doctrine\Common\Annotations\DocParser->Arrayx()                                                                                       
 #4 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1300): Doctrine\Common\Annotations\DocParser->PlainValue()                                                                                   
 #5 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1220): Doctrine\Common\Annotations\DocParser->FieldAssignment()                                                                              
 #6 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1063): Doctrine\Common\Annotations\DocParser->Value()                                                                                        
 #7 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(1035): Doctrine\Common\Annotations\DocParser->Values()                                                                                       
 #8 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(869): Doctrine\Common\Annotations\DocParser->MethodCall()                                                                                    
 #9 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(719): Doctrine\Common\Annotations\DocParser->Annotation()                                                                                    
 #10 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/DocParser.php(376): Doctrine\Common\Annotations\DocParser->Annotations()                                                                                  
 #11 /usr/src/app/vendor/doctrine/annotations/lib/Doctrine/Common/Annotations/AnnotationReader.php(146): Doctrine\Common\Annotations\DocParser->parse('/**\n * @ORM\\Ent...', 'class App\\...')                                    
 #12 /usr/src/app/vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/Driver/AnnotationDriver.php(853): Doctrine\Common\Annotations\AnnotationReader->getClassAnnotations(Object(ReflectionClass))                                             
 #13 /usr/src/app/vendor/doctrine/persistence/src/Persistence/Mapping/AbstractClassMetadataFactory.php(478): Doctrine\ORM\Mapping\Driver\AnnotationDriver->isTransient('Api\\Pric...')                                          
 #14 /usr/src/app/vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/ObjectMetadataResolver.php(82): Doctrine\Persistence\Mapping\AbstractClassMetadataFactory->isTransient('Api\\Pric...')                                      
 #15 /usr/src/app/vendor/phpstan/phpstan-doctrine/src/Type/Doctrine/ObjectMetadataResolver.php(116): PHPStan\Type\Doctrine\ObjectMetadataResolver->isTransient('Api\\Pric...')                                                  
 #16 /usr/src/app/vendor/phpstan/phpstan-doctrine/src/Rules/Doctrine/ORM/PropertiesExtension.php(26): PHPStan\Type\Doctrine\ObjectMetadataResolver->getClassMetadata('Api\\Pric...')                                            
 #17 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Rules/DeadCode/UnusedPrivatePropertyRule.php(106): PHPStan\Rules\Doctrine\ORM\PropertiesExtension->isAlwaysRead(Object(PHPStan\Reflection\Php\PhpPropertyReflection),  
 'id')                                                                                                                                                                                                                                  
 #18 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(105): PHPStan\Rules\DeadCode\UnusedPrivatePropertyRule->processNode(Object(PHPStan\Node\ClassPropertiesNode),                                
 Object(PHPStan\Analyser\MutatingScope))                                                                                                                                                                                                
 #19 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(569): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PHPStan\Node\ClassPropertiesNode),                               
 Object(PHPStan\Analyser\MutatingScope))                                                                                                                                                                                                
 #20 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(332): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Class_), Object(PHPStan\Analyser\MutatingScope),   
 Object(Closure))                                                                                                                                                                                                                       
 #21 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(540): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array,                               
 Object(PHPStan\Analyser\MutatingScope), Object(Closure))                                                                                                                                                                               
 #22 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(302): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_),                                       
 Object(PHPStan\Analyser\MutatingScope), Object(Closure))                                                                                                                                                                               
 #23 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(174): PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))                       
 #24 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(147): PHPStan\Analyser\FileAnalyser->analyseFile('/usr/src/app/sr...', Array, Object(PHPStan\Rules\Registry),                                
 Object(PHPStan\Collectors\Registry), NULL)                                                                                                                                                                                             
 #25 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}(Array)                                        
 #26 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(110): _PHPStan_9a6ded56a\Evenement\EventEmitter->emit('data', Array)                                                              
 #27 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): _PHPStan_9a6ded56a\Clue\React\NDJson\Decoder->handleData(Array)                                        
 #28 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62): _PHPStan_9a6ded56a\Evenement\EventEmitter->emit('data', Array)                                                                       
 #29 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): _PHPStan_9a6ded56a\React\Stream\Util::_PHPStan_9a6ded56a\React\Stream\{closure}('{"action":"anal...')  
 #30 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154): _PHPStan_9a6ded56a\Evenement\EventEmitter->emit('data', Array)                                                      
 #31 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201): _PHPStan_9a6ded56a\React\Stream\DuplexResourceStream->handleData(Resource id #6039)                                 
 #32 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173): _PHPStan_9a6ded56a\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)                                    
 #33 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(107): _PHPStan_9a6ded56a\React\EventLoop\StreamSelectLoop->run()                                                                             
 #34 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259): PHPStan\Command\WorkerCommand->execute(Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Input\ArgvInput),              
 Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Output\ConsoleOutput))                                                                                                                                                             
 #35 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(865):                                                                                                                               
 _PHPStan_9a6ded56a\Symfony\Component\Console\Command\Command->run(Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Output\ConsoleOutput))                     
 #36 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(259): _PHPStan_9a6ded56a\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\WorkerCommand),                 
 Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Output\ConsoleOutput))                                                                                       
 #37 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157):                                                                                                                               
 _PHPStan_9a6ded56a\Symfony\Component\Console\Application->doRun(Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_9a6ded56a\Symfony\Component\Console\Output\ConsoleOutput))                       
 #38 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(127): _PHPStan_9a6ded56a\Symfony\Component\Console\Application->run()                                                                                          
 #39 phar:///usr/src/app/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(128): _PHPStan_9a6ded56a\{closure}()                                                                                                                           
 #40 /usr/src/app/vendor/phpstan/phpstan/phpstan(7): require('phar:///usr/src...')                                                                                                                                                      
 #41 /usr/src/app/vendor/bin/phpstan(112): include('/usr/src/app/ve...')                                                                                                                                                                
 #42 {main}                                                                     

Code snippet that reproduces the problem

when i put just that class annotation into the phpstan try website, the check passes. is the doctrine plugin active there? is it maybe missing more things to run into the problem.

Expected output

I think the annotation is fine. if it is not, phpstan should output an error report, and not run into an internal error

Did PHPStan help you today? Did it make you happy in any way?

I am upgrading all my vendors in a large application. This would be a nightmare without phpstan pointing out where changes in the dependencies mean I should adjust my code. Thanks for that!

dbu commented 2 years ago

hm, seems to be an esoteric problem. it works on our CI server, just not in my docker machine. i will try to figure out our setup problem.

github-actions[bot] commented 2 years ago

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.