diff --git a/src/Php/PhpVersions.php b/src/Php/PhpVersions.php index 84bd2c3f5f2..6fe7ae260f8 100644 --- a/src/Php/PhpVersions.php +++ b/src/Php/PhpVersions.php @@ -193,6 +193,11 @@ public function supportsDeprecatedTraits(): TrinaryLogic return IntegerRangeType::fromInterval(80500, null)->isSuperTypeOf($this->phpVersions)->result; } + public function supportsDebugInfoOnEnums(): TrinaryLogic + { + return IntegerRangeType::fromInterval(80600, null)->isSuperTypeOf($this->phpVersions)->result; + } + public function arrayFunctionsReturnNullWithNonArray(): TrinaryLogic { return IntegerRangeType::fromInterval(null, 79999)->isSuperTypeOf($this->phpVersions)->result; diff --git a/src/Rules/Classes/EnumSanityRule.php b/src/Rules/Classes/EnumSanityRule.php index d5e84aad004..5c1eead481f 100644 --- a/src/Rules/Classes/EnumSanityRule.php +++ b/src/Rules/Classes/EnumSanityRule.php @@ -80,7 +80,10 @@ public function processNode(Node $node, Scope $scope): array ->line($methodNode->getStartLine()) ->nonIgnorable() ->build(); - } elseif (!array_key_exists($lowercasedMethodName, self::ALLOWED_MAGIC_METHODS)) { + } elseif ( + !array_key_exists($lowercasedMethodName, self::ALLOWED_MAGIC_METHODS) + && ($lowercasedMethodName !== '__debuginfo' || !$scope->getPhpVersion()->supportsDebugInfoOnEnums()->yes()) + ) { $errors[] = RuleErrorBuilder::message(sprintf( 'Enum %s contains magic method %s().', $classReflection->getDisplayName(), diff --git a/tests/PHPStan/Rules/Classes/EnumSanityRuleConfigPhpTest.php b/tests/PHPStan/Rules/Classes/EnumSanityRuleConfigPhpTest.php new file mode 100644 index 00000000000..6b3bb67dbe1 --- /dev/null +++ b/tests/PHPStan/Rules/Classes/EnumSanityRuleConfigPhpTest.php @@ -0,0 +1,45 @@ + + */ +class EnumSanityRuleConfigPhpTest extends RuleTestCase +{ + + protected function getRule(): Rule + { + return new EnumSanityRule( + self::getContainer()->getByType(InitializerExprTypeResolver::class), + ); + } + + #[RequiresPhp('>= 8.1.0')] + public function testDebugInfoPhpVersionRangeSpanning86(): void + { + $this->analyse([__DIR__ . '/data/enum-debug-info-php-versions.php'], [ + [ + 'Enum EnumDebugInfoPhpVersions\UnsupportedInBranch contains magic method __debugInfo().', + 18, + ], + [ + 'Enum EnumDebugInfoPhpVersions\DependsOnPhpVersion contains magic method __debugInfo().', + 27, + ], + ]); + } + + public static function getAdditionalConfigFiles(): array + { + return [ + __DIR__ . '/data/enum-debug-info-php-version.neon', + ]; + } + +} diff --git a/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php b/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php index 1d4ff07cc78..e2146395987 100644 --- a/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php +++ b/tests/PHPStan/Rules/Classes/EnumSanityRuleTest.php @@ -6,6 +6,7 @@ use PHPStan\Rules\Rule; use PHPStan\Testing\RuleTestCase; use PHPUnit\Framework\Attributes\RequiresPhp; +use const PHP_VERSION_ID; /** * @extends RuleTestCase @@ -190,4 +191,23 @@ public function testBug11891(): void ]); } + #[RequiresPhp('>= 8.1.0')] + public function testDebugInfoPhpVersions(): void + { + $errors = [ + [ + 'Enum EnumDebugInfoPhpVersions\\UnsupportedInBranch contains magic method __debugInfo().', + 18, + ], + ]; + if (PHP_VERSION_ID < 80600) { + $errors[] = [ + 'Enum EnumDebugInfoPhpVersions\\DependsOnPhpVersion contains magic method __debugInfo().', + 27, + ]; + } + + $this->analyse([__DIR__ . '/data/enum-debug-info-php-versions.php'], $errors); + } + } diff --git a/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-version.neon b/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-version.neon new file mode 100644 index 00000000000..37a89190078 --- /dev/null +++ b/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-version.neon @@ -0,0 +1,4 @@ +parameters: + phpVersion: + min: 80500 + max: 80600 diff --git a/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-versions.php b/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-versions.php new file mode 100644 index 00000000000..ac03ec03371 --- /dev/null +++ b/tests/PHPStan/Rules/Classes/data/enum-debug-info-php-versions.php @@ -0,0 +1,31 @@ += 8.1 + +namespace EnumDebugInfoPhpVersions; + +if (PHP_VERSION_ID >= 80600) { + enum SupportedInBranch + { + public function __debugInfo(): array + { + return []; + } + } +} + +if (PHP_VERSION_ID < 80600) { + enum UnsupportedInBranch + { + public function __debugInfo(): array + { + return []; + } + } +} + +enum DependsOnPhpVersion +{ + public function __debugInfo(): array + { + return []; + } +}