From f05a1bc2d702e4706ed607783c571ddbd4878e97 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 3 Apr 2026 21:13:15 +0700 Subject: [PATCH 1/2] [DowngradePhp80] Handle in array dim fetch on DowngradeMatchToSwitchRector --- .../Fixture/in_array_dim_fetch.php.inc | 42 +++++++++++++++++++ .../DowngradeMatchToSwitchRector.php | 24 ++++++++++- 2 files changed, 64 insertions(+), 2 deletions(-) create mode 100644 rules-tests/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector/Fixture/in_array_dim_fetch.php.inc diff --git a/rules-tests/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector/Fixture/in_array_dim_fetch.php.inc b/rules-tests/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector/Fixture/in_array_dim_fetch.php.inc new file mode 100644 index 00000000..80222490 --- /dev/null +++ b/rules-tests/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector/Fixture/in_array_dim_fetch.php.inc @@ -0,0 +1,42 @@ + 'TypeError', + 'Exception' => 'ErrorException', + default => $c, + }][$n] = $v; + } +} + +?> +----- + diff --git a/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php b/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php index 5f7ba9bb..fc79fe18 100644 --- a/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php +++ b/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php @@ -8,6 +8,7 @@ use PhpParser\Node\Arg; use PhpParser\Node\ArrayItem; use PhpParser\Node\Expr; +use PhpParser\Node\Expr\ArrayDimFetch; use PhpParser\Node\Expr\ArrowFunction; use PhpParser\Node\Expr\Assign; use PhpParser\Node\Expr\BinaryOp; @@ -19,6 +20,7 @@ use PhpParser\Node\Expr\NullsafeMethodCall; use PhpParser\Node\Expr\StaticCall; use PhpParser\Node\Expr\Throw_; +use PhpParser\Node\Expr\Variable; use PhpParser\Node\MatchArm; use PhpParser\Node\Stmt; use PhpParser\Node\Stmt\Break_; @@ -29,6 +31,7 @@ use PhpParser\Node\Stmt\Switch_; use PhpParser\NodeVisitor; use PHPStan\Analyser\Scope; +use Rector\Naming\Naming\VariableNaming; use Rector\NodeTypeResolver\Node\AttributeKey; use Rector\Php72\NodeFactory\AnonymousFunctionFactory; use Rector\PHPStan\ScopeFetcher; @@ -44,7 +47,8 @@ final class DowngradeMatchToSwitchRector extends AbstractRector { public function __construct( - private readonly AnonymousFunctionFactory $anonymousFunctionFactory + private readonly AnonymousFunctionFactory $anonymousFunctionFactory, + private readonly VariableNaming $variableNaming ) { } @@ -101,8 +105,9 @@ public function getNodeTypes(): array /** * @param Echo_|Expression|Return_ $node + * @return null|Node|Node[] */ - public function refactor(Node $node): ?Node + public function refactor(Node $node): null|Node|array { /** @var Match_|null $match */ $match = null; @@ -110,6 +115,21 @@ public function refactor(Node $node): ?Node $scope = ScopeFetcher::fetch($node); + if ($node instanceof Expression + && $node->expr instanceof Assign + && $node->expr->var instanceof ArrayDimFetch + && $node->expr->var->var instanceof ArrayDimFetch + && $node->expr->var->var->dim instanceof Match_) { + $matchVariable = new Variable($this->variableNaming->createCountedValueName('match', $scope)); + $expression = new Expression(new Assign($matchVariable, $node->expr->var->var->dim)); + $expression->setAttribute(AttributeKey::SCOPE, $scope); + $expression = $this->refactor($expression); + + $node->expr->var->var->dim = $matchVariable; + + return [$expression, $node]; + } + $this->traverseNodesWithCallable( $node, function (Node $subNode) use ($node, &$match, &$hasChanged, $scope) { From 429f20b66da7d41eb76607c6e08ca8970273f376 Mon Sep 17 00:00:00 2001 From: Abdul Malik Ikhsan Date: Fri, 3 Apr 2026 21:21:51 +0700 Subject: [PATCH 2/2] fix phpstan --- phpstan.neon | 1 + .../Expression/DowngradeMatchToSwitchRector.php | 13 ++++++++++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 1def084a..375f1f41 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -107,6 +107,7 @@ parameters: - rules/DowngradePhp74/Rector/MethodCall/DowngradeReflectionGetTypeRector.php - rules/DowngradePhp80/Rector/MethodCall/DowngradeReflectionGetAttributesRector.php - rules/DowngradePhp73/Rector/String_/DowngradeFlexibleHeredocSyntaxRector.php + - rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php # local attribute key - '#Parameter \#2 \$attributeKey of static method Rector\\PhpParser\\NodeTraverser\\SimpleNodeTraverser\:\:decorateWithAttributeValue\(\) expects#' diff --git a/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php b/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php index fc79fe18..b9171bf1 100644 --- a/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php +++ b/rules/DowngradePhp80/Rector/Expression/DowngradeMatchToSwitchRector.php @@ -105,7 +105,6 @@ public function getNodeTypes(): array /** * @param Echo_|Expression|Return_ $node - * @return null|Node|Node[] */ public function refactor(Node $node): null|Node|array { @@ -123,11 +122,19 @@ public function refactor(Node $node): null|Node|array $matchVariable = new Variable($this->variableNaming->createCountedValueName('match', $scope)); $expression = new Expression(new Assign($matchVariable, $node->expr->var->var->dim)); $expression->setAttribute(AttributeKey::SCOPE, $scope); - $expression = $this->refactor($expression); + $refactored = $this->refactor($expression); + + if ($refactored === null) { + return null; + } $node->expr->var->var->dim = $matchVariable; - return [$expression, $node]; + $stmts = is_array($refactored) + ? $refactored : + [$refactored]; + + return [...$stmts, $node]; } $this->traverseNodesWithCallable(