1<?php 2/** 3 * Checks the nesting level for methods. 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 16/** 17 * Checks the nesting level for methods. 18 * 19 * @category PHP 20 * @package PHP_CodeSniffer 21 * @author Johann-Peter Hartmann <hartmann@mayflower.de> 22 * @author Greg Sherwood <gsherwood@squiz.net> 23 * @copyright 2007-2014 Mayflower GmbH 24 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 25 * @version Release: @package_version@ 26 * @link http://pear.php.net/package/PHP_CodeSniffer 27 */ 28class Generic_Sniffs_Metrics_NestingLevelSniff implements PHP_CodeSniffer_Sniff 29{ 30 31 /** 32 * A nesting level higher than this value will throw a warning. 33 * 34 * @var int 35 */ 36 public $nestingLevel = 5; 37 38 /** 39 * A nesting level higher than this value will throw an error. 40 * 41 * @var int 42 */ 43 public $absoluteNestingLevel = 10; 44 45 46 /** 47 * Returns an array of tokens this test wants to listen for. 48 * 49 * @return array 50 */ 51 public function register() 52 { 53 return array(T_FUNCTION); 54 55 }//end register() 56 57 58 /** 59 * Processes this test, when one of its tokens is encountered. 60 * 61 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 62 * @param int $stackPtr The position of the current token 63 * in the stack passed in $tokens. 64 * 65 * @return void 66 */ 67 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 68 { 69 $tokens = $phpcsFile->getTokens(); 70 71 // Ignore abstract methods. 72 if (isset($tokens[$stackPtr]['scope_opener']) === false) { 73 return; 74 } 75 76 // Detect start and end of this function definition. 77 $start = $tokens[$stackPtr]['scope_opener']; 78 $end = $tokens[$stackPtr]['scope_closer']; 79 80 $nestingLevel = 0; 81 82 // Find the maximum nesting level of any token in the function. 83 for ($i = ($start + 1); $i < $end; $i++) { 84 $level = $tokens[$i]['level']; 85 if ($nestingLevel < $level) { 86 $nestingLevel = $level; 87 } 88 } 89 90 // We subtract the nesting level of the function itself. 91 $nestingLevel = ($nestingLevel - $tokens[$stackPtr]['level'] - 1); 92 93 if ($nestingLevel > $this->absoluteNestingLevel) { 94 $error = 'Function\'s nesting level (%s) exceeds allowed maximum of %s'; 95 $data = array( 96 $nestingLevel, 97 $this->absoluteNestingLevel, 98 ); 99 $phpcsFile->addError($error, $stackPtr, 'MaxExceeded', $data); 100 } else if ($nestingLevel > $this->nestingLevel) { 101 $warning = 'Function\'s nesting level (%s) exceeds %s; consider refactoring the function'; 102 $data = array( 103 $nestingLevel, 104 $this->nestingLevel, 105 ); 106 $phpcsFile->addWarning($warning, $stackPtr, 'TooHigh', $data); 107 } 108 109 }//end process() 110 111 112}//end class 113