*/ public function register() { return Collections::arrayOpenTokensBC(); } /** * Processes this test, when one of its tokens is encountered. * * @since 9.2.0 * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(File $phpcsFile, $stackPtr) { if (ScannedCode::shouldRunOnOrBelow('7.3') === false) { return; } if (Context::inAttribute($phpcsFile, $stackPtr) === true) { // If the syntax is used within an attribute, it will be interpreted as a comment on PHP < 8.0, so not an issue. return; } /* * Determine the array opener & closer. */ $openClose = Arrays::getOpenClose($phpcsFile, $stackPtr); if ($openClose === false) { // Parse error, live coding or short list, not short array. return; } $opener = $openClose['opener']; $closer = $openClose['closer']; $tokens = $phpcsFile->getTokens(); $nestingLevel = 0; if (isset($tokens[($opener + 1)]['nested_parenthesis'])) { $nestingLevel = \count($tokens[($opener + 1)]['nested_parenthesis']); } $find = Collections::arrayOpenTokensBC(); $find[\T_ELLIPSIS] = \T_ELLIPSIS; $find[\T_OPEN_CURLY_BRACKET] = \T_OPEN_CURLY_BRACKET; for ($i = $opener; $i < $closer;) { $i = $phpcsFile->findNext($find, ($i + 1), $closer); if ($i === false) { return; } if (isset($tokens[$i]['bracket_closer']) === true) { // Skip over nested short arrays. These will be handled when the array opener // of the nested array is passed. $i = $tokens[$i]['bracket_closer']; continue; } if (isset($tokens[$i]['parenthesis_closer']) === true) { // Skip over nested long arrays. These will be handled when the array opener // of the nested array is passed. $i = $tokens[$i]['parenthesis_closer']; continue; } if ($tokens[$i]['code'] !== \T_ELLIPSIS) { // Shouldn't be possible. Live coding or parse error. continue; } // Ensure this is not function call variable unpacking. if (isset($tokens[$i]['nested_parenthesis']) && \count($tokens[$i]['nested_parenthesis']) > $nestingLevel ) { continue; } // Ok, found one. $nextNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, ($i + 1), null, true); $snippet = GetTokensAsString::compact($phpcsFile, $i, $nextNonEmpty, true); $phpcsFile->addError( 'Array unpacking within array declarations using the spread operator is not supported in PHP 7.3 or earlier. Found: %s', $i, 'Found', [$snippet] ); } } }