From 5ae7a3d95286f6f2252009ab99a09010b1aaae14 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Mon, 30 Oct 2023 15:30:17 +0100 Subject: [PATCH] StrictFunctionCallsRule - support named arguments --- composer.json | 2 +- .../StrictCalls/StrictFunctionCallsRule.php | 14 +++++++++++--- .../StrictFunctionCallsRuleTest.php | 9 +++++++++ tests/Rules/StrictCalls/data/bug-231.php | 18 ++++++++++++++++++ 4 files changed, 39 insertions(+), 4 deletions(-) create mode 100644 tests/Rules/StrictCalls/data/bug-231.php diff --git a/composer.json b/composer.json index 9cf4e652..47e2e112 100644 --- a/composer.json +++ b/composer.json @@ -7,7 +7,7 @@ ], "require": { "php": "^7.2 || ^8.0", - "phpstan/phpstan": "^1.10" + "phpstan/phpstan": "^1.10.34" }, "require-dev": { "nikic/php-parser": "^4.13.0", diff --git a/src/Rules/StrictCalls/StrictFunctionCallsRule.php b/src/Rules/StrictCalls/StrictFunctionCallsRule.php index b27c25fe..3b5c4588 100644 --- a/src/Rules/StrictCalls/StrictFunctionCallsRule.php +++ b/src/Rules/StrictCalls/StrictFunctionCallsRule.php @@ -5,7 +5,9 @@ use PhpParser\Node; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Name; +use PHPStan\Analyser\ArgumentsNormalizer; use PHPStan\Analyser\Scope; +use PHPStan\Reflection\ParametersAcceptorSelector; use PHPStan\Reflection\ReflectionProvider; use PHPStan\Rules\Rule; use PHPStan\Type\Constant\ConstantBooleanType; @@ -47,11 +49,17 @@ public function processNode(Node $node, Scope $scope): array return []; } - $functionName = $this->reflectionProvider->resolveFunctionName($node->name, $scope); - if ($functionName === null) { + if (!$this->reflectionProvider->hasFunction($node->name, $scope)) { return []; } - $functionName = strtolower($functionName); + + $function = $this->reflectionProvider->getFunction($node->name, $scope); + $parametersAcceptor = ParametersAcceptorSelector::selectFromArgs($scope, $node->getArgs(), $function->getVariants()); + $node = ArgumentsNormalizer::reorderFuncArguments($parametersAcceptor, $node); + if ($node === null) { + return []; + } + $functionName = strtolower($function->getName()); if (!array_key_exists($functionName, $this->functionArguments)) { return []; } diff --git a/tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php b/tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php index 8a1ce29c..8c46b360 100644 --- a/tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php +++ b/tests/Rules/StrictCalls/StrictFunctionCallsRuleTest.php @@ -4,6 +4,7 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; +use const PHP_VERSION_ID; class StrictFunctionCallsRuleTest extends RuleTestCase { @@ -71,4 +72,12 @@ public function testRule(): void ]); } + public function testBug231(): void + { + if (PHP_VERSION_ID < 80100) { + $this->markTestSkipped('Test requires PHP 8.1.'); + } + $this->analyse([__DIR__ . '/data/bug-231.php'], []); + } + } diff --git a/tests/Rules/StrictCalls/data/bug-231.php b/tests/Rules/StrictCalls/data/bug-231.php new file mode 100644 index 00000000..2dac686f --- /dev/null +++ b/tests/Rules/StrictCalls/data/bug-231.php @@ -0,0 +1,18 @@ += 8.1 + +namespace Bug231; + +enum MyEnum: string +{ + case Foo = 'foo'; + case Bar = 'bar'; + case Baz = 'baz'; + + public function isB(): bool + { + return in_array($this, strict: true, haystack: [ + self::Bar, + self::Baz, + ]); + } +}