72 lines
2.0 KiB
Python
72 lines
2.0 KiB
Python
from dataclasses import dataclass
|
|
from functools import cached_property
|
|
from typing import overload
|
|
from lsprotocol.types import Position, Range
|
|
|
|
from parsimonious.nodes import Node
|
|
|
|
|
|
# @total_ordering
|
|
# class Position(NamedTuple):
|
|
# line: int
|
|
# char: int
|
|
#
|
|
# def __lt__(self, other: Self) -> bool:
|
|
# return (self.line < other.line) or (
|
|
# (self.line == other.line) and (self.char < other.char)
|
|
# )
|
|
#
|
|
# def __eq__(self, other: Self) -> bool:
|
|
# return (self.line == other.line) and (self.char == other.char)
|
|
#
|
|
#
|
|
# class Range(NamedTuple):
|
|
# start: Position
|
|
# end: Position
|
|
#
|
|
# def __add__(self, other: Self) -> Self:
|
|
# start = min(self.start, other.start)
|
|
# end = max(self.end, other.end)
|
|
# return Range(start, end)
|
|
#
|
|
# def contained_by(self, possibly_contained_by: Self) -> bool:
|
|
# return (self.start >= possibly_contained_by.start) and (
|
|
# self.end <= possibly_contained_by.end
|
|
# )
|
|
#
|
|
# def contains(self, possibly_contains: Self) -> bool:
|
|
# return (self.start <= possibly_contains.start) and (
|
|
# self.end >= possibly_contains.end
|
|
# )
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Locator:
|
|
raw: str
|
|
|
|
@cached_property
|
|
def newlines(self) -> tuple[int, ...]:
|
|
t = tuple(i for i, char in enumerate(self.raw) if char == "\n")
|
|
return t
|
|
|
|
def _locate_pos(self, index: int) -> Position:
|
|
line = next(i for i, char in enumerate(self.newlines) if char >= index)
|
|
return Position(line - 1, index - (self.newlines[line - 1] if line > 0 else 0))
|
|
|
|
@overload
|
|
def locate(self, index: int) -> Position:
|
|
...
|
|
|
|
@overload
|
|
def locate(self, index: Node) -> Range:
|
|
...
|
|
|
|
def locate(self, index: int | Node) -> Position | Range:
|
|
if isinstance(index, int):
|
|
return self._locate_pos(index)
|
|
|
|
start = self._locate_pos(index.start)
|
|
end = self._locate_pos(index.end)
|
|
|
|
return Range(start, end)
|