diff --git a/rules-tests/CodeQuality/Rector/Class_/ConvertStaticToSelfRector/Fixture/skip_final_doc_class_constant.php.inc b/rules-tests/CodeQuality/Rector/Class_/ConvertStaticToSelfRector/Fixture/skip_final_doc_class_constant.php.inc new file mode 100644 index 00000000000..b99cf940eaa --- /dev/null +++ b/rules-tests/CodeQuality/Rector/Class_/ConvertStaticToSelfRector/Fixture/skip_final_doc_class_constant.php.inc @@ -0,0 +1,16 @@ +withRules([ConvertStaticToSelfRector::class]); + ->withRules([ConvertStaticToSelfRector::class]) + ->withPhpVersion(PhpVersionFeature::FINAL_CLASS_CONSTANTS); diff --git a/rules/CodeQuality/Rector/Class_/ConvertStaticToSelfRector.php b/rules/CodeQuality/Rector/Class_/ConvertStaticToSelfRector.php index 217cf69d72a..a83cf169ba0 100644 --- a/rules/CodeQuality/Rector/Class_/ConvertStaticToSelfRector.php +++ b/rules/CodeQuality/Rector/Class_/ConvertStaticToSelfRector.php @@ -16,8 +16,11 @@ use PHPStan\Reflection\ClassReflection; use Rector\Configuration\Parameter\FeatureFlags; use Rector\Enum\ObjectReference; +use Rector\Php\PhpVersionProvider; use Rector\PHPStan\ScopeFetcher; use Rector\Rector\AbstractRector; +use Rector\ValueObject\PhpVersionFeature; +use ReflectionClassConstant; use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample; use Symplify\RuleDocGenerator\ValueObject\RuleDefinition; @@ -31,6 +34,11 @@ */ final class ConvertStaticToSelfRector extends AbstractRector { + public function __construct( + private readonly PhpVersionProvider $phpVersionProvider + ) { + } + public function getRuleDefinition(): RuleDefinition { return new RuleDefinition('Change `static::*` to `self::*` on final class or private static members', [ @@ -163,10 +171,23 @@ private function shouldSkip( } if (! $isFinal) { - $memberIsFinal = $reflection instanceof ClassConstantReflection - ? $reflection->isFinal() - : $reflection->isFinalByKeyword() + // init + $memberIsFinal = false; + if ($reflection instanceof ClassConstantReflection) { + // Get the native ReflectionClassConstant + $declaringClass = $reflection->getDeclaringClass(); + $nativeReflectionClass = $declaringClass->getNativeReflection(); + $constantName = $reflection->getName(); + + if ($this->phpVersionProvider->isAtLeastPhpVersion(PhpVersionFeature::FINAL_CLASS_CONSTANTS)) { + // PHP 8.1+ + $nativeReflection = $nativeReflectionClass->getReflectionConstant($constantName); + $memberIsFinal = $nativeReflection instanceof ReflectionClassConstant && $nativeReflection->isFinal(); + } + } else { + $memberIsFinal = $reflection->isFinalByKeyword() ->yes(); + } // Final native members can be safely converted if ($memberIsFinal) {