"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const syntaxTree = require("./lib-syntax-tree.cjs");
const stream = require("./lib-utils-stream.cjs");
function streamCst(node) {
  return new stream.TreeStreamImpl(node, (element) => {
    if (syntaxTree.isCompositeCstNode(element)) {
      return element.content;
    } else {
      return [];
    }
  }, { includeRoot: true });
}
function isChildNode(child, parent) {
  while (child.container) {
    child = child.container;
    if (child === parent) {
      return true;
    }
  }
  return false;
}
function tokenToRange(token) {
  return {
    start: {
      character: token.startColumn - 1,
      line: token.startLine - 1
    },
    end: {
      character: token.endColumn,
      // endColumn uses the correct index
      line: token.endLine - 1
    }
  };
}
function toDocumentSegment(node) {
  if (!node) {
    return void 0;
  }
  const { offset, end, range } = node;
  return {
    range,
    offset,
    end,
    length: end - offset
  };
}
exports.RangeComparison = void 0;
(function(RangeComparison) {
  RangeComparison[RangeComparison["Before"] = 0] = "Before";
  RangeComparison[RangeComparison["After"] = 1] = "After";
  RangeComparison[RangeComparison["OverlapFront"] = 2] = "OverlapFront";
  RangeComparison[RangeComparison["OverlapBack"] = 3] = "OverlapBack";
  RangeComparison[RangeComparison["Inside"] = 4] = "Inside";
  RangeComparison[RangeComparison["Outside"] = 5] = "Outside";
})(exports.RangeComparison || (exports.RangeComparison = {}));
function compareRange(range, to) {
  if (range.end.line < to.start.line || range.end.line === to.start.line && range.end.character <= to.start.character) {
    return exports.RangeComparison.Before;
  } else if (range.start.line > to.end.line || range.start.line === to.end.line && range.start.character >= to.end.character) {
    return exports.RangeComparison.After;
  }
  const startInside = range.start.line > to.start.line || range.start.line === to.start.line && range.start.character >= to.start.character;
  const endInside = range.end.line < to.end.line || range.end.line === to.end.line && range.end.character <= to.end.character;
  if (startInside && endInside) {
    return exports.RangeComparison.Inside;
  } else if (startInside) {
    return exports.RangeComparison.OverlapBack;
  } else if (endInside) {
    return exports.RangeComparison.OverlapFront;
  } else {
    return exports.RangeComparison.Outside;
  }
}
function inRange(range, to) {
  const comparison = compareRange(range, to);
  return comparison > exports.RangeComparison.After;
}
const DefaultNameRegexp = /^[\w\p{L}]$/u;
function findCommentNode(cstNode, commentNames) {
  if (cstNode) {
    const previous = getPreviousNode(cstNode, true);
    if (previous && isCommentNode(previous, commentNames)) {
      return previous;
    }
    if (syntaxTree.isRootCstNode(cstNode)) {
      const endIndex = cstNode.content.findIndex((e) => !e.hidden);
      for (let i = endIndex - 1; i >= 0; i--) {
        const child = cstNode.content[i];
        if (isCommentNode(child, commentNames)) {
          return child;
        }
      }
    }
  }
  return void 0;
}
function isCommentNode(cstNode, commentNames) {
  return syntaxTree.isLeafCstNode(cstNode) && commentNames.includes(cstNode.tokenType.name);
}
function getPreviousNode(node, hidden = true) {
  while (node.container) {
    const parent = node.container;
    let index = parent.content.indexOf(node);
    while (index > 0) {
      index--;
      const previous = parent.content[index];
      if (hidden || !previous.hidden) {
        return previous;
      }
    }
    node = parent;
  }
  return void 0;
}
exports.DefaultNameRegexp = DefaultNameRegexp;
exports.compareRange = compareRange;
exports.findCommentNode = findCommentNode;
exports.getPreviousNode = getPreviousNode;
exports.inRange = inRange;
exports.isChildNode = isChildNode;
exports.isCommentNode = isCommentNode;
exports.streamCst = streamCst;
exports.toDocumentSegment = toDocumentSegment;
exports.tokenToRange = tokenToRange;
//# sourceMappingURL=lib-utils-cst-utils.cjs.map
