Skip to content

Commit fc13aff

Browse files
committed
Updated Rector to commit 9e4dc598b59992584b4c9c13822cb409cde0d2e9
rectorphp/rector-src@9e4dc59 [DeadCode] Skip (void) cast with #[NoDiscard] on target method call on RemoveDeadStmtRector (#8038)
1 parent dabec70 commit fc13aff

7 files changed

Lines changed: 119 additions & 68 deletions

File tree

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
<?php
2+
3+
declare (strict_types=1);
4+
namespace Rector\DeadCode\NodeAnalyzer;
5+
6+
use PhpParser\Node\Expr;
7+
use PhpParser\Node\Expr\FuncCall;
8+
use PhpParser\Node\Expr\MethodCall;
9+
use PhpParser\Node\Expr\NullsafeMethodCall;
10+
use PhpParser\Node\Expr\StaticCall;
11+
use PhpParser\Node\Name;
12+
use PHPStan\Reflection\AttributeReflection;
13+
use PHPStan\Reflection\ReflectionProvider;
14+
use Rector\NodeNameResolver\NodeNameResolver;
15+
use Rector\NodeTypeResolver\NodeTypeResolver;
16+
use Rector\PHPStan\ScopeFetcher;
17+
final class NoDiscardCallAnalyzer
18+
{
19+
/**
20+
* @readonly
21+
*/
22+
private NodeNameResolver $nodeNameResolver;
23+
/**
24+
* @readonly
25+
*/
26+
private NodeTypeResolver $nodeTypeResolver;
27+
/**
28+
* @readonly
29+
*/
30+
private ReflectionProvider $reflectionProvider;
31+
public function __construct(NodeNameResolver $nodeNameResolver, NodeTypeResolver $nodeTypeResolver, ReflectionProvider $reflectionProvider)
32+
{
33+
$this->nodeNameResolver = $nodeNameResolver;
34+
$this->nodeTypeResolver = $nodeTypeResolver;
35+
$this->reflectionProvider = $reflectionProvider;
36+
}
37+
public function isNoDiscardCall(Expr $expr): bool
38+
{
39+
if ($expr instanceof FuncCall) {
40+
$name = $this->nodeNameResolver->getName($expr);
41+
if ($name === null) {
42+
return \false;
43+
}
44+
$scope = ScopeFetcher::fetch($expr);
45+
$functionName = new Name($name);
46+
if (!$this->reflectionProvider->hasFunction($functionName, $scope)) {
47+
return \false;
48+
}
49+
return $this->hasNoDiscardAttribute($this->reflectionProvider->getFunction($functionName, $scope)->getAttributes());
50+
}
51+
if ($expr instanceof StaticCall) {
52+
$classNames = $this->nodeTypeResolver->getType($expr->class)->getObjectClassNames();
53+
$methodName = $this->nodeNameResolver->getName($expr->name);
54+
} elseif ($expr instanceof MethodCall || $expr instanceof NullsafeMethodCall) {
55+
$classNames = $this->nodeTypeResolver->getType($expr->var)->getObjectClassNames();
56+
$methodName = $this->nodeNameResolver->getName($expr->name);
57+
} else {
58+
return \false;
59+
}
60+
if ($classNames === [] || $methodName === null) {
61+
return \false;
62+
}
63+
foreach ($classNames as $className) {
64+
if (!$this->reflectionProvider->hasClass($className)) {
65+
continue;
66+
}
67+
$classReflection = $this->reflectionProvider->getClass($className);
68+
if (!$classReflection->hasNativeMethod($methodName)) {
69+
continue;
70+
}
71+
if ($this->hasNoDiscardAttribute($classReflection->getNativeMethod($methodName)->getAttributes())) {
72+
return \true;
73+
}
74+
}
75+
return \false;
76+
}
77+
/**
78+
* @param AttributeReflection[] $attributes
79+
*/
80+
private function hasNoDiscardAttribute(array $attributes): bool
81+
{
82+
foreach ($attributes as $attribute) {
83+
if ($attribute->getName() === 'NoDiscard') {
84+
return \true;
85+
}
86+
}
87+
return \false;
88+
}
89+
}

rules/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector.php

Lines changed: 5 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -11,28 +11,22 @@
1111
use PhpParser\Node\Expr\Closure;
1212
use PhpParser\Node\Expr\FuncCall;
1313
use PhpParser\Node\Expr\Include_;
14-
use PhpParser\Node\Expr\MethodCall;
15-
use PhpParser\Node\Expr\NullsafeMethodCall;
16-
use PhpParser\Node\Expr\StaticCall;
1714
use PhpParser\Node\Expr\Variable;
18-
use PhpParser\Node\Name;
1915
use PhpParser\Node\Stmt;
2016
use PhpParser\Node\Stmt\Class_;
2117
use PhpParser\Node\Stmt\ClassMethod;
2218
use PhpParser\Node\Stmt\Expression;
2319
use PhpParser\Node\Stmt\Function_;
2420
use PhpParser\NodeVisitor;
25-
use PHPStan\Reflection\AttributeReflection;
2621
use PHPStan\Reflection\ClassReflection;
27-
use PHPStan\Reflection\ReflectionProvider;
2822
use PHPStan\Type\ObjectType;
23+
use Rector\DeadCode\NodeAnalyzer\NoDiscardCallAnalyzer;
2924
use Rector\DeadCode\SideEffect\SideEffectNodeDetector;
3025
use Rector\NodeAnalyzer\VariableAnalyzer;
3126
use Rector\NodeManipulator\StmtsManipulator;
3227
use Rector\Php\ReservedKeywordAnalyzer;
3328
use Rector\PhpParser\Enum\NodeGroup;
3429
use Rector\PhpParser\Node\BetterNodeFinder;
35-
use Rector\PHPStan\ScopeFetcher;
3630
use Rector\Rector\AbstractRector;
3731
use Rector\ValueObject\MethodName;
3832
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@@ -65,15 +59,15 @@ final class RemoveUnusedVariableAssignRector extends AbstractRector
6559
/**
6660
* @readonly
6761
*/
68-
private ReflectionProvider $reflectionProvider;
69-
public function __construct(ReservedKeywordAnalyzer $reservedKeywordAnalyzer, SideEffectNodeDetector $sideEffectNodeDetector, VariableAnalyzer $variableAnalyzer, BetterNodeFinder $betterNodeFinder, StmtsManipulator $stmtsManipulator, ReflectionProvider $reflectionProvider)
62+
private NoDiscardCallAnalyzer $noDiscardCallAnalyzer;
63+
public function __construct(ReservedKeywordAnalyzer $reservedKeywordAnalyzer, SideEffectNodeDetector $sideEffectNodeDetector, VariableAnalyzer $variableAnalyzer, BetterNodeFinder $betterNodeFinder, StmtsManipulator $stmtsManipulator, NoDiscardCallAnalyzer $noDiscardCallAnalyzer)
7064
{
7165
$this->reservedKeywordAnalyzer = $reservedKeywordAnalyzer;
7266
$this->sideEffectNodeDetector = $sideEffectNodeDetector;
7367
$this->variableAnalyzer = $variableAnalyzer;
7468
$this->betterNodeFinder = $betterNodeFinder;
7569
$this->stmtsManipulator = $stmtsManipulator;
76-
$this->reflectionProvider = $reflectionProvider;
70+
$this->noDiscardCallAnalyzer = $noDiscardCallAnalyzer;
7771
}
7872
public function getRuleDefinition(): RuleDefinition
7973
{
@@ -249,7 +243,7 @@ private function resolvedAssignedVariablesByStmtPosition(array $stmts): array
249243
if ($this->shouldSkipVariable($assign->var, $variableName, $refVariableNames)) {
250244
continue;
251245
}
252-
if ($this->isNoDiscardCall($assign->expr)) {
246+
if ($this->noDiscardCallAnalyzer->isNoDiscardCall($assign->expr)) {
253247
continue;
254248
}
255249
$assignedVariableNamesByStmtPosition[$key] = $variableName;
@@ -269,55 +263,4 @@ private function shouldSkipVariable(Variable $variable, string $variableName, ar
269263
}
270264
return in_array($variableName, $refVariableNames, \true);
271265
}
272-
private function isNoDiscardCall(Expr $expr): bool
273-
{
274-
if ($expr instanceof FuncCall) {
275-
$name = $this->getName($expr);
276-
if ($name === null) {
277-
return \false;
278-
}
279-
$scope = ScopeFetcher::fetch($expr);
280-
if (!$this->reflectionProvider->hasFunction(new Name($name), $scope)) {
281-
return \false;
282-
}
283-
return $this->hasNoDiscardAttribute($this->reflectionProvider->getFunction(new Name($name), $scope)->getAttributes());
284-
}
285-
if ($expr instanceof StaticCall) {
286-
$classNames = $this->getType($expr->class)->getObjectClassNames();
287-
$methodName = $this->getName($expr->name);
288-
} elseif ($expr instanceof MethodCall || $expr instanceof NullsafeMethodCall) {
289-
$classNames = $this->getType($expr->var)->getObjectClassNames();
290-
$methodName = $this->getName($expr->name);
291-
} else {
292-
return \false;
293-
}
294-
if ($classNames === [] || $methodName === null) {
295-
return \false;
296-
}
297-
foreach ($classNames as $className) {
298-
if (!$this->reflectionProvider->hasClass($className)) {
299-
continue;
300-
}
301-
$classReflection = $this->reflectionProvider->getClass($className);
302-
if (!$classReflection->hasNativeMethod($methodName)) {
303-
continue;
304-
}
305-
if ($this->hasNoDiscardAttribute($classReflection->getNativeMethod($methodName)->getAttributes())) {
306-
return \true;
307-
}
308-
}
309-
return \false;
310-
}
311-
/**
312-
* @param AttributeReflection[] $attributes
313-
*/
314-
private function hasNoDiscardAttribute(array $attributes): bool
315-
{
316-
foreach ($attributes as $attribute) {
317-
if ($attribute->getName() === 'NoDiscard') {
318-
return \true;
319-
}
320-
}
321-
return \false;
322-
}
323266
}

rules/DeadCode/Rector/Expression/RemoveDeadStmtRector.php

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,12 @@
55

66
use PhpParser\Comment\Doc;
77
use PhpParser\Node;
8+
use PhpParser\Node\Expr\Cast\Void_;
89
use PhpParser\Node\Stmt\Expression;
910
use PhpParser\Node\Stmt\Nop;
1011
use PhpParser\NodeVisitor;
1112
use PHPStan\Reflection\Php\PhpPropertyReflection;
13+
use Rector\DeadCode\NodeAnalyzer\NoDiscardCallAnalyzer;
1214
use Rector\DeadCode\NodeManipulator\LivingCodeManipulator;
1315
use Rector\NodeAnalyzer\PropertyFetchAnalyzer;
1416
use Rector\Rector\AbstractRector;
@@ -24,6 +26,10 @@ final class RemoveDeadStmtRector extends AbstractRector
2426
* @readonly
2527
*/
2628
private LivingCodeManipulator $livingCodeManipulator;
29+
/**
30+
* @readonly
31+
*/
32+
private NoDiscardCallAnalyzer $noDiscardCallAnalyzer;
2733
/**
2834
* @readonly
2935
*/
@@ -32,9 +38,10 @@ final class RemoveDeadStmtRector extends AbstractRector
3238
* @readonly
3339
*/
3440
private ReflectionResolver $reflectionResolver;
35-
public function __construct(LivingCodeManipulator $livingCodeManipulator, PropertyFetchAnalyzer $propertyFetchAnalyzer, ReflectionResolver $reflectionResolver)
41+
public function __construct(LivingCodeManipulator $livingCodeManipulator, NoDiscardCallAnalyzer $noDiscardCallAnalyzer, PropertyFetchAnalyzer $propertyFetchAnalyzer, ReflectionResolver $reflectionResolver)
3642
{
3743
$this->livingCodeManipulator = $livingCodeManipulator;
44+
$this->noDiscardCallAnalyzer = $noDiscardCallAnalyzer;
3845
$this->propertyFetchAnalyzer = $propertyFetchAnalyzer;
3946
$this->reflectionResolver = $reflectionResolver;
4047
}
@@ -65,6 +72,9 @@ public function refactor(Node $node)
6572
if ($this->hasGetMagic($node)) {
6673
return null;
6774
}
75+
if ($this->isVoidCastNoDiscardCall($node)) {
76+
return null;
77+
}
6878
$livingCode = $this->livingCodeManipulator->keepLivingCodeFromExpr($node->expr);
6979
if ($livingCode === []) {
7080
return $this->removeNodeAndKeepComments($node);
@@ -94,6 +104,13 @@ private function hasGetMagic(Expression $expression): bool
94104
*/
95105
return !$phpPropertyReflection instanceof PhpPropertyReflection;
96106
}
107+
private function isVoidCastNoDiscardCall(Expression $expression): bool
108+
{
109+
if (!$expression->expr instanceof Void_) {
110+
return \false;
111+
}
112+
return $this->noDiscardCallAnalyzer->isNoDiscardCall($expression->expr->expr);
113+
}
97114
/**
98115
* @return NodeVisitor::REMOVE_NODE|Node
99116
*/

rules/DeadCode/Rector/Switch_/RemoveDuplicatedCaseInSwitchRector.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -89,9 +89,9 @@ public function refactor(Node $node): ?Node
8989
}
9090
private function removeDuplicatedCases(Switch_ $switch): void
9191
{
92-
/** @var Case_[] */
92+
/** @var Case_[] $result */
9393
$result = [];
94-
/** @var int[] */
94+
/** @var int[] $processedCasesKeys */
9595
$processedCasesKeys = [];
9696
foreach ($switch->cases as $outerCaseKey => $outerCase) {
9797
if (in_array($outerCaseKey, $processedCasesKeys)) {
@@ -104,7 +104,7 @@ private function removeDuplicatedCases(Switch_ $switch): void
104104
}
105105
/** @var array<int, Case_> */
106106
$casesWithoutStmts = [];
107-
/** @var Case_[] */
107+
/** @var Case_[] $equalCases */
108108
$equalCases = [];
109109
foreach ($switch->cases as $innerCaseKey => $innerCase) {
110110
if (in_array($innerCaseKey, $processedCasesKeys)) {

src/Application/VersionResolver.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,12 @@ final class VersionResolver
1919
* @api
2020
* @var string
2121
*/
22-
public const PACKAGE_VERSION = 'a01724e1e63cdb4456f3d121cf7580d608bab603';
22+
public const PACKAGE_VERSION = '9e4dc598b59992584b4c9c13822cb409cde0d2e9';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2026-06-11 23:36:14';
27+
public const RELEASE_DATE = '2026-06-13 23:55:19';
2828
/**
2929
* @var int
3030
*/

vendor/composer/autoload_classmap.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1396,6 +1396,7 @@
13961396
'Rector\\DeadCode\\NodeAnalyzer\\CallLikeParamDefaultResolver' => $baseDir . '/rules/DeadCode/NodeAnalyzer/CallLikeParamDefaultResolver.php',
13971397
'Rector\\DeadCode\\NodeAnalyzer\\ExprUsedInNodeAnalyzer' => $baseDir . '/rules/DeadCode/NodeAnalyzer/ExprUsedInNodeAnalyzer.php',
13981398
'Rector\\DeadCode\\NodeAnalyzer\\IsClassMethodUsedAnalyzer' => $baseDir . '/rules/DeadCode/NodeAnalyzer/IsClassMethodUsedAnalyzer.php',
1399+
'Rector\\DeadCode\\NodeAnalyzer\\NoDiscardCallAnalyzer' => $baseDir . '/rules/DeadCode/NodeAnalyzer/NoDiscardCallAnalyzer.php',
13991400
'Rector\\DeadCode\\NodeAnalyzer\\ParentClassAnalyzer' => $baseDir . '/rules/DeadCode/NodeAnalyzer/ParentClassAnalyzer.php',
14001401
'Rector\\DeadCode\\NodeAnalyzer\\PropertyWriteonlyAnalyzer' => $baseDir . '/rules/DeadCode/NodeAnalyzer/PropertyWriteonlyAnalyzer.php',
14011402
'Rector\\DeadCode\\NodeAnalyzer\\SafeLeftTypeBooleanAndOrAnalyzer' => $baseDir . '/rules/DeadCode/NodeAnalyzer/SafeLeftTypeBooleanAndOrAnalyzer.php',

vendor/composer/autoload_static.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1656,6 +1656,7 @@ class ComposerStaticInit66a3c22cfbd40cb049dcb2d9e47672e9
16561656
'Rector\\DeadCode\\NodeAnalyzer\\CallLikeParamDefaultResolver' => __DIR__ . '/../..' . '/rules/DeadCode/NodeAnalyzer/CallLikeParamDefaultResolver.php',
16571657
'Rector\\DeadCode\\NodeAnalyzer\\ExprUsedInNodeAnalyzer' => __DIR__ . '/../..' . '/rules/DeadCode/NodeAnalyzer/ExprUsedInNodeAnalyzer.php',
16581658
'Rector\\DeadCode\\NodeAnalyzer\\IsClassMethodUsedAnalyzer' => __DIR__ . '/../..' . '/rules/DeadCode/NodeAnalyzer/IsClassMethodUsedAnalyzer.php',
1659+
'Rector\\DeadCode\\NodeAnalyzer\\NoDiscardCallAnalyzer' => __DIR__ . '/../..' . '/rules/DeadCode/NodeAnalyzer/NoDiscardCallAnalyzer.php',
16591660
'Rector\\DeadCode\\NodeAnalyzer\\ParentClassAnalyzer' => __DIR__ . '/../..' . '/rules/DeadCode/NodeAnalyzer/ParentClassAnalyzer.php',
16601661
'Rector\\DeadCode\\NodeAnalyzer\\PropertyWriteonlyAnalyzer' => __DIR__ . '/../..' . '/rules/DeadCode/NodeAnalyzer/PropertyWriteonlyAnalyzer.php',
16611662
'Rector\\DeadCode\\NodeAnalyzer\\SafeLeftTypeBooleanAndOrAnalyzer' => __DIR__ . '/../..' . '/rules/DeadCode/NodeAnalyzer/SafeLeftTypeBooleanAndOrAnalyzer.php',

0 commit comments

Comments
 (0)