Skip to content

Conversation

jrfnl
Copy link
Member

@jrfnl jrfnl commented Aug 30, 2025

Description

This PR actions proposal #1201 and, for the sniffs, largely backports the tests previously added in the 4.x branch via #1042, though with different sniff changes.

Note: the previously made sniff changes for #1042 in the 4.x branch will for the most part be reverted when this PR is merged up into 4.x, as they will no longer be needed.

Additionally when this PR will be merged up into the 4.x branch:

  • A different Tokenizer fix will be applied;
  • Additional tests will be added specifically related to changed functionality in the 4.x branch (T_EXIT as parenthesis owner, goto label tokenization);
  • And the tests included in this PR will be updated (for the different solution for the 4.x branch + for changed expectations for namespaced names).

Commits

Tokenizer/PHP: improved tokenization of fully qualified exit/die/true/false/null

As described in more detail in #1201, if the exit/die/true/false/null keywords were used in their fully qualified form, this was previously tokenized as T_NS_SEPARATOR + T_STRING, which was rarely, if ever, handled correctly by sniffs.

This commit now changes the tokenization of fully qualified exit/die/true/false/null to be T_NS_SEPARATOR + the relevant dedicated token, i.e T_EXIT/T_TRUE/T_FALSE or T_NULL.

Includes plenty of tests, including tests to safeguard against regressions which could be caused by this change in the "context sensitive keywords" layer and the "undo PHP 8.0+ namespaced names" layer.

Fixes #1201 (for PHPCS 3.x).

Related to #734

Generic/UnconditionalIfStatement: handle FQN true/false/null

This sniff checks for if/elseif which only contain "true" or "false", i.e. don't actually compare to anything.

This commit fixes the sniff to still function correctly when it encounters "fully qualified true/false".

Includes tests.

Generic/DisallowYodaConditions: handle FQN true/false/null

This commit fixes the sniff to handle "fully qualified true/false" the same as unqualified true/false.

Includes tests.

Generic/[Lower|Upper]CaseConstant: add tests with FQN true/false/null

These are the only two sniffs explicitly targetting true, false and null.

This commit adds some tests to safeguard these sniffs function correctly on "fully qualified true/false/null".

PEAR/ValidDefaultValue: handle FQN null

This commit fixes the sniff to handle "fully qualified null" as a default value, the same as unqualified null.

Includes tests.

Squiz/ComparisonOperatorUsage: adds tests with FQN true/false/null

Squiz/NonExecutableCode: handle FQN exit/die

This commit fixes the sniff to handle "fully qualified exit/die" the same as unqualified exit/die.

Includes tests.

Related to #734

Suggested changelog entry

Added:

  • Tokenizer support for the PHP 8.4 "exit as a function call" change.
    • The PHP 8.4 change means that exit/die can now be used as fully qualified "function calls".
    • The following sniff has been updated to handle this correctly:
      • Squiz.PHP.NonExecutableCode
        Fixed:
  • Tokenizer/PHP: fully qualified true/false/null was incorrectly tokenized as T_NS_SEPARATOR + T_STRING instead of as T_NS_SEPARATOR + T_TRUE/T_FALSE/T_NULL.
    • Additionally, the following sniffs have been updated to handle FQN true/false/null correctly:
      • Generic.CodeAnalysis.UnconditionalIfStatement
      • Generic.ControlStructures.DisallowYodaConditions
      • PEAR.Functions/ValidDefaultValue

Related issues/external references

Fixes #1201

jrfnl added 7 commits August 30, 2025 14:26
…/false/null

As described in more detail in 1201, if the `exit`/`die`/`true`/`false`/`null` keywords were used in their fully qualified form, this was previously tokenized as `T_NS_SEPARATOR` + `T_STRING`, which was rarely, if ever, handled correctly by sniffs.

This commit now changes the tokenization of fully qualified `exit`/`die`/`true`/`false`/`null` to be `T_NS_SEPARATOR` + the relevant dedicated token, i.e `T_EXIT`/`T_TRUE`/`T_FALSE` or `T_NULL`.

Includes plenty of tests, including tests to safeguard against regressions which could be caused by this change in the "context sensitive keywords" layer and the "undo PHP 8.0+ namespaced names" layer.

Fixes 1201 (for PHPCS 3.x).
This sniff checks for `if`/`elseif` which only contain "true" or "false", i.e. don't actually compare to anything.

This commit fixes the sniff to still function correctly when it encounters "fully qualified true/false".

Includes tests.
This commit fixes the sniff to handle "fully qualified true/false" the same as unqualified true/false.

Includes tests.
…`null`

These are the only two sniffs explicitly targetting `true`, `false` and `null`.

This commit adds some tests to safeguard these sniffs function correctly on "fully qualified true/false/null".
This commit fixes the sniff to handle "fully qualified null" as a default value, the same as unqualified null.

Includes tests.
This commit fixes the sniff to handle "fully qualified exit/die" the same as unqualified exit/die.

Includes tests.
@jrfnl jrfnl added this to the 3.13.3 milestone Aug 30, 2025
@jrfnl jrfnl changed the title Feature/1201 tokenizer php fqn exit die true false null Tokenizer/PHP: improved tokenization of fully qualified exit/die/true/false/null Aug 30, 2025
Copy link
Member

@fredden fredden left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have looked through these changes on a call with @jrfnl.

@jrfnl
Copy link
Member Author

jrfnl commented Sep 4, 2025

FYI: I've also opened a PR to update the Dev upgrade guide for PHPCS 4.0 in the wiki: PHPCSStandards/PHP_CodeSniffer-documentation#53

@jrfnl jrfnl merged commit df4784c into master Sep 4, 2025
93 checks passed
@jrfnl jrfnl deleted the feature/1201-tokenizer-php-fqn-exit-die-true-false-null branch September 4, 2025 13:45
@jrfnl
Copy link
Member Author

jrfnl commented Sep 4, 2025

The additional changes for 4.x have been applied in the "merge-up" commit for this PR: 5dace4b

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Proposal to fix Tokenizer issue with FQN exit/die/true/false/null
2 participants