1<?php 2/** 3 * Class Declaration Test. 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 * Class Declaration Test. 18 * 19 * Checks the declaration of the class is correct. 20 * 21 * @category PHP 22 * @package PHP_CodeSniffer 23 * @author Greg Sherwood <gsherwood@squiz.net> 24 * @author Marc McIntyre <mmcintyre@squiz.net> 25 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 26 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 27 * @version Release: @package_version@ 28 * @link http://pear.php.net/package/PHP_CodeSniffer 29 */ 30class PEAR_Sniffs_Classes_ClassDeclarationSniff implements PHP_CodeSniffer_Sniff 31{ 32 33 /** 34 * The number of spaces code should be indented. 35 * 36 * @var int 37 */ 38 public $indent = 4; 39 40 41 /** 42 * Returns an array of tokens this test wants to listen for. 43 * 44 * @return array 45 */ 46 public function register() 47 { 48 return array( 49 T_CLASS, 50 T_INTERFACE, 51 T_TRAIT, 52 ); 53 54 }//end register() 55 56 57 /** 58 * Processes this test, when one of its tokens is encountered. 59 * 60 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 61 * @param integer $stackPtr The position of the current token in the 62 * stack passed in $tokens. 63 * 64 * @return void 65 */ 66 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 67 { 68 $tokens = $phpcsFile->getTokens(); 69 $errorData = array(strtolower($tokens[$stackPtr]['content'])); 70 71 if (isset($tokens[$stackPtr]['scope_opener']) === false) { 72 $error = 'Possible parse error: %s missing opening or closing brace'; 73 $phpcsFile->addWarning($error, $stackPtr, 'MissingBrace', $errorData); 74 return; 75 } 76 77 $curlyBrace = $tokens[$stackPtr]['scope_opener']; 78 $lastContent = $phpcsFile->findPrevious(T_WHITESPACE, ($curlyBrace - 1), $stackPtr, true); 79 $classLine = $tokens[$lastContent]['line']; 80 $braceLine = $tokens[$curlyBrace]['line']; 81 if ($braceLine === $classLine) { 82 $phpcsFile->recordMetric($stackPtr, 'Class opening brace placement', 'same line'); 83 $error = 'Opening brace of a %s must be on the line after the definition'; 84 $fix = $phpcsFile->addFixableError($error, $curlyBrace, 'OpenBraceNewLine', $errorData); 85 if ($fix === true) { 86 $phpcsFile->fixer->beginChangeset(); 87 if ($tokens[($curlyBrace - 1)]['code'] === T_WHITESPACE) { 88 $phpcsFile->fixer->replaceToken(($curlyBrace - 1), ''); 89 } 90 91 $phpcsFile->fixer->addNewlineBefore($curlyBrace); 92 $phpcsFile->fixer->endChangeset(); 93 } 94 95 return; 96 } else { 97 $phpcsFile->recordMetric($stackPtr, 'Class opening brace placement', 'new line'); 98 99 if ($braceLine > ($classLine + 1)) { 100 $error = 'Opening brace of a %s must be on the line following the %s declaration; found %s line(s)'; 101 $data = array( 102 $tokens[$stackPtr]['content'], 103 $tokens[$stackPtr]['content'], 104 ($braceLine - $classLine - 1), 105 ); 106 $fix = $phpcsFile->addFixableError($error, $curlyBrace, 'OpenBraceWrongLine', $data); 107 if ($fix === true) { 108 $phpcsFile->fixer->beginChangeset(); 109 for ($i = ($curlyBrace - 1); $i > $lastContent; $i--) { 110 if ($tokens[$i]['line'] === ($tokens[$curlyBrace]['line'] + 1)) { 111 break; 112 } 113 114 $phpcsFile->fixer->replaceToken($i, ''); 115 } 116 117 $phpcsFile->fixer->endChangeset(); 118 } 119 120 return; 121 }//end if 122 }//end if 123 124 if ($tokens[($curlyBrace + 1)]['content'] !== $phpcsFile->eolChar) { 125 $error = 'Opening %s brace must be on a line by itself'; 126 $fix = $phpcsFile->addFixableError($error, $curlyBrace, 'OpenBraceNotAlone', $errorData); 127 if ($fix === true) { 128 $phpcsFile->fixer->addNewline($curlyBrace); 129 } 130 } 131 132 if ($tokens[($curlyBrace - 1)]['code'] === T_WHITESPACE) { 133 $prevContent = $tokens[($curlyBrace - 1)]['content']; 134 if ($prevContent === $phpcsFile->eolChar) { 135 $spaces = 0; 136 } else { 137 $blankSpace = substr($prevContent, strpos($prevContent, $phpcsFile->eolChar)); 138 $spaces = strlen($blankSpace); 139 } 140 141 $expected = ($tokens[$stackPtr]['level'] * $this->indent); 142 if ($spaces !== $expected) { 143 $error = 'Expected %s spaces before opening brace; %s found'; 144 $data = array( 145 $expected, 146 $spaces, 147 ); 148 149 $fix = $phpcsFile->addFixableError($error, $curlyBrace, 'SpaceBeforeBrace', $data); 150 if ($fix === true) { 151 $indent = str_repeat(' ', $expected); 152 if ($spaces === 0) { 153 $phpcsFile->fixer->addContentBefore($curlyBrace, $indent); 154 } else { 155 $phpcsFile->fixer->replaceToken(($curlyBrace - 1), $indent); 156 } 157 } 158 } 159 }//end if 160 161 }//end process() 162 163 164}//end class 165