Conditions | 49 |
Paths | 48 |
Total Lines | 250 |
Code Lines | 146 |
Lines | 0 |
Ratio | 0 % |
Changes | 0 |
Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.
For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.
Commonly applied refactorings include:
If many parameters/temporary variables are present:
1 | <?php |
||
117 | public static function getFunctionCalls($source, $line, $function) |
||
118 | { |
||
119 | static $up = array( |
||
120 | '(' => true, |
||
121 | '[' => true, |
||
122 | '{' => true, |
||
123 | T_CURLY_OPEN => true, |
||
124 | T_DOLLAR_OPEN_CURLY_BRACES => true, |
||
125 | ); |
||
126 | static $down = array( |
||
127 | ')' => true, |
||
128 | ']' => true, |
||
129 | '}' => true, |
||
130 | ); |
||
131 | static $modifiers = array( |
||
132 | '!' => true, |
||
133 | '@' => true, |
||
134 | '~' => true, |
||
135 | '+' => true, |
||
136 | '-' => true, |
||
137 | ); |
||
138 | static $identifier = array( |
||
139 | T_DOUBLE_COLON => true, |
||
140 | T_STRING => true, |
||
141 | T_NS_SEPARATOR => true, |
||
142 | ); |
||
143 | |||
144 | if (KINT_PHP56) { |
||
145 | self::$operator[T_POW] = true; |
||
146 | self::$operator[T_POW_EQUAL] = true; |
||
147 | } |
||
148 | |||
149 | if (KINT_PHP70) { |
||
150 | self::$operator[T_SPACESHIP] = true; |
||
151 | } |
||
152 | |||
153 | if (KINT_PHP74) { |
||
154 | self::$operator[T_COALESCE_EQUAL] = true; |
||
155 | } |
||
156 | |||
157 | $tokens = \token_get_all($source); |
||
158 | $cursor = 1; |
||
159 | $function_calls = array(); |
||
160 | /** @var array<int, null|array|string> Performance optimization preventing backwards loops */ |
||
161 | $prev_tokens = array(null, null, null); |
||
162 | |||
163 | if (\is_array($function)) { |
||
164 | $class = \explode('\\', $function[0]); |
||
165 | $class = \strtolower(\end($class)); |
||
166 | $function = \strtolower($function[1]); |
||
167 | } else { |
||
168 | $class = null; |
||
169 | $function = \strtolower($function); |
||
170 | } |
||
171 | |||
172 | // Loop through tokens |
||
173 | foreach ($tokens as $index => $token) { |
||
174 | if (!\is_array($token)) { |
||
175 | continue; |
||
176 | } |
||
177 | |||
178 | // Count newlines for line number instead of using $token[2] |
||
179 | // since certain situations (String tokens after whitespace) may |
||
180 | // not have the correct line number unless you do this manually |
||
181 | $cursor += \substr_count($token[1], "\n"); |
||
182 | if ($cursor > $line) { |
||
183 | break; |
||
184 | } |
||
185 | |||
186 | // Store the last real tokens for later |
||
187 | if (isset(self::$ignore[$token[0]])) { |
||
188 | continue; |
||
189 | } |
||
190 | |||
191 | $prev_tokens = array($prev_tokens[1], $prev_tokens[2], $token); |
||
192 | |||
193 | // Check if it's the right type to be the function we're looking for |
||
194 | if (T_STRING !== $token[0] || \strtolower($token[1]) !== $function) { |
||
195 | continue; |
||
196 | } |
||
197 | |||
198 | // Check if it's a function call |
||
199 | $nextReal = self::realTokenIndex($tokens, $index); |
||
200 | if (!isset($nextReal, $tokens[$nextReal]) || '(' !== $tokens[$nextReal]) { |
||
201 | continue; |
||
202 | } |
||
203 | |||
204 | // Check if it matches the signature |
||
205 | if (null === $class) { |
||
206 | if ($prev_tokens[1] && \in_array($prev_tokens[1][0], array(T_DOUBLE_COLON, T_OBJECT_OPERATOR), true)) { |
||
207 | continue; |
||
208 | } |
||
209 | } else { |
||
210 | if (!$prev_tokens[1] || T_DOUBLE_COLON !== $prev_tokens[1][0]) { |
||
211 | continue; |
||
212 | } |
||
213 | |||
214 | if (!$prev_tokens[0] || T_STRING !== $prev_tokens[0][0] || \strtolower($prev_tokens[0][1]) !== $class) { |
||
215 | continue; |
||
216 | } |
||
217 | } |
||
218 | |||
219 | $inner_cursor = $cursor; |
||
220 | $depth = 1; // The depth respective to the function call |
||
221 | $offset = $nextReal + 1; // The start of the function call |
||
222 | $instring = false; // Whether we're in a string or not |
||
223 | $realtokens = false; // Whether the current scope contains anything meaningful or not |
||
224 | $paramrealtokens = false; // Whether the current parameter contains anything meaningful |
||
225 | $params = array(); // All our collected parameters |
||
226 | $shortparam = array(); // The short version of the parameter |
||
227 | $param_start = $offset; // The distance to the start of the parameter |
||
228 | |||
229 | // Loop through the following tokens until the function call ends |
||
230 | while (isset($tokens[$offset])) { |
||
231 | $token = $tokens[$offset]; |
||
232 | |||
233 | // Ensure that the $inner_cursor is correct and |
||
234 | // that $token is either a T_ constant or a string |
||
235 | if (\is_array($token)) { |
||
236 | $inner_cursor += \substr_count($token[1], "\n"); |
||
237 | } |
||
238 | |||
239 | if (!isset(self::$ignore[$token[0]]) && !isset($down[$token[0]])) { |
||
240 | $paramrealtokens = $realtokens = true; |
||
241 | } |
||
242 | |||
243 | // If it's a token that makes us to up a level, increase the depth |
||
244 | if (isset($up[$token[0]])) { |
||
245 | if (1 === $depth) { |
||
246 | $shortparam[] = $token; |
||
247 | $realtokens = false; |
||
248 | } |
||
249 | |||
250 | ++$depth; |
||
251 | } elseif (isset($down[$token[0]])) { |
||
252 | --$depth; |
||
253 | |||
254 | // If this brings us down to the parameter level, and we've had |
||
255 | // real tokens since going up, fill the $shortparam with an ellipsis |
||
256 | if (1 === $depth) { |
||
257 | if ($realtokens) { |
||
258 | $shortparam[] = '...'; |
||
259 | } |
||
260 | $shortparam[] = $token; |
||
261 | } |
||
262 | } elseif ('"' === $token[0]) { |
||
263 | // Strings use the same symbol for up and down, but we can |
||
264 | // only ever be inside one string, so just use a bool for that |
||
265 | if ($instring) { |
||
266 | --$depth; |
||
267 | if (1 === $depth) { |
||
268 | $shortparam[] = '...'; |
||
269 | } |
||
270 | } else { |
||
271 | ++$depth; |
||
272 | } |
||
273 | |||
274 | $instring = !$instring; |
||
|
|||
275 | |||
276 | $shortparam[] = '"'; |
||
277 | } elseif (1 === $depth) { |
||
278 | if (',' === $token[0]) { |
||
279 | $params[] = array( |
||
280 | 'full' => \array_slice($tokens, $param_start, $offset - $param_start), |
||
281 | 'short' => $shortparam, |
||
282 | ); |
||
283 | $shortparam = array(); |
||
284 | $paramrealtokens = false; |
||
285 | $param_start = $offset + 1; |
||
286 | } elseif (T_CONSTANT_ENCAPSED_STRING === $token[0] && \strlen($token[1]) > 2) { |
||
287 | $shortparam[] = $token[1][0].'...'.$token[1][0]; |
||
288 | } else { |
||
289 | $shortparam[] = $token; |
||
290 | } |
||
291 | } |
||
292 | |||
293 | // Depth has dropped to 0 (So we've hit the closing paren) |
||
294 | if ($depth <= 0) { |
||
295 | if ($paramrealtokens) { |
||
296 | $params[] = array( |
||
297 | 'full' => \array_slice($tokens, $param_start, $offset - $param_start), |
||
298 | 'short' => $shortparam, |
||
299 | ); |
||
300 | } |
||
301 | |||
302 | break; |
||
303 | } |
||
304 | |||
305 | ++$offset; |
||
306 | } |
||
307 | |||
308 | // If we're not passed (or at) the line at the end |
||
309 | // of the function call, we're too early so skip it |
||
310 | if ($inner_cursor < $line) { |
||
311 | continue; |
||
312 | } |
||
313 | |||
314 | // Format the final output parameters |
||
315 | foreach ($params as &$param) { |
||
316 | $name = self::tokensFormatted($param['short']); |
||
317 | $expression = false; |
||
318 | foreach ($name as $token) { |
||
319 | if (self::tokenIsOperator($token)) { |
||
320 | $expression = true; |
||
321 | break; |
||
322 | } |
||
323 | } |
||
324 | |||
325 | $param = array( |
||
326 | 'name' => self::tokensToString($name), |
||
327 | 'path' => self::tokensToString(self::tokensTrim($param['full'])), |
||
328 | 'expression' => $expression, |
||
329 | ); |
||
330 | } |
||
331 | |||
332 | // Get the modifiers |
||
333 | --$index; |
||
334 | |||
335 | while (isset($tokens[$index])) { |
||
336 | if (!isset(self::$ignore[$tokens[$index][0]]) && !isset($identifier[$tokens[$index][0]])) { |
||
337 | break; |
||
338 | } |
||
339 | |||
340 | --$index; |
||
341 | } |
||
342 | |||
343 | $mods = array(); |
||
344 | |||
345 | while (isset($tokens[$index])) { |
||
346 | if (isset(self::$ignore[$tokens[$index][0]])) { |
||
347 | --$index; |
||
348 | continue; |
||
349 | } |
||
350 | |||
351 | if (isset($modifiers[$tokens[$index][0]])) { |
||
352 | $mods[] = $tokens[$index]; |
||
353 | --$index; |
||
354 | continue; |
||
355 | } |
||
356 | |||
357 | break; |
||
358 | } |
||
359 | |||
360 | $function_calls[] = array( |
||
361 | 'parameters' => $params, |
||
362 | 'modifiers' => $mods, |
||
363 | ); |
||
364 | } |
||
365 | |||
366 | return $function_calls; |
||
367 | } |
||
474 |