static function visitInParallel($visitors)
{
$visitorsCount = count($visitors);
$skipping = new \SplFixedArray($visitorsCount);
return ['enter' => function ($node) use($visitors, $skipping, $visitorsCount) {
for ($i = 0; $i < $visitorsCount; $i++) {
if (empty($skipping[$i])) {
$fn = self::getVisitFn($visitors[$i], $node->kind, false);
if ($fn) {
$result = call_user_func_array($fn, func_get_args());
if ($result instanceof VisitorOperation) {
if ($result->doContinue) {
$skipping[$i] = $node;
} else {
if ($result->doBreak) {
$skipping[$i] = $result;
} else {
if ($result->removeNode) {
return $result;
}
}
}
} else {
if ($result !== null) {
return $result;
}
}
}
}
}
}, 'leave' => function ($node) use($visitors, $skipping, $visitorsCount) {
for ($i = 0; $i < $visitorsCount; $i++) {
if (empty($skipping[$i])) {
$fn = self::getVisitFn($visitors[$i], $node->kind, true);
if ($fn) {
$result = call_user_func_array($fn, func_get_args());
if ($result instanceof VisitorOperation) {
if ($result->doBreak) {
$skipping[$i] = $result;
} else {
if ($result->removeNode) {
return $result;
}
}
} else {
if ($result !== null) {
return $result;
}
}
}
} else {
if ($skipping[$i] === $node) {
$skipping[$i] = null;
}
}
}
}];
}