33namespace PHPStan \Rules ;
44
55use PhpParser \Node ;
6+ use PhpParser \Node \Expr \Variable ;
67use PHPStan \Analyser \Scope ;
78use PHPStan \Reflection \ReflectionProvider ;
9+ use PHPStan \ShouldNotHappenException ;
810use PHPStan \Type \Constant \ConstantStringType ;
9- use function array_fill_keys ;
10- use function array_keys ;
11+ use function array_combine ;
12+ use function array_map ;
1113use function array_merge ;
1214use function is_array ;
1315use function is_string ;
1618final class UnusedFunctionParametersCheck
1719{
1820
19- public function __construct (private ReflectionProvider $ reflectionProvider )
21+ public function __construct (
22+ private ReflectionProvider $ reflectionProvider ,
23+ private bool $ reportExactLine ,
24+ )
2025 {
2126 }
2227
2328 /**
24- * @param string [] $parameterNames
29+ * @param Variable [] $parameterVars
2530 * @param Node[] $statements
2631 * @param 'constructor.unusedParameter'|'closure.unusedUse' $identifier
2732 * @return list<IdentifierRuleError>
2833 */
2934 public function getUnusedParameters (
3035 Scope $ scope ,
31- array $ parameterNames ,
36+ array $ parameterVars ,
3237 array $ statements ,
3338 string $ unusedParameterMessage ,
3439 string $ identifier ,
3540 ): array
3641 {
37- $ unusedParameters = array_fill_keys ($ parameterNames , true );
42+ $ parameterNames = array_map (static function (Variable $ variable ): string {
43+ if (!is_string ($ variable ->name )) {
44+ throw new ShouldNotHappenException ();
45+ }
46+ return $ variable ->name ;
47+ }, $ parameterVars );
48+ $ unusedParameters = array_combine ($ parameterNames , $ parameterVars );
3849 foreach ($ this ->getUsedVariables ($ scope , $ statements ) as $ variableName ) {
3950 if (!isset ($ unusedParameters [$ variableName ])) {
4051 continue ;
@@ -43,10 +54,12 @@ public function getUnusedParameters(
4354 unset($ unusedParameters [$ variableName ]);
4455 }
4556 $ errors = [];
46- foreach (array_keys ($ unusedParameters ) as $ name ) {
47- $ errors [] = RuleErrorBuilder::message (
48- sprintf ($ unusedParameterMessage , $ name ),
49- )->identifier ($ identifier )->build ();
57+ foreach ($ unusedParameters as $ name => $ variable ) {
58+ $ errorBuilder = RuleErrorBuilder::message (sprintf ($ unusedParameterMessage , $ name ))->identifier ($ identifier );
59+ if ($ this ->reportExactLine ) {
60+ $ errorBuilder ->line ($ variable ->getStartLine ());
61+ }
62+ $ errors [] = $ errorBuilder ->build ();
5063 }
5164
5265 return $ errors ;
@@ -66,7 +79,7 @@ private function getUsedVariables(Scope $scope, $node): array
6679 return $ scope ->getDefinedVariables ();
6780 }
6881 }
69- if ($ node instanceof Node \ Expr \ Variable && is_string ($ node ->name ) && $ node ->name !== 'this ' ) {
82+ if ($ node instanceof Variable && is_string ($ node ->name ) && $ node ->name !== 'this ' ) {
7083 return [$ node ->name ];
7184 }
7285 if ($ node instanceof Node \ClosureUse && is_string ($ node ->var ->name )) {
0 commit comments