in src/__Private/whitespace_from_nodelist.hack [27:67]
function whitespace_from_nodelist(NodeList<Node> $list): NodeList<Trivia> {
if ($list->isEmpty()) {
// Nothing to analyze, single space should be a reasonable default.
return NodeList::createMaybeEmptyList(vec[new WhiteSpace(' ')]);
}
// If there is an EndOfLine between the last and second-to-last item, we take
// the last EndOfLine + any whitespace immediately after it (i.e. we exactly
// preserve the current indentation). If there is no EndOfLine, we take
// whitespace from immediately after the previous item. In both cases, we stop
// when we hit the first non-whitespace trivium (e.g. a comment).
$last_child = C\lastx($list->getChildren());
$previous_child = $list->getCount() === 1
? $last_child // technically incorrect but should provide good enough result
: $list->getChildren()[$list->getCount() - 2];
$trivia = Vec\concat(
$previous_child->getLastTokenx()->getTrailing()->getChildren(),
$last_child->getFirstTokenx()->getLeading()->getChildren(),
);
if (!C\is_empty($trivia)) {
for ($start_idx = C\count($trivia) - 1; $start_idx > 0; --$start_idx) {
if ($trivia[$start_idx] is EndOfLine) {
break;
}
}
$trivia = Vec\drop($trivia, $start_idx);
}
for ($take_cnt = 0; $take_cnt < C\count($trivia); ++$take_cnt) {
if (!$trivia[$take_cnt] is WhiteSpace && !$trivia[$take_cnt] is EndOfLine) {
break;
}
}
$ret = NodeList::createMaybeEmptyList(Vec\take($trivia, $take_cnt));
// Special case for a single-line single-item list: If no other whitespace was
// detected, we arbitrarily choose one space.
if ($list->getCount() === 1 && $ret->isEmpty()) {
$ret = NodeList::createMaybeEmptyList(vec[new WhiteSpace(' ')]);
}
return $ret;
}