$callback) { // ... } CODE_SAMPLE ), new CodeSample( <<<'CODE_SAMPLE' while (list($key) = each($callbacks)) { // ... } CODE_SAMPLE , <<<'CODE_SAMPLE' foreach (array_keys($callbacks) as $key) { // ... } CODE_SAMPLE ), ] ); } /** * @return string[] */ public function getNodeTypes(): array { return [While_::class]; } /** * @param While_ $node */ public function refactor(Node $node): ?Node { if (! $node->cond instanceof Assign) { return null; } /** @var Assign $assignNode */ $assignNode = $node->cond; if (! $this->isListToEachAssign($assignNode)) { return null; } /** @var FuncCall $eachFuncCall */ $eachFuncCall = $assignNode->expr; /** @var List_ $listNode */ $listNode = $assignNode->var; $foreachedExpr = count($listNode->items) === 1 ? $this->createFunction( 'array_keys', [$eachFuncCall->args[0]] ) : $eachFuncCall->args[0]->value; /** @var ArrayItem $valueItem */ $valueItem = array_pop($listNode->items); $foreachNode = new Foreach_($foreachedExpr, $valueItem, [ 'stmts' => $node->stmts, ]); // is key included? add it to foreach if (count($listNode->items) > 0) { /** @var ArrayItem $keyItem */ $keyItem = array_pop($listNode->items); $foreachNode->keyVar = $keyItem->value; } return $foreachNode; } private function isListToEachAssign(Assign $assign): bool { if (! $assign->var instanceof List_) { return false; } return $assign->expr instanceof FuncCall && $this->isName($assign->expr, 'each'); } }