From d9766f8175e6798429d3acf45b9deef9dbd55dd9 Mon Sep 17 00:00:00 2001 From: jrfnl Date: Tue, 8 Jul 2025 00:45:54 +0200 Subject: [PATCH] PSR2/SwitchDeclaration: make "wrong opener" fixable if opener is a semi-colon The PHP 8.5 deprecations RFC contains a proposal to deprecate the use of semicolons as scope openers for `switch` `case` and `default` statements. The `PSR2.ControlStructures.SwitchDeclaration` sniff already detects and flags this issue under the `WrongOpenercase` and `WrongOpenerdefault` error codes, but as the same error code is also used for `case`/`default` statements using the `: { ... }` syntax, the error code was non-fixable. With an eye on the PHP 8.5 deprecation, it seems prudent to ensure that a semi-colon `case`/`default` scope opener can be auto-fixed to a `colon`. Making the `: { ... }` syntax auto-fixable may be more complex, so is left as future scope. Includes tests. Note: if this were a new sniff, I would probably have introduced new error code(s), so the fixable and the non-fixable errors would have separate error codes. However, as this is a pre-existing sniff, doing so would be a breaking change and not one I deem strictly necessary. Ref: * https://wiki.php.net/rfc/deprecations_php_8_5#deprecate_semicolon_after_case_in_switch_statement --- .../ControlStructures/SwitchDeclarationSniff.php | 10 +++++++++- .../ControlStructures/SwitchDeclarationUnitTest.inc | 13 +++++++++++++ .../SwitchDeclarationUnitTest.inc.fixed | 13 +++++++++++++ .../ControlStructures/SwitchDeclarationUnitTest.php | 5 +++++ 4 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php b/src/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php index c846e43e8a..0c8355d2e2 100644 --- a/src/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php +++ b/src/Standards/PSR2/Sniffs/ControlStructures/SwitchDeclarationSniff.php @@ -172,7 +172,15 @@ public function process(File $phpcsFile, $stackPtr) }//end if } else { $error = strtoupper($type).' statements must be defined using a colon'; - $phpcsFile->addError($error, $nextCase, 'WrongOpener'.$type); + if ($tokens[$opener]['code'] === T_SEMICOLON) { + $fix = $phpcsFile->addFixableError($error, $nextCase, 'WrongOpener'.$type); + if ($fix === true) { + $phpcsFile->fixer->replaceToken($opener, ':'); + } + } else { + // Probably a case/default statement with colon + curly braces. + $phpcsFile->addError($error, $nextCase, 'WrongOpener'.$type); + } }//end if // We only want cases from here on in. diff --git a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc index 440cf8a38a..7db00c23f9 100644 --- a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc +++ b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc @@ -609,3 +609,16 @@ switch ( $a ) { jumpOut: doSomething(); + +// Fixable semicolon as case/default scope opener. +switch ($value) { + case 'foo'; + case 'bar' /*comment*/ ; + case 'baz' ; + echo 'foo, bar, or baz'; + break; + default; + echo 'Other'; + default ; + echo 'Other'; +} diff --git a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed index ca39c76d02..c84f389ddc 100644 --- a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed +++ b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.inc.fixed @@ -604,3 +604,16 @@ switch ( $a ) { jumpOut: doSomething(); + +// Fixable semicolon as case/default scope opener. +switch ($value) { + case 'foo': + case 'bar' /*comment*/: + case 'baz': + echo 'foo, bar, or baz'; + break; + default: + echo 'Other'; + default: + echo 'Other'; +} diff --git a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.php b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.php index a292503dcc..187d9f48ce 100644 --- a/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.php +++ b/src/Standards/PSR2/Tests/ControlStructures/SwitchDeclarationUnitTest.php @@ -63,6 +63,11 @@ public function getErrorList() 541 => 1, 558 => 1, 575 => 1, + 615 => 1, + 616 => 1, + 617 => 1, + 620 => 1, + 622 => 1, ]; }//end getErrorList()