From 9ae8feaaa0c59272c2cc44ec2367e69e387191ca Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 25 Aug 2025 22:07:50 +0700 Subject: [PATCH 1/2] [DowngradePhp81] Handle version_compare() in If_ on DowngradeHashAlgorithmXxHashRector --- .../DowngradeHashAlgorithmXxHashRector.php | 46 ++++++++++++++++++- 1 file changed, 44 insertions(+), 2 deletions(-) diff --git a/rules/DowngradePhp81/Rector/FuncCall/DowngradeHashAlgorithmXxHashRector.php b/rules/DowngradePhp81/Rector/FuncCall/DowngradeHashAlgorithmXxHashRector.php index a6f34aaf..fcbccb99 100644 --- a/rules/DowngradePhp81/Rector/FuncCall/DowngradeHashAlgorithmXxHashRector.php +++ b/rules/DowngradePhp81/Rector/FuncCall/DowngradeHashAlgorithmXxHashRector.php @@ -7,10 +7,14 @@ use PhpParser\Node; use PhpParser\Node\Arg; use PhpParser\Node\Expr; +use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\ConstFetch; use PhpParser\Node\Expr\FuncCall; use PhpParser\Node\Expr\Ternary; use PhpParser\Node\Scalar\String_; +use PhpParser\Node\Stmt\Expression; +use PhpParser\Node\Stmt\If_; +use PhpParser\Node\Stmt\Return_; use PhpParser\NodeVisitor; use PHPStan\Type\IntegerRangeType; use Rector\DeadCode\ConditionResolver; @@ -80,14 +84,22 @@ public function run() */ public function getNodeTypes(): array { - return [Ternary::class, FuncCall::class]; + return [If_::class, Ternary::class, FuncCall::class]; } /** - * @param Ternary|FuncCall $node + * @param If_|Ternary|FuncCall $node */ public function refactor(Node $node): null|int|Node { + if ($node instanceof If_) { + if ($this->isVersionCompareIf($node)) { + return NodeVisitor::DONT_TRAVERSE_CHILDREN; + } + + return null; + } + if ($node instanceof Ternary) { if ($this->isVersionCompareTernary($node)) { return NodeVisitor::DONT_TRAVERSE_CHILDREN; @@ -118,6 +130,36 @@ public function refactor(Node $node): null|int|Node return $node; } + private function isVersionCompareIf(If_ $if): bool + { + if ($if->cond instanceof FuncCall) { + // per use case reported only + if (count($if->stmts) !== 1) { + return false; + } + + $versionCompare = $this->conditionResolver->resolveFromExpr($if->cond); + + if (! $versionCompare instanceof VersionCompareCondition || $versionCompare->getSecondVersion() !== 80100) { + return false; + } + + if ($versionCompare->getCompareSign() !== '>=') { + return false; + } + + if ($if->stmts[0] instanceof Expression && $if->stmts[0]->expr instanceof Assign && $if->stmts[0]->expr->expr instanceof FuncCall) { + return $this->isName($if->stmts[0]->expr->expr, 'hash'); + } + + if ($if->stmts[0] instanceof Return_ && $if->stmts[0]->expr instanceof FuncCall) { + return $this->isName($if->stmts[0]->expr, 'hash'); + } + } + + return false; + } + private function isVersionCompareTernary(Ternary $ternary): bool { if ($ternary->if instanceof Expr && $ternary->cond instanceof FuncCall) { From c5695e014a0dd6afc3afcfdc8524be67890e6287 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Mon, 25 Aug 2025 22:07:54 +0700 Subject: [PATCH 2/2] [DowngradePhp81] Handle version_compare() in If_ on DowngradeHashAlgorithmXxHashRector --- .../skip_check_version_compare_on_if.php.inc | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 rules-tests/DowngradePhp81/Rector/FuncCall/DowngradeHashAlgorithmXxHash/Fixture/skip_check_version_compare_on_if.php.inc diff --git a/rules-tests/DowngradePhp81/Rector/FuncCall/DowngradeHashAlgorithmXxHash/Fixture/skip_check_version_compare_on_if.php.inc b/rules-tests/DowngradePhp81/Rector/FuncCall/DowngradeHashAlgorithmXxHash/Fixture/skip_check_version_compare_on_if.php.inc new file mode 100644 index 00000000..bc8d6f3f --- /dev/null +++ b/rules-tests/DowngradePhp81/Rector/FuncCall/DowngradeHashAlgorithmXxHash/Fixture/skip_check_version_compare_on_if.php.inc @@ -0,0 +1,26 @@ +=' ) ) { + return hash( 'xxh128', $value ); + } + + return hash( 'md4', $value ); + } + + public function run_v2() + { + if (version_compare( PHP_VERSION, '8.1', '>=' ) ) { + $hash = hash( 'xxh128', $value ); + } else { + $hash = hash( 'md4', $value ); + } + + return $hash; + } +}