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: if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) { Chris@0: $error = 'Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found'; Chris@0: throw new PHP_CodeSniffer_Exception($error); Chris@0: } Chris@0: Chris@0: /** Chris@0: * A class to find T_VARIABLE tokens. Chris@0: * Chris@0: * This class can distinguish between normal T_VARIABLE tokens, and those tokens Chris@0: * that represent class members. If a class member is encountered, then the Chris@0: * processMemberVar method is called so the extending class can process it. If Chris@0: * the token is found to be a normal T_VARIABLE token, then processVariable is Chris@0: * called. 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_AbstractVariableSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff Chris@0: { Chris@0: Chris@0: /** Chris@0: * The end token of the current function that we are in. Chris@0: * Chris@0: * @var int Chris@0: */ Chris@0: private $_endFunction = -1; Chris@0: Chris@0: /** Chris@0: * TRUE if a function is currently open. Chris@0: * Chris@0: * @var boolean Chris@0: */ Chris@0: private $_functionOpen = false; Chris@0: Chris@0: /** Chris@0: * The current PHP_CodeSniffer file that we are processing. Chris@0: * Chris@0: * @var PHP_CodeSniffer_File Chris@0: */ Chris@0: protected $currentFile = null; Chris@0: Chris@0: Chris@0: /** Chris@0: * Constructs an AbstractVariableTest. Chris@0: */ Chris@0: public function __construct() Chris@0: { Chris@0: $scopes = array( Chris@0: T_CLASS, Chris@0: T_ANON_CLASS, Chris@0: T_TRAIT, Chris@0: T_INTERFACE, Chris@0: ); Chris@0: Chris@0: $listen = array( Chris@0: T_FUNCTION, Chris@0: T_VARIABLE, Chris@0: T_DOUBLE_QUOTED_STRING, Chris@0: T_HEREDOC, Chris@0: ); Chris@0: Chris@0: parent::__construct($scopes, $listen, true); Chris@0: Chris@0: }//end __construct() Chris@0: Chris@0: Chris@0: /** Chris@0: * Processes the token in the specified PHP_CodeSniffer_File. Chris@0: * Chris@0: * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this Chris@0: * token was found. Chris@0: * @param int $stackPtr The position where the token was found. Chris@0: * @param array $currScope The current scope opener token. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: protected final function processTokenWithinScope( Chris@0: PHP_CodeSniffer_File $phpcsFile, Chris@0: $stackPtr, Chris@0: $currScope Chris@0: ) { Chris@0: if ($this->currentFile !== $phpcsFile) { Chris@0: $this->currentFile = $phpcsFile; Chris@0: $this->_functionOpen = false; Chris@0: $this->_endFunction = -1; Chris@0: } Chris@0: Chris@0: $tokens = $phpcsFile->getTokens(); Chris@0: Chris@0: if ($stackPtr > $this->_endFunction) { Chris@0: $this->_functionOpen = false; Chris@0: } Chris@0: Chris@0: if ($tokens[$stackPtr]['code'] === T_FUNCTION Chris@0: && $this->_functionOpen === false Chris@0: ) { Chris@0: $this->_functionOpen = true; Chris@0: Chris@0: $methodProps = $phpcsFile->getMethodProperties($stackPtr); Chris@0: Chris@0: // If the function is abstract, or is in an interface, Chris@0: // then set the end of the function to it's closing semicolon. Chris@0: if ($methodProps['is_abstract'] === true Chris@0: || $tokens[$currScope]['code'] === T_INTERFACE Chris@0: ) { Chris@0: $this->_endFunction Chris@0: = $phpcsFile->findNext(array(T_SEMICOLON), $stackPtr); Chris@0: } else { Chris@0: if (isset($tokens[$stackPtr]['scope_closer']) === false) { Chris@0: $error = 'Possible parse error: non-abstract method defined as abstract'; Chris@0: $phpcsFile->addWarning($error, $stackPtr); Chris@0: return; Chris@0: } Chris@0: Chris@0: $this->_endFunction = $tokens[$stackPtr]['scope_closer']; Chris@0: } Chris@0: }//end if Chris@0: Chris@0: if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING Chris@0: || $tokens[$stackPtr]['code'] === T_HEREDOC Chris@0: ) { Chris@0: // Check to see if this string has a variable in it. Chris@0: $pattern = '|(?processVariableInString($phpcsFile, $stackPtr); Chris@0: } Chris@0: Chris@0: return; Chris@0: } Chris@0: Chris@0: if ($this->_functionOpen === true) { Chris@0: if ($tokens[$stackPtr]['code'] === T_VARIABLE) { Chris@0: $this->processVariable($phpcsFile, $stackPtr); Chris@0: } Chris@0: } else { Chris@0: // What if we assign a member variable to another? Chris@0: // ie. private $_count = $this->_otherCount + 1;. Chris@0: $this->processMemberVar($phpcsFile, $stackPtr); Chris@0: } Chris@0: Chris@0: }//end processTokenWithinScope() Chris@0: Chris@0: Chris@0: /** Chris@0: * Processes the token outside the scope in the file. Chris@0: * Chris@0: * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this Chris@0: * token was found. Chris@0: * @param int $stackPtr The position where the token was found. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: protected final function processTokenOutsideScope( Chris@0: PHP_CodeSniffer_File $phpcsFile, Chris@0: $stackPtr Chris@0: ) { Chris@0: $tokens = $phpcsFile->getTokens(); Chris@0: // These variables are not member vars. Chris@0: if ($tokens[$stackPtr]['code'] === T_VARIABLE) { Chris@0: $this->processVariable($phpcsFile, $stackPtr); Chris@0: } else if ($tokens[$stackPtr]['code'] === T_DOUBLE_QUOTED_STRING Chris@0: || $tokens[$stackPtr]['code'] === T_HEREDOC Chris@0: ) { Chris@0: // Check to see if this string has a variable in it. Chris@0: $pattern = '|(?processVariableInString($phpcsFile, $stackPtr); Chris@0: } Chris@0: } Chris@0: Chris@0: }//end processTokenOutsideScope() Chris@0: Chris@0: Chris@0: /** Chris@0: * Called to process class member vars. Chris@0: * Chris@0: * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this Chris@0: * token was found. Chris@0: * @param int $stackPtr The position where the token was found. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: abstract protected function processMemberVar( Chris@0: PHP_CodeSniffer_File $phpcsFile, Chris@0: $stackPtr Chris@0: ); Chris@0: Chris@0: Chris@0: /** Chris@0: * Called to process normal member vars. Chris@0: * Chris@0: * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this Chris@0: * token was found. Chris@0: * @param int $stackPtr The position where the token was found. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: abstract protected function processVariable( Chris@0: PHP_CodeSniffer_File $phpcsFile, Chris@0: $stackPtr Chris@0: ); Chris@0: Chris@0: Chris@0: /** Chris@0: * Called to process variables found in double quoted strings or heredocs. Chris@0: * Chris@0: * Note that there may be more than one variable in the string, which will Chris@0: * result only in one call for the string or one call per line for heredocs. Chris@0: * Chris@0: * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this Chris@0: * token was found. Chris@0: * @param int $stackPtr The position where the double quoted Chris@0: * string was found. Chris@0: * Chris@0: * @return void Chris@0: */ Chris@0: abstract protected function processVariableInString( Chris@0: PHP_CodeSniffer_File Chris@0: $phpcsFile, Chris@0: $stackPtr Chris@0: ); Chris@0: Chris@0: Chris@0: }//end class