@@ -93,7 +93,7 @@ public static function findContainingOpeningBracket(File $phpcsFile, $stackPtr)
9393 $ tokens = $ phpcsFile ->getTokens ();
9494 if (isset ($ tokens [$ stackPtr ]['nested_parenthesis ' ])) {
9595 /**
96- * @var array <int|string|null >
96+ * @var list <int|string>
9797 */
9898 $ openPtrs = array_keys ($ tokens [$ stackPtr ]['nested_parenthesis ' ]);
9999 return (int )end ($ openPtrs );
@@ -319,8 +319,22 @@ public static function findFunctionCall(File $phpcsFile, $stackPtr)
319319 if (is_int ($ openPtr )) {
320320 // First non-whitespace thing and see if it's a T_STRING function name
321321 $ 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+ }
324338 }
325339 }
326340 return null ;
@@ -364,9 +378,6 @@ public static function findFunctionCallArguments(File $phpcsFile, $stackPtr)
364378 if (self ::findContainingOpeningBracket ($ phpcsFile , $ nextPtr ) === $ openPtr ) {
365379 // Comma is at our level of brackets, it's an argument delimiter.
366380 $ range = range ($ lastArgComma + 1 , $ nextPtr - 1 );
367- $ range = array_filter ($ range , function ($ element ) {
368- return is_int ($ element );
369- });
370381 array_push ($ argPtrs , $ range );
371382 $ lastArgComma = $ nextPtr ;
372383 }
@@ -394,7 +405,8 @@ public static function getNextAssignPointer(File $phpcsFile, $stackPtr)
394405
395406 // Is the next non-whitespace an assignment?
396407 $ nextPtr = $ phpcsFile ->findNext (Tokens::$ emptyTokens , $ stackPtr + 1 , null , true , null , true );
397- if (is_int ($ nextPtr )
408+ if (
409+ is_int ($ nextPtr )
398410 && isset (Tokens::$ assignmentTokens [$ tokens [$ nextPtr ]['code ' ]])
399411 // Ignore double arrow to prevent triggering on `foreach ( $array as $k => $v )`.
400412 && $ tokens [$ nextPtr ]['code ' ] !== T_DOUBLE_ARROW
@@ -549,6 +561,16 @@ public static function findVariableScopeExceptArrowFunctions(File $phpcsFile, $s
549561 T_HEREDOC ,
550562 T_STRING ,
551563 ];
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+ }
552574 if (! in_array ($ tokens [$ stackPtr ]['code ' ], $ allowedTypes , true )) {
553575 throw new \Exception ("Cannot find variable scope for non-variable {$ tokens [$ stackPtr ]['type ' ]}" );
554576 }
@@ -1290,7 +1312,7 @@ public static function getFunctionIndexForFunctionCallArgument(File $phpcsFile,
12901312 return null ;
12911313 }
12921314 /**
1293- * @var array <int|string|null >
1315+ * @var list <int|string>
12941316 */
12951317 $ startingParenthesis = array_keys ($ token ['nested_parenthesis ' ]);
12961318 $ startOfArguments = end ($ startingParenthesis );
@@ -1681,9 +1703,30 @@ public static function getFunctionNameWithNamespace(File $phpcsFile, $stackPtr)
16811703 $ startOfScope = self ::findVariableScope ($ phpcsFile , $ stackPtr );
16821704 $ functionName = $ tokens [$ stackPtr ]['content ' ];
16831705
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+
16841718 // Move backwards from the token, collecting namespace separators and
16851719 // strings, until we encounter whitespace or something else.
16861720 $ 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+ }
16871730 for ($ i = $ stackPtr - 1 ; $ i > $ startOfScope ; $ i --) {
16881731 if (! in_array ($ tokens [$ i ]['code ' ], $ partOfNamespace , true )) {
16891732 break ;
@@ -1708,6 +1751,15 @@ private static function isTokenPossiblyPartOfTypehint(File $phpcsFile, $stackPtr
17081751 if ($ token ['code ' ] === 'PHPCS_T_NULLABLE ' ) {
17091752 return true ;
17101753 }
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+ }
17111763 if ($ token ['code ' ] === T_NS_SEPARATOR ) {
17121764 return true ;
17131765 }
0 commit comments