@@ -44,7 +44,7 @@ public static function getIntOrNull($value)
44
44
public static function findContainingOpeningSquareBracket (File $ phpcsFile , $ stackPtr )
45
45
{
46
46
$ previousStatementPtr = self ::getPreviousStatementPtr ($ phpcsFile , $ stackPtr );
47
- return self ::getIntOrNull ($ phpcsFile ->findPrevious ([T_OPEN_SHORT_ARRAY ], $ stackPtr - 1 , $ previousStatementPtr ));
47
+ return self ::getIntOrNull ($ phpcsFile ->findPrevious ([T_OPEN_SHORT_ARRAY , T_OPEN_SQUARE_BRACKET ], $ stackPtr - 1 , $ previousStatementPtr ));
48
48
}
49
49
50
50
/**
@@ -654,7 +654,70 @@ public static function getArrowFunctionOpenClose(File $phpcsFile, $stackPtr)
654
654
}
655
655
656
656
/**
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.
658
721
*
659
722
* @param File $phpcsFile
660
723
* @param int $listOpenerIndex
@@ -719,6 +782,10 @@ public static function getListAssignments(File $phpcsFile, $listOpenerIndex)
719
782
++$ currentPtr ;
720
783
}
721
784
785
+ if (! self ::isListAssignment ($ phpcsFile , $ listOpenerIndex )) {
786
+ return null ;
787
+ }
788
+
722
789
return $ variablePtrs ;
723
790
}
724
791
0 commit comments