From 093ffbd32bea6dc4cbfa045316f231a34a06641a Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Sun, 4 Oct 2026 21:44:49 +0200 Subject: [PATCH] Split shared-line commas in an already-multiline array A multiline associative array could still carry a top-level comma that shared its line with the next item ("], 'attr' => ["). ArrayListItemNewline skipped multiline arrays entirely; now it breaks each such comma (Symplify ArrayItemNewliner behavior), leaving array_indentation to align them. --- .../fixer/rules/array_list_item_newline.go | 47 +++++++++++++++++-- .../rules/array_list_item_newline_test.go | 6 +++ 2 files changed, 50 insertions(+), 3 deletions(-) diff --git a/blink/internal/fixer/rules/array_list_item_newline.go b/blink/internal/fixer/rules/array_list_item_newline.go index 39bdd4b525..fcbce91066 100644 --- a/blink/internal/fixer/rules/array_list_item_newline.go +++ b/blink/internal/fixer/rules/array_list_item_newline.go @@ -37,12 +37,18 @@ func (ArrayListItemNewline) Fix(s *tokens.Stream) bool { if closeIdx < 0 || sigNext(s, open) == closeIdx { continue // empty [] } - if arrayTopLevelMultiline(s, open, closeIdx) { - continue // items already on their own lines: array_indentation aligns it - } if !arrayHasTopLevelArrow(s, open, closeIdx) { continue // plain list array: leave inline } + if arrayTopLevelMultiline(s, open, closeIdx) { + // already spread over lines, but a top-level comma may still share its + // line with the next item ("], 'attr' => ["); break each such comma and + // let array_indentation align the result + if splitTopLevelCommas(s, open, closeIdx) { + changed = true + } + continue + } // a multiline array carries a trailing comma; add it before reflowing so // the last item ends up on its own line with the comma if last := sigPrev(s, closeIdx); last > open && s.At(last).Value != "," { @@ -57,6 +63,41 @@ func (ArrayListItemNewline) Fix(s *tokens.Stream) bool { return changed } +// splitTopLevelCommas breaks every top-level comma of a multiline array onto a +// new line when it still shares its line with the next item, mirroring Symplify's +// ArrayItemNewliner. A comma already followed by a newline, by a comment, or by a +// "{" is left alone; array_indentation then aligns the inserted breaks. +func splitTopLevelCommas(s *tokens.Stream, open, closeIdx int) bool { + changed := false + for i := open + 1; i < closeIdx; i++ { + t := s.At(i) + if t.Kind != token.Punct { + continue + } + switch t.Value { + case "(", "[", "{": + if c := s.MatchForward(i); c > 0 && c < closeIdx { + i = c + } + case ",": + if i+1 < closeIdx && s.At(i+1).Kind == token.Whitespace && hasNewline(s.At(i+1).Value) { + continue // already on its own line + } + ns := nextSignificantIndex(s, i) + if ns < 0 || ns >= closeIdx { + continue // trailing comma before "]" + } + if isComment(s.At(ns)) || (s.At(ns).Kind == token.Punct && s.At(ns).Value == "{") { + continue + } + if editSlotAfter(s, i, "\n") { + changed = true + } + } + } + return changed +} + // arrayTopLevelMultiline reports whether the array already has a newline at its // own nesting level (an item on its own line). Newlines only inside a nested // element (e.g. a match block) do not count. diff --git a/blink/internal/fixer/rules/array_list_item_newline_test.go b/blink/internal/fixer/rules/array_list_item_newline_test.go index 8d32c5c82a..bbd19720dd 100644 --- a/blink/internal/fixer/rules/array_list_item_newline_test.go +++ b/blink/internal/fixer/rules/array_list_item_newline_test.go @@ -37,4 +37,10 @@ func TestArrayListItemNewline(t *testing.T) { if _, changed := apply(t, f, " 1,\n 'y' => [\n 'z' => 2,\n ], 'w' => 3,\n];") + if want := " 1,\n 'y' => [\n 'z' => 2,\n ],\n'w' => 3,\n];"; !changed || got != want { + t.Fatalf("multiline split: changed=%v got=%q", changed, got) + } }