Skip to content

Commit 96274aa

Browse files
committed
Use the same technique for finding list assignments as phpcs might
See squizlabs/PHP_CodeSniffer#3632
1 parent 459c69b commit 96274aa

File tree

1 file changed

+68
-17
lines changed

1 file changed

+68
-17
lines changed

VariableAnalysis/Lib/Helpers.php

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -654,7 +654,70 @@ public static function getArrowFunctionOpenClose(File $phpcsFile, $stackPtr)
654654
}
655655

656656
/**
657-
* Return a list of indices for variables assigned within a list assignment
657+
* Determine if a token is a list opener for list assignment/destructuring.
658+
*
659+
* The index provided can be either the opening square brace of a short list
660+
* assignment like the first character of `[$a] = $b;` or the `list` token of
661+
* an expression like `list($a) = $b;` or the opening parenthesis of that
662+
* expression.
663+
*
664+
* @param File $phpcsFile
665+
* @param int $listOpenerIndex
666+
*
667+
* @return bool
668+
*/
669+
private static function isListAssignment(File $phpcsFile, $listOpenerIndex)
670+
{
671+
$tokens = $phpcsFile->getTokens();
672+
// Match `[$a] = $b;` except for when the previous token is a parenthesis.
673+
if ($tokens[$listOpenerIndex]['code'] === T_OPEN_SHORT_ARRAY) {
674+
return true;
675+
}
676+
// Match `list($a) = $b;`
677+
if ($tokens[$listOpenerIndex]['code'] === T_LIST) {
678+
return true;
679+
}
680+
681+
// If $listOpenerIndex is the open parenthesis of `list($a) = $b;`, then
682+
// match that too.
683+
if ($tokens[$listOpenerIndex]['code'] === T_OPEN_PARENTHESIS) {
684+
$previousTokenPtr = $phpcsFile->findPrevious(Tokens::$emptyTokens, $listOpenerIndex - 1, null, true);
685+
if (
686+
isset($tokens[$previousTokenPtr])
687+
&& $tokens[$previousTokenPtr]['code'] === T_LIST
688+
) {
689+
return true;
690+
}
691+
return true;
692+
}
693+
694+
// If the list opener token is a square bracket that is preceeded by a
695+
// close parenthesis that has an owner which is a scope opener, then this
696+
// is a list assignment and not an array access.
697+
//
698+
// Match `if (true) [$a] = $b;`
699+
if ($tokens[$listOpenerIndex]['code'] === T_OPEN_SQUARE_BRACKET) {
700+
$previousTokenPtr = $phpcsFile->findPrevious(Tokens::$emptyTokens, $listOpenerIndex - 1, null, true);
701+
if (
702+
isset($tokens[$previousTokenPtr])
703+
&& $tokens[$previousTokenPtr]['code'] === T_CLOSE_PARENTHESIS
704+
&& isset($tokens[$previousTokenPtr]['parenthesis_owner'])
705+
&& isset(Tokens::$scopeOpeners[$tokens[$tokens[$previousTokenPtr]['parenthesis_owner']]['code']])
706+
) {
707+
return true;
708+
}
709+
}
710+
711+
return false;
712+
}
713+
714+
/**
715+
* Return a list of indices for variables assigned within a list assignment.
716+
*
717+
* The index provided can be either the opening square brace of a short list
718+
* assignment like the first character of `[$a] = $b;` or the `list` token of
719+
* an expression like `list($a) = $b;` or the opening parenthesis of that
720+
* expression.
658721
*
659722
* @param File $phpcsFile
660723
* @param int $listOpenerIndex
@@ -666,22 +729,6 @@ public static function getListAssignments(File $phpcsFile, $listOpenerIndex)
666729
$tokens = $phpcsFile->getTokens();
667730
self::debug('getListAssignments', $listOpenerIndex, $tokens[$listOpenerIndex]);
668731

669-
// If the list opener token is preceeded by a variable or a bracket (a
670-
// multidimensional array), this is an array access and not a list
671-
// assignment.
672-
$previousStatementPtr = self::getPreviousStatementPtr($phpcsFile, $listOpenerIndex);
673-
$previousTokenPtr = $phpcsFile->findPrevious(Tokens::$emptyTokens, $listOpenerIndex - 1, $previousStatementPtr, true);
674-
$arrayAccessEvidence = [
675-
T_VARIABLE,
676-
T_CLOSE_SQUARE_BRACKET,
677-
];
678-
if (
679-
isset($tokens[$previousTokenPtr])
680-
&& in_array($tokens[$previousTokenPtr]['code'], $arrayAccessEvidence, true)
681-
) {
682-
return null;
683-
}
684-
685732
// First find the end of the list
686733
$closePtr = null;
687734
if (isset($tokens[$listOpenerIndex]['parenthesis_closer'])) {
@@ -735,6 +782,10 @@ public static function getListAssignments(File $phpcsFile, $listOpenerIndex)
735782
++$currentPtr;
736783
}
737784

785+
if (! self::isListAssignment($phpcsFile, $listOpenerIndex)) {
786+
return null;
787+
}
788+
738789
return $variablePtrs;
739790
}
740791

0 commit comments

Comments
 (0)