import { streamContents as c, streamAllContents as p } from "../utils/ast-utils.js";
import { MultiMap as m } from "../utils/collections.js";
import { interruptAndCheck as i } from "../utils/promise-utils.js";
import { c as n } from "../../../../../../../_virtual/cancellation.js";
class h {
  constructor(o) {
    this.nameProvider = o.references.NameProvider, this.descriptions = o.workspace.AstNodeDescriptionProvider;
  }
  async computeExports(o, e = n.CancellationToken.None) {
    return this.computeExportsForNode(o.parseResult.value, o, void 0, e);
  }
  /**
   * Creates {@link AstNodeDescription AstNodeDescriptions} for the given {@link AstNode parentNode} and its children.
   * The list of children to be considered is determined by the function parameter {@link children}.
   * By default only the direct children of {@link parentNode} are visited, nested nodes are not exported.
   *
   * @param parentNode AST node to be exported, i.e., of which an {@link AstNodeDescription} shall be added to the returned list.
   * @param document The document containing the AST node to be exported.
   * @param children A function called with {@link parentNode} as single argument and returning an {@link Iterable} supplying the children to be visited, which must be directly or transitively contained in {@link parentNode}.
   * @param cancelToken Indicates when to cancel the current operation.
   * @throws `OperationCancelled` if a user action occurs during execution.
   * @returns A list of {@link AstNodeDescription AstNodeDescriptions} to be published to index.
   */
  async computeExportsForNode(o, e, s = c, t = n.CancellationToken.None) {
    const r = [];
    this.exportNode(o, r, e);
    for (const a of s(o))
      await i(t), this.exportNode(a, r, e);
    return r;
  }
  /**
   * Add a single node to the list of exports if it has a name. Override this method to change how
   * symbols are exported, e.g. by modifying their exported name.
   */
  exportNode(o, e, s) {
    const t = this.nameProvider.getName(o);
    t && e.push(this.descriptions.createDescription(o, t, s));
  }
  async computeLocalScopes(o, e = n.CancellationToken.None) {
    const s = o.parseResult.value, t = new m();
    for (const r of p(s))
      await i(e), this.processNode(r, o, t);
    return t;
  }
  /**
   * Process a single node during scopes computation. The default implementation makes the node visible
   * in the subtree of its container (if the node has a name). Override this method to change this,
   * e.g. by increasing the visibility to a higher level in the AST.
   */
  processNode(o, e, s) {
    const t = o.$container;
    if (t) {
      const r = this.nameProvider.getName(o);
      r && s.add(t, this.descriptions.createDescription(o, r, e));
    }
  }
}
export {
  h as DefaultScopeComputation
};
