Skip to content

Commit dd7c4bf

Browse files
committed
[cleanup] Make FirstClassCallableRector use attributes over node traverser hacks
1 parent 3ec5fda commit dd7c4bf

File tree

4 files changed

+56
-9
lines changed

4 files changed

+56
-9
lines changed

rules/Php81/Rector/Array_/FirstClassCallableRector.php

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@
1212
use PhpParser\Node\Expr\PropertyFetch;
1313
use PhpParser\Node\Expr\StaticCall;
1414
use PhpParser\Node\Expr\Variable;
15-
use PhpParser\Node\Stmt\ClassConst;
16-
use PhpParser\Node\Stmt\Property;
1715
use PhpParser\Node\VariadicPlaceholder;
1816
use PhpParser\NodeVisitor;
1917
use PHPStan\Analyser\Scope;
2018
use PHPStan\Reflection\ClassReflection;
2119
use PHPStan\Reflection\ReflectionProvider;
2220
use Rector\NodeCollector\NodeAnalyzer\ArrayCallableMethodMatcher;
2321
use Rector\NodeCollector\ValueObject\ArrayCallable;
22+
use Rector\NodeTypeResolver\Node\AttributeKey;
2423
use Rector\PHPStan\ScopeFetcher;
2524
use Rector\Rector\AbstractRector;
2625
use Rector\Reflection\ReflectionResolver;
@@ -86,14 +85,14 @@ public function name()
8685
*/
8786
public function getNodeTypes(): array
8887
{
89-
return [Property::class, ClassConst::class, Array_::class, Closure::class];
88+
return [Array_::class, Closure::class];
9089
}
9190

9291
/**
93-
* @param Property|ClassConst|Array_|Closure $node
92+
* @param Array_|Closure $node
9493
* @return StaticCall|MethodCall|null|NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN
9594
*/
96-
public function refactor(Node $node): int|null|StaticCall|MethodCall
95+
public function refactor(Node $node): StaticCall|MethodCall|null|int
9796
{
9897
if ($node instanceof Closure) {
9998
if ($this->symfonyPhpClosureDetector->detect($node)) {
@@ -103,10 +102,6 @@ public function refactor(Node $node): int|null|StaticCall|MethodCall
103102
return null;
104103
}
105104

106-
if ($node instanceof Property || $node instanceof ClassConst) {
107-
return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
108-
}
109-
110105
$scope = ScopeFetcher::fetch($node);
111106

112107
$arrayCallable = $this->arrayCallableMethodMatcher->match($node, $scope);
@@ -119,6 +114,14 @@ public function refactor(Node $node): int|null|StaticCall|MethodCall
119114
return null;
120115
}
121116

117+
if ($node->getAttribute(AttributeKey::IS_DEFAULT_CLASS_CONST_VALUE)) {
118+
return null;
119+
}
120+
121+
if ($node->getAttribute(AttributeKey::IS_DEFAULT_PROPERTY_VALUE)) {
122+
return null;
123+
}
124+
122125
$args = [new VariadicPlaceholder()];
123126
if ($callerExpr instanceof ClassConstFetch) {
124127
$type = $this->getType($callerExpr->class);

src/DependencyInjection/LazyContainerFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\ContextNodeVisitor;
103103
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\GlobalVariableNodeVisitor;
104104
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\NameNodeVisitor;
105+
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\PropertyOrClassConstDefaultNodeVisitor;
105106
use Rector\NodeTypeResolver\PHPStan\Scope\NodeVisitor\StaticVariableNodeVisitor;
106107
use Rector\NodeTypeResolver\PHPStan\Scope\PHPStanNodeScopeResolver;
107108
use Rector\NodeTypeResolver\Reflection\BetterReflection\SourceLocatorProvider\DynamicSourceLocatorProvider;
@@ -243,6 +244,7 @@ final class LazyContainerFactory
243244
GlobalVariableNodeVisitor::class,
244245
NameNodeVisitor::class,
245246
StaticVariableNodeVisitor::class,
247+
PropertyOrClassConstDefaultNodeVisitor::class,
246248
];
247249

248250
/**

src/NodeTypeResolver/Node/AttributeKey.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -286,4 +286,8 @@ final class AttributeKey
286286
* @var string
287287
*/
288288
public const HAS_MERGED_COMMENTS = 'has_merged_comments';
289+
290+
public const IS_DEFAULT_PROPERTY_VALUE = 'is_default_property_value';
291+
292+
public const IS_DEFAULT_CLASS_CONST_VALUE = 'is_default_class_const_value';
289293
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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;
9+
use PhpParser\Node\Stmt\ClassConst;
10+
use PhpParser\Node\Stmt\Property;
11+
use PhpParser\NodeVisitorAbstract;
12+
use Rector\Contract\PhpParser\DecoratingNodeVisitorInterface;
13+
use Rector\NodeTypeResolver\Node\AttributeKey;
14+
15+
final class PropertyOrClassConstDefaultNodeVisitor extends NodeVisitorAbstract implements DecoratingNodeVisitorInterface
16+
{
17+
public function enterNode(Node $node): ?Node
18+
{
19+
if ($node instanceof Property) {
20+
foreach ($node->props as $propertyItem) {
21+
$default = $propertyItem->default;
22+
if (! $default instanceof Expr) {
23+
continue;
24+
}
25+
26+
$default->setAttribute(AttributeKey::IS_DEFAULT_PROPERTY_VALUE, true);
27+
}
28+
}
29+
30+
if ($node instanceof ClassConst) {
31+
foreach ($node->consts as $const) {
32+
$const->value->setAttribute(AttributeKey::IS_DEFAULT_CLASS_CONST_VALUE, true);
33+
}
34+
}
35+
36+
return null;
37+
}
38+
}

0 commit comments

Comments
 (0)