PHP close tag should be regarded as scope opener for switch case/default statements #1316
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Description
Tokenizer/PHP: PHP close tag should be regarded as scope opener for switch case/default statements
In PHP, if the statement before a PHP close tag is "unclosed", PHP will automagically insert a semi-colon before the PHP close tag when compiling the file.
As
caseanddefaultcondition statements in aswitchstructure can be "closed" with a semi-colon, this will not result in a parse error, but will be perfectly valid code.However, the practice of "closing"
case/defaultstatements with a semi-colon is deprecated as of PHP 8.5 and while looking into that deprecation, I realized that the deprecation also applies to the "implied"/automagically inserted semi-colon when acase/defaultstatement ends on a PHP close tag.Digging deeper, it turned out that a PHP close tag was not supported in PHPCS as a scope opener for
case/defaultstatements, which in turn meant that if that type of code was seen by sniffs, all sorts of false positives/negatives and potentialUndefined array key "scope_opener/closer"notices would start to get thrown.This commit fixes the tokenizer part of the issue and adds tests with a variety of scope openers for
case/defaultstatements to a number of Tokenizer related test files.PSR2/SwitchDeclaration: make implied semicolon via close tag auto-fixable
The
PSR2.ControlStructures.SwitchDeclarationsniff includes a rule/error flagging when the scope opener is not a:colon.This error was previously already made auto-fixable when the
scope_openeris a semi-colon (via PR #1161).This commit now also makes that error auto-fixable if the
scope_openeris a PHP close tag.Includes tests.
These tests also document how the sniff otherwise behaves when the code within a
switchmoves in and out of PHP a lot.Squiz/SwitchDeclaration: make implied semicolon via close tag auto-fixable
The
Squiz.ControlStructures.SwitchDeclarationsniff does not include a rule/error for the scope opener not being a:colon, though all the error messages have the presumption of the scope opener being a colon in the textual content.The sniff does have tests with a semicolon scope opener and as there is no error related to the semicolon being a scope opener, I can only presume that it was previously decided to allow that in the Squiz standard.
Considering that this is a code style sniff, it is not for this sniff to enforce PHP cross-version compatibility of code, so the PHP 8.5 deprecation is irrelevant and there is no reason to change the behaviour of the sniff for semicolon scope openers.
However, the sniff definitely did not function correctly for code moving in and out of PHP within a
switchstatement.PR #1315 was a first step towards supporting this.
This commit now adds a new error to disallow a PHP close tag as the "scope_opener" for
case/defaultstatements.The error is auto-fixable and will insert a colon before the PHP close tag as the fix.
With this additional error in place, the sniff's handling of code within a
switchmoving in and out of PHP has greatly improved.Includes tests.
Squiz/NonExecutableCode: bug fix - false positive with PHP close tag after case/default
The
Squiz.PHP.NonExecutableCodesniff would flag PHP open/close tags and indentation whitespace in inline HTML as (non-)executable code, while these tokens should be disregarded for the purposes of this sniff.Fixed now.
Includes tests.
Various sniffs: update tests to safeguard handling of case/
defaultwith PHP close tag as scope openerWith the tokenizer fix in place, these sniffs already handle these test cases correctly. The tests are just being added to safeguard this for the future.
Suggested changelog entry
Changed:
Fixed:
switchcase condition or after adefaultkeyword, was not regarded as a "scope_opener" for thecase/defaultbody.WrongOpenererror is now also auto-fixable if the wrong opener is a PHP close tag.Related issues/external references
Ref: https://wiki.php.net/rfc/deprecations_php_8_5#languagesyntax_deprecations
Types of changes