Skip to content

Commit 34a00c1

Browse files
committed
fix: enhance ArrayToArrGetRector to skip isset, empty checks, and assignments
1 parent ca9c906 commit 34a00c1

File tree

3 files changed

+130
-3
lines changed

3 files changed

+130
-3
lines changed

src/Rector/ArrayDimFetch/ArrayToArrGetRector.php

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@
88
use PhpParser\Node\Arg;
99
use PhpParser\Node\Expr;
1010
use PhpParser\Node\Expr\ArrayDimFetch;
11+
use PhpParser\Node\Expr\Assign;
12+
use PhpParser\Node\Expr\AssignOp;
1113
use PhpParser\Node\Expr\BinaryOp\Coalesce;
14+
use PhpParser\Node\Expr\Empty_;
15+
use PhpParser\Node\Expr\Isset_;
1216
use PhpParser\Node\Expr\StaticCall;
1317
use PhpParser\Node\Expr\Throw_;
1418
use PhpParser\Node\Name\FullyQualified;
@@ -31,21 +35,27 @@ final class ArrayToArrGetRector extends AbstractRector
3135
public function getRuleDefinition(): RuleDefinition
3236
{
3337
return new RuleDefinition(
34-
'Convert array access to Arr::get() method call, skips null coalesce with throw expressions',
38+
'Convert array access to Arr::get() method call, skips isset/empty checks, assignments, and null coalesce with throw expressions',
3539
[new CodeSample(
3640
<<<'CODE_SAMPLE'
3741
$array['key'];
3842
$array['nested']['key'];
3943
$array['key'] ?? 'default';
4044
$array['nested']['key'] ?? 'default';
4145
$array['key'] ?? throw new Exception('Required');
46+
isset($array['key']);
47+
empty($array['key']);
48+
$array['key'] = 'value';
4249
CODE_SAMPLE,
4350
<<<'CODE_SAMPLE'
4451
\Illuminate\Support\Arr::get($array, 'key');
4552
\Illuminate\Support\Arr::get($array, 'nested.key');
4653
\Illuminate\Support\Arr::get($array, 'key', 'default');
4754
\Illuminate\Support\Arr::get($array, 'nested.key', 'default');
4855
$array['key'] ?? throw new Exception('Required');
56+
isset($array['key']);
57+
empty($array['key']);
58+
$array['key'] = 'value';
4959
CODE_SAMPLE
5060
)]
5161
);
@@ -56,14 +66,33 @@ public function getRuleDefinition(): RuleDefinition
5666
*/
5767
public function getNodeTypes(): array
5868
{
59-
return [ArrayDimFetch::class, Coalesce::class];
69+
return [ArrayDimFetch::class, Coalesce::class, Isset_::class, Empty_::class, Assign::class, AssignOp::class];
6070
}
6171

6272
/**
63-
* @param ArrayDimFetch|Coalesce $node
73+
* @param ArrayDimFetch|Coalesce|Isset_|Empty_|Assign|AssignOp $node
6474
*/
6575
public function refactor(Node $node): ?StaticCall
6676
{
77+
if ($node instanceof Isset_) {
78+
$this->markIssetArrayDimFetchesAsProcessed($node);
79+
return null;
80+
}
81+
82+
if ($node instanceof Empty_) {
83+
if ($node->expr instanceof ArrayDimFetch) {
84+
$this->markArrayDimFetchAsProcessed($node->expr);
85+
}
86+
return null;
87+
}
88+
89+
if ($node instanceof Assign || $node instanceof AssignOp) {
90+
if ($node->var instanceof ArrayDimFetch) {
91+
$this->markArrayDimFetchAsProcessed($node->var);
92+
}
93+
return null;
94+
}
95+
6796
if ($node instanceof Coalesce) {
6897
$result = $this->refactorCoalesce($node);
6998
if ($result instanceof StaticCall && $node->left instanceof ArrayDimFetch) {
@@ -213,4 +242,13 @@ private function markArrayDimFetchAsProcessed(ArrayDimFetch $arrayDimFetch): voi
213242
$current = $current->var;
214243
}
215244
}
245+
246+
private function markIssetArrayDimFetchesAsProcessed(Isset_ $isset): void
247+
{
248+
foreach ($isset->vars as $var) {
249+
if ($var instanceof ArrayDimFetch) {
250+
$this->markArrayDimFetchAsProcessed($var);
251+
}
252+
}
253+
}
216254
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\ArrayDimFetch\ArrayToArrGetRector\Fixture;
4+
5+
class SkipCompoundAssignment
6+
{
7+
public function run()
8+
{
9+
$array = ['count' => 5, 'value' => 10];
10+
11+
// Should skip compound assignment operators - no transformation
12+
$array['count'] += 1;
13+
$array['value'] -= 2;
14+
$array['value'] *= 3;
15+
$array['value'] /= 2;
16+
$array['value'] %= 4;
17+
$array['text'] .= ' appended';
18+
19+
// Should transform - normal read access
20+
$value = $array['count'];
21+
}
22+
}
23+
24+
?>
25+
-----
26+
<?php
27+
28+
namespace RectorLaravel\Tests\Rector\ArrayDimFetch\ArrayToArrGetRector\Fixture;
29+
30+
class SkipCompoundAssignment
31+
{
32+
public function run()
33+
{
34+
$array = ['count' => 5, 'value' => 10];
35+
36+
// Should skip compound assignment operators - no transformation
37+
$array['count'] += 1;
38+
$array['value'] -= 2;
39+
$array['value'] *= 3;
40+
$array['value'] /= 2;
41+
$array['value'] %= 4;
42+
$array['text'] .= ' appended';
43+
44+
// Should transform - normal read access
45+
$value = \Illuminate\Support\Arr::get($array, 'count');
46+
}
47+
}
48+
49+
?>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
<?php
2+
3+
namespace RectorLaravel\Tests\Rector\ArrayDimFetch\ArrayToArrGetRector\Fixture;
4+
5+
class SkipIssetEmptyAssignment
6+
{
7+
public function run()
8+
{
9+
$array = ['key' => 'value', 'nested' => ['inner' => 'data']];
10+
11+
// Should skip isset checks - no transformation
12+
if (isset($array['key'])) {
13+
echo 'exists';
14+
}
15+
16+
if (isset($array['nested']['inner'])) {
17+
echo 'nested exists';
18+
}
19+
20+
// Should skip empty checks - no transformation
21+
if (empty($array['key'])) {
22+
echo 'empty';
23+
}
24+
25+
if (empty($array['nested']['inner'])) {
26+
echo 'nested empty';
27+
}
28+
29+
// Should skip assignment operations - no transformation
30+
$array['key'] = 'new value';
31+
$array['nested']['inner'] = 'new data';
32+
$array['new_key'] = 'added';
33+
34+
// Should transform - normal read access
35+
$value = \Illuminate\Support\Arr::get($array, 'key');
36+
$nested = \Illuminate\Support\Arr::get($array, 'nested.inner');
37+
}
38+
}
39+
40+
?>

0 commit comments

Comments
 (0)