in src/__Private/Resolution/get_uses_directly_in_scope.hack [25:107]
function get_uses_directly_in_scope(?NodeList<Node> $scope): shape(
'namespaces' => dict<string, Script::TAliasedNamespace>,
'types' => dict<string, Script::TAliasedNamespace>,
'functions' => dict<string, Script::TAliasedNamespace>,
) {
if ($scope === null) {
return shape(
'namespaces' => dict[],
'types' => dict[],
'functions' => dict[],
);
}
$uses = vec[];
// use [kind] Foo, [kind] Bar;
$statements = $scope->getChildrenByType<NamespaceUseDeclaration>();
foreach ($statements as $statement) {
$kind = $statement->getKind();
$clauses = $statement->getClauses()
->getDescendantsByType<NamespaceUseClause>();
foreach ($clauses as $clause) {
$uses[] = tuple(
$clause->hasClauseKind() ? $clause->getClauseKind() : $kind,
$clause,
Str\trim($clause->getNameUNTYPED()?->getCode() ?? ''),
$clause->getAlias(),
);
}
}
// use [kind] Foo\{Bar, [kind] Baz}
$statements = $scope->getChildrenByType<NamespaceGroupUseDeclaration>();
foreach ($statements as $statement) {
$kind = $statement->getKind();
$prefix = $statement->getPrefix()->getCode()
|> Str\trim($$)
|> Str\strip_prefix($$, '\\');
$clauses = $statement->getClauses()
->getDescendantsByType<NamespaceUseClause>();
foreach ($clauses as $clause) {
$uses[] = tuple(
$clause->hasClauseKind() ? $clause->getClauseKind() : $kind,
$clause,
$prefix.Str\trim($clause->getNameUNTYPED()?->getCode() ?? ''),
$clause->getAlias(),
);
}
}
$namespaces = dict[];
$types = dict[];
$functions = dict[];
foreach ($uses as $use) {
list($kind, $clause, $name, $alias) = $use;
// Leading "\" in "use" declarations does nothing.
$name = Str\strip_prefix($name, '\\');
$alias = $alias === null
? $name
|> \explode('\\', $$)
|> C\lastx($$)
: $alias->getCode()
|> Str\trim($$)
|> Str\strip_prefix($$, '\\');
$target = shape('name' => $name, 'use_clause' => $clause);
if ($kind === null) {
$namespaces[$alias] ??= $target;
$types[$alias] ??= $target;
$functions[$alias] ??= $target;
} else if ($kind is NamespaceToken) {
$namespaces[$alias] = $target;
} else if ($kind is TypeToken) {
$types[$alias] = $target;
} else if ($kind is FunctionToken) {
$functions[$alias] = $target;
}
}
return shape(
'namespaces' => $namespaces,
'types' => $types,
'functions' => $functions,
);
}