@@ -93,7 +93,7 @@ public static function findContainingOpeningBracket(File $phpcsFile, $stackPtr)
93
93
$ tokens = $ phpcsFile ->getTokens ();
94
94
if (isset ($ tokens [$ stackPtr ]['nested_parenthesis ' ])) {
95
95
/**
96
- * @var array <int|string|null >
96
+ * @var list <int|string>
97
97
*/
98
98
$ openPtrs = array_keys ($ tokens [$ stackPtr ]['nested_parenthesis ' ]);
99
99
return (int )end ($ openPtrs );
@@ -319,8 +319,22 @@ public static function findFunctionCall(File $phpcsFile, $stackPtr)
319
319
if (is_int ($ openPtr )) {
320
320
// First non-whitespace thing and see if it's a T_STRING function name
321
321
$ functionPtr = $ phpcsFile ->findPrevious (Tokens::$ emptyTokens , $ openPtr - 1 , null , true , null , true );
322
- if (is_int ($ functionPtr ) && $ tokens [$ functionPtr ]['code ' ] === T_STRING ) {
323
- return $ functionPtr ;
322
+ if (is_int ($ functionPtr )) {
323
+ $ functionTokenCode = $ tokens [$ functionPtr ]['code ' ];
324
+ // In PHPCS 4.x, function names can be T_NAME_FULLY_QUALIFIED, T_NAME_QUALIFIED, or T_NAME_RELATIVE
325
+ $ validFunctionTokens = [T_STRING ];
326
+ if (defined ('T_NAME_FULLY_QUALIFIED ' )) {
327
+ $ validFunctionTokens [] = T_NAME_FULLY_QUALIFIED ;
328
+ }
329
+ if (defined ('T_NAME_QUALIFIED ' )) {
330
+ $ validFunctionTokens [] = T_NAME_QUALIFIED ;
331
+ }
332
+ if (defined ('T_NAME_RELATIVE ' )) {
333
+ $ validFunctionTokens [] = T_NAME_RELATIVE ;
334
+ }
335
+ if (in_array ($ functionTokenCode , $ validFunctionTokens , true )) {
336
+ return $ functionPtr ;
337
+ }
324
338
}
325
339
}
326
340
return null ;
@@ -364,9 +378,6 @@ public static function findFunctionCallArguments(File $phpcsFile, $stackPtr)
364
378
if (self ::findContainingOpeningBracket ($ phpcsFile , $ nextPtr ) === $ openPtr ) {
365
379
// Comma is at our level of brackets, it's an argument delimiter.
366
380
$ range = range ($ lastArgComma + 1 , $ nextPtr - 1 );
367
- $ range = array_filter ($ range , function ($ element ) {
368
- return is_int ($ element );
369
- });
370
381
array_push ($ argPtrs , $ range );
371
382
$ lastArgComma = $ nextPtr ;
372
383
}
@@ -394,7 +405,8 @@ public static function getNextAssignPointer(File $phpcsFile, $stackPtr)
394
405
395
406
// Is the next non-whitespace an assignment?
396
407
$ nextPtr = $ phpcsFile ->findNext (Tokens::$ emptyTokens , $ stackPtr + 1 , null , true , null , true );
397
- if (is_int ($ nextPtr )
408
+ if (
409
+ is_int ($ nextPtr )
398
410
&& isset (Tokens::$ assignmentTokens [$ tokens [$ nextPtr ]['code ' ]])
399
411
// Ignore double arrow to prevent triggering on `foreach ( $array as $k => $v )`.
400
412
&& $ tokens [$ nextPtr ]['code ' ] !== T_DOUBLE_ARROW
@@ -549,6 +561,16 @@ public static function findVariableScopeExceptArrowFunctions(File $phpcsFile, $s
549
561
T_HEREDOC ,
550
562
T_STRING ,
551
563
];
564
+ // In PHPCS 4.x, function names can be T_NAME_FULLY_QUALIFIED, T_NAME_QUALIFIED, or T_NAME_RELATIVE
565
+ if (defined ('T_NAME_FULLY_QUALIFIED ' )) {
566
+ $ allowedTypes [] = T_NAME_FULLY_QUALIFIED ;
567
+ }
568
+ if (defined ('T_NAME_QUALIFIED ' )) {
569
+ $ allowedTypes [] = T_NAME_QUALIFIED ;
570
+ }
571
+ if (defined ('T_NAME_RELATIVE ' )) {
572
+ $ allowedTypes [] = T_NAME_RELATIVE ;
573
+ }
552
574
if (! in_array ($ tokens [$ stackPtr ]['code ' ], $ allowedTypes , true )) {
553
575
throw new \Exception ("Cannot find variable scope for non-variable {$ tokens [$ stackPtr ]['type ' ]}" );
554
576
}
@@ -1290,7 +1312,7 @@ public static function getFunctionIndexForFunctionCallArgument(File $phpcsFile,
1290
1312
return null ;
1291
1313
}
1292
1314
/**
1293
- * @var array <int|string|null >
1315
+ * @var list <int|string>
1294
1316
*/
1295
1317
$ startingParenthesis = array_keys ($ token ['nested_parenthesis ' ]);
1296
1318
$ startOfArguments = end ($ startingParenthesis );
@@ -1681,9 +1703,30 @@ public static function getFunctionNameWithNamespace(File $phpcsFile, $stackPtr)
1681
1703
$ startOfScope = self ::findVariableScope ($ phpcsFile , $ stackPtr );
1682
1704
$ functionName = $ tokens [$ stackPtr ]['content ' ];
1683
1705
1706
+ // In PHPCS 4.x, T_NAME_FULLY_QUALIFIED, T_NAME_QUALIFIED, and T_NAME_RELATIVE
1707
+ // tokens already contain the full namespaced name, so we can return early.
1708
+ if (defined ('T_NAME_FULLY_QUALIFIED ' ) && $ tokens [$ stackPtr ]['code ' ] === T_NAME_FULLY_QUALIFIED ) {
1709
+ return $ functionName ;
1710
+ }
1711
+ if (defined ('T_NAME_QUALIFIED ' ) && $ tokens [$ stackPtr ]['code ' ] === T_NAME_QUALIFIED ) {
1712
+ return $ functionName ;
1713
+ }
1714
+ if (defined ('T_NAME_RELATIVE ' ) && $ tokens [$ stackPtr ]['code ' ] === T_NAME_RELATIVE ) {
1715
+ return $ functionName ;
1716
+ }
1717
+
1684
1718
// Move backwards from the token, collecting namespace separators and
1685
1719
// strings, until we encounter whitespace or something else.
1686
1720
$ partOfNamespace = [T_NS_SEPARATOR , T_STRING ];
1721
+ if (defined ('T_NAME_QUALIFIED ' )) {
1722
+ $ partOfNamespace [] = T_NAME_QUALIFIED ;
1723
+ }
1724
+ if (defined ('T_NAME_RELATIVE ' )) {
1725
+ $ partOfNamespace [] = T_NAME_RELATIVE ;
1726
+ }
1727
+ if (defined ('T_NAME_FULLY_QUALIFIED ' )) {
1728
+ $ partOfNamespace [] = T_NAME_FULLY_QUALIFIED ;
1729
+ }
1687
1730
for ($ i = $ stackPtr - 1 ; $ i > $ startOfScope ; $ i --) {
1688
1731
if (! in_array ($ tokens [$ i ]['code ' ], $ partOfNamespace , true )) {
1689
1732
break ;
@@ -1708,6 +1751,15 @@ private static function isTokenPossiblyPartOfTypehint(File $phpcsFile, $stackPtr
1708
1751
if ($ token ['code ' ] === 'PHPCS_T_NULLABLE ' ) {
1709
1752
return true ;
1710
1753
}
1754
+ if (defined ('T_NAME_QUALIFIED ' ) && $ token ['code ' ] === T_NAME_QUALIFIED ) {
1755
+ return true ;
1756
+ }
1757
+ if (defined ('T_NAME_RELATIVE ' ) && $ token ['code ' ] === T_NAME_RELATIVE ) {
1758
+ return true ;
1759
+ }
1760
+ if (defined ('T_NAME_FULLY_QUALIFIED ' ) && $ token ['code ' ] === T_NAME_FULLY_QUALIFIED ) {
1761
+ return true ;
1762
+ }
1711
1763
if ($ token ['code ' ] === T_NS_SEPARATOR ) {
1712
1764
return true ;
1713
1765
}
0 commit comments