Conversation
A long attribute was printed like an array, breaking the `#[...]` block
before the attribute name:
#[
AsCommand(
name: 'app:insertions:autorenew',
description: '...',
),
]
PER-CS 12.3 says that when an attribute's argument list is split over
several lines the attribute must be the only one in its block and the
arguments follow the multiline function call rules:
#[AsCommand(
name: 'app:insertions:autorenew',
description: '...',
)]
A block with one attribute now only ever breaks inside the argument
list. A block with several attributes stays on one line while it fits;
otherwise each attribute gets a block of its own (`#[A] #[B]` is the
same declaration as `#[A, B]`), which also gives the one-attribute-per-
line layout for Doctrine-style stacks. Inline attributes (parameters,
closures, anonymous classes) keep the newline after `]` when they
break, which puts a parameter's attribute on its own line as 12.2
requires.
`clean()` flattens a node's attribute groups so the AST comparison
treats the split blocks as equivalent.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A long attribute is printed like an array, breaking the
#[...]block before the attribute name and indenting the whole attribute:#[ AsCommand( name: 'app:insertions:autorenew', description: 'Automatically applies a new IO for carriers with an IO marked auto-renew', ), ] class ApplyAutoRenewInsertionCommand extends CommandPER-CS 12.3 says:
with the example in 12.4:
#[Complex( prop: 'val', other: 5, )]This is also the form Symfony, Doctrine and PhpStorm produce, so the current output fights every other tool in a project.
Change
printAttrGroup():A block with one attribute is
["#[", attr, "]"], so only the argument list can break —#[AsCommand(…)].A block with several attributes stays on one line while it fits (
#[Other, Stuff]); otherwise it becomes one block per attribute (#[A] #[B]is the same declaration as#[A, B]), which is what 12.3 requires and gives the familiar one-per-line Doctrine layout:Inline attributes (parameters, closures, anonymous classes) keep the existing newline after
]when they break, which puts a parameter's attribute on its own line before the parameter as 12.2 requires.clean()flattens a node's attribute groups soAST_COMPARE=1treats the split blocks as equivalent.This is a formatting change: two existing snapshots (
attributes,attributes-trail-comma) change from the array-like layout to the PER-CS one. The trailing comma from #1885 now lives inside the argument list, whereprintArgumentsListalready puts it.Tests
New
tests/attributes/attributes-per-cs.phpcovers a long single attribute on a class, property, method, enum case and constant; a multi-attribute block that fits and one that splits; attributes on parameters in a multiline list, on closures and on an anonymous class. Full suite passes withAST_COMPARE=1; the output is idempotent and passesphp -l.🤖 Generated with Claude Code