Skip to content

Commit 37a0957

Browse files
committed
add SymfonyClosureNodeVisitor
1 parent 8e2ae85 commit 37a0957

File tree

5 files changed

+53
-13
lines changed

5 files changed

+53
-13
lines changed

phpstan.neon

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,3 +387,12 @@ parameters:
387387
-
388388
path: rules/TypeDeclaration/Rector/StmtsAwareInterface/IncreaseDeclareStrictTypesRector.php
389389
identifier: rector.noOnlyNullReturnInRefactor
390+
391+
# handle next
392+
-
393+
identifier: rector.noIntegerRefactorReturn
394+
paths:
395+
- rules/CodeQuality/Rector/FuncCall/SetTypeToCastRector.php
396+
- rules/Php55/Rector/String_/StringClassNameToClassConstantRector.php
397+
- rules/Php80/Rector/Switch_/ChangeSwitchToMatchRector.php
398+
- tests/Issues/InfiniteLoop/Rector/MethodCall/InfinityLoopRector.php

rules/Php81/Rector/Array_/FirstClassCallableRector.php

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,11 @@
77
use PhpParser\Node;
88
use PhpParser\Node\Expr\Array_;
99
use PhpParser\Node\Expr\ClassConstFetch;
10-
use PhpParser\Node\Expr\Closure;
1110
use PhpParser\Node\Expr\MethodCall;
1211
use PhpParser\Node\Expr\PropertyFetch;
1312
use PhpParser\Node\Expr\StaticCall;
1413
use PhpParser\Node\Expr\Variable;
1514
use PhpParser\Node\VariadicPlaceholder;
16-
use PhpParser\NodeVisitor;
1715
use PHPStan\Analyser\Scope;
1816
use PHPStan\Reflection\ClassReflection;
1917
use PHPStan\Reflection\ReflectionProvider;
@@ -24,7 +22,6 @@
2422
use Rector\Rector\AbstractRector;
2523
use Rector\Reflection\ReflectionResolver;
2624
use Rector\StaticTypeMapper\ValueObject\Type\FullyQualifiedObjectType;
27-
use Rector\Symfony\NodeAnalyzer\SymfonyPhpClosureDetector;
2825
use Rector\ValueObject\PhpVersion;
2926
use Rector\VersionBonding\Contract\MinPhpVersionInterface;
3027
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@@ -40,7 +37,6 @@ public function __construct(
4037
private readonly ArrayCallableMethodMatcher $arrayCallableMethodMatcher,
4138
private readonly ReflectionProvider $reflectionProvider,
4239
private readonly ReflectionResolver $reflectionResolver,
43-
private readonly SymfonyPhpClosureDetector $symfonyPhpClosureDetector
4440
) {
4541
}
4642

@@ -85,20 +81,15 @@ public function name()
8581
*/
8682
public function getNodeTypes(): array
8783
{
88-
return [Array_::class, Closure::class];
84+
return [Array_::class];
8985
}
9086

9187
/**
92-
* @param Array_|Closure $node
93-
* @return StaticCall|MethodCall|null|NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN
88+
* @param Array_ $node
9489
*/
95-
public function refactor(Node $node): StaticCall|MethodCall|null|int
90+
public function refactor(Node $node): StaticCall|MethodCall|null
9691
{
97-
if ($node instanceof Closure) {
98-
if ($this->symfonyPhpClosureDetector->detect($node)) {
99-
return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
100-
}
101-
92+
if ($node->getAttribute(AttributeKey::IS_INSIDE_SYMFONY_PHP_CLOSURE)) {
10293
return null;
10394
}
10495

src/DependencyInjection/LazyContainerFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,7 @@
104104
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\NameNodeVisitor;
105105
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\PropertyOrClassConstDefaultNodeVisitor;
106106
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\StaticVariableNodeVisitor;
107+
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\SymfonyClosureNodeVisitor;
107108
use Rector\NodeTypeResolver\PHPStan\Scope\PHPStanNodeScopeResolver;
108109
use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocatorProvider;
109110
use Rector\Php80\AttributeDecorator\DoctrineConverterAttributeDecorator;
@@ -238,6 +239,7 @@ final class LazyContainerFactory
238239
private const DECORATING_NODE_VISITOR_CLASSES = [
239240
ArgNodeVisitor::class,
240241
AssignedToNodeVisitor::class,
242+
SymfonyClosureNodeVisitor::class,
241243
ByRefReturnNodeVisitor::class,
242244
ByRefVariableNodeVisitor::class,
243245
ContextNodeVisitor::class,

src/NodeTypeResolver/Node/AttributeKey.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -290,4 +290,6 @@ final class AttributeKey
290290
public const IS_DEFAULT_PROPERTY_VALUE = 'is_default_property_value';
291291

292292
public const IS_CLASS_CONST_VALUE = 'is_default_class_const_value';
293+
294+
public const IS_INSIDE_SYMFONY_PHP_CLOSURE = 'is_inside_symfony_php_closure';
293295
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor;
6+
7+
use PhpParser\Node;
8+
use PhpParser\Node\Expr\Closure;
9+
use PhpParser\NodeVisitorAbstract;
10+
use Rector\Contract\PhpParser\DecoratingNodeVisitorInterface;
11+
use Rector\NodeTypeResolver\Node\AttributeKey;
12+
use Rector\PhpParser\NodeTraverser\SimpleTraverser;
13+
use Rector\Symfony\NodeAnalyzer\SymfonyPhpClosureDetector;
14+
15+
final class SymfonyClosureNodeVisitor extends NodeVisitorAbstract implements DecoratingNodeVisitorInterface
16+
{
17+
public function __construct(
18+
private readonly SymfonyPhpClosureDetector $symfonyPhpClosureDetector
19+
) {
20+
}
21+
22+
public function enterNode(Node $node): ?Node
23+
{
24+
if (! $node instanceof Closure) {
25+
return null;
26+
}
27+
28+
if (! $this->symfonyPhpClosureDetector->detect($node)) {
29+
return null;
30+
}
31+
32+
SimpleTraverser::decorateWithTrueAttribute($node, AttributeKey::IS_INSIDE_SYMFONY_PHP_CLOSURE);
33+
34+
return null;
35+
}
36+
}

0 commit comments

Comments
 (0)