• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

PHPCSStandards / PHP_CodeSniffer / 14517893327

17 Apr 2025 02:21PM UTC coverage: 77.984% (-0.006%) from 77.99%
14517893327

push

github

web-flow
Merge pull request #1013 from PHPCSStandards/phpcs-4.0/feature/sq-2593-tokenizer-closure-use-parentheses-owner

Tokenizer: T_USE tokens for closure use now contain parenthesis information

32 of 34 new or added lines in 9 files covered. (94.12%)

1 existing line in 1 file now uncovered.

19439 of 24927 relevant lines covered (77.98%)

79.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/src/Sniffs/AbstractVariableSniff.php
1
<?php
2
/**
3
 * A class to find T_VARIABLE tokens.
4
 *
5
 * This class can distinguish between normal T_VARIABLE tokens, and those tokens
6
 * that represent class members. If a class member is encountered, then the
7
 * processMemberVar method is called so the extending class can process it. If
8
 * the token is found to be a normal T_VARIABLE token, then processVariable is
9
 * called.
10
 *
11
 * @author    Greg Sherwood <gsherwood@squiz.net>
12
 * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600)
13
 * @license   https://github.com/PHPCSStandards/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
14
 */
15

16
namespace PHP_CodeSniffer\Sniffs;
17

18
use PHP_CodeSniffer\Files\File;
19
use PHP_CodeSniffer\Util\Tokens;
20

21
abstract class AbstractVariableSniff extends AbstractScopeSniff
22
{
23

24
    /**
25
     * List of PHP Reserved variables.
26
     *
27
     * Used by various naming convention sniffs.
28
     *
29
     * @var array
30
     */
31
    protected $phpReservedVars = [
32
        '_SERVER'              => true,
33
        '_GET'                 => true,
34
        '_POST'                => true,
35
        '_REQUEST'             => true,
36
        '_SESSION'             => true,
37
        '_ENV'                 => true,
38
        '_COOKIE'              => true,
39
        '_FILES'               => true,
40
        'GLOBALS'              => true,
41
        'http_response_header' => true,
42
        'HTTP_RAW_POST_DATA'   => true,
43
        'php_errormsg'         => true,
44
    ];
45

46

47
    /**
48
     * Constructs an AbstractVariableTest.
49
     */
50
    public function __construct()
×
51
    {
52
        $scopes = Tokens::$ooScopeTokens;
×
53

54
        $listen = [
55
            T_VARIABLE,
×
56
            T_DOUBLE_QUOTED_STRING,
×
57
            T_HEREDOC,
×
58
        ];
59

60
        parent::__construct($scopes, $listen, true);
×
61

62
    }//end __construct()
63

64

65
    /**
66
     * Processes the token in the specified PHP_CodeSniffer\Files\File.
67
     *
68
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where this
69
     *                                               token was found.
70
     * @param int                         $stackPtr  The position where the token was found.
71
     * @param int                         $currScope The current scope opener token.
72
     *
73
     * @return void|int Optionally returns a stack pointer. The sniff will not be
74
     *                  called again on the current file until the returned stack
75
     *                  pointer is reached. Return `$phpcsFile->numTokens` to skip
76
     *                  the rest of the file.
77
     */
78
    final protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope)
×
79
    {
80
        $tokens = $phpcsFile->getTokens();
×
81

82
        if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING
×
83
            || $tokens[$stackPtr]['code'] === T_HEREDOC
×
84
        ) {
85
            // Check to see if this string has a variable in it.
86
            $pattern = '|(?<!\\\\)(?:\\\\{2})*\${?[a-zA-Z0-9_]+}?|';
×
87
            if (preg_match($pattern, $tokens[$stackPtr]['content']) !== 0) {
×
88
                return $this->processVariableInString($phpcsFile, $stackPtr);
×
89
            }
90

91
            return;
×
92
        }
93

94
        // If this token is nested inside a function at a deeper
95
        // level than the current OO scope that was found, it's a normal
96
        // variable and not a member var.
97
        $conditions = array_reverse($tokens[$stackPtr]['conditions'], true);
×
98
        $inFunction = false;
×
99
        foreach ($conditions as $scope => $code) {
×
100
            if (isset(Tokens::$ooScopeTokens[$code]) === true) {
×
101
                break;
×
102
            }
103

104
            if ($code === T_FUNCTION || $code === T_CLOSURE) {
×
105
                $inFunction = true;
×
106
            }
107
        }
108

109
        if ($scope !== $currScope) {
×
110
            // We found a closer scope to this token, so ignore
111
            // this particular time through the sniff. We will process
112
            // this token when this closer scope is found to avoid
113
            // duplicate checks.
114
            return;
×
115
        }
116

117
        // Just make sure this isn't a variable in a function declaration.
118
        if ($inFunction === false && isset($tokens[$stackPtr]['nested_parenthesis']) === true) {
×
119
            foreach ($tokens[$stackPtr]['nested_parenthesis'] as $opener => $closer) {
×
120
                if (isset($tokens[$opener]['parenthesis_owner']) === false) {
×
UNCOV
121
                    continue;
×
122
                }
123

124
                $owner = $tokens[$opener]['parenthesis_owner'];
×
125
                if ($tokens[$owner]['code'] === T_FUNCTION
×
126
                    || $tokens[$owner]['code'] === T_CLOSURE
×
NEW
127
                    || $tokens[$owner]['code'] === T_USE
×
128
                ) {
129
                    $inFunction = true;
×
130
                    break;
×
131
                }
132
            }
133
        }//end if
134

135
        if ($inFunction === true) {
×
136
            return $this->processVariable($phpcsFile, $stackPtr);
×
137
        } else {
138
            return $this->processMemberVar($phpcsFile, $stackPtr);
×
139
        }
140

141
    }//end processTokenWithinScope()
142

143

144
    /**
145
     * Processes the token outside the scope in the file.
146
     *
147
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where this
148
     *                                               token was found.
149
     * @param int                         $stackPtr  The position where the token was found.
150
     *
151
     * @return void|int Optionally returns a stack pointer. The sniff will not be
152
     *                  called again on the current file until the returned stack
153
     *                  pointer is reached. Return `$phpcsFile->numTokens` to skip
154
     *                  the rest of the file.
155
     */
156
    final protected function processTokenOutsideScope(File $phpcsFile, $stackPtr)
×
157
    {
158
        $tokens = $phpcsFile->getTokens();
×
159
        // These variables are not member vars.
160
        if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
×
161
            return $this->processVariable($phpcsFile, $stackPtr);
×
162
        } else if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING
×
163
            || $tokens[$stackPtr]['code'] === T_HEREDOC
×
164
        ) {
165
            // Check to see if this string has a variable in it.
166
            $pattern = '|(?<!\\\\)(?:\\\\{2})*\${?[a-zA-Z0-9_]+}?|';
×
167
            if (preg_match($pattern, $tokens[$stackPtr]['content']) !== 0) {
×
168
                return $this->processVariableInString($phpcsFile, $stackPtr);
×
169
            }
170
        }
171

172
    }//end processTokenOutsideScope()
173

174

175
    /**
176
     * Called to process class member vars.
177
     *
178
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where this
179
     *                                               token was found.
180
     * @param int                         $stackPtr  The position where the token was found.
181
     *
182
     * @return void|int Optionally returns a stack pointer. The sniff will not be
183
     *                  called again on the current file until the returned stack
184
     *                  pointer is reached. Return `$phpcsFile->numTokens` to skip
185
     *                  the rest of the file.
186
     */
187
    abstract protected function processMemberVar(File $phpcsFile, $stackPtr);
188

189

190
    /**
191
     * Called to process normal member vars.
192
     *
193
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where this
194
     *                                               token was found.
195
     * @param int                         $stackPtr  The position where the token was found.
196
     *
197
     * @return void|int Optionally returns a stack pointer. The sniff will not be
198
     *                  called again on the current file until the returned stack
199
     *                  pointer is reached. Return `$phpcsFile->numTokens` to skip
200
     *                  the rest of the file.
201
     */
202
    abstract protected function processVariable(File $phpcsFile, $stackPtr);
203

204

205
    /**
206
     * Called to process variables found in double quoted strings or heredocs.
207
     *
208
     * Note that there may be more than one variable in the string, which will
209
     * result only in one call for the string or one call per line for heredocs.
210
     *
211
     * @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where this
212
     *                                               token was found.
213
     * @param int                         $stackPtr  The position where the double quoted
214
     *                                               string was found.
215
     *
216
     * @return void|int Optionally returns a stack pointer. The sniff will not be
217
     *                  called again on the current file until the returned stack
218
     *                  pointer is reached. Return `$phpcsFile->numTokens` to skip
219
     *                  the rest of the file.
220
     */
221
    abstract protected function processVariableInString(File $phpcsFile, $stackPtr);
222

223

224
}//end class
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc