Skip to content

Commit 4aecddd

Browse files
committed
Merge branch 'main' of github.com:rectorphp/rector-src into scoper-patch
2 parents 7637665 + cbc8ee5 commit 4aecddd

6 files changed

Lines changed: 107 additions & 10 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodeQuality\Rector\ClassConstFetch\ConvertStaticPrivateConstantToSelfRector\Fixture;
4+
5+
use Rector\Tests\CodeQuality\Rector\ClassConstFetch\ConvertStaticPrivateConstantToSelfRector\Source\ParentClass;
6+
7+
final class FinalClassWithInheritedConstant extends ParentClass
8+
{
9+
public function run(): void
10+
{
11+
return static::FAILURE;
12+
return static::SUCCESS;
13+
}
14+
}
15+
16+
?>
17+
-----
18+
<?php
19+
20+
namespace Rector\Tests\CodeQuality\Rector\ClassConstFetch\ConvertStaticPrivateConstantToSelfRector\Fixture;
21+
22+
use Rector\Tests\CodeQuality\Rector\ClassConstFetch\ConvertStaticPrivateConstantToSelfRector\Source\ParentClass;
23+
24+
final class FinalClassWithInheritedConstant extends ParentClass
25+
{
26+
public function run(): void
27+
{
28+
return self::FAILURE;
29+
return self::SUCCESS;
30+
}
31+
}
32+
33+
?>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodeQuality\Rector\ClassConstFetch\ConvertStaticPrivateConstantToSelfRector\Source;
4+
5+
class ParentClass
6+
{
7+
public const FAILURE = 1;
8+
protected const SUCCESS = 0;
9+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodeQuality\Rector\Class_\StaticToSelfStaticMethodCallOnFinalClassRector\Fixture;
4+
5+
use Rector\Tests\CodeQuality\Rector\Class_\StaticToSelfStaticMethodCallOnFinalClassRector\Source\BaseClass;
6+
7+
final class ParentStaticMethod extends BaseClass
8+
{
9+
public function test(): string
10+
{
11+
return static::parentMethod();
12+
}
13+
}
14+
15+
?>
16+
-----
17+
<?php
18+
19+
namespace Rector\Tests\CodeQuality\Rector\Class_\StaticToSelfStaticMethodCallOnFinalClassRector\Fixture;
20+
21+
use Rector\Tests\CodeQuality\Rector\Class_\StaticToSelfStaticMethodCallOnFinalClassRector\Source\BaseClass;
22+
23+
final class ParentStaticMethod extends BaseClass
24+
{
25+
public function test(): string
26+
{
27+
return self::parentMethod();
28+
}
29+
}
30+
31+
?>
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Rector\Tests\CodeQuality\Rector\Class_\StaticToSelfStaticMethodCallOnFinalClassRector\Source;
4+
5+
class BaseClass
6+
{
7+
protected static function parentMethod(): string
8+
{
9+
return 'parent method';
10+
}
11+
}

rules/CodeQuality/Rector/ClassConstFetch/ConvertStaticPrivateConstantToSelfRector.php

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,36 +17,41 @@
1717
* @see \Rector\Tests\CodeQuality\Rector\ClassConstFetch\ConvertStaticPrivateConstantToSelfRector\ConvertStaticPrivateConstantToSelfRectorTest
1818
*
1919
* @see https://3v4l.org/8Y0ba
20+
* @see https://3v4l.org/ZIeA1
2021
* @see https://phpstan.org/r/11d4c850-1a40-4fae-b665-291f96104d11
2122
*/
2223
final class ConvertStaticPrivateConstantToSelfRector extends AbstractRector
2324
{
2425
public function getRuleDefinition(): RuleDefinition
2526
{
2627
return new RuleDefinition(
27-
'Replaces static::* access to private constants with self::*',
28+
'Replaces static::* constant access with self::* for private constants and in final classes.',
2829
[
2930
new CodeSample(
3031
<<<'CODE_SAMPLE'
31-
final class Foo
32+
class Foo
3233
{
3334
private const BAR = 'bar';
35+
public const BAZ = 'baz';
3436
3537
public function run()
3638
{
3739
$bar = static::BAR;
40+
$baz = static::BAZ;
3841
}
3942
}
4043
CODE_SAMPLE
4144
,
4245
<<<'CODE_SAMPLE'
43-
final class Foo
46+
class Foo
4447
{
4548
private const BAR = 'bar';
49+
public const BAZ = 'baz';
4650
4751
public function run()
4852
{
4953
$bar = self::BAR;
54+
$baz = static::BAZ;
5055
}
5156
}
5257
CODE_SAMPLE
@@ -68,7 +73,7 @@ public function getNodeTypes(): array
6873
*/
6974
public function refactor(Node $node): ?Class_
7075
{
71-
if ($node->getConstants() === []) {
76+
if ($node->getConstants() === [] && ! $node->isFinal()) {
7277
return null;
7378
}
7479

rules/CodeQuality/Rector/Class_/StaticToSelfStaticMethodCallOnFinalClassRector.php

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,16 @@
99
use PhpParser\Node\Identifier;
1010
use PhpParser\Node\Name;
1111
use PhpParser\Node\Stmt\Class_;
12-
use PhpParser\Node\Stmt\ClassMethod;
12+
use PHPStan\Reflection\ClassReflection;
1313
use Rector\Configuration\Parameter\FeatureFlags;
1414
use Rector\Enum\ObjectReference;
15+
use Rector\PHPStan\ScopeFetcher;
1516
use Rector\Rector\AbstractRector;
1617
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
1718
use Symplify\RuleDocGenerator\ValueObject\RuleDefinition;
1819

1920
/**
21+
* @see https://3v4l.org/VbcrN
2022
* @see \Rector\Tests\CodeQuality\Rector\Class_\StaticToSelfStaticMethodCallOnFinalClassRector\StaticToSelfStaticMethodCallOnFinalClassRectorTest
2123
*/
2224
final class StaticToSelfStaticMethodCallOnFinalClassRector extends AbstractRector
@@ -76,8 +78,14 @@ public function refactor(Node $node): ?Class_
7678
}
7779

7880
$hasChanged = false;
81+
$scope = ScopeFetcher::fetch($node);
82+
$classReflection = $scope->getClassReflection();
7983

80-
$this->traverseNodesWithCallable($node->stmts, function (Node $subNode) use (&$hasChanged, $node): ?StaticCall {
84+
if (! $classReflection instanceof ClassReflection) {
85+
return null;
86+
}
87+
88+
$this->traverseNodesWithCallable($node->stmts, function (Node $subNode) use (&$hasChanged, $classReflection): ?StaticCall {
8189
if (! $subNode instanceof StaticCall) {
8290
return null;
8391
}
@@ -92,15 +100,15 @@ public function refactor(Node $node): ?Class_
92100
}
93101

94102
$methodName = (string) $this->getName($subNode->name);
95-
$targetClassMethod = $node->getMethod($methodName);
96103

97-
// skip call non-existing method from current class to ensure transformation is safe
98-
if (! $targetClassMethod instanceof ClassMethod) {
104+
if (! $classReflection->hasNativeMethod($methodName)) {
99105
return null;
100106
}
101107

108+
$methodReflection = $classReflection->getNativeMethod($methodName);
109+
102110
// avoid overlapped change
103-
if (! $targetClassMethod->isStatic()) {
111+
if (! $methodReflection->isStatic()) {
104112
return null;
105113
}
106114

0 commit comments

Comments
 (0)