Skip to content

Commit a268587

Browse files
ArshidArshid
authored andcommitted
DowngradeFinalPropertyPromotionRector
1 parent 8ab1dce commit a268587

File tree

6 files changed

+166
-0
lines changed

6 files changed

+166
-0
lines changed

config/set/downgrade-php85.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
declare(strict_types=1);
44

55
use Rector\Config\RectorConfig;
6+
use Rector\DowngradePhp85\Rector\Class_\DowngradeFinalPropertyPromotionRector;
67
use Rector\DowngradePhp85\Rector\FuncCall\DowngradeArrayFirstLastRector;
78
use Rector\Renaming\Rector\ClassConstFetch\RenameClassConstFetchRector;
89
use Rector\Renaming\Rector\MethodCall\RenameMethodRector;
@@ -14,6 +15,7 @@
1415
$rectorConfig->phpVersion(PhpVersion::PHP_84);
1516
$rectorConfig->rules([
1617
DowngradeArrayFirstLastRector::class,
18+
DowngradeFinalPropertyPromotionRector::class,
1719
]);
1820

1921
// https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_driver_specific_pdo_constants_and_methods
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Tests\DowngradePhp85\Rector\Class_\DowngradeFinalPropertyPromotionRector;
6+
7+
use Iterator;
8+
use PHPUnit\Framework\Attributes\DataProvider;
9+
use Rector\Testing\PHPUnit\AbstractRectorTestCase;
10+
11+
final class DowngradeFinalPropertyPromotionRectorTest extends AbstractRectorTestCase
12+
{
13+
#[DataProvider('provideData')]
14+
public function test(string $filePath): void
15+
{
16+
$this->doTestFile($filePath);
17+
}
18+
19+
public static function provideData(): Iterator
20+
{
21+
return self::yieldFilesFromDirectory(__DIR__ . '/Fixture');
22+
}
23+
24+
public function provideConfigFilePath(): string
25+
{
26+
return __DIR__ . '/config/configured_rule.php';
27+
}
28+
}
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?php
2+
3+
namespace Rector\Tests\DowngradeFinalPropertyPromotionRector\Rector\Class_\DowngradePropertyPromotionRector\Fixture;
4+
5+
class Fixture
6+
{
7+
public function __construct(
8+
final public string $id
9+
) {}
10+
}
11+
12+
?>
13+
-----
14+
<?php
15+
16+
namespace Rector\Tests\DowngradeFinalPropertyPromotionRector\Rector\Class_\DowngradePropertyPromotionRector\Fixture;
17+
18+
class Fixture
19+
{
20+
public function __construct(
21+
/** @final */
22+
public string $id
23+
) {}
24+
}
25+
26+
?>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Rector\Tests\DowngradeFinalPropertyPromotionRector\Rector\Class_\DowngradePropertyPromotionRector\Fixture;
4+
5+
class Fixture
6+
{
7+
public function __construct(readonly string $id)
8+
{
9+
}
10+
}
11+
12+
?>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
use Rector\Config\RectorConfig;
6+
use Rector\DowngradePhp85\Rector\Class_\DowngradeFinalPropertyPromotionRector;
7+
8+
return static function (RectorConfig $rectorConfig): void {
9+
$rectorConfig->rule(DowngradeFinalPropertyPromotionRector::class);
10+
};
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\DowngradePhp85\Rector\Class_;
6+
7+
use PhpParser\Comment\Doc;
8+
use PhpParser\Modifiers;
9+
use PhpParser\Node;
10+
use PhpParser\Node\Param;
11+
use PhpParser\Node\Stmt\Class_;
12+
use PhpParser\Node\Stmt\ClassMethod;
13+
use PhpParser\Node\Stmt\Trait_;
14+
use Rector\BetterPhpDocParser\PhpDocInfo\PhpDocInfoFactory;
15+
use Rector\BetterPhpDocParser\PhpDocManipulator\PhpDocTypeChanger;
16+
use Rector\PhpParser\Node\BetterNodeFinder;
17+
use Rector\PhpParser\Printer\BetterStandardPrinter;
18+
use Rector\Rector\AbstractRector;
19+
use Rector\ValueObject\MethodName;
20+
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
21+
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
22+
23+
/**
24+
* @changelog https://wiki.php.net/rfc/final_promotion
25+
*
26+
* @see \Rector\Tests\DowngradePhp85\Rector\Class_\DowngradeFinalPropertyPromotionRector\DowngradeFinalPropertyPromotionRectorTest
27+
*/
28+
final class DowngradeFinalPropertyPromotionRector extends AbstractRector
29+
{
30+
public function getRuleDefinition(): RuleDefinition
31+
{
32+
return new RuleDefinition('Change constructor final property promotion to @final annotation assign', [
33+
new CodeSample(
34+
<<<'CODE_SAMPLE'
35+
class SomeClass
36+
{
37+
public function __construct(
38+
final public string $id
39+
){}
40+
}
41+
CODE_SAMPLE
42+
43+
,
44+
<<<'CODE_SAMPLE'
45+
class SomeClass
46+
{
47+
public function __construct(
48+
/** @final */
49+
public string $id
50+
) {}
51+
}
52+
CODE_SAMPLE
53+
),
54+
]);
55+
}
56+
57+
/**
58+
* @return array<class-string<Node>>
59+
*/
60+
public function getNodeTypes(): array
61+
{
62+
return [Class_::class, Trait_::class];
63+
}
64+
65+
/**
66+
* @param Class_|Trait_ $node
67+
*/
68+
public function refactor(Node $node): null
69+
{
70+
$constructorClassMethod = $node->getMethod(MethodName::CONSTRUCT);
71+
if (! $constructorClassMethod instanceof ClassMethod) {
72+
return null;
73+
}
74+
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+
}
83+
}
84+
}
85+
86+
return null;
87+
}
88+
}

0 commit comments

Comments
 (0)