Skip to content

Add short closure (T_FN) support to Squiz.Functions.MultiLineFunctionDeclaration #1436

Description

@rodrigoprimo

Setting the scene

PER-CS 1.0 (PSR-12) requires that when a function or closure parameter list is split across multiple lines, the first parameter MUST be on the line after the opening parenthesis, and there MUST be only one parameter per line. PER-CS 2.0 extends these rules to short closures (Section 7.1):

Short closures, also known as arrow functions, MUST follow the same guidelines and principles as long closures above (...).

Squiz.Functions.MultiLineFunctionDeclaration already enforces this for function/method declarations and long closures (error codes FirstParamSpacing and OneParamPerLine), but its register() method (inherited from PEAR.Functions.FunctionDeclaration) returns only [T_FUNCTION, T_CLOSURE], not T_FN.

Proposed change

Add T_FN support to Squiz.Functions.MultiLineFunctionDeclaration so the existing FirstParamSpacing and OneParamPerLine checks (and their fixers) also apply to short closures. Two things need care:

  1. PSR-12 compatibility: this sniff is included in both the PSR12 and PSR2 rulesets, which must keep matching their specs. PSR-12 does not define short-closure formatting, so the new T_FN behaviour must be opt-in. The same kind of PER-compatibility toggle being discussed in #566 could be used here (a $per_compatible sniff property).
  2. Rules that do not apply to short closures: The sniff also enforces opening-brace placement and the closure use (...) list. Short closures have neither, so those branches must be skipped for T_FN, leaving only the parameter-list checks.

If adding this to Squiz.Functions.MultiLineFunctionDeclaration turns out to be too convoluted, I suggest a dedicated Universal.FunctionDeclarations.MultiLineArrowFunctionDeclaration sniff in PHPCSExtra that mirrors the parameter-list logic for T_FN.

Describe the solution you'd like

With the $per_compatible property set to '2.0', the sniff should flag and auto-fix the following:

// OK: single-line parameter list.
$fn = fn($a, $b) => $a + $b;

// OK: multi-line, first parameter on the next line, one per line.
$fn = fn(
    $a,
    $b,
) => $a + $b;

// Error (FirstParamSpacing): first parameter on the same line as the opening parenthesis.
$fn = fn($a,
    $b
) => $a + $b;

// Error (OneParamPerLine): more than one parameter on a line.
$fn = fn(
    $a, $b
) => $a + $b;

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