-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathFinalClassVisibilitySniff.php
85 lines (64 loc) · 2.45 KB
/
FinalClassVisibilitySniff.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
<?php
declare(strict_types = 1);
namespace InfinityloopCodingStandard\Sniffs\Classes;
use \SlevomatCodingStandard\Helpers\TokenHelper;
/**
* This sniff prohibits the use of protected variables and functions inside final class
*/
class FinalClassVisibilitySniff implements \PHP_CodeSniffer\Sniffs\Sniff
{
/**
* @var bool
*/
public $ignoreInheritingClasses = true;
public function register() : array
{
return [
\T_VARIABLE,
\T_FUNCTION,
];
}
public function process(\PHP_CodeSniffer\Files\File $phpcsFile, $variablePointer) : void
{
$tokens = $phpcsFile->getTokens();
if (\count($tokens[$variablePointer]['conditions']) === 0) {
return;
}
$classPointer = \array_keys($tokens[$variablePointer]['conditions'])[\count($tokens[$variablePointer]['conditions']) - 1];
\assert(\is_int($classPointer));
if ($tokens[$classPointer]['code'] !== \T_CLASS) {
return;
}
$classVisibilityPointer = TokenHelper::findPreviousEffective($phpcsFile, $classPointer - 1);
if ($tokens[$classVisibilityPointer]['code'] !== \T_FINAL) {
return;
}
$extendsPointer = $phpcsFile->findNext(\T_EXTENDS, $classPointer);
if ($this->ignoreInheritingClasses && $tokens[$extendsPointer]['code'] === \T_EXTENDS) {
return;
}
$visibilityPointer = $this->findVisibilityPointer($phpcsFile, $variablePointer);
if ($visibilityPointer === null || $tokens[$visibilityPointer]['code'] !== \T_PROTECTED) {
return;
}
$fix = $phpcsFile->addFixableError(
'Protected variables and functions inside final class are forbidden',
$variablePointer,
'FinalClassVisibility',
);
if (!$fix) {
return;
}
$phpcsFile->fixer->beginChangeset();
$phpcsFile->fixer->replaceToken($visibilityPointer, 'private');
$phpcsFile->fixer->endChangeset();
}
private function findVisibilityPointer(\PHP_CodeSniffer\Files\File $phpcsFile, $variablePointer) : int|bool|null
{
$visibilityPointer = $phpcsFile->findPrevious([\T_PUBLIC, \T_PROTECTED, \T_PRIVATE], $variablePointer);
if (\in_array($phpcsFile->getTokens()[$visibilityPointer]['code'], [\T_PUBLIC, \T_PROTECTED, \T_PRIVATE], true)) {
return $visibilityPointer;
}
return null;
}
}