source: greatly improve location reporting for multi-line source extracts
This commit is contained in:
parent
fc9b6b30c6
commit
820fa1760d
1 changed files with 29 additions and 12 deletions
|
|
@ -1,8 +1,11 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from dataclasses import dataclass
|
||||
|
||||
from beartype import beartype
|
||||
from beartype.typing import Optional
|
||||
from dataclasses import dataclass
|
||||
|
||||
|
||||
@beartype
|
||||
@dataclass
|
||||
|
|
@ -44,21 +47,35 @@ class SourceLocation:
|
|||
source_lines[-1] = source_lines[-1][:self.end.character]
|
||||
return "\n".join(source_lines)
|
||||
|
||||
def show_in_source(self) -> str:
|
||||
source = self.source.splitlines(keepends=False)
|
||||
source_line = source[self.begin.line]
|
||||
result = [source_line]
|
||||
if self.begin.line != self.end.line:
|
||||
return "\n".join(result)
|
||||
|
||||
line = " " * self.begin.character
|
||||
line += "^" + "-" * max(0, (self.end.character - self.begin.character - 1))
|
||||
line += " " * (len(source_line) - len(line))
|
||||
@staticmethod
|
||||
def underline(string: str, begin: int, end: int) -> str:
|
||||
assert begin <= end
|
||||
result = [string]
|
||||
line = " " * begin
|
||||
line += "^" + "~" * max(0, (end - begin - 1))
|
||||
line += " " * (len(string) - len(line))
|
||||
|
||||
result += [line]
|
||||
|
||||
return "\n".join(result)
|
||||
|
||||
def show_in_source(self) -> str:
|
||||
source = self.source.splitlines(keepends=False)
|
||||
line_number_maxlen = int(math.log10(len(source)) + 1)
|
||||
lines = source[self.begin.line:self.end.line + 1]
|
||||
result = []
|
||||
begin_char = self.begin.character
|
||||
while len(lines) > 0:
|
||||
line = lines.pop(0)
|
||||
end_char = self.end.character if len(lines) == 0 else len(line)
|
||||
result += [SourceLocation.underline(line, begin_char, end_char)]
|
||||
begin_char = 0
|
||||
|
||||
for i, source_line in enumerate(result):
|
||||
line_prefix = f"Line {self.begin.line + i:0>{line_number_maxlen}}: "
|
||||
lines = source_line.splitlines(keepends=False)
|
||||
lines[0] = line_prefix + lines[0]
|
||||
lines[1] = " " * len(line_prefix) + lines[1]
|
||||
result[i] = "\n".join(lines)
|
||||
|
||||
|
||||
return "\n".join(result)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue