import { streamContents, streamAllContents } from "./lib-utils-ast-utils.js";
import { MultiMap } from "./lib-utils-collections.js";
import { interruptAndCheck } from "./lib-utils-promise-utils.js";
import { c as cancellationExports } from "../../_virtual/cancellation.js";
class DefaultScopeComputation {
  constructor(services) {
    this.nameProvider = services.references.NameProvider;
    this.descriptions = services.workspace.AstNodeDescriptionProvider;
  }
  async computeExports(document, cancelToken = cancellationExports.CancellationToken.None) {
    return this.computeExportsForNode(document.parseResult.value, document, void 0, cancelToken);
  }
  /**
   * 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(parentNode, document, children = streamContents, cancelToken = cancellationExports.CancellationToken.None) {
    const exports$1 = [];
    this.exportNode(parentNode, exports$1, document);
    for (const node of children(parentNode)) {
      await interruptAndCheck(cancelToken);
      this.exportNode(node, exports$1, document);
    }
    return exports$1;
  }
  /**
   * 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(node, exports$1, document) {
    const name = this.nameProvider.getName(node);
    if (name) {
      exports$1.push(this.descriptions.createDescription(node, name, document));
    }
  }
  async computeLocalScopes(document, cancelToken = cancellationExports.CancellationToken.None) {
    const rootNode = document.parseResult.value;
    const scopes = new MultiMap();
    for (const node of streamAllContents(rootNode)) {
      await interruptAndCheck(cancelToken);
      this.processNode(node, document, scopes);
    }
    return scopes;
  }
  /**
   * 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(node, document, scopes) {
    const container = node.$container;
    if (container) {
      const name = this.nameProvider.getName(node);
      if (name) {
        scopes.add(container, this.descriptions.createDescription(node, name, document));
      }
    }
  }
}
export {
  DefaultScopeComputation
};
//# sourceMappingURL=lib-references-scope-computation.js.map
