From 91a947bdd038c2bdc71d0d73ceb47bc4589520a9 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Mon, 10 Aug 2026 21:26:32 +0200 Subject: [PATCH] [deprecation] Deprecate AddReturnArrayDocblockBasedOnArrayMapRector --- phpstan.neon | 1 + ...ArrayDocblockBasedOnArrayMapRectorTest.php | 28 ----- .../Fixture/function_array_map_return.php.inc | 34 ----- .../Fixture/improve_simple_array.php.inc | 37 ------ .../Fixture/include_arrow_function.php.inc | 30 ----- .../Fixture/multiple_filters.php.inc | 46 ------- .../Fixture/multiple_types.php.inc | 46 ------- .../Fixture/override_mixyed.php.inc | 39 ------ .../Fixture/skip_already_class.php.inc | 18 --- .../skip_already_has_return_doc.php.inc | 18 --- .../Fixture/skip_first_class_callable.php.inc | 11 -- .../Fixture/skip_if_else.php.inc | 17 --- .../Fixture/skip_override.php.inc | 17 --- .../config/configured_rule.php | 9 -- ...turnArrayDocblockBasedOnArrayMapRector.php | 118 ++---------------- .../Level/TypeDeclarationDocblocksLevel.php | 2 - 16 files changed, 9 insertions(+), 462 deletions(-) delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/AddReturnArrayDocblockBasedOnArrayMapRectorTest.php delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/function_array_map_return.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/improve_simple_array.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/include_arrow_function.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/multiple_filters.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/multiple_types.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/override_mixyed.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_already_class.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_already_has_return_doc.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_first_class_callable.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_if_else.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_override.php.inc delete mode 100644 rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/config/configured_rule.php diff --git a/phpstan.neon b/phpstan.neon index bc725b29610..5e74f14907b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -468,6 +468,7 @@ parameters: - '#Class "Rector\\TypeDeclarationDocblocks\\Rector\\ClassMethod\\AddReturnDocblockForDimFetchArrayFromAssignsRector" is missing @see annotation with test case class reference#' - '#Class "Rector\\Assert\\Rector\\ClassMethod\\AddAssertArrayFromClassMethodDocblockRector" is missing @see annotation with test case class reference#' - '#Class "Rector\\TypeDeclarationDocblocks\\Rector\\ClassMethod\\AddParamArrayDocblockBasedOnArrayMapRector" is missing @see annotation with test case class reference#' + - '#Class "Rector\\TypeDeclaration\\Rector\\ClassMethod\\AddReturnArrayDocblockBasedOnArrayMapRector" is missing @see annotation with test case class reference#' # @todo fix in phpstan-rules - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/AddReturnArrayDocblockBasedOnArrayMapRectorTest.php b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/AddReturnArrayDocblockBasedOnArrayMapRectorTest.php deleted file mode 100644 index 178d257c36d..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/AddReturnArrayDocblockBasedOnArrayMapRectorTest.php +++ /dev/null @@ -1,28 +0,0 @@ -doTestFile($filePath); - } - - public static function provideData(): Iterator - { - return self::yieldFilesFromDirectory(__DIR__ . '/Fixture'); - } - - public function provideConfigFilePath(): string - { - return __DIR__ . '/config/configured_rule.php'; - } -} diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/function_array_map_return.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/function_array_map_return.php.inc deleted file mode 100644 index b323fea4d6e..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/function_array_map_return.php.inc +++ /dev/null @@ -1,34 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/improve_simple_array.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/improve_simple_array.php.inc deleted file mode 100644 index f1056a5025c..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/improve_simple_array.php.inc +++ /dev/null @@ -1,37 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/include_arrow_function.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/include_arrow_function.php.inc deleted file mode 100644 index daaa287326e..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/include_arrow_function.php.inc +++ /dev/null @@ -1,30 +0,0 @@ - 1000, $items); - } -} - -?> ------ - 1000, $items); - } -} - -?> diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/multiple_filters.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/multiple_filters.php.inc deleted file mode 100644 index fd6e008958a..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/multiple_filters.php.inc +++ /dev/null @@ -1,46 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/multiple_types.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/multiple_types.php.inc deleted file mode 100644 index 044c3d40c4a..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/multiple_types.php.inc +++ /dev/null @@ -1,46 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/override_mixyed.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/override_mixyed.php.inc deleted file mode 100644 index caa3455e01e..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/override_mixyed.php.inc +++ /dev/null @@ -1,39 +0,0 @@ - ------ - diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_already_class.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_already_class.php.inc deleted file mode 100644 index 4bea83fb7c9..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_already_class.php.inc +++ /dev/null @@ -1,18 +0,0 @@ - - */ - public function process(array $items) - { - return array_map(function ($item): stdClass { - return $item; - }, $items); - } -} diff --git a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_first_class_callable.php.inc b/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_first_class_callable.php.inc deleted file mode 100644 index 98d8044330c..00000000000 --- a/rules-tests/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector/Fixture/skip_first_class_callable.php.inc +++ /dev/null @@ -1,11 +0,0 @@ -withRules([AddReturnArrayDocblockBasedOnArrayMapRector::class]); diff --git a/rules/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector.php b/rules/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector.php index 4471a3658d2..d7817970101 100644 --- a/rules/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector.php +++ b/rules/TypeDeclaration/Rector/ClassMethod/AddReturnArrayDocblockBasedOnArrayMapRector.php @@ -5,41 +5,19 @@ 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\FunctionLike; -use PhpParser\Node\Identifier; use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Function_; -use PHPStan\Type\ArrayType; -use PHPStan\Type\IntersectionType; -use PHPStan\Type\MixedType; -use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; -use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; -use Rector\NodeTypeResolver\PHPStan\Type\TypeFactory; -use Rector\PhpParser\Node\BetterNodeFinder; +use Rector\Configuration\Deprecation\Contract\DeprecatedInterface; +use Rector\Exception\ShouldNotHappenException; use Rector\Rector\AbstractRector; -use Rector\StaticTypeMapper\StaticTypeMapper; -use Rector\TypeDeclaration\NodeAnalyzer\ReturnAnalyzer; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; /** - * @see \Rector\Tests\TypeDeclaration\Rector\ClassMethod\AddReturnArrayDocblockBasedOnArrayMapRector\AddReturnArrayDocblockBasedOnArrayMapRectorTest + * @deprecated This rule is deprecated, as too niche and of little practical value. It only fires when array_map() gets an inline closure with an explicit return type, where static analysis already knows the item type without the docblock. */ -final class AddReturnArrayDocblockBasedOnArrayMapRector extends AbstractRector +final class AddReturnArrayDocblockBasedOnArrayMapRector extends AbstractRector implements DeprecatedInterface { - public function __construct( - private readonly BetterNodeFinder $betterNodeFinder, - private readonly ReturnAnalyzer $returnAnalyzer, - private readonly StaticTypeMapper $staticTypeMapper, - private readonly TypeFactory $typeFactory, - private readonly PhpDocTypeChanger $phpDocTypeChanger, - private readonly PhpDocInfoFactory $phpDocInfoFactory, - ) { - } - public function getRuleDefinition(): RuleDefinition { return new RuleDefinition( @@ -86,89 +64,9 @@ public function getNodeTypes(): array */ public function refactor(Node $node): null|Function_|ClassMethod { - $returnsScoped = $this->betterNodeFinder->findReturnsScoped($node); - - if ($this->hasNonArrayReturnType($node)) { - return null; - } - - // nothing to return? skip it - if ($returnsScoped === []) { - return null; - } - - // only returns with expr and no void - if (! $this->returnAnalyzer->hasOnlyReturnWithExpr($node, $returnsScoped)) { - return null; - } - - $closureReturnTypes = []; - - foreach ($returnsScoped as $returnScoped) { - if (! $returnScoped->expr instanceof FuncCall) { - return null; - } - - $arrayMapClosure = $this->matchArrayMapClosure($returnScoped->expr); - if (! $arrayMapClosure instanceof FunctionLike) { - return null; - } - - if (! $arrayMapClosure->returnType instanceof Node) { - return null; - } - - $closureReturnTypes[] = $this->staticTypeMapper->mapPhpParserNodePHPStanType($arrayMapClosure->returnType); - } - - $returnType = $this->typeFactory->createMixedPassedOrUnionType($closureReturnTypes); - $arrayType = new ArrayType(new MixedType(), $returnType); - - $functionLikePhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node); - - $returnOriginalType = $functionLikePhpDocInfo->getReturnType(); - - if ($returnOriginalType instanceof ArrayType && ! $returnOriginalType->getItemType() instanceof MixedType) { - return null; - } - - if ($returnOriginalType instanceof IntersectionType) { - return null; - } - - $hasChanged = $this->phpDocTypeChanger->changeReturnType($node, $functionLikePhpDocInfo, $arrayType); - if ($hasChanged) { - return $node; - } - - return null; - } - - private function hasNonArrayReturnType(ClassMethod|Function_ $functionLike): bool - { - if (! $functionLike->returnType instanceof Identifier) { - return false; - } - - return $functionLike->returnType->toLowerString() !== 'array'; - } - - private function matchArrayMapClosure(FuncCall $funcCall): Closure|ArrowFunction|null - { - if (! $this->isName($funcCall, 'array_map')) { - return null; - } - - if ($funcCall->isFirstClassCallable()) { - return null; - } - - // lets infer strict array_map() type - $firstArg = $funcCall->getArgs()[0]; - if (! $firstArg->value instanceof Closure && ! $firstArg->value instanceof ArrowFunction) { - return null; - } - - return $firstArg->value; + throw new ShouldNotHappenException(sprintf( + '"%s" rule is deprecated, as too niche and of little practical value. The item type is already known from the inline closure return type', + self::class + )); } } diff --git a/src/Config/Level/TypeDeclarationDocblocksLevel.php b/src/Config/Level/TypeDeclarationDocblocksLevel.php index b9de49b8866..69054a7aff1 100644 --- a/src/Config/Level/TypeDeclarationDocblocksLevel.php +++ b/src/Config/Level/TypeDeclarationDocblocksLevel.php @@ -6,7 +6,6 @@ use Rector\Contract\Rector\RectorInterface; use Rector\TypeDeclaration\Rector\ClassMethod\AddParamArrayDocblockBasedOnCallableNativeFuncCallRector; -use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnArrayDocblockBasedOnArrayMapRector; use Rector\TypeDeclaration\Rector\ClassMethod\AddReturnDocblockForScalarArrayFromAssignsRector; use Rector\TypeDeclarationDocblocks\Rector\Class_\AddVarArrayDocblockFromDimFetchAssignRector; use Rector\TypeDeclarationDocblocks\Rector\Class_\ClassMethodArrayDocblockParamFromLocalCallsRector; @@ -40,7 +39,6 @@ final class TypeDeclarationDocblocksLevel // return AddReturnDocblockForCommonObjectDenominatorRector::class, - AddReturnArrayDocblockBasedOnArrayMapRector::class, AddReturnDocblockForScalarArrayFromAssignsRector::class, DocblockReturnArrayFromDirectArrayInstanceRector::class, AddReturnDocblockForArrayDimAssignedObjectRector::class,