function get_uses_directly_in_scope()

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,
  );
}