Skip to content

Commit fc9d780

Browse files
committed
Updated Rector to commit 07fce8301826c36630ece64dad558ff6ea2fe109
rectorphp/rector-src@07fce83 fix: OOM crash in RemoveUnusedVariableAssignRector (#7964)
1 parent 319264f commit fc9d780

2 files changed

Lines changed: 62 additions & 18 deletions

File tree

rules/DeadCode/Rector/Assign/RemoveUnusedVariableAssignRector.php

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,27 @@
1212
use PhpParser\Node\Expr\FuncCall;
1313
use PhpParser\Node\Expr\Include_;
1414
use PhpParser\Node\Expr\MethodCall;
15-
use PhpParser\Node\Expr\New_;
1615
use PhpParser\Node\Expr\NullsafeMethodCall;
1716
use PhpParser\Node\Expr\StaticCall;
1817
use PhpParser\Node\Expr\Variable;
18+
use PhpParser\Node\Name;
1919
use PhpParser\Node\Stmt;
2020
use PhpParser\Node\Stmt\Class_;
2121
use PhpParser\Node\Stmt\ClassMethod;
2222
use PhpParser\Node\Stmt\Expression;
2323
use PhpParser\Node\Stmt\Function_;
2424
use PhpParser\NodeVisitor;
25+
use PHPStan\Reflection\AttributeReflection;
2526
use PHPStan\Reflection\ClassReflection;
27+
use PHPStan\Reflection\ReflectionProvider;
2628
use PHPStan\Type\ObjectType;
2729
use Rector\DeadCode\SideEffect\SideEffectNodeDetector;
2830
use Rector\NodeAnalyzer\VariableAnalyzer;
2931
use Rector\NodeManipulator\StmtsManipulator;
3032
use Rector\Php\ReservedKeywordAnalyzer;
31-
use Rector\Php80\NodeAnalyzer\PhpAttributeAnalyzer;
32-
use Rector\PhpParser\AstResolver;
3333
use Rector\PhpParser\Enum\NodeGroup;
3434
use Rector\PhpParser\Node\BetterNodeFinder;
35+
use Rector\PHPStan\ScopeFetcher;
3536
use Rector\Rector\AbstractRector;
3637
use Rector\ValueObject\MethodName;
3738
use Symplify\RuleDocGenerator\ValueObject\CodeSample\CodeSample;
@@ -64,20 +65,15 @@ final class RemoveUnusedVariableAssignRector extends AbstractRector
6465
/**
6566
* @readonly
6667
*/
67-
private AstResolver $astResolver;
68-
/**
69-
* @readonly
70-
*/
71-
private PhpAttributeAnalyzer $phpAttributeAnalyzer;
72-
public function __construct(ReservedKeywordAnalyzer $reservedKeywordAnalyzer, SideEffectNodeDetector $sideEffectNodeDetector, VariableAnalyzer $variableAnalyzer, BetterNodeFinder $betterNodeFinder, StmtsManipulator $stmtsManipulator, AstResolver $astResolver, PhpAttributeAnalyzer $phpAttributeAnalyzer)
68+
private ReflectionProvider $reflectionProvider;
69+
public function __construct(ReservedKeywordAnalyzer $reservedKeywordAnalyzer, SideEffectNodeDetector $sideEffectNodeDetector, VariableAnalyzer $variableAnalyzer, BetterNodeFinder $betterNodeFinder, StmtsManipulator $stmtsManipulator, ReflectionProvider $reflectionProvider)
7370
{
7471
$this->reservedKeywordAnalyzer = $reservedKeywordAnalyzer;
7572
$this->sideEffectNodeDetector = $sideEffectNodeDetector;
7673
$this->variableAnalyzer = $variableAnalyzer;
7774
$this->betterNodeFinder = $betterNodeFinder;
7875
$this->stmtsManipulator = $stmtsManipulator;
79-
$this->astResolver = $astResolver;
80-
$this->phpAttributeAnalyzer = $phpAttributeAnalyzer;
76+
$this->reflectionProvider = $reflectionProvider;
8177
}
8278
public function getRuleDefinition(): RuleDefinition
8379
{
@@ -253,11 +249,8 @@ private function resolvedAssignedVariablesByStmtPosition(array $stmts): array
253249
if ($this->shouldSkipVariable($assign->var, $variableName, $refVariableNames)) {
254250
continue;
255251
}
256-
if ($assign->expr instanceof FuncCall || $assign->expr instanceof StaticCall || $assign->expr instanceof MethodCall || $assign->expr instanceof New_ || $assign->expr instanceof NullsafeMethodCall) {
257-
$targetCall = $this->astResolver->resolveClassMethodOrFunctionFromCall($assign->expr);
258-
if (($targetCall instanceof ClassMethod || $targetCall instanceof Function_) && $this->phpAttributeAnalyzer->hasPhpAttribute($targetCall, 'NoDiscard')) {
259-
continue;
260-
}
252+
if ($this->isNoDiscardCall($assign->expr)) {
253+
continue;
261254
}
262255
$assignedVariableNamesByStmtPosition[$key] = $variableName;
263256
}
@@ -276,4 +269,55 @@ private function shouldSkipVariable(Variable $variable, string $variableName, ar
276269
}
277270
return in_array($variableName, $refVariableNames, \true);
278271
}
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+
}
279323
}

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 = 'c03bb57aa2dadd48639eac8d8f9c55ce771498c4';
22+
public const PACKAGE_VERSION = '07fce8301826c36630ece64dad558ff6ea2fe109';
2323
/**
2424
* @api
2525
* @var string
2626
*/
27-
public const RELEASE_DATE = '2026-04-07 17:15:22';
27+
public const RELEASE_DATE = '2026-04-08 01:09:37';
2828
/**
2929
* @var int
3030
*/

0 commit comments

Comments
 (0)