Skip to content

Commit dc89e52

Browse files
committed
add union null type support to RemoveNullFromNullableCollectionTypeRector
1 parent cea5e66 commit dc89e52

2 files changed

Lines changed: 83 additions & 5 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\RemoveNullFromNullableCollectionTypeRector\Fixture;
4+
5+
use Doctrine\Common\Collections\ArrayCollection;
6+
use Doctrine\Common\Collections\Collection;
7+
8+
final class RemoveUnionFromPropertyDocblock
9+
{
10+
/**
11+
* @var Collection<int, string>|null
12+
*/
13+
private Collection $collection;
14+
15+
public function __construct()
16+
{
17+
$this->collection = new ArrayCollection([]);
18+
}
19+
}
20+
21+
?>
22+
-----
23+
<?php
24+
25+
namespace Rector\Doctrine\Tests\TypedCollections\Rector\ClassMethod\RemoveNullFromNullableCollectionTypeRector\Fixture;
26+
27+
use Doctrine\Common\Collections\ArrayCollection;
28+
use Doctrine\Common\Collections\Collection;
29+
30+
final class RemoveUnionFromPropertyDocblock
31+
{
32+
/**
33+
* @var Collection<int, string>
34+
*/
35+
private Collection $collection;
36+
37+
public function __construct()
38+
{
39+
$this->collection = new ArrayCollection([]);
40+
}
41+
}
42+
43+
?>

rules/TypedCollections/Rector/ClassMethod/RemoveNullFromNullableCollectionTypeRector.php

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
use PhpParser\Node\Stmt\ClassMethod;
1111
use PhpParser\Node\Stmt\Property;
1212
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
13+
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
1314
use PHPStan\PhpDocParser\Ast\Type\NullableTypeNode;
15+
use PHPStan\PhpDocParser\Ast\Type\UnionTypeNode;
1416
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
1517
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
1618
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
@@ -137,18 +139,39 @@ private function refactorProperty(Property $property): ?Property
137139
return null;
138140
}
139141

142+
if ($varTagValueNode->type instanceof UnionTypeNode) {
143+
$hasChanged = false;
144+
145+
$unionTypeNode = $varTagValueNode->type;
146+
147+
foreach ($unionTypeNode->types as $key => $unionedType) {
148+
if ($unionedType instanceof IdentifierTypeNode && $unionedType->name === 'null') {
149+
unset($unionTypeNode->types[$key]);
150+
$hasChanged = true;
151+
}
152+
}
153+
154+
if ($hasChanged) {
155+
// only one type left, lets use it directly
156+
if (count($unionTypeNode->types) === 1) {
157+
$onlyType = array_pop($unionTypeNode->types);
158+
$varTagValueNode->type = $onlyType;
159+
}
160+
161+
$this->updateVarTagValueNode($phpDocInfo, $varTagValueNode, $property);
162+
163+
return $property;
164+
}
165+
}
166+
140167
// remove nullable if has one
141168
if (! $varTagValueNode->type instanceof NullableTypeNode) {
142169
return null;
143170
}
144171

145172
// unwrap nullable type
146173
$varTagValueNode->type = $varTagValueNode->type->type;
147-
148-
$phpDocInfo->removeByType(VarTagValueNode::class);
149-
$phpDocInfo->addTagValueNode($varTagValueNode);
150-
151-
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($property);
174+
$this->updateVarTagValueNode($phpDocInfo, $varTagValueNode, $property);
152175

153176
return $property;
154177
}
@@ -161,4 +184,16 @@ private function hasNativeCollectionType(Property $property): bool
161184

162185
return $this->isName($property->type, DoctrineClass::COLLECTION);
163186
}
187+
188+
private function updateVarTagValueNode(
189+
PhpDocInfo $phpDocInfo,
190+
VarTagValueNode $varTagValueNode,
191+
Property $property
192+
): void {
193+
194+
$phpDocInfo->removeByType(VarTagValueNode::class);
195+
$phpDocInfo->addTagValueNode($varTagValueNode);
196+
197+
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($property);
198+
}
164199
}

0 commit comments

Comments
 (0)