Skip to content

Commit 23f7b6d

Browse files
committed
Implement TODO: handle multiple type nodes in AddReturnDocblockForDimFetchArrayFromAssignsRector
When a method returns a variable whose PHPStan-inferred type is a union of multiple distinct ConstantArrayTypes, the rector previously only used the first generalized type node and discarded the rest. Now it correctly creates a BracketsAwareUnionTypeNode from all non-empty type nodes, producing a union @return docblock (e.g. array<string, int>|array<string, string>). Also adds a guard for the case where all union members are empty arrays (would previously crash with an undefined index on $genericUnionedTypeNodes[0]). https://claude.ai/code/session_01L2wfcmkihik6MVWq5qwEfw
1 parent 89d191b commit 23f7b6d

2 files changed

Lines changed: 56 additions & 2 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\AddReturnDocblockForDimFetchArrayFromAssignsRector\Fixture;
4+
5+
final class UnionFromIfElseAssign
6+
{
7+
public function toArray(): array
8+
{
9+
$items = [];
10+
11+
if (mt_rand(0, 1)) {
12+
$items = ['id' => 1];
13+
} else {
14+
$items = ['name' => 'test'];
15+
}
16+
17+
return $items;
18+
}
19+
}
20+
21+
?>
22+
-----
23+
<?php
24+
25+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\ClassMethod\AddReturnDocblockForDimFetchArrayFromAssignsRector\Fixture;
26+
27+
final class UnionFromIfElseAssign
28+
{
29+
/**
30+
* @return array<string, int>|array<string, string>
31+
*/
32+
public function toArray(): array
33+
{
34+
$items = [];
35+
36+
if (mt_rand(0, 1)) {
37+
$items = ['id' => 1];
38+
} else {
39+
$items = ['name' => 'test'];
40+
}
41+
42+
return $items;
43+
}
44+
}
45+
46+
?>

rules/TypeDeclarationDocblocks/Rector/ClassMethod/AddReturnDocblockForDimFetchArrayFromAssignsRector.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use PHPStan\Type\UnionType;
1717
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
1818
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
19+
use Rector\BetterPhpDocParser\ValueObject\Type\BracketsAwareUnionTypeNode;
1920
use Rector\Rector\AbstractRector;
2021
use Rector\TypeDeclarationDocblocks\NodeFinder\ReturnNodeFinder;
2122
use Rector\TypeDeclarationDocblocks\TagNodeAnalyzer\UsefulArrayTagNodeAnalyzer;
@@ -166,8 +167,15 @@ public function refactor(Node $node): ?ClassMethod
166167
return $node;
167168
}
168169

169-
// @todo handle multiple type nodes
170-
$this->phpDocTypeChanger->changeReturnTypeNode($node, $phpDocInfo, $genericUnionedTypeNodes[0]);
170+
if ($genericUnionedTypeNodes === []) {
171+
return null;
172+
}
173+
174+
$typeNode = count($genericUnionedTypeNodes) === 1
175+
? $genericUnionedTypeNodes[0]
176+
: new BracketsAwareUnionTypeNode($genericUnionedTypeNodes);
177+
178+
$this->phpDocTypeChanger->changeReturnTypeNode($node, $phpDocInfo, $typeNode);
171179

172180
return $node;
173181
}

0 commit comments

Comments
 (0)