_processed[$phpcsFile->getFilename()])) { return; } $filename = $phpcsFile->getFilename(); $this->_uses = []; $next = $stackPtr; while ($next !== false) { $this->_checkUseToken($phpcsFile, $next); $next = $phpcsFile->findNext(T_USE, $next + 1); } // Prevent multiple uses in the same file from entering $this->_processed[$phpcsFile->getFilename()] = true; foreach ($this->_uses as $scope => $used) { $defined = $sorted = array_keys($used); natcasesort($sorted); $sorted = array_values($sorted); if ($sorted === $defined) { continue; } foreach ($defined as $i => $name) { if ($name !== $sorted[$i]) { $error = 'Use classes must be in alphabetical order. Was expecting ' . $sorted[$i]; $phpcsFile->addError($error, $used[$name], 'UseInAlphabeticalOrder'); } } } } /** * Check all the use tokens in a file. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file to check. * @param int $stackPtr The index of the first use token. * @return void */ protected function _checkUseToken($phpcsFile, $stackPtr) { // If the use token is for a closure we want to ignore it. $isClosure = $this->_isClosure($phpcsFile, $stackPtr); if ($isClosure) { return; } $tokens = $phpcsFile->getTokens(); $scope = 'use'; $useType = $phpcsFile->findNext(Tokens::$emptyTokens, ($stackPtr + 1), null, true); if ($useType !== false && $tokens[$useType]['code'] === T_STRING) { $useContent = strtolower($tokens[$useType]['content']); if ($useContent === 'function' || $useContent === 'const') { $scope .= ' ' . $useContent; $stackPtr = $useType + 1; } } $content = ''; $end = $phpcsFile->findNext([T_SEMICOLON, T_OPEN_CURLY_BRACKET], $stackPtr); $useTokens = array_slice($tokens, $stackPtr, $end - $stackPtr, true); foreach ($useTokens as $index => $token) { if ($token['code'] === T_STRING || $token['code'] === T_NS_SEPARATOR) { $content .= $token['content']; } } // Check for class scoping on use. Traits should be // ordered independently. if (!empty($token['conditions'])) { $scope .= key($token['conditions']); } $this->_uses[$scope][$content] = $stackPtr; } /** * Check if the current stackPtr is a use token that is for a closure. * * @param \PHP_CodeSniffer\Files\File $phpcsFile The file being scanned. * @param int $stackPtr The index of the first use token. * @return bool */ protected function _isClosure($phpcsFile, $stackPtr) { return $phpcsFile->findPrevious( [T_CLOSURE], ($stackPtr - 1), null, false, null, true ); } }