1<?php 2/** 3 * Parses and verifies the variable doc comment. 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_AbstractVariableSniff', true) === false) { 17 throw new PHP_CodeSniffer_Exception('Class PHP_CodeSniffer_Standards_AbstractVariableSniff not found'); 18} 19 20/** 21 * Parses and verifies the variable doc comment. 22 * 23 * @category PHP 24 * @package PHP_CodeSniffer 25 * @author Greg Sherwood <gsherwood@squiz.net> 26 * @author Marc McIntyre <mmcintyre@squiz.net> 27 * @copyright 2006-2014 Squiz Pty Ltd (ABN 77 084 670 600) 28 * @license https://github.com/squizlabs/PHP_CodeSniffer/blob/master/licence.txt BSD Licence 29 * @version Release: @package_version@ 30 * @link http://pear.php.net/package/PHP_CodeSniffer 31 */ 32 33class Squiz_Sniffs_Commenting_VariableCommentSniff extends PHP_CodeSniffer_Standards_AbstractVariableSniff 34{ 35 36 37 /** 38 * Called to process class member vars. 39 * 40 * @param PHP_CodeSniffer_File $phpcsFile The file being scanned. 41 * @param int $stackPtr The position of the current token 42 * in the stack passed in $tokens. 43 * 44 * @return void 45 */ 46 public function processMemberVar(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 47 { 48 $tokens = $phpcsFile->getTokens(); 49 $ignore = array( 50 T_PUBLIC, 51 T_PRIVATE, 52 T_PROTECTED, 53 T_VAR, 54 T_STATIC, 55 T_WHITESPACE, 56 ); 57 58 $commentEnd = $phpcsFile->findPrevious($ignore, ($stackPtr - 1), null, true); 59 if ($commentEnd === false 60 || ($tokens[$commentEnd]['code'] !== T_DOC_COMMENT_CLOSE_TAG 61 && $tokens[$commentEnd]['code'] !== T_COMMENT) 62 ) { 63 $phpcsFile->addError('Missing member variable doc comment', $stackPtr, 'Missing'); 64 return; 65 } 66 67 if ($tokens[$commentEnd]['code'] === T_COMMENT) { 68 $phpcsFile->addError('You must use "/**" style comments for a member variable comment', $stackPtr, 'WrongStyle'); 69 return; 70 } 71 72 $commentStart = $tokens[$commentEnd]['comment_opener']; 73 74 $foundVar = null; 75 foreach ($tokens[$commentStart]['comment_tags'] as $tag) { 76 if ($tokens[$tag]['content'] === '@var') { 77 if ($foundVar !== null) { 78 $error = 'Only one @var tag is allowed in a member variable comment'; 79 $phpcsFile->addError($error, $tag, 'DuplicateVar'); 80 } else { 81 $foundVar = $tag; 82 } 83 } else if ($tokens[$tag]['content'] === '@see') { 84 // Make sure the tag isn't empty. 85 $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $tag, $commentEnd); 86 if ($string === false || $tokens[$string]['line'] !== $tokens[$tag]['line']) { 87 $error = 'Content missing for @see tag in member variable comment'; 88 $phpcsFile->addError($error, $tag, 'EmptySees'); 89 } 90 } else { 91 $error = '%s tag is not allowed in member variable comment'; 92 $data = array($tokens[$tag]['content']); 93 $phpcsFile->addWarning($error, $tag, 'TagNotAllowed', $data); 94 }//end if 95 }//end foreach 96 97 // The @var tag is the only one we require. 98 if ($foundVar === null) { 99 $error = 'Missing @var tag in member variable comment'; 100 $phpcsFile->addError($error, $commentEnd, 'MissingVar'); 101 return; 102 } 103 104 $firstTag = $tokens[$commentStart]['comment_tags'][0]; 105 if ($foundVar !== null && $tokens[$firstTag]['content'] !== '@var') { 106 $error = 'The @var tag must be the first tag in a member variable comment'; 107 $phpcsFile->addError($error, $foundVar, 'VarOrder'); 108 } 109 110 // Make sure the tag isn't empty and has the correct padding. 111 $string = $phpcsFile->findNext(T_DOC_COMMENT_STRING, $foundVar, $commentEnd); 112 if ($string === false || $tokens[$string]['line'] !== $tokens[$foundVar]['line']) { 113 $error = 'Content missing for @var tag in member variable comment'; 114 $phpcsFile->addError($error, $foundVar, 'EmptyVar'); 115 return; 116 } 117 118 $varType = $tokens[($foundVar + 2)]['content']; 119 $suggestedType = PHP_CodeSniffer::suggestType($varType); 120 if ($varType !== $suggestedType) { 121 $error = 'Expected "%s" but found "%s" for @var tag in member variable comment'; 122 $data = array( 123 $suggestedType, 124 $varType, 125 ); 126 127 $fix = $phpcsFile->addFixableError($error, ($foundVar + 2), 'IncorrectVarType', $data); 128 if ($fix === true) { 129 $phpcsFile->fixer->replaceToken(($foundVar + 2), $suggestedType); 130 } 131 } 132 133 }//end processMemberVar() 134 135 136 /** 137 * Called to process a normal variable. 138 * 139 * Not required for this sniff. 140 * 141 * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this token was found. 142 * @param int $stackPtr The position where the double quoted 143 * string was found. 144 * 145 * @return void 146 */ 147 protected function processVariable(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 148 { 149 150 }//end processVariable() 151 152 153 /** 154 * Called to process variables found in double quoted strings. 155 * 156 * Not required for this sniff. 157 * 158 * @param PHP_CodeSniffer_File $phpcsFile The PHP_CodeSniffer file where this token was found. 159 * @param int $stackPtr The position where the double quoted 160 * string was found. 161 * 162 * @return void 163 */ 164 protected function processVariableInString(PHP_CodeSniffer_File $phpcsFile, $stackPtr) 165 { 166 167 }//end processVariableInString() 168 169 170}//end class 171