From b6439a4fc3bdf1ffff12d387cbf568533558fe34 Mon Sep 17 00:00:00 2001 From: mscherer Date: Fri, 10 Apr 2026 16:46:00 +0200 Subject: [PATCH 1/2] Fix docblock indentation loss when fixing empty enclosing line When EmptyEnclosingLine sniff fixed empty lines after class opening brace, it removed all tokens including the newline that should remain. Combined with other fixers (like DisallowTabIndent that converts tabs to spaces), this caused the first content line (typically a docblock) to lose its indentation entirely. The fix explicitly preserves one newline after the opening brace by replacing the first token with a newline character, then removing the remaining tokens up to the content line. --- PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniff.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniff.php b/PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniff.php index b3d8077..83508a0 100644 --- a/PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniff.php +++ b/PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniff.php @@ -91,7 +91,9 @@ public function process(File $phpcsFile, $stackPtr): void if ($contentLine < $braceLine + 1) { $phpcsFile->fixer->addNewline($curlyBraceStartIndex); } else { - for ($i = $curlyBraceStartIndex + 1; $i < $beginningOfLine - 1; $i++) { + // Replace first token with newline, remove the rest + $phpcsFile->fixer->replaceToken($curlyBraceStartIndex + 1, $phpcsFile->eolChar); + for ($i = $curlyBraceStartIndex + 2; $i < $beginningOfLine; $i++) { $phpcsFile->fixer->replaceToken($i, ''); } } From 3a3917f19a72001838bcba36a83d4f7908a38dd4 Mon Sep 17 00:00:00 2001 From: mscherer Date: Fri, 10 Apr 2026 16:51:39 +0200 Subject: [PATCH 2/2] Add tests for tabs indentation preservation Adds test cases to verify that the EmptyEnclosingLine sniff correctly preserves indentation when removing empty lines after class opening braces, particularly when using tabs. --- .../EmptyEnclosingLineSniffTest.php | 27 +++++++++++++++++++ tests/_data/EmptyEnclosingLine/tabs-after.php | 15 +++++++++++ .../_data/EmptyEnclosingLine/tabs-before.php | 16 +++++++++++ 3 files changed, 58 insertions(+) create mode 100644 tests/_data/EmptyEnclosingLine/tabs-after.php create mode 100644 tests/_data/EmptyEnclosingLine/tabs-before.php diff --git a/tests/PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniffTest.php b/tests/PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniffTest.php index e3f19ce..2881894 100644 --- a/tests/PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniffTest.php +++ b/tests/PhpCollective/Sniffs/WhiteSpace/EmptyEnclosingLineSniffTest.php @@ -27,4 +27,31 @@ public function testEmptyEnclosingLineFixer(): void { $this->assertSnifferCanFixErrors(new EmptyEnclosingLineSniff()); } + + /** + * Tests that tabs are preserved when fixing empty enclosing line. + * + * @return void + */ + public function testTabsPreservedSniffer(): void + { + $this->prefix = 'tabs-'; + $this->assertSnifferFindsErrors(new EmptyEnclosingLineSniff(), 1); + $this->prefix = null; + } + + /** + * Tests fixer preserves indentation with tabs. + * + * This test verifies the fix for the bug where indentation was lost + * when removing empty lines after opening braces. + * + * @return void + */ + public function testTabsPreservedFixer(): void + { + $this->prefix = 'tabs-'; + $this->assertSnifferCanFixErrors(new EmptyEnclosingLineSniff()); + $this->prefix = null; + } } diff --git a/tests/_data/EmptyEnclosingLine/tabs-after.php b/tests/_data/EmptyEnclosingLine/tabs-after.php new file mode 100644 index 0000000..b31986a --- /dev/null +++ b/tests/_data/EmptyEnclosingLine/tabs-after.php @@ -0,0 +1,15 @@ +