Key is the item number; value the stack point to the first non empty token in the item. */ private $itemsWithoutKey = []; /** * Process the array declaration. * * @since 1.0.0 * * @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where the * token was found. * * @return void */ public function processArray(File $phpcsFile) { // Reset properties before processing this array. $this->hasKeys = false; $this->itemsWithoutKey = []; parent::processArray($phpcsFile); } /** * Process the tokens in an array key. * * @since 1.0.0 * * @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where the * token was found. * @param int $startPtr The stack pointer to the first token in the "key" part of * an array item. * @param int $endPtr The stack pointer to the last token in the "key" part of * an array item. * @param int $itemNr Which item in the array is being handled. * * @return void */ public function processKey(File $phpcsFile, $startPtr, $endPtr, $itemNr) { $this->hasKeys = true; // Process any previously encountered items without keys. if (empty($this->itemsWithoutKey) === false) { foreach ($this->itemsWithoutKey as $itemNr => $stackPtr) { $phpcsFile->addError( 'Inconsistent array detected. A mix of keyed and unkeyed array items is not allowed.' . ' The array item in position %d does not have an array key.', $stackPtr, 'Found', [$itemNr] ); } // No need to do this again. $this->itemsWithoutKey = []; } } /** * Process an array item without an array key. * * @since 1.0.0 * * @param \PHP_CodeSniffer\Files\File $phpcsFile The PHP_CodeSniffer file where the * token was found. * @param int $startPtr The stack pointer to the first token in the array item, * which in this case will be the first token of the array * value part of the array item. * @param int $itemNr Which item in the array is being handled. * * @return void */ public function processNoKey(File $phpcsFile, $startPtr, $itemNr) { $firstNonEmpty = $phpcsFile->findNext(Tokens::$emptyTokens, $startPtr, null, true); if ($firstNonEmpty === false || $this->tokens[$firstNonEmpty]['code'] === \T_COMMA) { // Shouldn't really be possible, but this must be a parse error (empty array item). return; } // If we already know there are keys in the array, throw an error message straight away. if ($this->hasKeys === true) { $phpcsFile->addError( 'Inconsistent array detected. A mix of keyed and unkeyed array items is not allowed.' . ' The array item in position %d does not have an array key.', $firstNonEmpty, 'Found', [$itemNr] ); } else { // Save the array item info for later in case we do encounter an array key later on in the array. $this->itemsWithoutKey[$itemNr] = $firstNonEmpty; } } }