Chris@0
|
1 <?php
|
Chris@0
|
2 /**
|
Chris@0
|
3 * A class to find T_VARIABLE tokens.
|
Chris@0
|
4 *
|
Chris@0
|
5 * PHP version 5
|
Chris@0
|
6 *
|
Chris@0
|
7 * @category PHP
|
Chris@0
|
8 * @package PHP_CodeSniffer
|
Chris@0
|
9 * @author Greg Sherwood <gsherwood@squiz.net>
|
Chris@0
|
10 * @author Marc McIntyre <mmcintyre@squiz.net>
|
Chris@0
|
11 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
Chris@0
|
12 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
Chris@0
|
13 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
14 */
|
Chris@0
|
15
|
Chris@0
|
16 if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) {
|
Chris@0
|
17 $error = 'Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found';
|
Chris@0
|
18 throw new PHP_CodeSniffer_Exception($error);
|
Chris@0
|
19 }
|
Chris@0
|
20
|
Chris@0
|
21 /**
|
Chris@0
|
22 * A class to find T_VARIABLE tokens.
|
Chris@0
|
23 *
|
Chris@0
|
24 * This class can distinguish between normal T_VARIABLE tokens, and those tokens
|
Chris@0
|
25 * that represent class members. If a class member is encountered, then the
|
Chris@0
|
26 * processMemberVar method is called so the extending class can process it. If
|
Chris@0
|
27 * the token is found to be a normal T_VARIABLE token, then processVariable is
|
Chris@0
|
28 * called.
|
Chris@0
|
29 *
|
Chris@0
|
30 * @category PHP
|
Chris@0
|
31 * @package PHP_CodeSniffer
|
Chris@0
|
32 * @author Greg Sherwood <gsherwood@squiz.net>
|
Chris@0
|
33 * @author Marc McIntyre <mmcintyre@squiz.net>
|
Chris@0
|
34 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600)
|
Chris@0
|
35 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence
|
Chris@0
|
36 * @version Release: @package_version@
|
Chris@0
|
37 * @link http://pear.php.net/package/PHP_CodeSniffer
|
Chris@0
|
38 */
|
Chris@0
|
39 abstract class PHP_CodeSniffer_Standards_AbstractVariableSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff
|
Chris@0
|
40 {
|
Chris@0
|
41
|
Chris@0
|
42 /**
|
Chris@0
|
43 * The end token of the current function that we are in.
|
Chris@0
|
44 *
|
Chris@0
|
45 * @var int
|
Chris@0
|
46 */
|
Chris@0
|
47 private $_endFunction = -1;
|
Chris@0
|
48
|
Chris@0
|
49 /**
|
Chris@0
|
50 * TRUE if a function is currently open.
|
Chris@0
|
51 *
|
Chris@0
|
52 * @var boolean
|
Chris@0
|
53 */
|
Chris@0
|
54 private $_functionOpen = false;
|
Chris@0
|
55
|
Chris@0
|
56 /**
|
Chris@0
|
57 * The current PHP_CodeSniffer file that we are processing.
|
Chris@0
|
58 *
|
Chris@0
|
59 * @var PHP_CodeSniffer_File
|
Chris@0
|
60 */
|
Chris@0
|
61 protected $currentFile = null;
|
Chris@0
|
62
|
Chris@0
|
63
|
Chris@0
|
64 /**
|
Chris@0
|
65 * Constructs an AbstractVariableTest.
|
Chris@0
|
66 */
|
Chris@0
|
67 public function __construct()
|
Chris@0
|
68 {
|
Chris@0
|
69 $scopes = array(
|
Chris@0
|
70 T_CLASS,
|
Chris@0
|
71 T_ANON_CLASS,
|
Chris@0
|
72 T_TRAIT,
|
Chris@0
|
73 T_INTERFACE,
|
Chris@0
|
74 );
|
Chris@0
|
75
|
Chris@0
|
76 $listen = array(
|
Chris@0
|
77 T_FUNCTION,
|
Chris@0
|
78 T_VARIABLE,
|
Chris@0
|
79 T_DOUBLE_QUOTED_STRING,
|
Chris@0
|
80 T_HEREDOC,
|
Chris@0
|
81 );
|
Chris@0
|
82
|
Chris@0
|
83 parent::__construct($scopes, $listen, true);
|
Chris@0
|
84
|
Chris@0
|
85 }//end __construct()
|
Chris@0
|
86
|
Chris@0
|
87
|
Chris@0
|
88 /**
|
Chris@0
|
89 * Processes the token in the specified PHP_CodeSniffer_File.
|
Chris@0
|
90 *
|
Chris@0
|
91 * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
Chris@0
|
92 * token was found.
|
Chris@0
|
93 * @param int $stackPtr The position where the token was found.
|
Chris@0
|
94 * @param array $currScope The current scope opener token.
|
Chris@0
|
95 *
|
Chris@0
|
96 * @return void
|
Chris@0
|
97 */
|
Chris@0
|
98 protected final function processTokenWithinScope(
|
Chris@0
|
99 PHP_CodeSniffer_File $phpcsFile,
|
Chris@0
|
100 $stackPtr,
|
Chris@0
|
101 $currScope
|
Chris@0
|
102 ) {
|
Chris@0
|
103 if ($this->currentFile !== $phpcsFile) {
|
Chris@0
|
104 $this->currentFile = $phpcsFile;
|
Chris@0
|
105 $this->_functionOpen = false;
|
Chris@0
|
106 $this->_endFunction = -1;
|
Chris@0
|
107 }
|
Chris@0
|
108
|
Chris@0
|
109 $tokens = $phpcsFile->getTokens();
|
Chris@0
|
110
|
Chris@0
|
111 if ($stackPtr > $this->_endFunction) {
|
Chris@0
|
112 $this->_functionOpen = false;
|
Chris@0
|
113 }
|
Chris@0
|
114
|
Chris@0
|
115 if ($tokens[$stackPtr]['code'] === T_FUNCTION
|
Chris@0
|
116 && $this->_functionOpen === false
|
Chris@0
|
117 ) {
|
Chris@0
|
118 $this->_functionOpen = true;
|
Chris@0
|
119
|
Chris@0
|
120 $methodProps = $phpcsFile->getMethodProperties($stackPtr);
|
Chris@0
|
121
|
Chris@0
|
122 // If the function is abstract, or is in an interface,
|
Chris@0
|
123 // then set the end of the function to it's closing semicolon.
|
Chris@0
|
124 if ($methodProps['is_abstract'] === true
|
Chris@0
|
125 || $tokens[$currScope]['code'] === T_INTERFACE
|
Chris@0
|
126 ) {
|
Chris@0
|
127 $this->_endFunction
|
Chris@0
|
128 = $phpcsFile->findNext(array(T_SEMICOLON), $stackPtr);
|
Chris@0
|
129 } else {
|
Chris@0
|
130 if (isset($tokens[$stackPtr]['scope_closer']) === false) {
|
Chris@0
|
131 $error = 'Possible parse error: non-abstract method defined as abstract';
|
Chris@0
|
132 $phpcsFile->addWarning($error, $stackPtr);
|
Chris@0
|
133 return;
|
Chris@0
|
134 }
|
Chris@0
|
135
|
Chris@0
|
136 $this->_endFunction = $tokens[$stackPtr]['scope_closer'];
|
Chris@0
|
137 }
|
Chris@0
|
138 }//end if
|
Chris@0
|
139
|
Chris@0
|
140 if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING
|
Chris@0
|
141 || $tokens[$stackPtr]['code'] === T_HEREDOC
|
Chris@0
|
142 ) {
|
Chris@0
|
143 // Check to see if this string has a variable in it.
|
Chris@0
|
144 $pattern = '|(?<!\\\\)(?:\\\\{2})*\${?[a-zA-Z0-9_]+}?|';
|
Chris@0
|
145 if (preg_match($pattern, $tokens[$stackPtr]['content']) !== 0) {
|
Chris@0
|
146 $this->processVariableInString($phpcsFile, $stackPtr);
|
Chris@0
|
147 }
|
Chris@0
|
148
|
Chris@0
|
149 return;
|
Chris@0
|
150 }
|
Chris@0
|
151
|
Chris@0
|
152 if ($this->_functionOpen === true) {
|
Chris@0
|
153 if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
|
Chris@0
|
154 $this->processVariable($phpcsFile, $stackPtr);
|
Chris@0
|
155 }
|
Chris@0
|
156 } else {
|
Chris@0
|
157 // What if we assign a member variable to another?
|
Chris@0
|
158 // ie. private $_count = $this->_otherCount + 1;.
|
Chris@0
|
159 $this->processMemberVar($phpcsFile, $stackPtr);
|
Chris@0
|
160 }
|
Chris@0
|
161
|
Chris@0
|
162 }//end processTokenWithinScope()
|
Chris@0
|
163
|
Chris@0
|
164
|
Chris@0
|
165 /**
|
Chris@0
|
166 * Processes the token outside the scope in the file.
|
Chris@0
|
167 *
|
Chris@0
|
168 * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
Chris@0
|
169 * token was found.
|
Chris@0
|
170 * @param int $stackPtr The position where the token was found.
|
Chris@0
|
171 *
|
Chris@0
|
172 * @return void
|
Chris@0
|
173 */
|
Chris@0
|
174 protected final function processTokenOutsideScope(
|
Chris@0
|
175 PHP_CodeSniffer_File $phpcsFile,
|
Chris@0
|
176 $stackPtr
|
Chris@0
|
177 ) {
|
Chris@0
|
178 $tokens = $phpcsFile->getTokens();
|
Chris@0
|
179 // These variables are not member vars.
|
Chris@0
|
180 if ($tokens[$stackPtr]['code'] === T_VARIABLE) {
|
Chris@0
|
181 $this->processVariable($phpcsFile, $stackPtr);
|
Chris@0
|
182 } else if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING
|
Chris@0
|
183 || $tokens[$stackPtr]['code'] === T_HEREDOC
|
Chris@0
|
184 ) {
|
Chris@0
|
185 // Check to see if this string has a variable in it.
|
Chris@0
|
186 $pattern = '|(?<!\\\\)(?:\\\\{2})*\${?[a-zA-Z0-9_]+}?|';
|
Chris@0
|
187 if (preg_match($pattern, $tokens[$stackPtr]['content']) !== 0) {
|
Chris@0
|
188 $this->processVariableInString($phpcsFile, $stackPtr);
|
Chris@0
|
189 }
|
Chris@0
|
190 }
|
Chris@0
|
191
|
Chris@0
|
192 }//end processTokenOutsideScope()
|
Chris@0
|
193
|
Chris@0
|
194
|
Chris@0
|
195 /**
|
Chris@0
|
196 * Called to process class member vars.
|
Chris@0
|
197 *
|
Chris@0
|
198 * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
Chris@0
|
199 * token was found.
|
Chris@0
|
200 * @param int $stackPtr The position where the token was found.
|
Chris@0
|
201 *
|
Chris@0
|
202 * @return void
|
Chris@0
|
203 */
|
Chris@0
|
204 abstract protected function processMemberVar(
|
Chris@0
|
205 PHP_CodeSniffer_File $phpcsFile,
|
Chris@0
|
206 $stackPtr
|
Chris@0
|
207 );
|
Chris@0
|
208
|
Chris@0
|
209
|
Chris@0
|
210 /**
|
Chris@0
|
211 * Called to process normal member vars.
|
Chris@0
|
212 *
|
Chris@0
|
213 * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
Chris@0
|
214 * token was found.
|
Chris@0
|
215 * @param int $stackPtr The position where the token was found.
|
Chris@0
|
216 *
|
Chris@0
|
217 * @return void
|
Chris@0
|
218 */
|
Chris@0
|
219 abstract protected function processVariable(
|
Chris@0
|
220 PHP_CodeSniffer_File $phpcsFile,
|
Chris@0
|
221 $stackPtr
|
Chris@0
|
222 );
|
Chris@0
|
223
|
Chris@0
|
224
|
Chris@0
|
225 /**
|
Chris@0
|
226 * Called to process variables found in double quoted strings or heredocs.
|
Chris@0
|
227 *
|
Chris@0
|
228 * Note that there may be more than one variable in the string, which will
|
Chris@0
|
229 * result only in one call for the string or one call per line for heredocs.
|
Chris@0
|
230 *
|
Chris@0
|
231 * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this
|
Chris@0
|
232 * token was found.
|
Chris@0
|
233 * @param int $stackPtr The position where the double quoted
|
Chris@0
|
234 * string was found.
|
Chris@0
|
235 *
|
Chris@0
|
236 * @return void
|
Chris@0
|
237 */
|
Chris@0
|
238 abstract protected function processVariableInString(
|
Chris@0
|
239 PHP_CodeSniffer_File
|
Chris@0
|
240 $phpcsFile,
|
Chris@0
|
241 $stackPtr
|
Chris@0
|
242 );
|
Chris@0
|
243
|
Chris@0
|
244
|
Chris@0
|
245 }//end class
|