77use PHP_CodeSniffer \Files \File ;
88use PHP_CodeSniffer \Sniffs \Sniff ;
99use PHP_CodeSniffer \Util \Common ;
10- use PHP_CodeSniffer \Util \Tokens ;
1110use SymfonyCustom \Helpers \SniffHelper ;
1211
1312/**
1413 * Throws errors if scalar type name are not valid.
1514 */
1615class ValidScalarTypeNameSniff implements Sniff
1716{
17+ private const TYPING = '\\\\a-z0-9 ' ;
18+ private const OPENER = '\<\[\{\( ' ;
19+ private const CLOSER = '\>\]\}\) ' ;
20+ private const MIDDLE = '\,\:\&\| ' ;
21+
1822 /**
1923 * @return array
2024 */
@@ -33,7 +37,11 @@ public function process(File $phpcsFile, $stackPtr): void
3337
3438 if (in_array ($ tokens [$ stackPtr ]['content ' ], SniffHelper::TAGS_WITH_TYPE )) {
3539 preg_match (
36- '`^((?:\|?(?:array\([^\)]*\)|[ \\\\a-z0-9\[\<\,\>\]]+))*)( .*)?`i ' ,
40+ '`^((?: '
41+ .'[ ' .self ::OPENER .self ::MIDDLE .']\s* '
42+ .'|(?:[ ' .self ::TYPING .self ::CLOSER .']\s+)(?=[\| ' .self ::OPENER .self ::MIDDLE .self ::CLOSER .']) '
43+ .'|[ ' .self ::TYPING .self ::CLOSER .'] '
44+ .')+)(.*)?`i ' ,
3745 $ tokens [($ stackPtr + 2 )]['content ' ],
3846 $ match
3947 );
@@ -44,17 +52,7 @@ public function process(File $phpcsFile, $stackPtr): void
4452
4553 // Check type (can be multiple, separated by '|').
4654 $ type = $ match [1 ];
47- $ typeNames = explode ('| ' , $ type );
48- $ suggestedNames = [];
49- foreach ($ typeNames as $ i => $ typeName ) {
50- $ suggestedName = $ this ->getValidTypeName ($ typeName );
51-
52- if (in_array ($ suggestedName , $ suggestedNames , true ) === false ) {
53- $ suggestedNames [] = $ suggestedName ;
54- }
55- }
56-
57- $ suggestedType = implode ('| ' , $ suggestedNames );
55+ $ suggestedType = $ this ->getValidTypeName ($ type );
5856 if ($ type !== $ suggestedType ) {
5957 $ fix = $ phpcsFile ->addFixableError (
6058 'For type-hinting in PHPDocs, use %s instead of %s ' ,
@@ -82,7 +80,13 @@ public function process(File $phpcsFile, $stackPtr): void
8280 */
8381 private function getValidTypeName (string $ typeName ): string
8482 {
85- $ parts = preg_split ('/([\<\,\>])/ ' , $ typeName , -1 , PREG_SPLIT_DELIM_CAPTURE );
83+ $ typeNameWithoutSpace = str_replace (' ' , '' , $ typeName );
84+ $ parts = preg_split (
85+ '/([\| ' .self ::OPENER .self ::MIDDLE .self ::CLOSER .'])/ ' ,
86+ $ typeNameWithoutSpace ,
87+ -1 ,
88+ PREG_SPLIT_DELIM_CAPTURE
89+ );
8690 $ partsNumber = count ($ parts ) - 1 ;
8791
8892 $ validType = '' ;
@@ -104,10 +108,6 @@ private function getValidTypeName(string $typeName): string
104108 */
105109 private function suggestType (string $ typeName ): string
106110 {
107- if ('[] ' === substr ($ typeName , -2 )) {
108- return $ this ->suggestType (substr ($ typeName , 0 , -2 )).'[] ' ;
109- }
110-
111111 $ lowerType = strtolower ($ typeName );
112112 switch ($ lowerType ) {
113113 case 'bool ' :
0 commit comments