Skip to content

Fix phpcbf conflict on anonymous class bodies in ConsistentIndent#68

Merged
dereuromark merged 1 commit into
masterfrom
fix/consistent-indent-anon-class-conflict
May 28, 2026
Merged

Fix phpcbf conflict on anonymous class bodies in ConsistentIndent#68
dereuromark merged 1 commit into
masterfrom
fix/consistent-indent-anon-class-conflict

Conversation

@dereuromark
Copy link
Copy Markdown
Contributor

Summary

PhpCollective.WhiteSpace.ConsistentIndent and the bundled Generic.WhiteSpace.ScopeIndent disagree on the expected indentation of an anonymous class body when the anonymous class is passed as an argument to a multi-line function call:

return new Service(
    new class ($payload) extends Base {
        public function foo(): void {}
    },
);

The class scope is opened inside an unclosed parenthesis, so the body carries one extra continuation indent level. getExpectedIndent() only counts scope conditions, so it misses that level and dedents the body, while ScopeIndent re-indents it. phpcbf then oscillates between the two until it hits the loop limit and reports FAILED TO FIX (exit 7) — the file becomes unfixable.

Fix

Defer to ScopeIndent for anonymous class bodies — the same way closures, arrays and switch/case blocks are already skipped — via a new isInsideAnonClass() guard.

Before: phpcbf ran the full 50 loops (~75s) and reported FAILED TO FIX (a negative net fix count, the tell-tale sign of two fixers fighting).
After: the file converges in one pass (~8s), no conflict.

Tests

Added a correctly-indented anonymous-class-as-argument case to the ConsistentIndent before/after fixtures. Before this change the fixer wrongly dedented the body (fixer test red); now it is left untouched and no longer flagged.

PhpCollective.WhiteSpace.ConsistentIndent and the bundled
Generic.WhiteSpace.ScopeIndent disagreed on the expected indent of an
anonymous class body when the class is passed as an argument to a
multi-line function call, e.g.:

    return new Service(
        new class ($payload) extends Base {
            public function foo(): void {}
        },
    );

The class scope opens inside an unclosed parenthesis, so the body carries
one continuation indent level. getExpectedIndent() only counts scope
conditions and misses it, so ConsistentIndent dedented the body while
ScopeIndent re-indented it. phpcbf then oscillated until it hit the loop
limit and reported "FAILED TO FIX" (exit 7), leaving the file unfixable.

Defer to ScopeIndent for anonymous class bodies, the same way closures
and arrays are already skipped, by adding an isInsideAnonClass() guard.
@dereuromark dereuromark merged commit bfff5aa into master May 28, 2026
4 checks passed
@dereuromark dereuromark deleted the fix/consistent-indent-anon-class-conflict branch May 28, 2026 15:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant