Skip to content

Commit e6b5961

Browse files
authored
[TypeDeclarationDocblocks] Allow override dummy array var on DocblockVarArrayFromGetterReturnRector (#7381)
* [TypeDeclarationDocblocks] Allow override dummy array var on DocblockVarArrayFromGetterReturnRector * implemented 🎉
1 parent a559b9e commit e6b5961

File tree

5 files changed

+70
-33
lines changed

5 files changed

+70
-33
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
<?php
2+
3+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\DocblockVarArrayFromGetterReturnRector\Fixture;
4+
5+
final class OverrideDummyArrayVar
6+
{
7+
/**
8+
* @var array
9+
*/
10+
private array $names;
11+
12+
/**
13+
* @return string[]
14+
*/
15+
public function getNames(): array
16+
{
17+
return $this->names;
18+
}
19+
}
20+
21+
?>
22+
-----
23+
<?php
24+
25+
namespace Rector\Tests\TypeDeclarationDocblocks\Rector\Class_\DocblockVarArrayFromGetterReturnRector\Fixture;
26+
27+
final class OverrideDummyArrayVar
28+
{
29+
/**
30+
* @var string[]
31+
*/
32+
private array $names;
33+
34+
/**
35+
* @return string[]
36+
*/
37+
public function getNames(): array
38+
{
39+
return $this->names;
40+
}
41+
}
42+
43+
?>

rules/TypeDeclarationDocblocks/NodeDocblockTypeDecorator.php

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,6 @@
77
use PhpParser\Node\Param;
88
use PhpParser\Node\Stmt\ClassMethod;
99
use PhpParser\Node\Stmt\Property;
10-
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
11-
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
12-
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
1310
use PHPStan\PhpDocParser\Ast\Type\ArrayTypeNode;
1411
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
1512
use PHPStan\PhpDocParser\Ast\Type\TypeNode;
@@ -20,7 +17,6 @@
2017
use PHPStan\Type\Type;
2118
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfo;
2219
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
23-
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
2420
use Rector\Privatization\TypeManipulator\TypeNormalizer;
2521
use Rector\StaticTypeMapper\StaticTypeMapper;
2622

@@ -29,7 +25,6 @@
2925
public function __construct(
3026
private TypeNormalizer $typeNormalizer,
3127
private StaticTypeMapper $staticTypeMapper,
32-
private DocBlockUpdater $docBlockUpdater,
3328
private PhpDocTypeChanger $phpDocTypeChanger
3429
) {
3530
}
@@ -94,9 +89,7 @@ public function decorateGenericIterableVarType(Type $type, PhpDocInfo $phpDocInf
9489
return false;
9590
}
9691

97-
$varTagValueNode = new VarTagValueNode($typeNode, '', '');
98-
99-
$this->addTagValueNodeAndUpdatePhpDocInfo($phpDocInfo, $varTagValueNode, $property);
92+
$this->phpDocTypeChanger->changeVarTypeNode($property, $phpDocInfo, $typeNode);
10093

10194
return true;
10295
}
@@ -115,16 +108,6 @@ private function createTypeNode(Type $type): TypeNode
115108
return $typeNode;
116109
}
117110

118-
private function addTagValueNodeAndUpdatePhpDocInfo(
119-
PhpDocInfo $phpDocInfo,
120-
ParamTagValueNode|VarTagValueNode|ReturnTagValueNode $tagValueNode,
121-
Property|ClassMethod $stmt
122-
): void {
123-
$phpDocInfo->addTagValueNode($tagValueNode);
124-
125-
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($stmt);
126-
}
127-
128111
private function isBareMixedType(Type $type): bool
129112
{
130113
if ($type instanceof MixedType) {

rules/TypeDeclarationDocblocks/Rector/Class_/DocblockVarArrayFromGetterReturnRector.php

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
use PhpParser\Node\Stmt\Class_;
1010
use PhpParser\Node\Stmt\ClassMethod;
1111
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
12-
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
1312
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
14-
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
1513
use Rector\Rector\AbstractRector;
14+
use Rector\TypeDeclarationDocblocks\NodeDocblockTypeDecorator;
1615
use Rector\TypeDeclarationDocblocks\NodeFinder\PropertyGetterFinder;
16+
use Rector\TypeDeclarationDocblocks\TagNodeAnalyzer\UsefulArrayTagNodeAnalyzer;
1717
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1818
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
1919

@@ -25,7 +25,8 @@ final class DocblockVarArrayFromGetterReturnRector extends AbstractRector
2525
public function __construct(
2626
private readonly PhpDocInfoFactory $phpDocInfoFactory,
2727
private readonly PropertyGetterFinder $propertyGetterFinder,
28-
private readonly DocBlockUpdater $docBlockUpdater
28+
private readonly UsefulArrayTagNodeAnalyzer $usefulArrayTagNodeAnalyzer,
29+
private readonly NodeDocblockTypeDecorator $nodeDocblockTypeDecorator
2930
) {
3031
}
3132

@@ -98,7 +99,7 @@ public function refactor(Node $node): ?Node
9899
$propertyPhpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($property);
99100

100101
// type is already known, skip it
101-
if ($propertyPhpDocInfo->getVarTagValueNode() instanceof VarTagValueNode) {
102+
if ($this->usefulArrayTagNodeAnalyzer->isUsefulArrayTag($propertyPhpDocInfo->getVarTagValueNode())) {
102103
continue;
103104
}
104105

@@ -113,11 +114,15 @@ public function refactor(Node $node): ?Node
113114
continue;
114115
}
115116

116-
$varTagValeNode = new VarTagValueNode($returnTagValueNode->type, '', '');
117+
$isPropertyChanged = $this->nodeDocblockTypeDecorator->decorateGenericIterableVarType(
118+
$classMethodDocInfo->getReturnType(),
119+
$propertyPhpDocInfo,
120+
$property
121+
);
117122

118-
// find matching getter and its @return docblock
119-
$propertyPhpDocInfo->addTagValueNode($varTagValeNode);
120-
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($property);
123+
if (! $isPropertyChanged) {
124+
continue;
125+
}
121126

122127
$hasChanged = true;
123128
}

rules/TypeDeclarationDocblocks/TagNodeAnalyzer/UsefulArrayTagNodeAnalyzer.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,14 @@
66

77
use PHPStan\PhpDocParser\Ast\PhpDoc\ParamTagValueNode;
88
use PHPStan\PhpDocParser\Ast\PhpDoc\ReturnTagValueNode;
9+
use PHPStan\PhpDocParser\Ast\PhpDoc\VarTagValueNode;
910
use PHPStan\PhpDocParser\Ast\Type\IdentifierTypeNode;
1011

1112
final class UsefulArrayTagNodeAnalyzer
1213
{
13-
public function isUsefulArrayTag(null|ReturnTagValueNode|ParamTagValueNode $tagValueNode): bool
14+
public function isUsefulArrayTag(null|ReturnTagValueNode|ParamTagValueNode|VarTagValueNode $tagValueNode): bool
1415
{
15-
if (! $tagValueNode instanceof ReturnTagValueNode && ! $tagValueNode instanceof ParamTagValueNode) {
16+
if (! $tagValueNode instanceof ReturnTagValueNode && ! $tagValueNode instanceof ParamTagValueNode && ! $tagValueNode instanceof VarTagValueNode) {
1617
return false;
1718
}
1819

src/BetterPhpDocParser/PhpDocManipulator/PhpDocTypeChanger.php

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -115,7 +115,7 @@ public function changeReturnTypeNode(
115115
}
116116

117117
public function changeParamTypeNode(
118-
ClassMethod $functionLike,
118+
ClassMethod $classMethod,
119119
PhpDocInfo $phpDocInfo,
120120
Param $param,
121121
string $paramName,
@@ -129,7 +129,7 @@ public function changeParamTypeNode(
129129
$phpDocInfo->addTagValueNode($paramTagValueNode);
130130
}
131131

132-
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($functionLike);
132+
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($classMethod);
133133
}
134134

135135
public function changeReturnType(FunctionLike $functionLike, PhpDocInfo $phpDocInfo, Type $newType): bool
@@ -244,9 +244,14 @@ public function isAllowed(TypeNode $typeNode): bool
244244
*/
245245
public function changeVarTypeNode(Stmt $stmt, PhpDocInfo $phpDocInfo, TypeNode $typeNode): void
246246
{
247-
// add completely new one
248-
$varTagValueNode = new VarTagValueNode($typeNode, '', '');
249-
$phpDocInfo->addTagValueNode($varTagValueNode);
247+
$existingVarTagValueNode = $phpDocInfo->getVarTagValueNode();
248+
if ($existingVarTagValueNode instanceof VarTagValueNode) {
249+
$existingVarTagValueNode->type = $typeNode;
250+
} else {
251+
// add completely new one
252+
$varTagValueNode = new VarTagValueNode($typeNode, '', '');
253+
$phpDocInfo->addTagValueNode($varTagValueNode);
254+
}
250255

251256
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($stmt);
252257
}

0 commit comments

Comments
 (0)