Chris@0: Chris@0: * @author Marc McIntyre Chris@0: * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) Chris@0: * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence Chris@0: * @link http://pear.php.net/package/PHP_CodeSniffer Chris@0: */ Chris@0: Chris@0: /** Chris@0: * An AbstractScopeTest allows for tests that extend from this class to Chris@0: * listen for tokens within a particular scope. Chris@0: * Chris@0: * Below is a test that listens to methods that exist only within classes: Chris@0: * Chris@0: * class ClassScopeTest extends PHP_CodeSniffer_Standards_AbstractScopeSniff Chris@0: * { Chris@0: * public function __construct() Chris@0: * { Chris@0: * parent::__construct(array(T_CLASS), array(T_FUNCTION)); Chris@0: * } Chris@0: * Chris@0: * protected function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $) Chris@0: * { Chris@0: * $className = $phpcsFile->getDeclarationName($currScope); Chris@0: * echo 'encountered a method within class '.$className; Chris@0: * } Chris@0: * } Chris@0: * Chris@0: * Chris@0: * @category PHP Chris@0: * @package PHP_CodeSniffer Chris@0: * @author Greg Sherwood Chris@0: * @author Marc McIntyre Chris@0: * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) Chris@0: * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence Chris@0: * @version Release: @package_version@ Chris@0: * @link http://pear.php.net/package/PHP_CodeSniffer Chris@0: */ Chris@0: abstract class PHP_CodeSniffer_Standards_AbstractScopeSniff implements PHP_CodeSniffer_Sniff Chris@0: { Chris@0: Chris@0: /** Chris@0: * The token types that this test wishes to listen to within the scope. Chris@0: * Chris@0: * @var array Chris@0: */ Chris@0: private $_tokens = array(); Chris@0: Chris@0: /** Chris@0: * The type of scope opener tokens that this test wishes to listen to. Chris@0: * Chris@0: * @var string Chris@0: */ Chris@0: private $_scopeTokens = array(); Chris@0: Chris@0: /** Chris@0: * True if this test should fire on tokens outside of the scope. Chris@0: * Chris@0: * @var boolean Chris@0: */ Chris@0: private $_listenOutside = false; Chris@0: Chris@0: Chris@0: /** Chris@0: * Constructs a new AbstractScopeTest. Chris@0: * Chris@0: * @param array $scopeTokens The type of scope the test wishes to listen to. Chris@0: * @param array $tokens The tokens that the test wishes to listen to Chris@0: * within the scope. Chris@0: * @param boolean $listenOutside If true this test will also alert the Chris@0: * extending class when a token is found outside Chris@0: * the scope, by calling the Chris@0: * processTokenOutsideScope method. Chris@0: * Chris@0: * @see PHP_CodeSniffer.getValidScopeTokeners() Chris@0: * @throws PHP_CodeSniffer_Exception If the specified tokens array is empty. Chris@0: */ Chris@0: public function __construct( Chris@0: array $scopeTokens, Chris@0: array $tokens, Chris@0: $listenOutside=false Chris@0: ) { Chris@0: if (empty($scopeTokens) === true) { Chris@0: $error = 'The scope tokens list cannot be empty'; Chris@0: throw new PHP_CodeSniffer_Exception($error); Chris@0: } Chris@0: Chris@0: if (empty($tokens) === true) { Chris@0: $error = 'The tokens list cannot be empty'; Chris@0: throw new PHP_CodeSniffer_Exception($error); Chris@0: } Chris@0: Chris@0: $invalidScopeTokens = array_intersect($scopeTokens, $tokens); Chris@0: if (empty($invalidScopeTokens) === false) { Chris@0: $invalid = implode(', ', $invalidScopeTokens); Chris@0: $error = "Scope tokens [$invalid] can't be in the tokens array"; Chris@0: throw new PHP_CodeSniffer_Exception($error); Chris@0: } Chris@0: Chris@0: $this->_listenOutside = $listenOutside; Chris@0: $this->_scopeTokens = array_flip($scopeTokens); Chris@0: $this->_tokens = $tokens; Chris@0: Chris@0: }//end __construct() Chris@0: Chris@0: Chris@0: /** Chris@0: * The method that is called to register the tokens this test wishes to Chris@0: * listen to. Chris@0: * Chris@0: * DO NOT OVERRIDE THIS METHOD. Use the constructor of this class to register Chris@0: * for the desired tokens and scope. Chris@0: * Chris@0: * @return int[] Chris@0: * @see __constructor() Chris@0: */ Chris@0: public final function register() Chris@0: { Chris@0: return $this->_tokens; Chris@0: Chris@0: }//end register() Chris@0: Chris@0: Chris@0: /** Chris@0: * Processes the tokens that this test is listening for. Chris@0: * Chris@0: * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. Chris@0: * @param int $stackPtr The position in the stack where this Chris@0: * token was found. Chris@0: * Chris@0: * @return void Chris@0: * @see processTokenWithinScope() Chris@0: */ Chris@0: public final function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) Chris@0: { Chris@0: $tokens = $phpcsFile->getTokens(); Chris@0: Chris@0: $foundScope = false; Chris@0: foreach ($tokens[$stackPtr]['conditions'] as $scope => $code) { Chris@0: if (isset($this->_scopeTokens[$code]) === true) { Chris@0: $this->processTokenWithinScope($phpcsFile, $stackPtr, $scope); Chris@0: $foundScope = true; Chris@0: } Chris@0: } Chris@0: Chris@0: if ($this->_listenOutside === true && $foundScope === false) { Chris@0: $this->processTokenOutsideScope($phpcsFile, $stackPtr); Chris@0: } Chris@0: Chris@0: }//end process() Chris@0: Chris@0: Chris@0: /** Chris@0: * Processes a token that is found within the scope that this test is Chris@0: * listening to. Chris@0: * Chris@0: * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. Chris@0: * @param int $stackPtr The position in the stack where this Chris@0: * token was found. Chris@0: * @param int $currScope The position in the tokens array that Chris@0: * opened the scope that this test is Chris@0: * listening for. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: protected abstract function processTokenWithinScope( Chris@0: PHP_CodeSniffer_File $phpcsFile, Chris@0: $stackPtr, Chris@0: $currScope Chris@0: ); Chris@0: Chris@0: Chris@0: /** Chris@0: * Processes a token that is found outside the scope that this test is Chris@0: * listening to. Chris@0: * Chris@0: * @param PHP_CodeSniffer_File $phpcsFile The file where this token was found. Chris@0: * @param int $stackPtr The position in the stack where this Chris@0: * token was found. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: protected function processTokenOutsideScope( Chris@0: PHP_CodeSniffer_File $phpcsFile, Chris@0: $stackPtr Chris@0: ) { Chris@0: Chris@0: }//end processTokenOutsideScope() Chris@0: Chris@0: Chris@0: }//end class