From 436a6ff496a4971ce55f73a37f76d7711e5a731d Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 15 Oct 2026 13:19:19 +0200 Subject: [PATCH] [perf] Speed up callable param type rules by deferring type resolution until shape confirmed --- ...DocblockBasedOnCallableNativeFuncCallRector.php | 14 +++++++------- ...losureParamTypeFromIterableMethodCallRector.php | 8 ++++---- .../AddParamTypeSplFixedArrayRector.php | 3 ++- 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/rules/TypeDeclaration/Rector/ClassMethod/AddParamArrayDocblockBasedOnCallableNativeFuncCallRector.php b/rules/TypeDeclaration/Rector/ClassMethod/AddParamArrayDocblockBasedOnCallableNativeFuncCallRector.php index 333e5eb62a8..755c969daa7 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/AddParamArrayDocblockBasedOnCallableNativeFuncCallRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/AddParamArrayDocblockBasedOnCallableNativeFuncCallRector.php @@ -142,13 +142,6 @@ function (Node $subNode) use ($variableNamesWithArrayType, $node, &$paramsWithTy return null; } - $arrayArgValueType = $this->nodeTypeResolver->getNativeType($arrayArgValue); - - // type changed, eg: by reassign - if (! $arrayArgValueType->isArray()->yes()) { - return null; - } - $callbackArg = $subNode->getArg( 'callback', NativeFuncCallPositions::ARRAY_AND_CALLBACK_POSITIONS[$funcCallName]['callback'] @@ -185,6 +178,13 @@ function (Node $subNode) use ($variableNamesWithArrayType, $node, &$paramsWithTy return null; } + $arrayArgValueType = $this->nodeTypeResolver->getNativeType($arrayArgValue); + + // type changed, eg: by reassign + if (! $arrayArgValueType->isArray()->yes()) { + return null; + } + $arrayArgValueName = (string) $this->getName($arrayArgValue); $paramToUpdate = $this->getParamByName($node, $arrayArgValueName); diff --git a/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromIterableMethodCallRector.php b/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromIterableMethodCallRector.php index a35fe45fe33..64d0a2ebb0f 100644 --- a/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromIterableMethodCallRector.php +++ b/rules/TypeDeclaration/Rector/FunctionLike/AddClosureParamTypeFromIterableMethodCallRector.php @@ -98,6 +98,10 @@ public function refactor(Node $node): ?Node return null; } + if (! $this->callUsesClosures($node->getArgs())) { + return null; + } + $varType = $this->getType($node->var); if (! $varType instanceof IntersectionType || ! $varType->isIterable()->yes()) { @@ -127,10 +131,6 @@ public function refactor(Node $node): ?Node return null; } - if (! $this->callUsesClosures($node->getArgs())) { - return null; - } - $nameIndex = []; foreach ($parameters as $index => $parameter) { $nameIndex[$parameter->getName()] = $index; diff --git a/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeSplFixedArrayRector.php b/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeSplFixedArrayRector.php index 329cf4962ce..3e71d234e88 100644 --- a/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeSplFixedArrayRector.php +++ b/rules/TypeDeclaration/Rector/FunctionLike/AddParamTypeSplFixedArrayRector.php @@ -90,7 +90,7 @@ public function refactor(Node $node): ?Node return null; } - $functionLikePhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); + $functionLikePhpDocInfo = null; $hasChanged = false; foreach ($node->getParams() as $param) { @@ -116,6 +116,7 @@ public function refactor(Node $node): ?Node continue; } + $functionLikePhpDocInfo ??= $this->phpDocInfoFactory->createFromNodeOrEmpty($node); $paramName = $this->getName($param); $changedParamType = $this->phpDocTypeChanger->changeParamType( $node,