Chris@4: Chris@4: * class ClassScopeTest extends PHP_CodeSniffer_Standards_AbstractScopeSniff Chris@4: * { Chris@4: * public function __construct() Chris@4: * { Chris@4: * parent::__construct(array(T_CLASS), array(T_FUNCTION)); Chris@4: * } Chris@4: * Chris@4: * protected function processTokenWithinScope(\PHP_CodeSniffer\Files\File $phpcsFile, $stackPtr, $currScope) Chris@4: * { Chris@4: * $className = $phpcsFile->getDeclarationName($currScope); Chris@4: * echo 'encountered a method within class '.$className; Chris@4: * } Chris@4: * } Chris@4: * Chris@4: * Chris@4: * @author Greg Sherwood Chris@4: * @copyright 2006-2015 Squiz Pty Ltd (ABN 77 084 670 600) Chris@4: * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence Chris@4: */ Chris@4: Chris@4: namespace PHP_CodeSniffer\Sniffs; Chris@4: Chris@4: use PHP_CodeSniffer\Files\File; Chris@4: use PHP_CodeSniffer\Exceptions\RuntimeException; Chris@4: Chris@4: abstract class AbstractScopeSniff implements Sniff Chris@4: { Chris@4: Chris@4: /** Chris@4: * The token types that this test wishes to listen to within the scope. Chris@4: * Chris@4: * @var array Chris@4: */ Chris@4: private $tokens = []; Chris@4: Chris@4: /** Chris@4: * The type of scope opener tokens that this test wishes to listen to. Chris@4: * Chris@4: * @var string Chris@4: */ Chris@4: private $scopeTokens = []; Chris@4: Chris@4: /** Chris@4: * True if this test should fire on tokens outside of the scope. Chris@4: * Chris@4: * @var boolean Chris@4: */ Chris@4: private $listenOutside = false; Chris@4: Chris@4: Chris@4: /** Chris@4: * Constructs a new AbstractScopeTest. Chris@4: * Chris@4: * @param array $scopeTokens The type of scope the test wishes to listen to. Chris@4: * @param array $tokens The tokens that the test wishes to listen to Chris@4: * within the scope. Chris@4: * @param boolean $listenOutside If true this test will also alert the Chris@4: * extending class when a token is found outside Chris@4: * the scope, by calling the Chris@4: * processTokenOutsideScope method. Chris@4: * Chris@4: * @see PHP_CodeSniffer.getValidScopeTokeners() Chris@4: * @throws \PHP_CodeSniffer\Exceptions\RuntimeException If the specified tokens array is empty. Chris@4: */ Chris@4: public function __construct( Chris@4: array $scopeTokens, Chris@4: array $tokens, Chris@4: $listenOutside=false Chris@4: ) { Chris@4: if (empty($scopeTokens) === true) { Chris@4: $error = 'The scope tokens list cannot be empty'; Chris@4: throw new RuntimeException($error); Chris@4: } Chris@4: Chris@4: if (empty($tokens) === true) { Chris@4: $error = 'The tokens list cannot be empty'; Chris@4: throw new RuntimeException($error); Chris@4: } Chris@4: Chris@4: $invalidScopeTokens = array_intersect($scopeTokens, $tokens); Chris@4: if (empty($invalidScopeTokens) === false) { Chris@4: $invalid = implode(', ', $invalidScopeTokens); Chris@4: $error = "Scope tokens [$invalid] can't be in the tokens array"; Chris@4: throw new RuntimeException($error); Chris@4: } Chris@4: Chris@4: $this->listenOutside = $listenOutside; Chris@4: $this->scopeTokens = array_flip($scopeTokens); Chris@4: $this->tokens = $tokens; Chris@4: Chris@4: }//end __construct() Chris@4: Chris@4: Chris@4: /** Chris@4: * The method that is called to register the tokens this test wishes to Chris@4: * listen to. Chris@4: * Chris@4: * DO NOT OVERRIDE THIS METHOD. Use the constructor of this class to register Chris@4: * for the desired tokens and scope. Chris@4: * Chris@4: * @return int[] Chris@4: * @see __constructor() Chris@4: */ Chris@4: final public function register() Chris@4: { Chris@4: return $this->tokens; Chris@4: Chris@4: }//end register() Chris@4: Chris@4: Chris@4: /** Chris@4: * Processes the tokens that this test is listening for. Chris@4: * Chris@4: * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. Chris@4: * @param int $stackPtr The position in the stack where this Chris@4: * token was found. Chris@4: * Chris@4: * @return void|int Optionally returns a stack pointer. The sniff will not be Chris@4: * called again on the current file until the returned stack Chris@4: * pointer is reached. Return ($phpcsFile->numTokens + 1) to skip Chris@4: * the rest of the file. Chris@4: * @see processTokenWithinScope() Chris@4: */ Chris@4: final public function process(File $phpcsFile, $stackPtr) Chris@4: { Chris@4: $tokens = $phpcsFile->getTokens(); Chris@4: Chris@4: $foundScope = false; Chris@4: $skipPtrs = []; Chris@4: foreach ($tokens[$stackPtr]['conditions'] as $scope => $code) { Chris@4: if (isset($this->scopeTokens[$code]) === true) { Chris@4: $skipPtrs[] = $this->processTokenWithinScope($phpcsFile, $stackPtr, $scope); Chris@4: $foundScope = true; Chris@4: } Chris@4: } Chris@4: Chris@4: if ($this->listenOutside === true && $foundScope === false) { Chris@4: $skipPtrs[] = $this->processTokenOutsideScope($phpcsFile, $stackPtr); Chris@4: } Chris@4: Chris@4: if (empty($skipPtrs) === false) { Chris@4: return min($skipPtrs); Chris@4: } Chris@4: Chris@4: return; Chris@4: Chris@4: }//end process() Chris@4: Chris@4: Chris@4: /** Chris@4: * Processes a token that is found within the scope that this test is Chris@4: * listening to. Chris@4: * Chris@4: * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. Chris@4: * @param int $stackPtr The position in the stack where this Chris@4: * token was found. Chris@4: * @param int $currScope The position in the tokens array that Chris@4: * opened the scope that this test is Chris@4: * listening for. Chris@4: * Chris@4: * @return void|int Optionally returns a stack pointer. The sniff will not be Chris@4: * called again on the current file until the returned stack Chris@4: * pointer is reached. Return ($phpcsFile->numTokens + 1) to skip Chris@4: * the rest of the file. Chris@4: */ Chris@4: abstract protected function processTokenWithinScope(File $phpcsFile, $stackPtr, $currScope); Chris@4: Chris@4: Chris@4: /** Chris@4: * Processes a token that is found outside the scope that this test is Chris@4: * listening to. Chris@4: * Chris@4: * @param \PHP_CodeSniffer\Files\File $phpcsFile The file where this token was found. Chris@4: * @param int $stackPtr The position in the stack where this Chris@4: * token was found. Chris@4: * Chris@4: * @return void|int Optionally returns a stack pointer. The sniff will not be Chris@4: * called again on the current file until the returned stack Chris@4: * pointer is reached. Return (count($tokens) + 1) to skip Chris@4: * the rest of the file. Chris@4: */ Chris@4: abstract protected function processTokenOutsideScope(File $phpcsFile, $stackPtr); Chris@4: Chris@4: Chris@4: }//end class