Setting the scene
PHP 7.4 introduced arrow functions (short closures) via the fn() => expression syntax. PER-CS 2.0 states in section 7.1 that the => symbol must be surrounded by a single space, and gives a placement rule for when the expression is split across multiple lines. Neither PHPCS itself nor PHPCSExtra contains a sniff for this.
Proposed new sniff: Universal.WhiteSpace.FnArrowFormatting
To address these rules from PER:
The => symbol MUST be preceded and succeeded by a space.
The expression portion MAY be split to a subsequent line. If so, the => MUST be included on the second line, and MUST be indented once.
Notes for the implementation
[T_FN_ARROW] can be the entry point for this sniff. The SpacesFixer from PHPCSUtils handles the two spacing checks.
The space-before-=> check must be skipped when the expression is validly split across multiple lines, so the two rules do not conflict. For the indentation part of the placement rule, the expected indent is the indentation of the line the fn keyword starts on plus one level, where one level is the configurable $indent property.
Suggested error codes:
SpacingBefore: incorrect spacing before the =>.
SpacingAfter: incorrect spacing after the =>.
ArrowNotOnSecondLine: wrapped expression with the => left on the first line.
ArrowIndent: wrapped => not indented one level.
The sniff should be configurable and use PER-CS values as default values:
public $spacingBefore = 1;
public $spacingAfter = 1;
public $indent = 4;
Describe the solution you'd like
A new sniff as outlined above.
The sniff should be able to flag and auto-fix the following:
// OK.
$fn = fn($x) => $x + 1;
// OK: expression wrapped, => on the second line, indented once.
$fn = fn($x)
=> $x + 1;
// Error (SpacingBefore): no space before the =>.
$fn = fn($x)=> $x + 1;
// Error (SpacingAfter): no space after the =>.
$fn = fn($x) =>$x + 1;
// Error (SpacingBefore / SpacingAfter): more than one space around the =>.
$fn = fn($x) => $x + 1;
// Error (ArrowNotOnSecondLine): expression wrapped, but => left dangling on the first line.
$fn = fn($x) =>
$x + 1;
// Error (ArrowIndent): expression wrapped, => on the second line, but not indented once.
$fn = fn($x)
=> $x + 1;
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.
Setting the scene
PHP 7.4 introduced arrow functions (short closures) via the
fn() => expressionsyntax. PER-CS 2.0 states in section 7.1 that the=>symbol must be surrounded by a single space, and gives a placement rule for when the expression is split across multiple lines. Neither PHPCS itself nor PHPCSExtra contains a sniff for this.Proposed new sniff:
Universal.WhiteSpace.FnArrowFormattingTo address these rules from PER:
Notes for the implementation
[T_FN_ARROW]can be the entry point for this sniff. TheSpacesFixerfrom PHPCSUtils handles the two spacing checks.The space-before-
=>check must be skipped when the expression is validly split across multiple lines, so the two rules do not conflict. For the indentation part of the placement rule, the expected indent is the indentation of the line thefnkeyword starts on plus one level, where one level is the configurable$indentproperty.Suggested error codes:
SpacingBefore: incorrect spacing before the=>.SpacingAfter: incorrect spacing after the=>.ArrowNotOnSecondLine: wrapped expression with the=>left on the first line.ArrowIndent: wrapped=>not indented one level.The sniff should be configurable and use PER-CS values as default values:
public $spacingBefore = 1;public $spacingAfter = 1;public $indent = 4;Describe the solution you'd like
A new sniff as outlined above.
The sniff should be able to flag and auto-fix the following:
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.