1<?php 2/** 3 * Squiz_Sniffs_Commenting_EmptyCatchCommentSniff. 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 * Squiz_Sniffs_Commenting_DocCommentAlignmentSniff. 18 * 19 * Tests that the stars in a doc comment align correctly. 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 Squiz_Sniffs_Commenting_DocCommentAlignmentSniff implements PHP_CodeSniffer_Sniff 31{ 32 33 /** 34 * A list of tokenizers this sniff supports. 35 * 36 * @var array 37 */ 38 public $supportedTokenizers = array( 39 'PHP', 40 'JS', 41 ); 42 43 44 /** 45 * Returns an array of tokens this test wants to listen for. 46 * 47 * @return array 48 */ 49 public function register() 50 { 51 return array(T_DOC_COMMENT_OPEN_TAG); 52 53 }//end register() 54 55 56 /** 57 * Processes this test, when one of its tokens is encountered. 58 * 59 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 60 * @param int $stackPtr The position of the current token 61 * in the stack passed in $tokens. 62 * 63 * @return void 64 */ 65 public function process(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 66 { 67 $tokens = $phpcsFile->getTokens(); 68 69 // We are only interested in function/class/interface doc block comments. 70 $ignore = PHP_CodeSniffer_Tokens::$emptyTokens; 71 if ($phpcsFile->tokenizerType === 'JS') { 72 $ignore[] = T_EQUAL; 73 $ignore[] = T_STRING; 74 $ignore[] = T_OBJECT_OPERATOR; 75 } 76 77 $nextToken = $phpcsFile->findNext($ignore, ($stackPtr + 1), null, true); 78 $ignore = array( 79 T_CLASS => true, 80 T_INTERFACE => true, 81 T_FUNCTION => true, 82 T_PUBLIC => true, 83 T_PRIVATE => true, 84 T_PROTECTED => true, 85 T_STATIC => true, 86 T_ABSTRACT => true, 87 T_PROPERTY => true, 88 T_OBJECT => true, 89 T_PROTOTYPE => true, 90 T_VAR => true, 91 ); 92 93 if (isset($ignore[$tokens[$nextToken]['code']]) === false) { 94 // Could be a file comment. 95 $prevToken = $phpcsFile->findPrevious(PHP_CodeSniffer_Tokens::$emptyTokens, ($stackPtr - 1), null, true); 96 if ($tokens[$prevToken]['code'] !== T_OPEN_TAG) { 97 return; 98 } 99 } 100 101 // There must be one space after each star (unless it is an empty comment line) 102 // and all the stars must be aligned correctly. 103 $requiredColumn = ($tokens[$stackPtr]['column'] + 1); 104 $endComment = $tokens[$stackPtr]['comment_closer']; 105 for ($i = ($stackPtr + 1); $i <= $endComment; $i++) { 106 if ($tokens[$i]['code'] !== T_DOC_COMMENT_STAR 107 && $tokens[$i]['code'] !== T_DOC_COMMENT_CLOSE_TAG 108 ) { 109 continue; 110 } 111 112 if ($tokens[$i]['code'] === T_DOC_COMMENT_CLOSE_TAG) { 113 // Can't process the close tag if it is not the first thing on the line. 114 $prev = $phpcsFile->findPrevious(T_DOC_COMMENT_WHITESPACE, ($i - 1), $stackPtr, true); 115 if ($tokens[$prev]['line'] === $tokens[$i]['line']) { 116 continue; 117 } 118 } 119 120 if ($tokens[$i]['column'] !== $requiredColumn) { 121 $error = 'Expected %s space(s) before asterisk; %s found'; 122 $data = array( 123 ($requiredColumn - 1), 124 ($tokens[$i]['column'] - 1), 125 ); 126 $fix = $phpcsFile->addFixableError($error, $i, 'SpaceBeforeStar', $data); 127 if ($fix === true) { 128 $padding = str_repeat(' ', ($requiredColumn - 1)); 129 if ($tokens[$i]['column'] === 1) { 130 $phpcsFile->fixer->addContentBefore($i, $padding); 131 } else { 132 $phpcsFile->fixer->replaceToken(($i - 1), $padding); 133 } 134 } 135 } 136 137 if ($tokens[$i]['code'] !== T_DOC_COMMENT_STAR) { 138 continue; 139 } 140 141 if ($tokens[($i + 2)]['line'] !== $tokens[$i]['line']) { 142 // Line is empty. 143 continue; 144 } 145 146 if ($tokens[($i + 1)]['code'] !== T_DOC_COMMENT_WHITESPACE) { 147 $error = 'Expected 1 space after asterisk; 0 found'; 148 $fix = $phpcsFile->addFixableError($error, $i, 'NoSpaceAfterStar'); 149 if ($fix === true) { 150 $phpcsFile->fixer->addContent($i, ' '); 151 } 152 } else if ($tokens[($i + 2)]['code'] === T_DOC_COMMENT_TAG 153 && $tokens[($i + 1)]['content'] !== ' ' 154 ) { 155 $error = 'Expected 1 space after asterisk; %s found'; 156 $data = array(strlen($tokens[($i + 1)]['content'])); 157 $fix = $phpcsFile->addFixableError($error, $i, 'SpaceAfterStar', $data); 158 if ($fix === true) { 159 $phpcsFile->fixer->replaceToken(($i + 1), ' '); 160 } 161 } 162 }//end for 163 164 }//end process() 165 166 167}//end class 168