@@ -119,13 +119,14 @@ public static function findOopContext(File $file, int $position): int
119119 $ targetLevel = (int )$ tokens [$ position ]['level ' ] - 1 ;
120120
121121 foreach ($ tokens [$ position ]['conditions ' ] as $ condPosition => $ condCode ) {
122+ assert (is_int ($ condPosition ));
122123 $ condLevel = (int )($ tokens [$ condPosition ]['level ' ] ?? -1 );
123124
124125 if (
125126 in_array ($ condCode , Tokens::$ ooScopeTokens , true )
126127 && ($ condLevel === $ targetLevel )
127128 ) {
128- return ( int ) $ condPosition ;
129+ return $ condPosition ;
129130 }
130131 }
131132
@@ -288,7 +289,7 @@ public static function isHookClosure(
288289 /** @var array<int, array<string, mixed>> $tokens */
289290 $ tokens = $ file ->getTokens ();
290291
291- if (( $ tokens [$ position ]['code ' ] ?? '' ) !== T_CLOSURE ) {
292+ if (! in_array (( $ tokens [$ position ]['code ' ] ?? '' ), [ T_CLOSURE , T_FN ], true ) ) {
292293 return false ;
293294 }
294295
@@ -341,7 +342,7 @@ public static function functionDocBlockTags(
341342
342343 if (
343344 !array_key_exists ($ position , $ tokens )
344- || !in_array ($ tokens [$ position ]['code ' ], [T_FUNCTION , T_CLOSURE ], true )
345+ || !in_array ($ tokens [$ position ]['code ' ], [T_FUNCTION , T_CLOSURE , T_FN ], true )
345346 ) {
346347 return [];
347348 }
@@ -387,7 +388,7 @@ public static function functionDocBlockTags(
387388 $ normalizedTags = [];
388389 static $ rand ;
389390 $ rand or $ rand = bin2hex (random_bytes (3 ));
390- foreach ($ tags as list ( $ tagName , $ tagContent) ) {
391+ foreach ($ tags as [ $ tagName , $ tagContent] ) {
391392 empty ($ normalizedTags [$ tagName ]) and $ normalizedTags [$ tagName ] = [];
392393 if (!$ normalizeContent ) {
393394 $ normalizedTags [$ tagName ][] = $ tagContent ;
@@ -433,7 +434,7 @@ public static function functionDocBlockParamTypes(File $file, int $functionPosit
433434
434435 $ types = [];
435436 foreach ($ params as $ param ) {
436- preg_match ('~^([^$]+)\s*(\$(?:[^\s]+) )~ ' , trim ($ param ), $ matches );
437+ preg_match ('~^([^$]+)\s*(\$\S+ )~ ' , trim ($ param ), $ matches );
437438 if (empty ($ matches [1 ]) || empty ($ matches [2 ])) {
438439 continue ;
439440 }
@@ -461,7 +462,7 @@ public static function isHookFunction(File $file, int $position): bool
461462 */
462463 public static function functionBody (File $ file , int $ position ): string
463464 {
464- list ( $ start , $ end) = static ::functionBoundaries ($ file , $ position );
465+ [ $ start , $ end] = static ::functionBoundaries ($ file , $ position );
465466 if ($ start < 0 || $ end < 0 ) {
466467 return '' ;
467468 }
@@ -470,7 +471,7 @@ public static function functionBody(File $file, int $position): string
470471 $ tokens = $ file ->getTokens ();
471472 $ body = '' ;
472473 for ($ i = $ start + 1 ; $ i < $ end ; $ i ++) {
473- $ body .= (string )$ tokens [$ i ]['content ' ];
474+ $ body .= (string )( $ tokens [$ i ]['content ' ] ?? '' ) ;
474475 }
475476
476477 return $ body ;
@@ -479,30 +480,24 @@ public static function functionBody(File $file, int $position): string
479480 /**
480481 * @param File $file
481482 * @param int $position
482- * @return array {int, int}
483+ * @return list {int, int}
483484 */
484485 public static function functionBoundaries (File $ file , int $ position ): array
485486 {
486487 /** @var array<int, array<string, mixed>> $tokens */
487488 $ tokens = $ file ->getTokens ();
488489
489- if (!in_array (($ tokens [$ position ]['code ' ] ?? null ), [T_FUNCTION , T_CLOSURE ], true )) {
490+ if (!in_array (($ tokens [$ position ]['code ' ] ?? null ), [T_FUNCTION , T_CLOSURE , T_FN ], true )) {
490491 return [-1 , -1 ];
491492 }
492493
493- $ functionStart = (int )($ tokens [$ position ]['scope_opener ' ] ?? 0 );
494- $ functionEnd = (int )($ tokens [$ position ]['scope_closer ' ] ?? 0 );
495- if ($ functionStart <= 0 || $ functionEnd <= 0 || $ functionStart >= ($ functionEnd - 1 )) {
496- return [-1 , -1 ];
497- }
498- 499- return [$ functionStart , $ functionEnd ];
494+ return static ::boundaries ($ tokens , $ position );
500495 }
501496
502497 /**
503498 * @param File $file
504499 * @param int $position
505- * @return array {int, int}
500+ * @return list {int, int}
506501 */
507502 public static function classBoundaries (File $ file , int $ position ): array
508503 {
@@ -513,13 +508,7 @@ public static function classBoundaries(File $file, int $position): array
513508 return [-1 , -1 ];
514509 }
515510
516- $ start = (int )($ tokens [$ position ]['scope_opener ' ] ?? 0 );
517- $ end = (int )($ tokens [$ position ]['scope_closer ' ] ?? 0 );
518- if ($ start <= 0 || $ end <= 0 || $ start >= ($ end - 1 )) {
519- return [-1 , -1 ];
520- }
521- 522- return [$ start , $ end ];
511+ return static ::boundaries ($ tokens , $ position );
523512 }
524513
525514 /**
@@ -531,18 +520,22 @@ public static function returnsCountInfo(File $file, int $position): array
531520 {
532521 $ returnCount = ['nonEmpty ' => 0 , 'void ' => 0 , 'null ' => 0 , 'total ' => 0 ];
533522
534- list ( $ start , $ end) = self ::functionBoundaries ($ file , $ position );
523+ [ $ start , $ end] = self ::functionBoundaries ($ file , $ position );
535524 if ($ start < 0 || $ end <= 0 ) {
536525 return $ returnCount ;
537526 }
538527
539528 /** @var array<int, array<string, mixed>> $tokens */
540529 $ tokens = $ file ->getTokens ();
541530
531+ if (T_FN === ($ tokens [$ position ]['code ' ] ?? null )) {
532+ return ['nonEmpty ' => 1 , 'void ' => 0 , 'null ' => 0 , 'total ' => 1 ];
533+ }
534+ 542535 $ pos = $ start + 1 ;
543536 while ($ pos < $ end ) {
544- list ( , $ innerFunctionEnd) = self ::functionBoundaries ($ file , $ pos );
545- list ( , $ innerClassEnd) = self ::classBoundaries ($ file , $ pos );
537+ [ , $ innerFunctionEnd] = self ::functionBoundaries ($ file , $ pos );
538+ [ , $ innerClassEnd] = self ::classBoundaries ($ file , $ pos );
546539 if ($ innerFunctionEnd > 0 || $ innerClassEnd > 0 ) {
547540 $ pos = ($ innerFunctionEnd > 0 ) ? $ innerFunctionEnd + 1 : $ innerClassEnd + 1 ;
548541 continue ;
@@ -723,4 +716,20 @@ public static function isUntypedPsrMethod(File $file, int $position): bool
723716
724717 return false ;
725718 }
719+ 720+ /**
721+ * @param array<int, array<string, mixed>> $tokens
722+ * @param int $position
723+ * @return list{int, int}
724+ */
725+ private static function boundaries (array $ tokens , int $ position ): array
726+ {
727+ $ start = (int )($ tokens [$ position ]['scope_opener ' ] ?? 0 );
728+ $ end = (int )($ tokens [$ position ]['scope_closer ' ] ?? 0 );
729+ if ($ start <= 0 || $ end <= 0 || $ start >= ($ end - 1 )) {
730+ return [-1 , -1 ];
731+ }
732+ 733+ return [$ start , $ end ];
734+ }
726735}
0 commit comments