1717
1818final class CallableDefinitionSniff implements Sniff
1919{
20- public string $ syntax ;
21- public bool $ includeClosure = true ;
20+ private const WARNING = 'Callable description should contain definition ' ;
21+
22+ private const FORMAT_EXPLAIN = [
23+ 'short ' => 'fn(ArgType,...) => ReturnType ' ,
24+ 'long ' => 'function(ArgType,...): ReturnType '
25+ ];
2226
23- private $ regexp = [
27+ private const FORMAT_REGEXP = [
2428 'short ' => '#fn\([?a-zA-Z \\\\, |]*\) => \??[a-zA-Z \\\\|]+# ' ,
2529 'long ' => '#function\([?a-zA-Z \\\\, |]*\): \??[a-zA-Z \\\\|]+# '
2630 ];
2731
32+ public string $ syntax = 'both ' ;
33+ public bool $ includeClosure = true ;
34+
2835 public function register (): array
2936 {
3037 return [T_CLASS , T_TRAIT , T_INTERFACE ];
@@ -38,25 +45,23 @@ public function process(File $phpcsFile, $stackPtr): void
3845 if ($ tag !== '@param ' && $ tag !== '@return ' ) { continue ; }
3946
4047 if (!$ this ->validDescription ($ tokens [$ stackPtr + 2 ]['content ' ], $ tag === '@param ' )) {
41- $ phpcsFile ->addWarning (' Callable param description should contain definition ' , $ stackPtr , 'Found ' );
48+ $ phpcsFile ->addWarning ($ this -> warningMessage () , $ stackPtr , 'Found ' );
4249 }
4350 }
4451 }
4552
46- private function validDescription (string $ line , bool $ variable = true ): bool
53+ private function validDescription (string $ line , bool $ forArgument ): bool
4754 {
4855 if (!$ this ->isLambda ($ line )) { return true ; }
4956
50- $ varStart = $ variable ? strpos ($ line , '$ ' , 8 ) : 1 ;
57+ $ varStart = $ forArgument ? strpos ($ line , '$ ' , 8 ) : 1 ;
5158 $ descriptionStart = $ varStart ? strpos ($ line , ' ' , $ varStart ) : 0 ;
5259 $ description = $ descriptionStart ? trim (substr ($ line , $ descriptionStart )) : '' ;
5360 if (!$ description ) { return false ; }
5461
55- if (isset ($ this ->syntax , $ this ->regexp [$ this ->syntax ])) {
56- return (bool ) preg_match ($ this ->regexp [$ this ->syntax ], $ description );
57- }
58-
59- foreach ($ this ->regexp as $ syntax => $ pattern ) {
62+ $ selected = self ::FORMAT_REGEXP [$ this ->syntax ] ?? null ;
63+ $ patterns = $ selected ? [$ selected ] : array_values (self ::FORMAT_REGEXP );
64+ foreach ($ patterns as $ pattern ) {
6065 if (preg_match ($ pattern , $ description )) { return true ; }
6166 }
6267
@@ -75,6 +80,13 @@ private function isLambda(string $line): bool
7580 $ type = substr ($ type , 0 , -2 );
7681 }
7782
78- return $ type === 'callable ' || ($ this ->includeClosure && $ type === 'Closure ' );
83+ return $ type === 'callable ' || $ this ->includeClosure && $ type === 'Closure ' ;
84+ }
85+
86+ private function warningMessage (): string
87+ {
88+ $ selected = self ::FORMAT_EXPLAIN [$ this ->syntax ] ?? null ;
89+ $ format = $ selected ?: implode ('` or ` ' , self ::FORMAT_EXPLAIN );
90+ return self ::WARNING . ' [format: ` ' . $ format . '`] ' ;
7991 }
8092}
0 commit comments