Skip to content

Commit ba413d9

Browse files
authored
[CodeQuality] Skip used by static closure use on ControllerMethodInjectionToConstructorRector (#928)
1 parent 8e2adf2 commit ba413d9

2 files changed

Lines changed: 56 additions & 0 deletions

File tree

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\Symfony\Tests\CodeQuality\Rector\Class_\ControllerMethodInjectionToConstructorRector\Fixture;
6+
7+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
8+
use Symfony\Component\Routing\Annotation\Route;
9+
10+
final class SkipUsedByStaticClosureUse extends AbstractController
11+
{
12+
public function example(Foo $foo): Response
13+
{
14+
dump($foo);
15+
16+
$problematic = static function() use ($foo): void {
17+
dump($foo);
18+
};
19+
20+
$problematic();
21+
}
22+
}

rules/CodeQuality/Rector/Class_/ControllerMethodInjectionToConstructorRector.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PhpParser\Node\Name\FullyQualified;
1313
use PhpParser\Node\Stmt\Class_;
1414
use PhpParser\Node\Stmt\ClassMethod;
15+
use PhpParser\NodeVisitor;
1516
use PHPStan\Type\ObjectType;
1617
use Rector\NodeManipulator\ClassDependencyManipulator;
1718
use Rector\NodeTypeResolver\Node\AttributeKey;
@@ -208,6 +209,10 @@ public function refactor(Node $node): ?Node
208209
continue;
209210
}
210211

212+
if ($this->isUsedInStaticClosureUse($classMethod, $this->getName($param->var))) {
213+
continue;
214+
}
215+
211216
unset($classMethod->params[$key]);
212217
$propertyMetadatas[] = new PropertyMetadata($this->getName($param->var), $paramType);
213218
}
@@ -279,6 +284,35 @@ private function hasConflictedParamName(
279284
return false;
280285
}
281286

287+
private function isUsedInStaticClosureUse(ClassMethod $classMethod, string $paramName): bool
288+
{
289+
if ($classMethod->stmts === null) {
290+
return false;
291+
}
292+
293+
$found = false;
294+
$this->traverseNodesWithCallable($classMethod->stmts, function (Node $node) use ($paramName, &$found): ?int {
295+
if (! $node instanceof Closure) {
296+
return null;
297+
}
298+
299+
if (! $node->static) {
300+
return null;
301+
}
302+
303+
foreach ($node->uses as $closureUse) {
304+
if ($this->isName($closureUse->var, $paramName)) {
305+
$found = true;
306+
return NodeVisitor::STOP_TRAVERSAL;
307+
}
308+
}
309+
310+
return null;
311+
});
312+
313+
return $found;
314+
}
315+
282316
/**
283317
* @param string[] $paramNamesToReplace
284318
*/

0 commit comments

Comments
 (0)