in src/Migrations/HSLMigration.hack [503:590]
protected function findUseDeclarations(
vec<INamespaceUseDeclaration> $declarations,
): (vec<INamespaceUseDeclaration>, vec<HslNamespace>) {
$search = vec['HH', 'Lib'];
$nodes = vec[];
$suffixes = vec[];
foreach ($declarations as $decl) {
// we only care about "use namespace" directives
if (!($decl->getKind() is NamespaceToken)) {
continue;
}
if ($decl is NamespaceGroupUseDeclaration) {
// group declarations: does prefix match?
$parts = $decl->getPrefix()
->getParts()
->getChildrenOfItemsOfType(NameToken::class);
if (C\count($parts) !== 2) {
continue;
}
$found_prefix = true;
foreach ($parts as $i => $token) {
if ($token?->getText() === $search[$i]) {
continue;
}
$found_prefix = false;
break;
}
// prefix didn't match? skip this declaration
if (!$found_prefix) {
continue;
}
// prefix matches: add node to list of nodes
$nodes[] = $decl;
$clauses = $decl->getClauses()
->getDescendantsByType<NamespaceUseClause>();
$suffixes = $clauses
|> Vec\map(
$$,
$c ==> {
$n = $c->getName();
return $n is NameToken
? HslNamespace::coerce($n->getText())
: null;
},
)
|> Vec\filter_nulls($$)
|> Vec\concat($suffixes, $$);
} else {
invariant(
$decl is NamespaceUseDeclaration,
'Unhandled declaration type',
);
$clauses = $decl->getClauses()->getChildrenOfItems();
foreach ($clauses as $clause) {
$name = $clause->getName();
if ($name is QualifiedName) {
$parts = $name->getParts()
->getChildrenOfItemsOfType(NameToken::class);
if (C\count($parts) !== 3) {
continue;
}
foreach ($parts as $i => $token) {
if ($i < 2 && $token?->getText() !== $search[$i]) {
break;
}
if ($i === 2) {
// we found an HH\Lib\* use statement, add the node and suffix
$nodes[] = $decl;
$ns = HslNamespace::coerce($token?->getText());
if ($ns !== null) {
$suffixes[] = $ns;
}
}
}
}
}
}
}
return tuple($nodes, $suffixes);
}