Source code for pylasu.model.position

from dataclasses import dataclass, field
from pathlib import Path


[docs] @dataclass(order=True) class Point: line: int column: int def __post_init__(self): if self.line < 1: raise Exception(f"Line {self.line} cannot be less than 1") if self.column < 0: raise Exception(f"Column {self.column} cannot be less than 0")
[docs] def is_before(self, other: "Point"): return self < other
def __add__(self, other): if isinstance(other, str): if len(other) == 0: return self line = self.line column = self.column i = 0 while i < len(other): if other[i] == '\n' or other[i] == '\r': line += 1 column = 0 if other[i] == '\r' and i < len(other) - 1 and other[i + 1] == '\n': i += 1 # Count the \r\n sequence as 1 line else: column += 1 i += 1 return Point(line, column) else: raise NotImplementedError() def __repr__(self): return f"Line {self.line}, Column {self.column}" def __str__(self): return f"{self.line}:{self.column}"
[docs] class Source: pass
[docs] @dataclass class SourceSet: name: str root: Path
[docs] @dataclass class SourceSetElement(Source): sourceSet: SourceSet relativePath: Path
[docs] @dataclass class FileSource(Source): file: Path def __str__(self): return str(self.file)
[docs] @dataclass class StringSource(Source): code: str = None
[docs] @dataclass class URLSource(Source): url: str = None
[docs] @dataclass(order=True) class Position: """An area in a source file, from start to end. The start point is the point right before the starting character. The end point is the point right after the last character. An empty position will have coinciding points. Consider a file with one line, containing the text "HELLO". The Position of such text will be Position(Point(1, 0), Point(1, 5)).""" start: Point end: Point source: Source = field(compare=False, default=None) def __post_init__(self): if self.end < self.start: raise Exception(f"End point can't be before starting point: {self.start}{self.end}") def __contains__(self, pos): return isinstance(pos, Position) and self.start <= pos.start and self.end >= pos.end def __repr__(self): return f"Position(start={self.start}, end={self.end}"\ + (f", source={self.source}" if self.source is not None else "")\ + ")" def __str__(self): str_rep = (f"{self.source}:" if self.source is not None else "") + str(self.start) if self.start != self.end: str_rep += f"-{self.end}" return str_rep
[docs] def pos(start_line: int, start_col: int, end_line: int, end_col: int, source: Source = None): """Utility function to create a Position""" return Position(Point(start_line, start_col), Point(end_line, end_col), source)