SingleLineArrayWhitespaceSniff.php
Namespace
SlevomatCodingStandard\Sniffs\ArraysFile
-
vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Sniffs/ Arrays/ SingleLineArrayWhitespaceSniff.php
View source
<?php
declare (strict_types=1);
namespace SlevomatCodingStandard\Sniffs\Arrays;
use PHP_CodeSniffer\Files\File;
use PHP_CodeSniffer\Sniffs\Sniff;
use SlevomatCodingStandard\Helpers\ArrayHelper;
use SlevomatCodingStandard\Helpers\SniffSettingsHelper;
use SlevomatCodingStandard\Helpers\TokenHelper;
use function in_array;
use function sprintf;
use function str_repeat;
use const T_COMMA;
use const T_OPEN_PARENTHESIS;
use const T_WHITESPACE;
class SingleLineArrayWhitespaceSniff implements Sniff {
public const CODE_SPACE_BEFORE_COMMA = 'SpaceBeforeComma';
public const CODE_SPACE_AFTER_COMMA = 'SpaceAfterComma';
public const CODE_SPACE_AFTER_ARRAY_OPEN = 'SpaceAfterArrayOpen';
public const CODE_SPACE_BEFORE_ARRAY_CLOSE = 'SpaceBeforeArrayClose';
public const CODE_SPACE_IN_EMPTY_ARRAY = 'SpaceInEmptyArray';
/** @var int */
public $spacesAroundBrackets = 0;
/** @var bool */
public $enableEmptyArrayCheck = false;
/**
* @return array<int, (int|string)>
*/
public function register() : array {
return TokenHelper::$arrayTokenCodes;
}
/**
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
* @param int $stackPointer
*/
public function process(File $phpcsFile, $stackPointer) : int {
$this->spacesAroundBrackets = SniffSettingsHelper::normalizeInteger($this->spacesAroundBrackets);
$tokens = $phpcsFile->getTokens();
[
$arrayOpenerPointer,
$arrayCloserPointer,
] = ArrayHelper::openClosePointers($tokens[$stackPointer]);
// Check only single-line arrays.
if ($tokens[$arrayOpenerPointer]['line'] !== $tokens[$arrayCloserPointer]['line']) {
return $arrayCloserPointer;
}
$pointerContent = TokenHelper::findNextNonWhitespace($phpcsFile, $arrayOpenerPointer + 1, $arrayCloserPointer + 1);
if ($pointerContent === $arrayCloserPointer) {
// Empty array, but if the brackets aren't together, there's a problem.
if ($this->enableEmptyArrayCheck) {
$this->checkWhitespaceInEmptyArray($phpcsFile, $arrayOpenerPointer, $arrayCloserPointer);
}
// We can return here because there is nothing else to check.
// All code below can assume that the array is not empty.
return $arrayCloserPointer + 1;
}
$this->checkWhitespaceAfterOpeningBracket($phpcsFile, $arrayOpenerPointer);
$this->checkWhitespaceBeforeClosingBracket($phpcsFile, $arrayCloserPointer);
for ($i = $arrayOpenerPointer + 1; $i < $arrayCloserPointer; $i++) {
// Skip bracketed statements, like function calls.
if ($tokens[$i]['code'] === T_OPEN_PARENTHESIS) {
$i = $tokens[$i]['parenthesis_closer'];
continue;
}
// Skip nested arrays as they will be processed separately
if (in_array($tokens[$i]['code'], TokenHelper::$arrayTokenCodes, true)) {
$i = ArrayHelper::openClosePointers($tokens[$i])[1];
continue;
}
if ($tokens[$i]['code'] !== T_COMMA) {
continue;
}
// Before checking this comma, make sure we are not at the end of the array.
$next = TokenHelper::findNextNonWhitespace($phpcsFile, $i + 1, $arrayCloserPointer);
if ($next === null) {
return $arrayOpenerPointer + 1;
}
$this->checkWhitespaceBeforeComma($phpcsFile, $i);
$this->checkWhitespaceAfterComma($phpcsFile, $i);
}
return $arrayOpenerPointer + 1;
}
private function checkWhitespaceInEmptyArray(File $phpcsFile, int $arrayStart, int $arrayEnd) : void {
if ($arrayEnd - $arrayStart === 1) {
return;
}
$error = 'Empty array declaration must have no space between the parentheses.';
$fix = $phpcsFile->addFixableError($error, $arrayStart, self::CODE_SPACE_IN_EMPTY_ARRAY);
if (!$fix) {
return;
}
$phpcsFile->fixer
->replaceToken($arrayStart + 1, '');
}
private function checkWhitespaceAfterOpeningBracket(File $phpcsFile, int $arrayStart) : void {
$tokens = $phpcsFile->getTokens();
$whitespacePointer = $arrayStart + 1;
$spaceLength = 0;
if ($tokens[$whitespacePointer]['code'] === T_WHITESPACE) {
$spaceLength = $tokens[$whitespacePointer]['length'];
}
if ($spaceLength === $this->spacesAroundBrackets) {
return;
}
$error = sprintf('Expected %d spaces after array opening bracket, %d found.', $this->spacesAroundBrackets, $spaceLength);
$fix = $phpcsFile->addFixableError($error, $arrayStart, self::CODE_SPACE_AFTER_ARRAY_OPEN);
if (!$fix) {
return;
}
if ($spaceLength === 0) {
$phpcsFile->fixer
->addContent($arrayStart, str_repeat(' ', $this->spacesAroundBrackets));
}
else {
$phpcsFile->fixer
->replaceToken($whitespacePointer, str_repeat(' ', $this->spacesAroundBrackets));
}
}
private function checkWhitespaceBeforeClosingBracket(File $phpcsFile, int $arrayEnd) : void {
$tokens = $phpcsFile->getTokens();
$whitespacePointer = $arrayEnd - 1;
$spaceLength = 0;
if ($tokens[$whitespacePointer]['code'] === T_WHITESPACE) {
$spaceLength = $tokens[$whitespacePointer]['length'];
}
if ($spaceLength === $this->spacesAroundBrackets) {
return;
}
$error = sprintf('Expected %d spaces before array closing bracket, %d found.', $this->spacesAroundBrackets, $spaceLength);
$fix = $phpcsFile->addFixableError($error, $arrayEnd, self::CODE_SPACE_BEFORE_ARRAY_CLOSE);
if (!$fix) {
return;
}
if ($spaceLength === 0) {
$phpcsFile->fixer
->addContentBefore($arrayEnd, str_repeat(' ', $this->spacesAroundBrackets));
}
else {
$phpcsFile->fixer
->replaceToken($whitespacePointer, str_repeat(' ', $this->spacesAroundBrackets));
}
}
private function checkWhitespaceBeforeComma(File $phpcsFile, int $comma) : void {
$tokens = $phpcsFile->getTokens();
if ($tokens[$comma - 1]['code'] !== T_WHITESPACE) {
return;
}
if ($tokens[$comma - 2]['code'] === T_COMMA) {
return;
}
$error = sprintf('Expected 0 spaces between "%s" and comma, %d found.', $tokens[$comma - 2]['content'], $tokens[$comma - 1]['length']);
$fix = $phpcsFile->addFixableError($error, $comma, self::CODE_SPACE_BEFORE_COMMA);
if (!$fix) {
return;
}
$phpcsFile->fixer
->replaceToken($comma - 1, '');
}
private function checkWhitespaceAfterComma(File $phpcsFile, int $comma) : void {
$tokens = $phpcsFile->getTokens();
if ($tokens[$comma + 1]['code'] !== T_WHITESPACE) {
$error = sprintf('Expected 1 space between comma and "%s", 0 found.', $tokens[$comma + 1]['content']);
$fix = $phpcsFile->addFixableError($error, $comma, self::CODE_SPACE_AFTER_COMMA);
if ($fix) {
$phpcsFile->fixer
->addContent($comma, ' ');
}
return;
}
$spaceLength = $tokens[$comma + 1]['length'];
if ($spaceLength === 1) {
return;
}
$error = sprintf('Expected 1 space between comma and "%s", %d found.', $tokens[$comma + 2]['content'], $spaceLength);
$fix = $phpcsFile->addFixableError($error, $comma, self::CODE_SPACE_AFTER_COMMA);
if (!$fix) {
return;
}
$phpcsFile->fixer
->replaceToken($comma + 1, ' ');
}
}
Classes
Title | Deprecated | Summary |
---|---|---|
SingleLineArrayWhitespaceSniff |