diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector/Fixture/also_arrow_function.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector/Fixture/also_arrow_function.php.inc new file mode 100644 index 00000000000..f5604405706 --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector/Fixture/also_arrow_function.php.inc @@ -0,0 +1,41 @@ + $this->someTypedService->run($value); + } +} + +?> +----- + $this->someTypedService->run($value); + } +} + +?> diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector/Fixture/also_closure.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector/Fixture/also_closure.php.inc new file mode 100644 index 00000000000..bd270ca8e1d --- /dev/null +++ b/rules-tests/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector/Fixture/also_closure.php.inc @@ -0,0 +1,45 @@ +someTypedService->run($value); + }; + } +} + +?> +----- +someTypedService->run($value); + }; + } +} + +?> diff --git a/rules/TypeDeclaration/NodeAnalyzer/VariableInSprintfMaskMatcher.php b/rules/TypeDeclaration/NodeAnalyzer/VariableInSprintfMaskMatcher.php index 998e9109751..5c6a54cdbf8 100644 --- a/rules/TypeDeclaration/NodeAnalyzer/VariableInSprintfMaskMatcher.php +++ b/rules/TypeDeclaration/NodeAnalyzer/VariableInSprintfMaskMatcher.php @@ -31,7 +31,12 @@ public function __construct( public function matchMask(ClassMethod|Function_ $functionLike, string $variableName, string $mask): bool { $funcCalls = $this->betterNodeFinder->findInstancesOfScoped((array) $functionLike->stmts, FuncCall::class); - $funcCalls = array_values(array_filter($funcCalls, fn(FuncCall $funcCall): bool => $this->nodeNameResolver->isName($funcCall->name, 'sprintf'))); + $funcCalls = array_values( + array_filter($funcCalls, fn (FuncCall $funcCall): bool => $this->nodeNameResolver->isName( + $funcCall->name, + 'sprintf' + )) + ); if (count($funcCalls) !== 1) { return false; diff --git a/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector.php b/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector.php index 2988d97b9ed..63a5121d382 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/ParamTypeByMethodCallTypeRector.php @@ -5,12 +5,14 @@ namespace Rector\TypeDeclaration\Rector\ClassMethod; use PhpParser\Node; +use PhpParser\Node\Expr\ArrowFunction; +use PhpParser\Node\Expr\Closure; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\MethodCall; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Param; -use PhpParser\Node\Stmt\Class_; use PhpParser\Node\Stmt\ClassMethod; +use PhpParser\Node\Stmt\Function_; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory; use Rector\PhpParser\Node\BetterNodeFinder; @@ -96,33 +98,25 @@ public function go(string $value) */ public function getNodeTypes(): array { - return [Class_::class]; + return [ClassMethod::class, Function_::class, Closure::class, ArrowFunction::class]; } /** - * @param Class_ $node + * @param ClassMethod|Function_|Closure $node */ public function refactor(Node $node): ?Node { - $hasChanged = false; - - foreach ($node->getMethods() as $classMethod) { - if ($this->shouldSkipClassMethod($classMethod)) { - continue; - } - - /** @var array $callers */ - $callers = $this->betterNodeFinder->findInstancesOf( - $classMethod, - [StaticCall::class, MethodCall::class, FuncCall::class] - ); - - $hasClassMethodChanged = $this->refactorClassMethod($classMethod, $callers); - if ($hasClassMethodChanged) { - $hasChanged = true; - } + if ($node instanceof ClassMethod && $this->shouldSkipClassMethod($node)) { + return null; } + /** @var array $callers */ + $callers = $this->betterNodeFinder->findInstancesOf( + $node, + [StaticCall::class, MethodCall::class, FuncCall::class] + ); + + $hasChanged = $this->refactorFunctionLike($node, $callers); if ($hasChanged) { return $node; } @@ -139,8 +133,10 @@ private function shouldSkipClassMethod(ClassMethod $classMethod): bool return $this->parentClassMethodTypeOverrideGuard->hasParentClassMethod($classMethod); } - private function shouldSkipParam(Param $param, ClassMethod $classMethod): bool - { + private function shouldSkipParam( + Param $param, + ClassMethod|Function_|Closure|ArrowFunction $functionLike + ): bool { // already has type, skip if ($param->type instanceof Node) { return true; @@ -150,18 +146,24 @@ private function shouldSkipParam(Param $param, ClassMethod $classMethod): bool return true; } - return ! $this->paramTypeAddGuard->isLegal($param, $classMethod); + if (! $functionLike instanceof ClassMethod) { + return false; + } + + return ! $this->paramTypeAddGuard->isLegal($param, $functionLike); } /** * @param array $callers */ - private function refactorClassMethod(ClassMethod $classMethod, array $callers): bool - { + private function refactorFunctionLike( + ClassMethod|Closure|Function_|ArrowFunction $functionLike, + array $callers + ): bool { $hasChanged = false; - foreach ($classMethod->params as $param) { - if ($this->shouldSkipParam($param, $classMethod)) { + foreach ($functionLike->params as $param) { + if ($this->shouldSkipParam($param, $functionLike)) { continue; } diff --git a/src/ChangesReporting/Output/GitHubOutputFormatter.php b/src/ChangesReporting/Output/GitHubOutputFormatter.php index 8516157d619..56633532276 100644 --- a/src/ChangesReporting/Output/GitHubOutputFormatter.php +++ b/src/ChangesReporting/Output/GitHubOutputFormatter.php @@ -131,7 +131,7 @@ private function sanitizeAnnotationProperties(array $annotationProperties): stri ); $sanitizedProperties = array_map( - fn (string $key, $value): string => sprintf('%s=%s', $key, $this->sanitizeAnnotationProperty($value)), + fn (string $key, string|int|null $value): string => sprintf('%s=%s', $key, $this->sanitizeAnnotationProperty($value)), array_keys($nonNullProperties), $nonNullProperties );