Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 42 additions & 12 deletions src/Rector/ArrayDimFetch/ArrayToArrGetRector.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@
*/
final class ArrayToArrGetRector extends AbstractRector
{
private const string HAS_ARRAY_DIM_FETCH = 'has_array_dim_fetch';

public function getRuleDefinition(): RuleDefinition
{
return new RuleDefinition(
Expand Down Expand Up @@ -78,17 +80,20 @@ public function getNodeTypes(): array

/**
* @param ArrayDimFetch|Coalesce|Isset_|Empty_|AssignOp|Unset_ $node
* @return StaticCall|NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN|null
*/
public function refactor(Node $node): StaticCall|int|null
public function refactor(Node $node): ?StaticCall
{
if ($node->getAttribute(self::HAS_ARRAY_DIM_FETCH) === true) {
return null;
}

if ($node instanceof Coalesce) {
return $this->refactorCoalesce($node);
}

if (! $node instanceof ArrayDimFetch) {
if ($this->containsArrayDimFetch($node)) {
return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
$this->markArrayDimFetchNodes($node);
}

return null;
Expand All @@ -106,22 +111,25 @@ public function refactor(Node $node): StaticCall|int|null
return $this->createArrGetCall($node);
}

/**
* @return StaticCall|NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN
*/
private function refactorCoalesce(Coalesce $coalesce): StaticCall|int
private function refactorCoalesce(Coalesce $coalesce): ?StaticCall
{
if (! $coalesce->left instanceof ArrayDimFetch) {
return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
$this->markArrayDimFetchNodes($coalesce);

return null;
}

if ($coalesce->right instanceof Throw_) {
return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
$this->markArrayDimFetchNodes($coalesce);

return null;
}

$staticCall = $this->createArrGetCall($coalesce->left);
if (! $staticCall instanceof StaticCall) {
return NodeVisitor::DONT_TRAVERSE_CURRENT_AND_CHILDREN;
$this->markArrayDimFetchNodes($coalesce);

return null;
}

$staticCall->args[] = new Arg($coalesce->right);
Expand Down Expand Up @@ -225,12 +233,34 @@ private function getRootVariable(ArrayDimFetch $arrayDimFetch): Expr
return $current;
}

private function markArrayDimFetchNodes(Node $node): void
{
$this->traverseNodesWithCallable($node, function (Node $subNode) use ($node): ?int {
// first visit is current node itself
if ($node === $subNode) {
return null;
}

if ($subNode instanceof ArrayDimFetch) {
$subNode->setAttribute(self::HAS_ARRAY_DIM_FETCH, true);
}

return null;
});
}

private function containsArrayDimFetch(Node $node): bool
{
$found = false;

$this->traverseNodesWithCallable($node, function (Node $node) use (&$found): ?int {
if ($node instanceof ArrayDimFetch) {
$originalNode = $node;
$this->traverseNodesWithCallable($node, function (Node $subNode) use (&$found, $originalNode): ?int {
// first visit is current node itself
if ($originalNode === $subNode) {
return null;
}

if ($subNode instanceof ArrayDimFetch) {
$found = true;

return NodeVisitor::STOP_TRAVERSAL;
Expand Down