PHPCSExtra icon indicating copy to clipboard operation
PHPCSExtra copied to clipboard

[FR] Attributes: sniff to normalize spacing on the inside of attribute brackets

Open jrfnl opened this issue 3 months ago • 0 comments

Setting the scene

PHP 8.0 introduced support for attributes via the #[...] syntax. At this moment, neither PHPCS itself, nor PHPCSExtra contain any sniffs to handle the formatting of attributes.

The PER Coding Standard from FIG, since PER 2.0, outlines a set of rules for attribute formatting to comply with, so using those rules as a starting point would allow for creating an initial set of sniffs to address attribute formatting.

Proposed new sniff: Universal.Attributes.AttributeBrackets

To address these rules from PER:

Attribute names MUST immediately follow the opening attribute block indicator #[ with no space.

The closing attribute block indicator ] MUST follow the last character of the attribute name or the closing ) of its argument list, with no preceding space.

Notes for the implementation

The name and categorization of this sniff still needs a good think - it could also be something like Universal.WhiteSpace.AttributeBracketSpacing.

Sniff should probably get the following configurable properties to give users some flexibility:

  • public $spacing = 0;
  • public $allowNewLine = false;

Suggested error codes:

  • SpaceAfterOpener
  • if $spacing > 0: NoSpaceAfterOpener
  • SpaceBeforeCloser
  • if $spacing > 0: NoSpaceBeforeCloser
  • if $allowNewLine === true: BlanklineAtStart => 1 new line = okay, more than 1 is not okay
  • if $allowNewLine === true: BlanklineAtEnd => dito

When $allowNewLine would be false and if it is deemed okay not to differentiate the errors too much (bundle SpaceAfterOpener and NoSpaceAfterOpener into one error code SpaceAfterOpener), the SpacesFixer from PHPCSUtils could make it pretty straight-forward to write this sniff.

Describe the solution you'd like

A new sniff as outlined above.

The sniff should be able to flag and auto-fix the spacing on the inside of the attribute brackets.

#[AttributeName] // <= Okay for `$spacing` = 0.
#[ AttributeName ] // <= Error for `$spacing` = 0 for both the attribute opener + the closer.

#[ AttributeName ] // <= Okay for `$spacing` = 1.
#[AttributeName] // <= Error for `$spacing` = 1 for both the attribute opener + the closer.
#[   AttributeName   ] // <= Error for `$spacing` = 1 for both the attribute opener + the closer.

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

Additional context (optional)

This ticket is part of a series of tickets related to PHP attributes and is the result of a detailed analysis of the rules as outlined in PER 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.

jrfnl avatar Sep 22 '25 23:09 jrfnl