Skip to content

Support for PHP 8.3 typed class constants #2546

@rodrigoprimo

Description

@rodrigoprimo

Typed class constants were introduced in PHP 8.3 (https://wiki.php.net/rfc/typed_class_constants). PHPCS started supporting it in version 3.9.0 (PHPCSStandards/PHP_CodeSniffer#321). Since WPCS requires PHPCS 3.13.x, with @jrfnl's help, I investigated what needed to be updated in the WPCS repository to accommodate this new syntax.

I already added safeguarding tests to two sniffs in #2547.

As far as I can check, no further changes to the sniffs are necessary, but two parts of the WPCS code still require changes. I'm creating this issue to document it.

ConstantsHelper::is_use_of_global_constant()

This helper method determines whether an arbitrary T_STRING token is the use of a global constant. It currently does not account for typed class constant syntax when checking if a variable is a class constant, leading to false positives.

For example, it incorrectly flags the following class constant as a global constant:

class MyClass {
    const string STYLESHEETPATH = 'something';
}

The method assumes that the first non-empty token before the constant name must be T_CONST for a constant to be a class constant, but this is not the case for typed class constants. The example above results in a false positive for the WordPress.WP.DiscouragedConstants as it discourages the use of the global STYLESHEETPATH constant.

A similar version of this method also exists in PHPCompatibility (https://github.com/PHPCompatibility/PHPCompatibility/blob/develop/PHPCompatibility/Helpers/MiscHelper.php#L45), and it will require similar changes. Since the version on PHPCompatibility is covered by tests, those changes will likely be implemented first in that repository and then ported here.

AbstractClassRestrictionsSniff

This abstract sniff class needs to be updated to check if the restricted classes are used as class constant types (and property types as well). Currently, it does not check for the use of the restricted classes in those places.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions