From 2f5e965d13f588b0cf432ab16983b1ce6850f0d9 Mon Sep 17 00:00:00 2001 From: Tomas Votruba Date: Thu, 15 Oct 2026 21:25:37 +0200 Subject: [PATCH] [perf] Speed up DeadCode rules with lazy docblock/walk and instanceof guard before scope type lookup --- .../BinaryOp/RemoveRedundantTypeCheckRector.php | 10 +++++++--- .../RemoveUnusedPromotedPropertyRector.php | 3 ++- .../RemoveDefaultValueFromAssignedPropertyRector.php | 12 +++++++----- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/rules/DeadCode/Rector/BinaryOp/RemoveRedundantTypeCheckRector.php b/rules/DeadCode/Rector/BinaryOp/RemoveRedundantTypeCheckRector.php index aef9f056fee..72eee05b76b 100644 --- a/rules/DeadCode/Rector/BinaryOp/RemoveRedundantTypeCheckRector.php +++ b/rules/DeadCode/Rector/BinaryOp/RemoveRedundantTypeCheckRector.php @@ -104,12 +104,12 @@ private function refactorBooleanOr(BooleanOr $booleanOr): ?Expr return null; } - // the docblock type can be wider than the real value - if ($this->exprAnalyzer->isNonTypedFromParam($nullComparedExpr)) { + if (! $booleanOr->right instanceof BooleanNot) { return null; } - if (! $booleanOr->right instanceof BooleanNot) { + // the docblock type can be wider than the real value + if ($this->exprAnalyzer->isNonTypedFromParam($nullComparedExpr)) { return null; } @@ -144,6 +144,10 @@ private function refactorBooleanAnd(BooleanAnd $booleanAnd): ?Expr return null; } + if (! $booleanAnd->right instanceof FuncCall) { + return null; + } + // the docblock type can be wider than the real value if ($this->exprAnalyzer->isNonTypedFromParam($booleanAnd->left)) { return null; diff --git a/rules/DeadCode/Rector/ClassMethod/RemoveUnusedPromotedPropertyRector.php b/rules/DeadCode/Rector/ClassMethod/RemoveUnusedPromotedPropertyRector.php index 9808a9a0844..c315a9192d1 100644 --- a/rules/DeadCode/Rector/ClassMethod/RemoveUnusedPromotedPropertyRector.php +++ b/rules/DeadCode/Rector/ClassMethod/RemoveUnusedPromotedPropertyRector.php @@ -111,7 +111,7 @@ public function refactor(Node $node): ?Node } $hasChanged = false; - $phpDocInfo = $this->phpDocInfoFactory->createFromNode($constructClassMethod); + $phpDocInfo = null; foreach ($constructClassMethod->params as $key => $param) { // only private local scope; removing public property might be dangerous @@ -140,6 +140,7 @@ public function refactor(Node $node): ?Node continue; } + $phpDocInfo ??= $this->phpDocInfoFactory->createFromNode($constructClassMethod); if ($phpDocInfo instanceof PhpDocInfo) { $paramTagValueNode = $phpDocInfo->getParamTagValueByName($paramName); if ($paramTagValueNode instanceof ParamTagValueNode) { diff --git a/rules/DeadCode/Rector/Property/RemoveDefaultValueFromAssignedPropertyRector.php b/rules/DeadCode/Rector/Property/RemoveDefaultValueFromAssignedPropertyRector.php index e0b4864b931..d6e2631c945 100644 --- a/rules/DeadCode/Rector/Property/RemoveDefaultValueFromAssignedPropertyRector.php +++ b/rules/DeadCode/Rector/Property/RemoveDefaultValueFromAssignedPropertyRector.php @@ -86,12 +86,8 @@ public function refactor(Node $node): ?Node return null; } - // early return can skip the assign, so the default value is still needed - if ($this->hasEarlyReturn($node, $constructClassMethod)) { - return null; - } - $hasChanged = false; + $hasEarlyReturn = null; $isFinal = $node->isFinal() || FeatureFlags::treatClassesAsFinal($node); foreach ($node->getProperties() as $property) { @@ -128,6 +124,12 @@ public function refactor(Node $node): ?Node continue; } + // early return can skip the assign, so the default value is still needed + $hasEarlyReturn ??= $this->hasEarlyReturn($node, $constructClassMethod); + if ($hasEarlyReturn) { + return null; + } + $propertyProperty->default = null; $hasChanged = true; }