matchAssignItemsOnlyForeachArrayVariable($node); if ($assignVariable === null) { return null; } $previousDeclaration = $this->findPreviousNodeUsage($node, $assignVariable); if ($previousDeclaration === null) { return null; } // covers https://github.com/Symplify/Symplify/pull/1733/checks?check_run_id=379368887#step:5:64 if ($this->shouldSkipAsPartOfNestedForeach($node)) { return null; } $previousDeclarationParentNode = $previousDeclaration->getAttribute(AttributeKey::PARENT_NODE); if (! $previousDeclarationParentNode instanceof Assign) { return null; } // must be empty array, othewise it will false override $defaultValue = $this->getValue($previousDeclarationParentNode->expr); if ($defaultValue !== []) { return null; } return new Assign($assignVariable, $node->expr); } private function matchAssignItemsOnlyForeachArrayVariable(Foreach_ $foreach): ?Expr { if (count($foreach->stmts) !== 1) { return null; } $onlyStatement = $foreach->stmts[0]; if ($onlyStatement instanceof Expression) { $onlyStatement = $onlyStatement->expr; } if (! $onlyStatement instanceof Assign) { return null; } if (! $onlyStatement->var instanceof ArrayDimFetch) { return null; } if ($onlyStatement->var->dim !== null) { return null; } if (! $this->areNodesEqual($foreach->valueVar, $onlyStatement->expr)) { return null; } return $onlyStatement->var->var; } private function findPreviousNodeUsage(Node $node, Expr $expr): ?Node { return $this->betterNodeFinder->findFirstPrevious($node, function (Node $node) use ($expr) { if ($node === $expr) { return false; } return $this->areNodesEqual($node, $expr); }); } private function findPreviousNodeUsageInForeach(Node $node, Expr $expr): ?Node { return $this->betterNodeFinder->findFirstPrevious($node, function (Node $node) use ($expr) { if ($node === $expr) { return false; } if (! $this->areNodesEqual($node, $expr)) { return false; } return $node->getAttribute(AttributeKey::PARENT_NODE) instanceof Foreach_; }); } private function shouldSkipAsPartOfNestedForeach(Foreach_ $foreach): bool { $previousForeachVariableUsage = $this->findPreviousNodeUsageInForeach($foreach, $foreach->expr); if ($previousForeachVariableUsage === null) { return false; } /** @var Foreach_ $previousForeachVariableUsageParentNode */ $previousForeachVariableUsageParentNode = $previousForeachVariableUsage->getAttribute( AttributeKey::PARENT_NODE ); return $this->areNodesEqual($previousForeachVariableUsageParentNode->valueVar, $foreach->expr); } }