From 5a565a2d3c774716a6a85edab84c85bc337f62ec Mon Sep 17 00:00:00 2001 From: Markus Staab Date: Sun, 27 Oct 2024 08:56:05 +0100 Subject: [PATCH] Fix signature type for default-null parameters --- .../SignatureMap/Php8SignatureMapProvider.php | 17 ++++++++++++++++- .../CallToFunctionParametersRuleTest.php | 6 ++++++ tests/PHPStan/Rules/Functions/data/bug-7522.php | 8 ++++++++ 3 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 tests/PHPStan/Rules/Functions/data/bug-7522.php diff --git a/src/Reflection/SignatureMap/Php8SignatureMapProvider.php b/src/Reflection/SignatureMap/Php8SignatureMapProvider.php index 7bfdf37f9b..8a0d689f66 100644 --- a/src/Reflection/SignatureMap/Php8SignatureMapProvider.php +++ b/src/Reflection/SignatureMap/Php8SignatureMapProvider.php @@ -3,6 +3,7 @@ namespace PHPStan\Reflection\SignatureMap; use PhpParser\Node\AttributeGroup; +use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\Variable; use PhpParser\Node\Scalar\String_; use PhpParser\Node\Stmt\ClassConst; @@ -21,6 +22,7 @@ use PHPStan\Type\MixedType; use PHPStan\Type\ParserNodeTypeToPHPStanType; use PHPStan\Type\Type; +use PHPStan\Type\TypeCombinator; use PHPStan\Type\TypehintHelper; use ReflectionFunctionAbstract; use function array_key_exists; @@ -400,10 +402,23 @@ private function getSignature( throw new ShouldNotHappenException(); } $parameterType = ParserNodeTypeToPHPStanType::resolve($param->type, null); + $phpDocParameterType = $phpDocParameterTypes[$name->name] ?? null; + + if ($param->default instanceof ConstFetch) { + $constName = (string) $param->default->name; + $loweredConstName = strtolower($constName); + if ($loweredConstName === 'null') { + $parameterType = TypeCombinator::addNull($parameterType); + if ($phpDocParameterType !== null) { + $phpDocParameterType = TypeCombinator::addNull($phpDocParameterType); + } + } + } + $parameters[] = new ParameterSignature( $name->name, $param->default !== null || $param->variadic, - TypehintHelper::decideType($parameterType, $phpDocParameterTypes[$name->name] ?? null), + TypehintHelper::decideType($parameterType, $phpDocParameterType), $parameterType, $param->byRef ? PassedByReference::createCreatesNewVariable() : PassedByReference::createNo(), $param->variadic, diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php index 98927b4bd2..61cc6e6fc6 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php @@ -1793,4 +1793,10 @@ public function testBug7082(): void ]); } + public function testBug7522(): void + { + $this->checkExplicitMixed = true; + $this->analyse([__DIR__ . '/data/bug-7522.php'], []); + } + } diff --git a/tests/PHPStan/Rules/Functions/data/bug-7522.php b/tests/PHPStan/Rules/Functions/data/bug-7522.php new file mode 100644 index 0000000000..cff0bc5897 --- /dev/null +++ b/tests/PHPStan/Rules/Functions/data/bug-7522.php @@ -0,0 +1,8 @@ +