diff --git a/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector/Fixture/union_from_if_else_assign.php.inc b/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector/Fixture/union_from_if_else_assign.php.inc new file mode 100644 index 00000000000..e92411f0748 --- /dev/null +++ b/rules-tests/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector/Fixture/union_from_if_else_assign.php.inc @@ -0,0 +1,46 @@ + 1]; + } else { + $items = ['name' => 'test']; + } + + return $items; + } +} + +?> +----- +|array + */ + public function toArray(): array + { + $items = []; + + if (mt_rand(0, 1)) { + $items = ['id' => 1]; + } else { + $items = ['name' => 'test']; + } + + return $items; + } +} + +?> diff --git a/rules/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector.php b/rules/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector.php index 3698f2bb697..8448031d710 100644 --- a/rules/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector.php +++ b/rules/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector.php @@ -11,11 +11,13 @@ use PhpParser\Node\Stmt\ClassMethod; use PhpParser\Node\Stmt\Expression; use PhpParser\Node\Stmt\Return_; +use PHPStan\PhpDocParser\Ast\Type\TypeNode; use PHPStan\Type\Constant\ConstantArrayType; use PHPStan\Type\Type; use PHPStan\Type\UnionType; use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory; use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger; +use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode; use Rector\Rector\AbstractRector; use Rector\TypeDeclarationDocblocks\NodeFinder\ReturnNodeFinder; use Rector\TypeDeclarationDocblocks\TagNodeAnalyzer\UsefulArrayTagNodeAnalyzer; @@ -166,8 +168,18 @@ public function refactor(Node $node): ?ClassMethod return $node; } - // @todo handle multiple type nodes - $this->phpDocTypeChanger->changeReturnTypeNode($node, $phpDocInfo, $genericUnionedTypeNodes[0]); + if ($genericUnionedTypeNodes === []) { + return null; + } + + // sort for deterministic output across PHP versions + usort($genericUnionedTypeNodes, static fn (TypeNode $a, TypeNode $b): int => (string) $a <=> (string) $b); + + $typeNode = count($genericUnionedTypeNodes) === 1 + ? $genericUnionedTypeNodes[0] + : new BracketsAwareUnionTypeNode($genericUnionedTypeNodes); + + $this->phpDocTypeChanger->changeReturnTypeNode($node, $phpDocInfo, $typeNode); return $node; }