class UselessSemicolonSniff
Hierarchy
- class \SlevomatCodingStandard\Sniffs\PHP\UselessSemicolonSniff implements \PHP_CodeSniffer\Sniffs\Sniff
Expanded class hierarchy of UselessSemicolonSniff
File
-
vendor/
slevomat/ coding-standard/ SlevomatCodingStandard/ Sniffs/ PHP/ UselessSemicolonSniff.php, line 24
Namespace
SlevomatCodingStandard\Sniffs\PHPView source
class UselessSemicolonSniff implements Sniff {
public const CODE_USELESS_SEMICOLON = 'UselessSemicolon';
/**
* @return array<int, (int|string)>
*/
public function register() : array {
return [
T_SEMICOLON,
];
}
/**
* @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint
* @param int $semicolonPointer
*/
public function process(File $phpcsFile, $semicolonPointer) : void {
$this->checkMultipleSemicolons($phpcsFile, $semicolonPointer);
$this->checkSemicolonAtTheBeginningOfScope($phpcsFile, $semicolonPointer);
$this->checkSemicolonAfterScope($phpcsFile, $semicolonPointer);
}
private function checkMultipleSemicolons(File $phpcsFile, int $semicolonPointer) : void {
$tokens = $phpcsFile->getTokens();
$previousPointer = TokenHelper::findPreviousEffective($phpcsFile, $semicolonPointer - 1);
if ($tokens[$previousPointer]['code'] !== T_SEMICOLON) {
return;
}
$possibleEndScopePointer = TokenHelper::findNextLocal($phpcsFile, T_CLOSE_PARENTHESIS, $semicolonPointer + 1);
if ($possibleEndScopePointer !== null && $tokens[$possibleEndScopePointer]['parenthesis_opener'] < $semicolonPointer && array_key_exists('parenthesis_owner', $tokens[$possibleEndScopePointer]) && $tokens[$tokens[$possibleEndScopePointer]['parenthesis_owner']]['code'] === T_FOR) {
return;
}
$fix = $phpcsFile->addFixableError('Useless semicolon.', $semicolonPointer, self::CODE_USELESS_SEMICOLON);
if (!$fix) {
return;
}
$this->removeUselessSemicolon($phpcsFile, $semicolonPointer);
}
private function checkSemicolonAtTheBeginningOfScope(File $phpcsFile, int $semicolonPointer) : void {
$tokens = $phpcsFile->getTokens();
$previousPointer = TokenHelper::findPreviousEffective($phpcsFile, $semicolonPointer - 1);
if (!in_array($tokens[$previousPointer]['code'], [
T_OPEN_TAG,
T_OPEN_CURLY_BRACKET,
], true)) {
return;
}
$fix = $phpcsFile->addFixableError('Useless semicolon.', $semicolonPointer, self::CODE_USELESS_SEMICOLON);
if (!$fix) {
return;
}
$this->removeUselessSemicolon($phpcsFile, $semicolonPointer);
}
private function checkSemicolonAfterScope(File $phpcsFile, int $semicolonPointer) : void {
$tokens = $phpcsFile->getTokens();
$previousPointer = TokenHelper::findPreviousEffective($phpcsFile, $semicolonPointer - 1);
if ($tokens[$previousPointer]['code'] !== T_CLOSE_CURLY_BRACKET) {
return;
}
if (!array_key_exists('scope_condition', $tokens[$previousPointer])) {
return;
}
$scopeOpenerPointer = $tokens[$previousPointer]['scope_condition'];
if (in_array($tokens[$scopeOpenerPointer]['code'], [
T_CLOSURE,
T_FN,
T_ANON_CLASS,
T_MATCH,
], true)) {
return;
}
$fix = $phpcsFile->addFixableError('Useless semicolon.', $semicolonPointer, self::CODE_USELESS_SEMICOLON);
if (!$fix) {
return;
}
$this->removeUselessSemicolon($phpcsFile, $semicolonPointer);
}
private function removeUselessSemicolon(File $phpcsFile, int $semicolonPointer) : void {
$tokens = $phpcsFile->getTokens();
$fixStartPointer = $semicolonPointer;
do {
if ($tokens[$fixStartPointer - 1]['code'] !== T_WHITESPACE) {
break;
}
$fixStartPointer--;
if ($tokens[$fixStartPointer]['content'] === $phpcsFile->eolChar) {
break;
}
} while (true);
$fixEndPointer = $semicolonPointer;
while ($fixEndPointer < count($tokens) - 1) {
if ($tokens[$fixEndPointer + 1]['code'] !== T_WHITESPACE) {
break;
}
if ($tokens[$fixEndPointer + 1]['content'] === $phpcsFile->eolChar) {
break;
}
$fixEndPointer++;
}
$phpcsFile->fixer
->beginChangeset();
FixerHelper::removeBetweenIncluding($phpcsFile, $fixStartPointer, $fixEndPointer);
$phpcsFile->fixer
->endChangeset();
}
}
Members
Title Sort descending | Modifiers | Object type | Summary | Overriden Title |
---|---|---|---|---|
UselessSemicolonSniff::checkMultipleSemicolons | private | function | ||
UselessSemicolonSniff::checkSemicolonAfterScope | private | function | ||
UselessSemicolonSniff::checkSemicolonAtTheBeginningOfScope | private | function | ||
UselessSemicolonSniff::CODE_USELESS_SEMICOLON | public | constant | ||
UselessSemicolonSniff::process | public | function | * @phpcsSuppress SlevomatCodingStandard.TypeHints.ParameterTypeHint.MissingNativeTypeHint * |
Overrides Sniff::process |
UselessSemicolonSniff::register | public | function | * | Overrides Sniff::register |
UselessSemicolonSniff::removeUselessSemicolon | private | function |