From b343bbf83d0dd08db917408d8efd99b140ce04c6 Mon Sep 17 00:00:00 2001 From: Ondrej Mirtes Date: Sat, 17 Aug 2019 14:49:22 +0200 Subject: [PATCH] Use verbosity level value() when the parameter type contains callable --- src/Rules/FunctionCallParametersCheck.php | 2 +- src/Type/TypeUtils.php | 17 +++++++++++++++++ .../CallToFunctionParametersRuleTest.php | 4 ++++ .../data/incorrect-call-to-function.php | 4 ++++ 4 files changed, 26 insertions(+), 1 deletion(-) diff --git a/src/Rules/FunctionCallParametersCheck.php b/src/Rules/FunctionCallParametersCheck.php index 36be6edcc6..228b1380d0 100644 --- a/src/Rules/FunctionCallParametersCheck.php +++ b/src/Rules/FunctionCallParametersCheck.php @@ -156,7 +156,7 @@ public function check( && !$this->ruleLevelHelper->accepts($parameterType, $argumentValueType, $scope->isDeclareStrictTypes()) && ($secondAccepts === null || !$secondAccepts) ) { - $verbosityLevel = $parameterType->isCallable()->yes() || count(TypeUtils::getConstantArrays($parameterType)) > 0 + $verbosityLevel = TypeUtils::containsCallable($parameterType) || count(TypeUtils::getConstantArrays($parameterType)) > 0 ? VerbosityLevel::value() : VerbosityLevel::typeOnly(); $errors[] = sprintf( diff --git a/src/Type/TypeUtils.php b/src/Type/TypeUtils.php index ec647ab020..9c8ba8b87c 100644 --- a/src/Type/TypeUtils.php +++ b/src/Type/TypeUtils.php @@ -242,4 +242,21 @@ public static function getAccessoryTypes(Type $type): array return self::map(AccessoryType::class, $type, true, false); } + public static function containsCallable(Type $type): bool + { + if ($type->isCallable()->yes()) { + return true; + } + + if ($type instanceof UnionType) { + foreach ($type->getTypes() as $innerType) { + if ($innerType->isCallable()->yes()) { + return true; + } + } + } + + return false; + } + } diff --git a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php index a0fa7ba1a4..094cbf4a67 100644 --- a/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php +++ b/tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php @@ -39,6 +39,10 @@ public function testCallToFunctionWithIncorrectParameters(): void 'Parameter #1 $foo of function IncorrectCallToFunction\bar expects int, string given.', 14, ], + [ + 'Parameter #1 $error_handler of function set_error_handler expects (callable(int, string, string, int, array): bool)|null, Closure(mixed, mixed, mixed, mixed): void given.', + 16, + ], ]); } diff --git a/tests/PHPStan/Rules/Functions/data/incorrect-call-to-function.php b/tests/PHPStan/Rules/Functions/data/incorrect-call-to-function.php index 6af6ccc98a..66a20ce9be 100644 --- a/tests/PHPStan/Rules/Functions/data/incorrect-call-to-function.php +++ b/tests/PHPStan/Rules/Functions/data/incorrect-call-to-function.php @@ -12,3 +12,7 @@ ]; $keys = array_keys($array); bar($keys[0]); + +set_error_handler(function ($errno, $errstr, $errfile, $errline): void { + // ... +});