Completed
Push — master ( 2d0943...e84d6e )
by Bill
02:22 queued 01:01
created

FinalPrivateSniff::handleProtectedVariableToken()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 4
nc 1
nop 2
1
<?php declare(strict_types = 1);
2
3
namespace Codor\Sniffs\Classes;
4
5
use PHP_CodeSniffer_Sniff;
6
use PHP_CodeSniffer_File;
7
8
/**
9
 * @SuppressWarnings(PHPMD.LongVariable)
10
 */
11
class FinalPrivateSniff implements PHP_CodeSniffer_Sniff
12
{
13
    /**
14
     * Returns the token types that this sniff is interested in.
15
     * @return array
16
     */
17
    public function register(): array
18
    {
19
        return [T_CLASS];
20
    }
21
22
    /**
23
     * Is the class marked as final?
24
     * @var boolean
25
     */
26
    protected $classIsMarkedFinal = false;
27
28
    /**
29
     * List of protected methods found.
30
     * @var array
31
     */
32
    protected $protectedMethodTokens = [];
33
34
    /**
35
     * List of protected variables found.
36
     * @var array
37
     */
38
    protected $protectedVariableTokens = [];
39
40
    /**
41
     * Processes the tokens that this sniff is interested in.
42
     *
43
     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
44
     * @param int                  $stackPtr  The position in the stack where
45
     *                                        the token was found.
46
     * @return void
47
     * @SuppressWarnings(PHPMD.UnusedLocalVariable)
48
     */
49
    public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr)
50
    {
51
        $this->classIsMarkedFinal = false;
52
        $this->protectedMethodTokens = [];
53
        $this->protectedVariableTokens = [];
54
55
        $tokens = $phpcsFile->getTokens();
56
57
        foreach ($tokens as $index => $token) {
58
            $this->handleToken($tokens, $index);
59
        }
60
61
        $this->handleErrors($phpcsFile, $stackPtr);
62
    }
63
64
    /**
65
     * Handle the incoming token.
66
     * @param  array   $tokens List of tokens.
67
     * @param  integer $index  Current token index.
68
     * @return void
69
     */
70
    protected function handleToken($tokens, $index)
71
    {
72
        $tokenType = $tokens[$index]['type'];
73
74
        if ($tokenType === 'T_FINAL') {
75
            $this->classIsMarkedFinal = true;
76
            return;
77
        }
78
79
        if (! $this->classIsMarkedFinal) {
80
            return;
81
        }
82
83
        if ($tokenType !== 'T_PROTECTED') {
84
            return;
85
        }
86
        
87
        $this->handleFoundProtectedElement($tokens, $index);
88
    }
89
90
    /**
91
     * Handles found protected method or variable within
92
     * a final class.
93
     * @param  array   $tokens List of tokens.
94
     * @param  integer $index  Current token index.
95
     * @return void
96
     */
97
    protected function handleFoundProtectedElement($tokens, $index)
98
    {
99
        $type = $tokens[$index+2]['type'];
100
101
        if ($type === 'T_VARIABLE') {
102
            $this->protectedVariableTokens[] = $tokens[$index+2];
103
            return;
104
        }
105
106
        $this->protectedMethodTokens[] = $tokens[$index+4];
107
    }
108
109
    /**
110
     * Handle any errors.
111
     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
112
     * @param int                  $stackPtr  The position in the stack where.
113
     * @return void
114
     */
115
    protected function handleErrors($phpcsFile, $stackPtr)
116
    {
117
        foreach ($this->protectedMethodTokens as $protectedMethodToken) {
118
            $this->handleProtectedMethodToken($protectedMethodToken, $phpcsFile);
119
        }
120
121
        foreach ($this->protectedVariableTokens as $protectedVariableToken) {
122
            $this->handleProtectedVariableToken($protectedVariableToken, $phpcsFile, $stackPtr);
0 ignored issues
show
Unused Code introduced by
The call to FinalPrivateSniff::handleProtectedVariableToken() has too many arguments starting with $stackPtr.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
123
        }
124
    }
125
126
    /**
127
     * Add a protected method found error.
128
     * @param  array                $token     Token data.
129
     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
130
     * @return void
131
     */
132
    protected function handleProtectedMethodToken($token, $phpcsFile)
133
    {
134
        $methodName = $token['content'];
135
        $line = $token['line'];
136
        $phpcsFile->addError("Final Class contains a protected method {$methodName} - should be private.", $line);
137
    }
138
139
    /**
140
     * Add a protected variable found error.
141
     * @param  array                $token     Token data.
142
     * @param PHP_CodeSniffer_File $phpcsFile The file where the token was found.
143
     * @return void
144
     */
145
    protected function handleProtectedVariableToken($token, $phpcsFile)
146
    {
147
        $variableName = $token['content'];
148
        $line = $token['line'];
149
        $phpcsFile->addError("Final Class contains a protected variable {$variableName} - should be private.", $line);
150
    }
151
}
152