spaze / phpstan-disallowed-calls

PHPStan rules to detect disallowed method & function calls, constant, namespace, attribute & superglobal usages
MIT License
263 stars 17 forks source link

Add support enum dynamic constant #241

Closed koraga closed 10 months ago

koraga commented 10 months ago

PHP: 8.3.1 When i use dynamic constants for enum. For example:

<?php declare(strict_types = 1);

enum Foo
{
    case Bar;
}

$variable = 'Bar';
$const = Foo::{$variable};

https://phpstan.org/r/fc74146a-7438-4cd8-ae4c-56c8db97dad5

Screenshot ![Screenshot 2024-01-21 at 4 04 15 PM](https://github.com/spaze/phpstan-disallowed-calls/assets/34651075/d73de7d4-73a8-4082-8362-8c0a14c04878)

I catch error

Uncaught PHPStan\ShouldNotHappenException: $node->name should be PhpParser\Node\Identifier but is PhpParser\Node\Expr\PropertyFetch in /api/vendor/spaze/phpstan-disallowed-calls/src/Usages/ClassConstantUsages.php: 84
#0 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(107): Spaze\PHPStan\Rules\Disallowed\Usages\ClassConstantUsages->processNode(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#1 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Node/ClassStatementsGatherer.php(108): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#2 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(567): PHPStan\Node\ClassStatementsGatherer-> __ invoke(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope)
#3 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2653): PHPStan\Analyser\NodeScopeResolver: : PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope))
#4 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1592): PHPStan\Analyser\NodeScopeResolver->callNodeCallbackWithExpression(Object(Closure), Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope), ObjectPHPStan\Analyser\ExpressionContext))
#5 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(605): PHPStan\Analyser\NodeScopeResolver->processExprNode(Object(PhpParser\Node\Stmt\Return_), Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\ExpressionContext))
#6 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(401): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Return_), Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))
#7 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(566): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\ClassMethod), Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))
#8 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(401): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\ClassMethod), Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer), Object(PHPStan\Analyser\StatementContext))
#9 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(668): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Class_), Array, Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer), Object(PHPStan\Analyser\StatementContext))
Screenshot ![Screenshot 2024-01-21 at 4 02 54 PM](https://github.com/spaze/phpstan-disallowed-calls/assets/34651075/6211a05c-870c-4cb5-83fc-7f4ae7dec17b)
spaze commented 10 months ago

Thanks @koraga, fixed the issue, will release it later today.

spaze commented 10 months ago

Released in 3.1.0 now. Thanks again!

koraga commented 10 months ago

I installed 3.1.0 but catch same error :(

For example my real code:

Screenshot ![Screenshot 2024-01-22 at 11 00 19 PM](https://github.com/spaze/phpstan-disallowed-calls/assets/34651075/7bec005a-6537-459c-ac74-ba4037317546) ![Screenshot 2024-01-22 at 10 58 34 PM](https://github.com/spaze/phpstan-disallowed-calls/assets/34651075/609d2cfd-b95f-4feb-8e14-c272368c0d16)
<?php

declare(strict_types=1);

namespace Modules\Admin\Http\Requests\AccessList;

use Illuminate\Foundation\Http\FormRequest;

/**
 * @property non-empty-string $type
 */
final class DownloadAccessListRequest extends FormRequest
{
    public function getType(): AccessListType
    {
        return AccessListType::{$this->type};
    }
}

// ...

enum AccessListType
{
    case White;
    case Black;
}

phpstan debug:

-- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Error                                                                                                                                                                                                                    
 -- ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- 
     Internal error: Internal error: $node->name should be PhpParser\Node\Identifier but is PhpParser\Node\Expr\PropertyFetch while analysing file /api/Modules/Admin/Http/Requests/AccessList/DownloadAccessListRequest.php  

     Post the following stack trace to https://github.com/phpstan/phpstan/issues/new?template=Bug_report.yaml:                                                                                                                
     ## /api/vendor/spaze/phpstan-disallowed-calls/src/Usages/ClassConstantUsages.php(99)                                                                                                                                     
     #0 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(107): Spaze\PHPStan\Rules\Disallowed\Usages\ClassConstantUsages->processNode(Object(PhpParser\Node\Expr\ClassConstFetch),               
     Object(PHPStan\Analyser\MutatingScope))                                                                                                                                                                                  
     #1 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Node/ClassStatementsGatherer.php(108): PHPStan\Analyser\FileAnalyser->PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\ClassConstFetch),                     
     Object(PHPStan\Analyser\MutatingScope))                                                                                                                                                                                  
     #2 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(567): PHPStan\Node\ClassStatementsGatherer->__invoke(Object(PhpParser\Node\Expr\ClassConstFetch),                                  
     Object(PHPStan\Analyser\MutatingScope))                                                                                                                                                                                  
     #3 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(2653): PHPStan\Analyser\NodeScopeResolver::PHPStan\Analyser\{closure}(Object(PhpParser\Node\Expr\ClassConstFetch),                 
     Object(PHPStan\Analyser\MutatingScope))                                                                                                                                                                                  
     #4 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(1592): PHPStan\Analyser\NodeScopeResolver->callNodeCallbackWithExpression(Object(Closure),                                         
     Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Analyser\ExpressionContext))                                                                                         
     #5 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(605): PHPStan\Analyser\NodeScopeResolver->processExprNode(Object(PhpParser\Node\Stmt\Return_),                                     
     Object(PhpParser\Node\Expr\ClassConstFetch), Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\ExpressionContext))                                                                        
     #6 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(401): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Return_),                                     
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                                                                      
     #7 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(566): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\ClassMethod), Array,                         
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                                                                      
     #8 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(401): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\ClassMethod),                                 
     Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer), Object(PHPStan\Analyser\StatementContext))                                                                                         
     #9 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(668): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Class_), Array,                              
     Object(PHPStan\Analyser\MutatingScope), Object(PHPStan\Node\ClassStatementsGatherer), Object(PHPStan\Analyser\StatementContext))                                                                                         
     #10 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(401): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Class_),                                     
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                                                                      
     #11 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(640): PHPStan\Analyser\NodeScopeResolver->processStmtNodes(Object(PhpParser\Node\Stmt\Namespace_), Array,                         
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                                                                      
     #12 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/NodeScopeResolver.php(370): PHPStan\Analyser\NodeScopeResolver->processStmtNode(Object(PhpParser\Node\Stmt\Namespace_),                                 
     Object(PHPStan\Analyser\MutatingScope), Object(Closure), Object(PHPStan\Analyser\StatementContext))                                                                                                                      
     #13 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Analyser/FileAnalyser.php(166): PHPStan\Analyser\NodeScopeResolver->processNodes(Array, Object(PHPStan\Analyser\MutatingScope), Object(Closure))                 
     #14 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(132): PHPStan\Analyser\FileAnalyser->analyseFile('/api/Modules/Ad...', Array, Object(PHPStan\Rules\LazyRegistry),                      
     Object(PHPStan\Collectors\Registry), NULL)                                                                                                                                                                               
     #15 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): PHPStan\Command\WorkerCommand->PHPStan\Command\{closure}(Array)                                  
     #16 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/clue/ndjson-react/src/Decoder.php(117): _PHPStan_3d4486d07\Evenement\EventEmitter->emit('data', Array)                                                        
     #17 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97): _PHPStan_3d4486d07\Clue\React\NDJson\Decoder->handleData(Array)                                  
     #18 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/Util.php(62): _PHPStan_3d4486d07\Evenement\EventEmitter->emit('data', Array)                                                                 
     #19 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/evenement/evenement/src/Evenement/EventEmitterTrait.php(97):                                                                                                  
     _PHPStan_3d4486d07\React\Stream\Util::_PHPStan_3d4486d07\React\Stream\{closure}('{"action":"anal...')                                                                                                                    
     #20 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/react/stream/src/DuplexResourceStream.php(154): _PHPStan_3d4486d07\Evenement\EventEmitter->emit('data', Array)                                                
     #21 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(201): _PHPStan_3d4486d07\React\Stream\DuplexResourceStream->handleData(Resource id #6235)                           
     #22 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/react/event-loop/src/StreamSelectLoop.php(173): _PHPStan_3d4486d07\React\EventLoop\StreamSelectLoop->waitForStreamActivity(NULL)                              
     #23 phar:///api/vendor/phpstan/phpstan/phpstan.phar/src/Command/WorkerCommand.php(98): _PHPStan_3d4486d07\React\EventLoop\StreamSelectLoop->run()                                                                        
     #24 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Command/Command.php(259): PHPStan\Command\WorkerCommand->execute(Object(_PHPStan_3d4486d07\Symfony\Component\Console\Input\ArgvInput),        
     Object(_PHPStan_3d4486d07\Symfony\Component\Console\Output\ConsoleOutput))                                                                                                                                               
     #25 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(870):                                                                                                                         
     _PHPStan_3d4486d07\Symfony\Component\Console\Command\Command->run(Object(_PHPStan_3d4486d07\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_3d4486d07\Symfony\Component\Console\Output\ConsoleOutput))       
     #26 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(261): _PHPStan_3d4486d07\Symfony\Component\Console\Application->doRunCommand(Object(PHPStan\Command\WorkerCommand),           
     Object(_PHPStan_3d4486d07\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_3d4486d07\Symfony\Component\Console\Output\ConsoleOutput))                                                                         
     #27 phar:///api/vendor/phpstan/phpstan/phpstan.phar/vendor/symfony/console/Application.php(157):                                                                                                                         
     _PHPStan_3d4486d07\Symfony\Component\Console\Application->doRun(Object(_PHPStan_3d4486d07\Symfony\Component\Console\Input\ArgvInput), Object(_PHPStan_3d4486d07\Symfony\Component\Console\Output\ConsoleOutput))         
     #28 phar:///api/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(124): _PHPStan_3d4486d07\Symfony\Component\Console\Application->run()                                                                                    
     #29 phar:///api/vendor/phpstan/phpstan/phpstan.phar/bin/phpstan(125): _PHPStan_3d4486d07\{closure}()                                                                                                                     
     #30 /api/vendor/phpstan/phpstan/phpstan(8): require('phar:///api/ven...')                                                                                                                                                
     #31 /api/vendor/bin/phpstan(119): include('/api/vendor/php...')                                                                                                                                                          
     #32 {main}                                                                                                                                                                             
spaze commented 10 months ago

Oh, a PhpParser\Node\Expr\PropertyFetch:

return AccessListType::{$this->type};

I see, I'll fix, and sorry for the trouble.

Btw, can you please post the code as code next time, not as a screenshot? It helps when I'm for example checking the issue on my mobile, or when I'm searching for things in the future or so. I have OCR'd the original description for the same reason.

koraga commented 10 months ago

Btw, can you please post the code as code next time, not as a screenshot? It helps when I'm for example checking the issue on my mobile, or when I'm searching for things in the future or so. I have OCR'd the original description for the same reason.

Okay, sorry

spaze commented 10 months ago

No problem and thanks for updating the comment! :-)

I have now fixed this (again!), hopefully for good this time 😅 Fix in 3.1.1 which replaces 3.1.0

Please let me know if it's alright, thanks.

koraga commented 10 months ago

It work! Thanks!

spaze commented 10 months ago

Awesome, thanks for the confirmation! 🎉