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
35 changes: 35 additions & 0 deletions PhpCollective/Sniffs/WhiteSpace/ConsistentIndentSniff.php
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,9 @@ public function process(File $phpcsFile, $stackPtr): void
if ($this->isInsideSwitchCase($phpcsFile, $nextToken, $tokens)) {
return;
}
if ($this->isInsideAnonClass($tokens, $nextToken)) {
return;
}
if ($tokens[$nextToken]['code'] === T_COMMENT || $tokens[$nextToken]['code'] === T_DOC_COMMENT_OPEN_TAG) {
return;
}
Expand Down Expand Up @@ -482,6 +485,38 @@ protected function isInsideSwitchCase(File $phpcsFile, int $stackPtr, array $tok
return false;
}

/**
* Check if the current position is inside an anonymous class body.
*
* Anonymous classes are frequently passed as arguments to a multi-line
* function call (e.g. `new Service(new class () extends Base { ... })`).
* In that case the class scope is opened inside an unclosed parenthesis,
* so the body carries one continuation indent level that `getExpectedIndent()`
* (which only counts scope conditions) cannot see. `Generic.WhiteSpace.ScopeIndent`
* does account for it, so flagging here produces a fixer conflict where the two
* sniffs dedent/indent the same lines forever ("FAILED TO FIX"). Defer to
* ScopeIndent for anonymous class bodies, the same way closures are skipped.
*
* @param array<int, array<string, mixed>> $tokens
* @param int $stackPtr
*
* @return bool
*/
protected function isInsideAnonClass(array $tokens, int $stackPtr): bool
{
if (empty($tokens[$stackPtr]['conditions'])) {
return false;
}

foreach ($tokens[$stackPtr]['conditions'] as $code) {
if ($code === T_ANON_CLASS) {
return true;
}
}

return false;
}

/**
* Check if the previous line is "complete" (ends with statement terminator or closing brace).
* If not, the next line might be a continuation.
Expand Down
17 changes: 17 additions & 0 deletions tests/_data/ConsistentIndent/after.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,21 @@ public function nullCoalesceShouldNotBeFlagged($params): ?int
?? $params['home_id']
?? null;
}

public function anonClassAsArgumentShouldNotBeFlagged(array $payload): object
{
return new Service(
new class ($payload) extends Base {
public function __construct(private array $payload)
{
parent::__construct();
}

public function defaultProvider(): string
{
return 'codex';
}
},
);
}
}
17 changes: 17 additions & 0 deletions tests/_data/ConsistentIndent/before.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,4 +108,21 @@ public function nullCoalesceShouldNotBeFlagged($params): ?int
?? $params['home_id']
?? null;
}

public function anonClassAsArgumentShouldNotBeFlagged(array $payload): object
{
return new Service(
new class ($payload) extends Base {
public function __construct(private array $payload)
{
parent::__construct();
}

public function defaultProvider(): string
{
return 'codex';
}
},
);
}
}
Loading