Skip to content

Commit 799b454

Browse files
authored
[CodeQuality] Skip Request param used by caller method on RemoveUnusedRequestParamRector (#675)
1 parent 974034e commit 799b454

File tree

2 files changed

+65
-31
lines changed

2 files changed

+65
-31
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Rector\Symfony\Tests\CodeQuality\Rector\ClassMethod\RemoveUnusedRequestParamRector\Fixture;
4+
5+
use Symfony\Component\HttpFoundation\Request;
6+
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
7+
8+
final class SkipUsedRequestParamOnCaller extends Controller
9+
{
10+
public function run(Request $request)
11+
{
12+
$this->verify($request);
13+
}
14+
15+
public function verify(Request $request)
16+
{
17+
}
18+
}

rules/CodeQuality/Rector/ClassMethod/RemoveUnusedRequestParamRector.php

Lines changed: 47 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,15 @@
66

77
use PhpParser\Node;
88
use PhpParser\Node\Expr\Variable;
9+
use PhpParser\Node\Stmt\Class_;
910
use PhpParser\Node\Stmt\ClassMethod;
11+
use PHPStan\Analyser\Scope;
1012
use PHPStan\Reflection\ClassReflection;
1113
use PHPStan\Type\ObjectType;
14+
use Rector\DeadCode\NodeAnalyzer\IsClassMethodUsedAnalyzer;
1215
use Rector\FamilyTree\NodeAnalyzer\ClassChildAnalyzer;
1316
use Rector\PhpParser\Node\BetterNodeFinder;
14-
use Rector\Rector\AbstractRector;
17+
use Rector\Rector\AbstractScopeAwareRector;
1518
use Rector\Reflection\ReflectionResolver;
1619
use Rector\Symfony\TypeAnalyzer\ControllerAnalyzer;
1720
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@@ -20,13 +23,14 @@
2023
/**
2124
* @see \Rector\Symfony\Tests\CodeQuality\Rector\ClassMethod\RemoveUnusedRequestParamRector\RemoveUnusedRequestParamRectorTest
2225
*/
23-
final class RemoveUnusedRequestParamRector extends AbstractRector
26+
final class RemoveUnusedRequestParamRector extends AbstractScopeAwareRector
2427
{
2528
public function __construct(
2629
private readonly ControllerAnalyzer $controllerAnalyzer,
2730
private readonly ReflectionResolver $reflectionResolver,
2831
private readonly ClassChildAnalyzer $classChildAnalyzer,
2932
private readonly BetterNodeFinder $betterNodeFinder,
33+
private readonly IsClassMethodUsedAnalyzer $isClassMethodUsedAnalyzer
3034
) {
3135
}
3236

@@ -69,56 +73,68 @@ public function run(int $id)
6973
*/
7074
public function getNodeTypes(): array
7175
{
72-
return [ClassMethod::class];
76+
return [Class_::class];
7377
}
7478

7579
/**
76-
* @param ClassMethod $node
80+
* @param Class_ $node
7781
*/
78-
public function refactor(Node $node): ?Node
82+
public function refactorWithScope(Node $node, Scope $scope): ?Node
7983
{
80-
if (! $node->isPublic()) {
81-
return null;
82-
}
83-
84-
if ($node->isAbstract() || $this->hasAbstractParentClassMethod($node)) {
85-
return null;
86-
}
87-
8884
if (! $this->controllerAnalyzer->isInsideController($node)) {
8985
return null;
9086
}
9187

92-
if ($node->getParams() === []) {
93-
return null;
94-
}
88+
$hasChanged = false;
9589

96-
// skip empty method
97-
if ($node->stmts === null) {
98-
return null;
99-
}
90+
foreach ($node->getMethods() as $classMethod) {
91+
if (! $classMethod->isPublic()) {
92+
continue;
93+
}
94+
95+
if ($classMethod->isAbstract() || $this->hasAbstractParentClassMethod($classMethod)) {
96+
continue;
97+
}
10098

101-
foreach ($node->getParams() as $paramPosition => $param) {
102-
if (! $param->type instanceof Node) {
99+
if ($classMethod->getParams() === []) {
103100
continue;
104101
}
105102

106-
if (! $this->isObjectType($param->type, new ObjectType('Symfony\Component\HttpFoundation\Request'))) {
103+
// skip empty method
104+
if ($classMethod->stmts === null) {
107105
continue;
108106
}
109107

110-
/** @var string $requestParamName */
111-
$requestParamName = $this->getName($param);
108+
foreach ($classMethod->getParams() as $paramPosition => $param) {
109+
if (! $param->type instanceof Node) {
110+
continue;
111+
}
112112

113-
// we have request param here
114-
$requestVariable = $this->betterNodeFinder->findVariableOfName($node->stmts, $requestParamName);
113+
if (! $this->isObjectType($param->type, new ObjectType('Symfony\Component\HttpFoundation\Request'))) {
114+
continue;
115+
}
115116

116-
// is variable used?
117-
if ($requestVariable instanceof Variable) {
118-
return null;
117+
/** @var string $requestParamName */
118+
$requestParamName = $this->getName($param);
119+
120+
// we have request param here
121+
$requestVariable = $this->betterNodeFinder->findVariableOfName($classMethod->stmts, $requestParamName);
122+
123+
// is variable used?
124+
if ($requestVariable instanceof Variable) {
125+
continue 2;
126+
}
127+
128+
if ($this->isClassMethodUsedAnalyzer->isClassMethodUsed($node, $classMethod, $scope)) {
129+
continue 2;
130+
}
131+
132+
unset($classMethod->params[$paramPosition]);
133+
$hasChanged = true;
119134
}
135+
}
120136

121-
unset($node->params[$paramPosition]);
137+
if ($hasChanged) {
122138
return $node;
123139
}
124140

0 commit comments

Comments
 (0)