Skip to content

Commit 861cdb0

Browse files
bkdotcomkukulich
authored andcommitted
Improved support for arrays in array() style
1 parent b3c64a3 commit 861cdb0

14 files changed

+228
-77
lines changed

SlevomatCodingStandard/Helpers/ArrayHelper.php

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -164,11 +164,22 @@ public static function isMultiLine(File $phpcsFile, int $pointer): bool
164164
$tokenOpener = $tokens[$pointerOpener];
165165
$tokenCloser = $tokens[$pointerCloser];
166166

167+
return $tokenOpener['line'] !== $tokenCloser['line'];
168+
}
169+
170+
/**
171+
* Test if effective tokens between open & closing tokens
172+
*/
173+
public static function isNotEmpty(File $phpcsFile, int $pointer): bool
174+
{
175+
$tokens = $phpcsFile->getTokens();
176+
$token = $tokens[$pointer];
177+
[$pointerOpener, $pointerCloser] = self::openClosePointers($token);
178+
167179
/** @var int $pointerPreviousToClose */
168180
$pointerPreviousToClose = TokenHelper::findPreviousEffective($phpcsFile, $pointerCloser - 1);
169181

170-
return $tokenOpener['line'] !== $tokenCloser['line']
171-
&& $pointerPreviousToClose !== $pointerOpener;
182+
return $pointerPreviousToClose !== $pointerOpener;
172183
}
173184

174185
/**
@@ -189,7 +200,7 @@ public static function isSortedByKey(array $keyValues): bool
189200

190201
/**
191202
* @param array<string, array<int, int|string>|int|string> $token
192-
* @return int[]
203+
* @return array{0: int, 1: int}
193204
*/
194205
public static function openClosePointers(array $token): array
195206
{

SlevomatCodingStandard/Sniffs/Arrays/MultiLineArrayEndBracketPlacementSniff.php

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,9 @@
44

55
use PHP_CodeSniffer\Files\File;
66
use PHP_CodeSniffer\Sniffs\Sniff;
7+
use SlevomatCodingStandard\Helpers\ArrayHelper;
78
use SlevomatCodingStandard\Helpers\TokenHelper;
8-
use const T_OPEN_SHORT_ARRAY;
9+
use function in_array;
910

1011
class MultiLineArrayEndBracketPlacementSniff implements Sniff
1112
{
@@ -17,42 +18,43 @@ class MultiLineArrayEndBracketPlacementSniff implements Sniff
1718
*/
1819
public function register(): array
1920
{
20-
return [T_OPEN_SHORT_ARRAY];
21+
return TokenHelper::$arrayTokenCodes;
2122
}
2223

2324
/**
2425
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
25-
* @param int $arrayStart
26+
* @param int $stackPointer
2627
*/
27-
public function process(File $phpcsFile, $arrayStart): void
28+
public function process(File $phpcsFile, $stackPointer): void
2829
{
2930
$tokens = $phpcsFile->getTokens();
3031

31-
$arrayEnd = $tokens[$arrayStart]['bracket_closer'];
32-
33-
if ($tokens[$arrayStart]['line'] === $tokens[$arrayEnd]['line']) {
32+
if (ArrayHelper::isMultiLine($phpcsFile, $stackPointer) === false) {
3433
return;
3534
}
3635

37-
$nextArrayStart = TokenHelper::findNextEffective($phpcsFile, $arrayStart + 1, $arrayEnd);
38-
if ($nextArrayStart === null || $tokens[$nextArrayStart]['code'] !== T_OPEN_SHORT_ARRAY) {
36+
[$arrayOpenerPointer, $arrayCloserPointer] = ArrayHelper::openClosePointers($tokens[$stackPointer]);
37+
38+
$nextEffective = TokenHelper::findNextEffective($phpcsFile, $arrayOpenerPointer + 1, $arrayCloserPointer);
39+
if ($nextEffective === null || in_array($tokens[$nextEffective]['code'], TokenHelper::$arrayTokenCodes, true) === false) {
3940
return;
4041
}
4142

42-
$nextArrayEnd = $tokens[$nextArrayStart]['bracket_closer'];
43-
$arraysStartAtSameLine = $tokens[$arrayStart]['line'] === $tokens[$nextArrayStart]['line'];
44-
$arraysEndAtSameLine = $tokens[$arrayEnd]['line'] === $tokens[$nextArrayEnd]['line'];
43+
[$nextPointerOpener, $nextPointerCloser] = ArrayHelper::openClosePointers($tokens[$nextEffective]);
44+
45+
$arraysStartAtSameLine = $tokens[$arrayOpenerPointer]['line'] === $tokens[$nextPointerOpener]['line'];
46+
$arraysEndAtSameLine = $tokens[$arrayCloserPointer]['line'] === $tokens[$nextPointerCloser]['line'];
4547
if (!$arraysStartAtSameLine || $arraysEndAtSameLine) {
4648
return;
4749
}
4850

4951
$error = "Expected nested array to end at the same line as it's parent. Either put the nested array's end at the same line as the parent's end, or put the nested array start on it's own line.";
50-
$fix = $phpcsFile->addFixableError($error, $arrayStart, self::CODE_ARRAY_END_WRONG_PLACEMENT);
52+
$fix = $phpcsFile->addFixableError($error, $arrayOpenerPointer, self::CODE_ARRAY_END_WRONG_PLACEMENT);
5153
if (!$fix) {
5254
return;
5355
}
5456

55-
$phpcsFile->fixer->addContent($arrayStart, $phpcsFile->eolChar);
57+
$phpcsFile->fixer->addContent($arrayOpenerPointer, $phpcsFile->eolChar);
5658
}
5759

5860
}

SlevomatCodingStandard/Sniffs/Arrays/SingleLineArrayWhitespaceSniff.php

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,14 @@
44

55
use PHP_CodeSniffer\Files\File;
66
use PHP_CodeSniffer\Sniffs\Sniff;
7+
use SlevomatCodingStandard\Helpers\ArrayHelper;
78
use SlevomatCodingStandard\Helpers\SniffSettingsHelper;
89
use SlevomatCodingStandard\Helpers\TokenHelper;
10+
use function in_array;
911
use function sprintf;
1012
use function str_repeat;
1113
use const T_COMMA;
1214
use const T_OPEN_PARENTHESIS;
13-
use const T_OPEN_SHORT_ARRAY;
1415
use const T_WHITESPACE;
1516

1617
class SingleLineArrayWhitespaceSniff implements Sniff
@@ -33,7 +34,7 @@ class SingleLineArrayWhitespaceSniff implements Sniff
3334
*/
3435
public function register(): array
3536
{
36-
return [T_OPEN_SHORT_ARRAY];
37+
return TokenHelper::$arrayTokenCodes;
3738
}
3839

3940
/**
@@ -46,30 +47,29 @@ public function process(File $phpcsFile, $stackPointer): int
4647

4748
$tokens = $phpcsFile->getTokens();
4849

49-
$arrayStart = $stackPointer;
50-
$arrayEnd = $tokens[$stackPointer]['bracket_closer'];
50+
[$arrayOpenerPointer, $arrayCloserPointer] = ArrayHelper::openClosePointers($tokens[$stackPointer]);
5151

5252
// Check only single-line arrays.
53-
if ($tokens[$arrayStart]['line'] !== $tokens[$arrayEnd]['line']) {
54-
return $arrayEnd;
53+
if ($tokens[$arrayOpenerPointer]['line'] !== $tokens[$arrayCloserPointer]['line']) {
54+
return $arrayCloserPointer;
5555
}
5656

57-
$content = TokenHelper::findNextNonWhitespace($phpcsFile, $arrayStart + 1, $arrayEnd + 1);
58-
if ($content === $arrayEnd) {
57+
$pointerContent = TokenHelper::findNextNonWhitespace($phpcsFile, $arrayOpenerPointer + 1, $arrayCloserPointer + 1);
58+
if ($pointerContent === $arrayCloserPointer) {
5959
// Empty array, but if the brackets aren't together, there's a problem.
6060
if ($this->enableEmptyArrayCheck) {
61-
$this->checkWhitespaceInEmptyArray($phpcsFile, $arrayStart, $arrayEnd);
61+
$this->checkWhitespaceInEmptyArray($phpcsFile, $arrayOpenerPointer, $arrayCloserPointer);
6262
}
6363

6464
// We can return here because there is nothing else to check.
6565
// All code below can assume that the array is not empty.
66-
return $arrayEnd + 1;
66+
return $arrayCloserPointer + 1;
6767
}
6868

69-
$this->checkWhitespaceAfterOpeningBracket($phpcsFile, $arrayStart);
70-
$this->checkWhitespaceBeforeClosingBracket($phpcsFile, $arrayEnd);
69+
$this->checkWhitespaceAfterOpeningBracket($phpcsFile, $arrayOpenerPointer);
70+
$this->checkWhitespaceBeforeClosingBracket($phpcsFile, $arrayCloserPointer);
7171

72-
for ($i = $arrayStart + 1; $i < $arrayEnd; $i++) {
72+
for ($i = $arrayOpenerPointer + 1; $i < $arrayCloserPointer; $i++) {
7373
// Skip bracketed statements, like function calls.
7474
if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS) {
7575
$i = $tokens[$i]['parenthesis_closer'];
@@ -78,8 +78,8 @@ public function process(File $phpcsFile, $stackPointer): int
7878
}
7979

8080
// Skip nested arrays as they will be processed separately
81-
if ($tokens[$i]['code'] === T_OPEN_SHORT_ARRAY) {
82-
$i = $tokens[$i]['bracket_closer'];
81+
if (in_array($tokens[$i]['code'], TokenHelper::$arrayTokenCodes, true)) {
82+
$i = ArrayHelper::openClosePointers($tokens[$i])[1];
8383

8484
continue;
8585
}
@@ -89,16 +89,16 @@ public function process(File $phpcsFile, $stackPointer): int
8989
}
9090

9191
// Before checking this comma, make sure we are not at the end of the array.
92-
$next = TokenHelper::findNextNonWhitespace($phpcsFile, $i + 1, $arrayEnd);
92+
$next = TokenHelper::findNextNonWhitespace($phpcsFile, $i + 1, $arrayCloserPointer);
9393
if ($next === null) {
94-
return $arrayStart + 1;
94+
return $arrayOpenerPointer + 1;
9595
}
9696

9797
$this->checkWhitespaceBeforeComma($phpcsFile, $i);
9898
$this->checkWhitespaceAfterComma($phpcsFile, $i);
9999
}
100100

101-
return $arrayStart + 1;
101+
return $arrayOpenerPointer + 1;
102102
}
103103

104104
private function checkWhitespaceInEmptyArray(File $phpcsFile, int $arrayStart, int $arrayEnd): void

SlevomatCodingStandard/Sniffs/Arrays/TrailingArrayCommaSniff.php

Lines changed: 9 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,13 @@
44

55
use PHP_CodeSniffer\Files\File;
66
use PHP_CodeSniffer\Sniffs\Sniff;
7+
use SlevomatCodingStandard\Helpers\ArrayHelper;
78
use SlevomatCodingStandard\Helpers\SniffSettingsHelper;
89
use SlevomatCodingStandard\Helpers\TokenHelper;
910
use function in_array;
10-
use const T_ARRAY;
1111
use const T_COMMA;
1212
use const T_END_HEREDOC;
1313
use const T_END_NOWDOC;
14-
use const T_OPEN_SHORT_ARRAY;
1514

1615
class TrailingArrayCommaSniff implements Sniff
1716
{
@@ -26,10 +25,7 @@ class TrailingArrayCommaSniff implements Sniff
2625
*/
2726
public function register(): array
2827
{
29-
return [
30-
T_OPEN_SHORT_ARRAY,
31-
T_ARRAY,
32-
];
28+
return TokenHelper::$arrayTokenCodes;
3329
}
3430

3531
/**
@@ -41,29 +37,21 @@ public function process(File $phpcsFile, $stackPointer): void
4137
$this->enableAfterHeredoc = SniffSettingsHelper::isEnabledByPhpVersion($this->enableAfterHeredoc, 70300);
4238

4339
$tokens = $phpcsFile->getTokens();
44-
$token = $tokens[$stackPointer];
45-
$isShortArray = $token['code'] === T_OPEN_SHORT_ARRAY;
46-
$pointerOpener = $isShortArray
47-
? $token['bracket_opener']
48-
: $token['parenthesis_opener'];
49-
$pointerCloser = $isShortArray
50-
? $token['bracket_closer']
51-
: $token['parenthesis_closer'];
52-
$tokenOpener = $tokens[$pointerOpener];
53-
$tokenCloser = $tokens[$pointerCloser];
54-
55-
if ($tokenOpener['line'] === $tokenCloser['line']) {
40+
41+
[$arrayOpenerPointer, $arrayCloserPointer] = ArrayHelper::openClosePointers($tokens[$stackPointer]);
42+
43+
if ($tokens[$arrayOpenerPointer]['line'] === $tokens[$arrayCloserPointer]['line']) {
5644
return;
5745
}
5846

5947
/** @var int $pointerPreviousToClose */
60-
$pointerPreviousToClose = TokenHelper::findPreviousEffective($phpcsFile, $pointerCloser - 1);
48+
$pointerPreviousToClose = TokenHelper::findPreviousEffective($phpcsFile, $arrayCloserPointer - 1);
6149
$tokenPreviousToClose = $tokens[$pointerPreviousToClose];
6250

6351
if (
64-
$pointerPreviousToClose === $pointerOpener
52+
$pointerPreviousToClose === $arrayOpenerPointer
6553
|| $tokenPreviousToClose['code'] === T_COMMA
66-
|| $tokenCloser['line'] === $tokenPreviousToClose['line']
54+
|| $tokens[$arrayCloserPointer]['line'] === $tokenPreviousToClose['line']
6755
) {
6856
return;
6957
}

0 commit comments

Comments
 (0)