Skip to content

Commit 2d6ca9d

Browse files
committed
Fix up array formatting.
1 parent b1ccffd commit 2d6ca9d

File tree

5 files changed

+237
-2
lines changed

5 files changed

+237
-2
lines changed
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
<?php
2+
3+
/**
4+
* MIT License
5+
* For full license information, please view the LICENSE file that was distributed with this source code.
6+
*/
7+
8+
namespace PhpCollective\Sniffs\Arrays;
9+
10+
use PHP_CodeSniffer\Files\File;
11+
use PHP_CodeSniffer\Sniffs\Sniff;
12+
13+
/**
14+
* Ensures no extra blank lines before closing brackets in arrays.
15+
*/
16+
class ArrayBracketSpacingSniff implements Sniff
17+
{
18+
/**
19+
* @inheritDoc
20+
*/
21+
public function register(): array
22+
{
23+
return [
24+
T_OPEN_SHORT_ARRAY,
25+
T_ARRAY,
26+
];
27+
}
28+
29+
/**
30+
* @inheritDoc
31+
*/
32+
public function process(File $phpcsFile, $stackPtr): void
33+
{
34+
$tokens = $phpcsFile->getTokens();
35+
36+
if ($tokens[$stackPtr]['code'] === T_ARRAY) {
37+
if (!isset($tokens[$stackPtr]['parenthesis_closer'])) {
38+
return;
39+
}
40+
$closerPtr = $tokens[$stackPtr]['parenthesis_closer'];
41+
} else {
42+
if (!isset($tokens[$stackPtr]['bracket_closer'])) {
43+
return;
44+
}
45+
$closerPtr = $tokens[$stackPtr]['bracket_closer'];
46+
}
47+
48+
// Only process multi-line arrays
49+
if ($tokens[$stackPtr]['line'] === $tokens[$closerPtr]['line']) {
50+
return;
51+
}
52+
53+
// Find the last non-empty token before the closer
54+
$lastContentPtr = $phpcsFile->findPrevious(
55+
T_WHITESPACE,
56+
$closerPtr - 1,
57+
$stackPtr,
58+
true,
59+
);
60+
61+
if ($lastContentPtr === false) {
62+
return;
63+
}
64+
65+
// Check if there are extra blank lines between last content and closer
66+
$lastContentLine = $tokens[$lastContentPtr]['line'];
67+
$closerLine = $tokens[$closerPtr]['line'];
68+
69+
// We expect the closer to be on the next line after the last content
70+
// Any extra blank lines should be removed
71+
if ($closerLine - $lastContentLine > 1) {
72+
$error = 'Extra blank lines found before array closing bracket';
73+
$fix = $phpcsFile->addFixableError($error, $closerPtr, 'ExtraBlankLineBeforeCloser');
74+
75+
if ($fix === true) {
76+
$phpcsFile->fixer->beginChangeset();
77+
78+
// Get the indentation for the closing bracket
79+
$indent = '';
80+
if ($tokens[$closerPtr]['column'] > 1) {
81+
// Get the current line's indentation
82+
$lineStart = $closerPtr;
83+
while ($lineStart > 0 && $tokens[$lineStart - 1]['line'] === $tokens[$closerPtr]['line']) {
84+
$lineStart--;
85+
}
86+
if ($lineStart < $closerPtr && $tokens[$lineStart]['code'] === T_WHITESPACE) {
87+
$indent = $tokens[$lineStart]['content'];
88+
// Remove any newlines from the indent
89+
$indent = str_replace(["\n", "\r"], '', $indent);
90+
}
91+
}
92+
93+
// Remove all tokens between last content and closer
94+
for ($i = $lastContentPtr + 1; $i < $closerPtr; $i++) {
95+
$phpcsFile->fixer->replaceToken($i, '');
96+
}
97+
98+
// Add a single newline with proper indentation after the last content
99+
$phpcsFile->fixer->addContent($lastContentPtr, "\n" . $indent);
100+
101+
$phpcsFile->fixer->endChangeset();
102+
}
103+
}
104+
}
105+
}

docs/sniffs.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# PhpCollective Code Sniffer
22

33

4-
The PhpCollectiveStrict standard contains 233 sniffs
4+
The PhpCollectiveStrict standard contains 234 sniffs
55

66
Generic (27 sniffs)
77
-------------------
@@ -48,8 +48,9 @@ PEAR (4 sniffs)
4848
- PEAR.Functions.ValidDefaultValue
4949
- PEAR.NamingConventions.ValidClassName
5050

51-
PhpCollective (80 sniffs)
51+
PhpCollective (81 sniffs)
5252
-------------------------
53+
- PhpCollective.Arrays.ArrayBracketSpacing
5354
- PhpCollective.Arrays.DisallowImplicitArrayCreation
5455
- PhpCollective.Classes.ClassFileName
5556
- PhpCollective.Classes.EnumCaseCasing
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/**
4+
* MIT License
5+
* For full license information, please view the LICENSE file that was distributed with this source code.
6+
*/
7+
8+
namespace PhpCollective\Test\PhpCollective\Sniffs\Arrays;
9+
10+
use PhpCollective\Sniffs\Arrays\ArrayBracketSpacingSniff;
11+
use PhpCollective\Test\TestCase;
12+
13+
class ArrayBracketSpacingSniffTest extends TestCase
14+
{
15+
/**
16+
* @return void
17+
*/
18+
public function testArrayBracketSpacingSniffer(): void
19+
{
20+
$this->assertSnifferFindsErrors(new ArrayBracketSpacingSniff(), 4);
21+
}
22+
23+
/**
24+
* @return void
25+
*/
26+
public function testArrayBracketSpacingFixer(): void
27+
{
28+
$this->assertSnifferCanFixErrors(new ArrayBracketSpacingSniff());
29+
}
30+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PhpCollective;
4+
5+
class FixMe
6+
{
7+
public function test(): void
8+
{
9+
// Extra blank lines before closing bracket
10+
$array1 = [
11+
'item1',
12+
'item2',
13+
'item3',
14+
];
15+
16+
// Multiple extra blank lines
17+
$array2 = [
18+
'key1' => 'value1',
19+
'key2' => 'value2',
20+
];
21+
22+
// Nested array with extra blank lines
23+
$array3 = [
24+
'contain' => [
25+
'x', 'y', 'z',
26+
'Brands', 'Styles', 'Samples',
27+
'12', '34',
28+
],
29+
];
30+
31+
// This is fine - single line array
32+
$array4 = ['a', 'b', 'c'];
33+
34+
// This is fine - no extra blank lines
35+
$array5 = [
36+
'item1',
37+
'item2',
38+
'item3',
39+
];
40+
41+
// This is fine - one blank line is acceptable
42+
$array6 = [
43+
'item1',
44+
'item2',
45+
];
46+
}
47+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace PhpCollective;
4+
5+
class FixMe
6+
{
7+
public function test(): void
8+
{
9+
// Extra blank lines before closing bracket
10+
$array1 = [
11+
'item1',
12+
'item2',
13+
'item3',
14+
15+
];
16+
17+
// Multiple extra blank lines
18+
$array2 = [
19+
'key1' => 'value1',
20+
'key2' => 'value2',
21+
22+
23+
];
24+
25+
// Nested array with extra blank lines
26+
$array3 = [
27+
'contain' => [
28+
'x', 'y', 'z',
29+
'Brands', 'Styles', 'Samples',
30+
'12', '34',
31+
32+
],
33+
];
34+
35+
// This is fine - single line array
36+
$array4 = ['a', 'b', 'c'];
37+
38+
// This is fine - no extra blank lines
39+
$array5 = [
40+
'item1',
41+
'item2',
42+
'item3',
43+
];
44+
45+
// This is fine - one blank line is acceptable
46+
$array6 = [
47+
'item1',
48+
'item2',
49+
50+
];
51+
}
52+
}

0 commit comments

Comments
 (0)