77use PHP_CodeSniffer \Exceptions \DeepExitException ;
88use PHP_CodeSniffer \Files \File ;
99use PHP_CodeSniffer \Sniffs \Sniff ;
10- use PHP_CodeSniffer \Util \Common ;
1110use SymfonyCustom \Helpers \SniffHelper ;
1211
1312/**
@@ -69,12 +68,18 @@ class ValidTypeHintSniff implements Sniff
6968 |
7069 (?<classString>
7170 class-string(?:
72- \s*<\s*[ \\\\\w]+\s*>
71+ \s*<\s*
72+ (?<classStringContent>
73+ (?&simple)
74+ )
75+ \s*>
7376 )?
7477 )
7578 |
7679 (?<simple>
77- [@$?]?[ \\\\\w]+
80+ \\\\?\w+(?: \\\\\w+)*
81+ |
82+ \$this
7883 )
7984 )
8085 )
@@ -84,6 +89,36 @@ class-string(?:
8489 )
8590 ' ;
8691
92+ private const PRIMITIVES_TYPES = [
93+ 'string ' ,
94+ 'int ' ,
95+ 'float ' ,
96+ 'bool ' ,
97+ 'array ' ,
98+ 'resource ' ,
99+ 'null ' ,
100+ 'callable ' ,
101+ 'iterable ' ,
102+ ];
103+ private const KEYWORD_TYPES = [
104+ 'mixed ' ,
105+ 'void ' ,
106+ 'object ' ,
107+ 'number ' ,
108+ 'false ' ,
109+ 'true ' ,
110+ 'self ' ,
111+ 'static ' ,
112+ '$this ' ,
113+ ];
114+ private const ALIAS_TYPES = [
115+ 'boolean ' => 'bool ' ,
116+ 'integer ' => 'int ' ,
117+ 'double ' => 'float ' ,
118+ 'real ' => 'float ' ,
119+ 'callback ' => 'callable ' ,
120+ ];
121+
87122 /**
88123 * @return array
89124 */
@@ -105,7 +140,7 @@ public function process(File $phpcsFile, $stackPtr): void
105140 }
106141
107142 $ matchingResult = preg_match (
108- '{^ ' .self ::REGEX_TYPES .'(?:[\s\t].*)?$}sx ' ,
143+ '{^ ' .self ::REGEX_TYPES .'(?:[\s\t].*)?$}six ' ,
109144 $ tokens [$ stackPtr + 2 ]['content ' ],
110145 $ matches
111146 );
@@ -153,16 +188,18 @@ private function getValidTypes(string $content): string
153188 $ types = [];
154189 $ separators = [];
155190 while ('' !== $ content && false !== $ content ) {
156- preg_match ('{^ ' .self ::REGEX_TYPES .'$}x ' , $ content , $ matches );
191+ preg_match ('{^ ' .self ::REGEX_TYPES .'$}ix ' , $ content , $ matches );
157192
158- if (isset ($ matches ['multiple ' ]) && '' !== $ matches ['multiple ' ]) {
193+ if (isset ($ matches ['array ' ]) && '' !== $ matches ['array ' ]) {
194+ $ validType = $ this ->getValidTypes (substr ($ matches ['array ' ], 0 , -2 )).'[] ' ;
195+ } elseif (isset ($ matches ['multiple ' ]) && '' !== $ matches ['multiple ' ]) {
159196 $ validType = '( ' .$ this ->getValidTypes ($ matches ['mutipleContent ' ]).') ' ;
160197 } elseif (isset ($ matches ['generic ' ]) && '' !== $ matches ['generic ' ]) {
161198 $ validType = $ this ->getValidGenericType ($ matches ['genericName ' ], $ matches ['genericContent ' ]);
162199 } elseif (isset ($ matches ['object ' ]) && '' !== $ matches ['object ' ]) {
163200 $ validType = $ this ->getValidObjectType ($ matches ['objectContent ' ]);
164- } elseif (isset ($ matches ['array ' ]) && '' !== $ matches ['array ' ]) {
165- $ validType = $ this -> getValidTypes ( substr ( $ matches [ ' array ' ], 0 , - 2 )). ' [] ' ;
201+ } elseif (isset ($ matches ['classString ' ]) && '' !== $ matches ['classString ' ]) {
202+ $ validType = preg_replace ( ' /class-string/i ' , ' class-string ' , $ matches [ ' classString ' ]) ;
166203 } else {
167204 $ validType = $ this ->getValidType ($ matches ['type ' ]);
168205 }
@@ -225,7 +262,7 @@ private function getValidGenericType(string $genericName, string $genericContent
225262 $ validType = $ this ->getValidType ($ genericName ).'< ' ;
226263
227264 while ('' !== $ genericContent && false !== $ genericContent ) {
228- preg_match ('{^ ' .self ::REGEX_TYPES .',?}x ' , $ genericContent , $ matches );
265+ preg_match ('{^ ' .self ::REGEX_TYPES .',?}ix ' , $ genericContent , $ matches );
229266
230267 $ validType .= $ this ->getValidTypes ($ matches ['types ' ]).', ' ;
231268 $ genericContent = substr ($ genericContent , strlen ($ matches ['types ' ]) + 1 );
@@ -253,7 +290,7 @@ private function getValidObjectType(string $objectContent): string
253290 $ objectContent = $ split [2 ];
254291 }
255292
256- preg_match ('{^ ' .self ::REGEX_TYPES .',?}x ' , $ objectContent , $ matches );
293+ preg_match ('{^ ' .self ::REGEX_TYPES .',?}ix ' , $ objectContent , $ matches );
257294
258295 $ validType .= $ this ->getValidTypes ($ matches ['types ' ]).', ' ;
259296 $ objectContent = substr ($ objectContent , strlen ($ matches ['types ' ]) + 1 );
@@ -270,15 +307,14 @@ private function getValidObjectType(string $objectContent): string
270307 private function getValidType (string $ typeName ): string
271308 {
272309 $ lowerType = strtolower ($ typeName );
273- switch ($ lowerType ) {
274- case 'bool ' :
275- case 'boolean ' :
276- return 'bool ' ;
277- case 'int ' :
278- case 'integer ' :
279- return 'int ' ;
310+ if (in_array ($ lowerType , self ::PRIMITIVES_TYPES ) || in_array ($ lowerType , self ::KEYWORD_TYPES )) {
311+ return $ lowerType ;
312+ }
313+
314+ if (isset (self ::ALIAS_TYPES [$ lowerType ])) {
315+ return self ::ALIAS_TYPES [$ lowerType ];
280316 }
281317
282- return Common:: suggestType ( $ typeName) ;
318+ return $ typeName ;
283319 }
284320}
0 commit comments