Skip to content

Commit 302dc93

Browse files
ArshidArshid
authored andcommitted
DowngradeFinalPropertyPromotionRector
1 parent a268587 commit 302dc93

File tree

5 files changed

+63
-20
lines changed

5 files changed

+63
-20
lines changed

rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRectorf/DowngradeFinalPropertyPromotionRectorTest.php renamed to rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/DowngradeFinalPropertyPromotionRectorTest.php

File renamed without changes.

rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRectorf/Fixture/fixture.php.inc renamed to rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/Fixture/fixture.php.inc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,9 @@ namespace Rector\Tests\DowngradeFinalPropertyPromotionRector\Rector\Class_\Downg
1818
class Fixture
1919
{
2020
public function __construct(
21-
/** @final */
21+
/**
22+
* @final
23+
*/
2224
public string $id
2325
) {}
2426
}

rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRectorf/Fixture/skip_fixture_readonly.php.inc renamed to rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/Fixture/skip_fixture_readonly.php.inc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Rector\Tests\DowngradeFinalPropertyPromotionRector\Rector\Class_\DowngradePropertyPromotionRector\Fixture;
44

5-
class Fixture
5+
class SkipFixtureReadonly
66
{
77
public function __construct(readonly string $id)
88
{

rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRectorf/config/configured_rule.php renamed to rules-tests/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector/config/configured_rule.php

File renamed without changes.

rules/DowngradePhp85/Rector/Class_/DowngradeFinalPropertyPromotionRector.php

Lines changed: 59 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,19 @@
44

55
namespace Rector\DowngradePhp85\Rector\Class_;
66

7-
use PhpParser\Comment\Doc;
7+
use PhpParser\Builder\Property;
88
use PhpParser\Modifiers;
99
use PhpParser\Node;
1010
use PhpParser\Node\Param;
11-
use PhpParser\Node\Stmt\Class_;
1211
use PhpParser\Node\Stmt\ClassMethod;
13-
use PhpParser\Node\Stmt\Trait_;
12+
use PHPStan\PhpDocParser\Ast\PhpDoc\GenericTagValueNode;
13+
use PHPStan\PhpDocParser\Ast\PhpDoc\PhpDocTagNode;
1414
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
15-
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
16-
use Rector\PhpParser\Node\BetterNodeFinder;
17-
use Rector\PhpParser\Printer\BetterStandardPrinter;
15+
use Rector\Comments\NodeDocBlock\DocBlockUpdater;
16+
use Rector\Privatization\NodeManipulator\VisibilityManipulator;
1817
use Rector\Rector\AbstractRector;
1918
use Rector\ValueObject\MethodName;
19+
use Rector\ValueObject\Visibility;
2020
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
2121
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
2222

@@ -27,6 +27,18 @@
2727
*/
2828
final class DowngradeFinalPropertyPromotionRector extends AbstractRector
2929
{
30+
/**
31+
* @var string
32+
*/
33+
private const TAGNAME = 'final';
34+
35+
public function __construct(
36+
private readonly VisibilityManipulator $visibilityManipulator,
37+
private readonly DocBlockUpdater $docBlockUpdater,
38+
private readonly PhpDocInfoFactory $phpDocInfoFactory,
39+
) {
40+
}
41+
3042
public function getRuleDefinition(): RuleDefinition
3143
{
3244
return new RuleDefinition('Change constructor final property promotion to @final annotation assign', [
@@ -59,30 +71,59 @@ public function __construct(
5971
*/
6072
public function getNodeTypes(): array
6173
{
62-
return [Class_::class, Trait_::class];
74+
return [ClassMethod::class];
6375
}
6476

6577
/**
66-
* @param Class_|Trait_ $node
78+
* @param ClassMethod $node
6779
*/
6880
public function refactor(Node $node): null
6981
{
70-
$constructorClassMethod = $node->getMethod(MethodName::CONSTRUCT);
71-
if (! $constructorClassMethod instanceof ClassMethod) {
82+
83+
if (! $this->isName($node, MethodName::CONSTRUCT)) {
7284
return null;
7385
}
7486

75-
foreach ($constructorClassMethod->params as $promotedParam) {
76-
if (($promotedParam->flags & Modifiers::FINAL) !== 0) {
77-
$promotedParam->flags &= ~Modifiers::FINAL;
78-
79-
$existingDoc = $promotedParam->getDocComment();
80-
if (! $existingDoc) {
81-
$promotedParam->setDocComment(new Doc('/** @final */'));
82-
}
87+
foreach ($node->params as $param) {
88+
if (! $param->isPromoted()) {
89+
continue;
90+
}
91+
if (! $this->visibilityManipulator->hasVisibility($param, Visibility::FINAL)) {
92+
continue;
8393
}
94+
95+
$this->makeNonFinal($param);
96+
97+
$this->addPhpDocTag($param);
98+
8499
}
85100

86101
return null;
87102
}
103+
104+
public function makeNonFinal(Param $node): void
105+
{
106+
if (! $this->isFinal($node)) {
107+
return;
108+
}
109+
110+
$node->flags -= Modifiers::FINAL;
111+
}
112+
113+
private function isFinal(Param $node): bool{
114+
return (bool) ($node->flags & Modifiers::FINAL);
115+
}
116+
117+
private function addPhpDocTag(Property|Param $node): bool
118+
{
119+
$phpDocInfo = $this->phpDocInfoFactory->createFromNodeOrEmpty($node);
120+
121+
if ($phpDocInfo->hasByName(self::TAGNAME)) {
122+
return false;
123+
}
124+
125+
$phpDocInfo->addPhpDocTagNode(new PhpDocTagNode('@' . self::TAGNAME, new GenericTagValueNode('')));
126+
$this->docBlockUpdater->updateRefactoredNodeWithPhpDocInfo($node);
127+
return true;
128+
}
88129
}

0 commit comments

Comments
 (0)