1<?php 2/** 3 * Squiz_Sniffs_Scope_StaticThisUsageSniff. 4 * 5 * PHP version 5 6 * 7 * @category PHP 8 * @package PHP_CodeSniffer 9 * @author Greg Sherwood <gsherwood@squiz.net> 10 * @author Marc McIntyre <mmcintyre@squiz.net> 11 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 12 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 13 * @link http://pear.php.net/package/PHP_CodeSniffer 14 */ 15 16if (class_exists('PHP_CodeSniffer_Standards_AbstractScopeSniff', true) === false) { 17 throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractScopeSniff not found'); 18} 19 20/** 21 * Squiz_Sniffs_Scope_StaticThisUsageSniff. 22 * 23 * Checks for usage of "$this" in static methods, which will cause 24 * runtime errors. 25 * 26 * @category PHP 27 * @package PHP_CodeSniffer 28 * @author Greg Sherwood <gsherwood@squiz.net> 29 * @author Marc McIntyre <mmcintyre@squiz.net> 30 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 31 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 32 * @version Release: @package_version@ 33 * @link http://pear.php.net/package/PHP_CodeSniffer 34 */ 35class Squiz_Sniffs_Scope_StaticThisUsageSniff extends PHP_CodeSniffer_Standards_AbstractScopeSniff 36{ 37 38 39 /** 40 * Constructs the test with the tokens it wishes to listen for. 41 */ 42 public function __construct() 43 { 44 parent::__construct(array(T_CLASS), array(T_FUNCTION)); 45 46 }//end __construct() 47 48 49 /** 50 * Processes this test, when one of its tokens is encountered. 51 * 52 * @param PHP_CodeSniffer_File $phpcsFile The current file being scanned. 53 * @param int $stackPtr The position of the current token in the 54 * stack passed in $tokens. 55 * @param int $currScope A pointer to the start of the scope. 56 * 57 * @return void 58 */ 59 public function processTokenWithinScope(PHP_CodeSniffer_File $phpcsFile, $stackPtr, $currScope) 60 { 61 $tokens = $phpcsFile->getTokens(); 62 $function = $tokens[($stackPtr + 2)]; 63 64 if ($function['code'] !== T_STRING) { 65 return; 66 } 67 68 $functionName = $function['content']; 69 $classOpener = $tokens[$currScope]['scope_condition']; 70 $className = $tokens[($classOpener + 2)]['content']; 71 72 $methodProps = $phpcsFile->getMethodProperties($stackPtr); 73 74 if ($methodProps['is_static'] === true) { 75 if (isset($tokens[$stackPtr]['scope_closer']) === false) { 76 // There is no scope opener or closer, so the function 77 // must be abstract. 78 return; 79 } 80 81 $thisUsage = $stackPtr; 82 while (($thisUsage = $phpcsFile->findNext(array(T_VARIABLE), ($thisUsage + 1), $tokens[$stackPtr]['scope_closer'], false, '$this')) !== false) { 83 if ($thisUsage === false) { 84 return; 85 } 86 87 $error = 'Usage of "$this" in static methods will cause runtime errors'; 88 $phpcsFile->addError($error, $thisUsage, 'Found'); 89 } 90 }//end if 91 92 }//end processTokenWithinScope() 93 94 95}//end class 96