skill-ls/skillls/checker.py

76 lines
1.8 KiB
Python

from dataclasses import dataclass
from enum import Enum, auto
from lsprotocol.types import Location, Position, Range
from skillls.types import URI
class SyntaxError(Exception):
pass
class ParenMismatchErrorKind(Enum):
TooManyClosed = "Found too many closing parens"
TooManyOpened = "Found too many open parens"
@dataclass
class ParenMismatchError(SyntaxError):
kind: ParenMismatchErrorKind
loc: Range
def _check_for_matching_parens(content: str) -> list[Exception]:
excs: list[Exception] = []
opened = 0
line = 0
col = 0
last_open: Position = Position(0, 0)
last_close: Position = Position(0, 0)
for char in content:
match char:
case "(":
opened += 1
last_open = Position(line, col)
case ")":
opened -= 1
if opened < 0:
excs.append(
ParenMismatchError(
ParenMismatchErrorKind.TooManyClosed,
Range(Position(line, col), Position(line, col + 1)),
)
)
opened = 0
last_close = Position(line, col)
case "\n":
line += 1
col = -1
case _:
pass
col += 1
if opened > 0:
excs.append(
ParenMismatchError(
ParenMismatchErrorKind.TooManyOpened,
Range(last_open, Position(last_open.line, last_open.character + 1)),
)
)
return excs
def check_content_for_errors(clean_content: str) -> None:
excs: list[Exception] = []
excs.extend(_check_for_matching_parens(clean_content))
if excs:
raise ExceptionGroup("", excs)