Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 15 additions & 1 deletion blink/internal/fixer/rules/binary_operator_spaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func (f BinaryOperatorSpaces) modeAt(s *tokens.Stream, i int) string {
}
return ""
}
if !legacy {
if !legacy && !binaryOperatorSpacesCompoundAssign(t.Value) {
return ""
}
if f.Default == "" {
Expand All @@ -200,6 +200,17 @@ func (f BinaryOperatorSpaces) modeAt(s *tokens.Stream, i int) string {
return f.Default
}

// binaryOperatorSpacesCompoundAssign reports the compound assignment operators.
// They are always binary, so they follow the default mode like "=", even without
// an explicit operators override (matching php-cs-fixer).
func binaryOperatorSpacesCompoundAssign(op string) bool {
switch op {
case "+=", "-=", "*=", "/=", ".=", "%=", "**=", "??=", "&=", "|=", "^=", "<<=", ">>=":
return true
}
return false
}

func binaryOperatorSpacesDefaultTarget(s *tokens.Stream, i int) bool {
t := s.At(i)
if t.Kind != token.Punct {
Expand All @@ -217,6 +228,9 @@ func binaryOperatorSpacesDefaultTarget(s *tokens.Stream, i int) bool {
// may only be spaced when explicitly configured through the operators option.
func binaryOperatorSpacesExtraTarget(s *tokens.Stream, i int) bool {
t := s.At(i)
if binaryOperatorSpacesCompoundAssign(t.Value) {
return true
}
switch t.Value {
case "**", "/", "%", "^", "<<", ">>":
return true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ func TestBinaryOperatorSpacesConfigCases(t *testing.T) {
{"collapse aligned arrow inside attribute", BinaryOperatorSpaces{}, "<?php #[X([\n 'a' => 1,\n 'bb' => 2,\n])]\nclass C {}", "<?php #[X([\n 'a' => 1,\n 'bb' => 2,\n])]\nclass C {}"},
{"arrow inside attribute string left alone", BinaryOperatorSpaces{}, "<?php #[X('a => b')]\nclass C {}", "<?php #[X('a => b')]\nclass C {}"},
{"reference assignment is spaced around =", BinaryOperatorSpaces{}, "<?php $a =&$b;", "<?php $a = &$b;"},
{"compound assign follows default without override", BinaryOperatorSpaces{}.WithConfig(map[string]any{"default": "single_space", "operators": map[string]any{"=>": "single_space", "=": "single_space"}}).(fixerRule), "<?php $url .='c'; $a .=$b;", "<?php $url .= 'c'; $a .= $b;"},
{"compound assign explicit no_space override", BinaryOperatorSpaces{}.WithConfig(map[string]any{"default": "single_space", "operators": map[string]any{".=": "no_space"}}).(fixerRule), "<?php $url .= 'c';", "<?php $url.='c';"},
}
for _, c := range cases {
got, _ := apply(t, c.rule, c.src)
Expand Down
Loading