@@ -37,6 +37,16 @@ class ClassPropertyPHPDocFormattingSniff extends AbstractVariableSniff
3737 */
3838 private $ PHPDocFormattingValidator ;
3939
40+ /**
41+ * @var array
42+ */
43+ private $ invalidTypes = [
44+ 'null ' ,
45+ 'false ' ,
46+ 'true ' ,
47+ 'self '
48+ ];
49+
4050 /**
4151 * Constructs an ClassPropertyPHPDocFormattingSniff.
4252 */
@@ -62,7 +72,12 @@ public function processMemberVar(File $phpcsFile, $stackPtr)
6272 );
6373
6474 if ($ commentEnd === false || $ tokens [$ commentEnd ]['code ' ] !== T_DOC_COMMENT_CLOSE_TAG ) {
65- $ phpcsFile ->addWarning ('Missing PHP DocBlock for class property. ' , $ stackPtr , 'Missing ' );
75+ // if the property has a valid type definition, we don't require a doc block
76+ if (!$ this ->hasValidType ($ phpcsFile , $ stackPtr )) {
77+ $ phpcsFile ->addWarning (
78+ 'Missing PHP DocBlock for class property without valid type. ' , $ stackPtr , 'Missing ' );
79+ }
80+ // no comment, so nothing further to process
6681 return ;
6782 }
6883
@@ -121,10 +136,10 @@ public function processMemberVar(File $phpcsFile, $stackPtr)
121136 );
122137
123138 if ($ this ->PHPDocFormattingValidator ->providesMeaning (
124- $ shortDescriptionAfterVarPosition ,
125- $ commentStart ,
126- $ tokens
127- ) !== true ) {
139+ $ shortDescriptionAfterVarPosition ,
140+ $ commentStart ,
141+ $ tokens
142+ ) !== true ) {
128143 preg_match (
129144 '`^((?:\|?(?:array\([^\)]*\)|[ \\\\\[\]]+))*)( .*)?`i ' ,
130145 $ tokens [($ varAnnotationPosition + 2 )]['content ' ],
@@ -143,6 +158,30 @@ public function processMemberVar(File $phpcsFile, $stackPtr)
143158 $ this ->processPropertyShortDescription ($ phpcsFile , $ stackPtr , $ varAnnotationPosition , $ commentStart );
144159 }
145160
161+ /**
162+ * Check if class property has a valid (not specifically invalid) type
163+ *
164+ * @param File $phpcsFile
165+ * @param int $propertyPosition
166+ * @return bool
167+ */
168+ private function hasValidType (File $ phpcsFile , int $ propertyPosition ): bool
169+ {
170+ // type token should be 2 before property. If not present, visibility token should be in its place
171+ $ typePosition = $ phpcsFile ->findPrevious (
172+ [T_STRING ],
173+ $ propertyPosition ,
174+ $ propertyPosition - 2
175+ );
176+
177+ if (!$ typePosition ) {
178+ return false ;
179+ }
180+
181+ $ type = $ phpcsFile ->getTokensAsString ($ typePosition , 1 );
182+ return !in_array (strtolower ($ type ), $ this ->invalidTypes );
183+ }
184+
146185 /**
147186 * Check if class has already have meaningful description before var tag
148187 *
0 commit comments