* @author Marc McIntyre * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence * @version CVS: $Id: LowerCaseConstantSniff.php,v 1.8 2008/02/18 00:01:06 squiz Exp $ * @link http://pear.php.net/package/PHP_CodeSniffer */ /** * Generic_Sniffs_PHP_LowerCaseConstantSniff. * * Checks that all uses of true, false and null are lowerrcase. * * @category PHP * @package PHP_CodeSniffer * @author Greg Sherwood * @author Marc McIntyre * @copyright 2006 Squiz Pty Ltd (ABN 77 084 670 600) * @license http://matrix.squiz.net/developer/tools/php_cs/licence BSD Licence * @version Release: 1.2.0a1 * @link http://pear.php.net/package/PHP_CodeSniffer */ class PhpHatesMe_Sniffs_Variables_UnitializedVariableSniff implements PHP_CodeSniffer_Sniff { private $tokens = array( ); /** * A list of tokenizers this sniff supports. * * @var array */ public $supportedTokenizers = array( 'PHP' ); /** * Returns an array of tokens this test wants to listen for. * * @return array */ public function register() { return array( T_FUNCTION ); }//end register() private function isAlwaysDefined( $stackPtr ) { if ( $this->tokens[$stackPtr]['content'] == '$this' ) { return true; } if( $this->isSuperGlobal( $stackPtr ) ) { return true; } if ( $this->isStaticVar( $stackPtr ) ) { return true; } return false; } private function isDefinition( $i ) { if ( $this->isForeachAsVar( $i ) ) { return true; } if ( $this->isForeachAsValueVar( $i ) ) { return true; } if ( $this->isGlobalVar( $i ) ) { return true; } if ( $this->isListFunction( $i ) ) { return true; } return false; } private function isListFunction( $stackPtr ) { $unimportantTokens = array( T_WHITESPACE, T_COMMENT, T_COMMA, T_OPEN_CURLY_BRACKET, T_OPEN_PARENTHESIS, T_VARIABLE ); $currentPointer = $stackPtr - 1; while( isset( $this->tokens[$currentPointer] ) ) { if ( !in_array( $this->tokens[$currentPointer]['code'], $unimportantTokens ) ) { return $this->tokens[$currentPointer]['code'] == T_LIST; } $currentPointer--; } return false; } private function setTokens( PHP_CodeSniffer_File $phpcsFile ) { $this->tokens = $phpcsFile->getTokens( ); } /** * Processes this sniff, when one of its tokens is encountered. * * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. * @param int $stackPtr The position of the current token in the * stack passed in $tokens. * * @return void */ public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) { static $lastStackPtr; if ( $lastStackPtr == $stackPtr ) return; $this->setTokens( $phpcsFile ); $tokens = $this->tokens; $functionToken = $this->tokens[$stackPtr]; $initializedVars = $this->getParameter( $this->tokens, $stackPtr ); // no body if it's an interface if ( !isset( $functionToken['scope_opener'] ) ) { return; } for( $i = $functionToken['scope_opener']; $i <= $functionToken['scope_closer']; $i++ ) { $currentToken = $this->tokens[$i]; if ( $currentToken['code'] == T_VARIABLE ) { if ( $this->isAlwaysDefined( $i ) ) { continue; } if ( $this->isDefinition( $i ) ) { $initializedVars[] = $currentToken['content']; continue; } $nextToken = $this->getNextExecutingToken( $this->tokens, $i ); if ( $nextToken['code'] == T_EQUAL ) { $initializedVars[] = $currentToken['content']; }else{ if ( !in_array( $currentToken['content'], $initializedVars ) ) { $error = 'Undefined variable: '.$currentToken['content'].'.'; $phpcsFile->addError($error, $i); } } } } $lastStackPtr = $stackPtr; } private function isForeachAsValueVar( $stackPtr ) { $this->tokens = $this->tokens; $unimportantTokens = array( T_WHITESPACE, T_COMMENT ); $this->tokens = $this->tokens; $currentPointer = $stackPtr - 1; while( isset( $this->tokens[$currentPointer] ) ) { if ( !in_array( $this->tokens[$currentPointer]['code'], $unimportantTokens ) ) { return $this->tokens[$currentPointer]['code'] == T_DOUBLE_ARROW; } $currentPointer--; } return false; } private function isSuperGlobal( $stackPtr ) { $superGlobals = array( '$_POST', '$_GET', '$_REQUEST', '$_SERVER', '$_COOKIE', '$_ENV', '$_SESSION', '$_FILES' ); $token = $this->tokens[$stackPtr]; return in_array( $token['content'], $superGlobals ); } private function isForeachAsVar( $stackPtr ) { $this->tokens = $this->tokens; $unimportantTokens = array( T_WHITESPACE, T_COMMENT ); $this->tokens = $this->tokens; $currentPointer = $stackPtr - 1; while( isset( $this->tokens[$currentPointer] ) ) { if ( !in_array( $this->tokens[$currentPointer]['code'], $unimportantTokens ) ) { return $this->tokens[$currentPointer]['code'] == T_AS; } $currentPointer--; } return false; } private function isStaticVar( $stackPtr ) { $unimportantTokens = array( T_WHITESPACE, T_COMMENT, T_DOUBLE_COLON ); $this->tokens = $this->tokens; $currentPointer = $stackPtr - 1; while( isset( $this->tokens[$currentPointer] ) ) { if ( !in_array( $this->tokens[$currentPointer]['code'], $unimportantTokens ) ) { return $this->tokens[$currentPointer]['code'] == T_SELF; } $currentPointer--; } return false; } private function isGlobalVar( $stackPtr ) { $unimportantTokens = array( T_WHITESPACE, T_COMMENT, T_COMMA, T_VARIABLE ); $this->tokens = $this->tokens; $currentPointer = $stackPtr - 1; while( isset( $this->tokens[$currentPointer] ) ) { if ( !in_array( $this->tokens[$currentPointer]['code'], $unimportantTokens ) ) { return $this->tokens[$currentPointer]['code'] == T_GLOBAL; } $currentPointer--; } return false; } private function getParameter( $tokens, $stackPtr ) { $parameters = array( ); $currentToken = $this->tokens[$stackPtr]; for( $i = $currentToken['parenthesis_opener']; $i < $currentToken['parenthesis_closer']; $i++ ) { if ( $this->tokens[$i]['code'] == T_VARIABLE ) { $parameters[] = $this->tokens[$i]['content']; } } return $parameters; } private function getNextExecutingToken( $tokens, $stackPtr ) { $unimportantTokens = array( T_WHITESPACE, T_COMMENT, T_OPEN_SQUARE_BRACKET, T_CLOSE_SQUARE_BRACKET, T_STRING, T_CONSTANT_ENCAPSED_STRING, T_VARIABLE ); $currentPointer = $stackPtr + 1; while( isset( $this->tokens[$currentPointer] ) ) { if ( !in_array( $this->tokens[$currentPointer]['code'], $unimportantTokens ) ) { return $this->tokens[$currentPointer]; } $currentPointer++; } } } ?>