Skip to content

[FR] Backed enums: sniff to enforce spacing around the colon #443

Description

@rodrigoprimo

Setting the scene

PHP 8.1 introduced enumerations, including backed enums which declare a scalar backing type via a colon after the enum name. Neither PHPCS itself nor PHPCSExtra contains a sniff to handle the spacing around this colon.

Since PER 2.0, the PER Coding Standard defines a rule for backed enum colon spacing, which can serve as the basis for such a sniff.

Proposed new sniff: Universal.WhiteSpace.EnumColonSpacing

To address this rule from PER:

When using a backed enum, there MUST NOT be a space between the enum name and colon, and there MUST be exactly one space between the colon and the backing type.

Notes for the implementation

The backing colon is a plain T_COLON with no dedicated token to distinguish it from other colons. Registering T_ENUM is a good entry point. Then the sniff can look for the single T_COLON between the enum name and the scope_opener. The sniff bails if there is no such colon (non-backed enum).

The SpacesFixer from PHPCSUtils handles both checks via two checkAndFix() calls: one between the name and the colon, one between the colon and the backing type. This mirrors the named-argument colon spacing proposed in #440.

Suggested error codes:

  • SpacingBefore
  • SpacingAfter

The sniff should be configurable and use PER-CS values as default values:

  • public $spacingBefore = 0;
  • public $spacingAfter = 1;

Describe the solution you'd like

A new sniff as outlined above.

The sniff should be able to flag and auto-fix the following (auto-fixing is skipped when a comment sits between the tokens, as the sniff cannot safely decide where to move it):

// OK.
enum Suit: string {}

// OK (non-backed enum, ignored).
enum Suit {}

// Error: space before the colon.
enum Suit : string {}

// Error: no space after the colon.
enum Suit:string {}

// Error: more than one space after the colon.
enum Suit:   string {}

// Error: a newline after the colon.
enum Suit:
    string {}

// Error: space before and no space after.
enum Suit :string {}

Also see the examples outlined in the PER documents (rules + migration guide).

Additional context (optional)

This ticket is the result of a detailed analysis of the rules as outlined in PER-CS 2.0, as well as a critical look at what's still missing rule-wise.

  • I intend to create a pull request to implement this feature.

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