Add references to error messages

That way, errors can reference other parts of the code, like duplicate
properties.
This commit is contained in:
James Westman 2022-05-27 15:06:56 -05:00
parent 824476bda1
commit d987b15374
No known key found for this signature in database
GPG key ID: CE2DBA0ADB654EA6
2 changed files with 23 additions and 2 deletions

View file

@ -138,7 +138,10 @@ class AstNode:
if type(child) is type(self): if type(child) is type(self):
if check is None or check(child): if check is None or check(child):
raise CompileError(error) raise CompileError(
error,
references=[ErrorReference(child.group.start, child.group.end, "previous declaration was here")]
)
def validate(token_name=None, end_token_name=None, skip_incomplete=False): def validate(token_name=None, end_token_name=None, skip_incomplete=False):

View file

@ -31,13 +31,20 @@ class PrintableError(Exception):
raise NotImplementedError() raise NotImplementedError()
@dataclass
class ErrorReference:
start: int
end: int
message: str
class CompileError(PrintableError): class CompileError(PrintableError):
""" A PrintableError with a start/end position and optional hints """ """ A PrintableError with a start/end position and optional hints """
category = "error" category = "error"
color = Colors.RED color = Colors.RED
def __init__(self, message, start=None, end=None, did_you_mean=None, hints=None, actions=None, fatal=False): def __init__(self, message, start=None, end=None, did_you_mean=None, hints=None, actions=None, fatal=False, references=None):
super().__init__(message) super().__init__(message)
self.message = message self.message = message
@ -45,6 +52,7 @@ class CompileError(PrintableError):
self.end = end self.end = end
self.hints = hints or [] self.hints = hints or []
self.actions = actions or [] self.actions = actions or []
self.references = references or []
self.fatal = fatal self.fatal = fatal
if did_you_mean is not None: if did_you_mean is not None:
@ -84,6 +92,16 @@ at {filename} line {line_num} column {col_num}:
for hint in self.hints: for hint in self.hints:
stream.write(f"{Colors.FAINT}hint: {hint}{Colors.CLEAR}\n") stream.write(f"{Colors.FAINT}hint: {hint}{Colors.CLEAR}\n")
for ref in self.references:
line_num, col_num = utils.idx_to_pos(ref.start + 1, code)
line = code.splitlines(True)[line_num]
line_num += 1
stream.write(f"""{Colors.FAINT}note: {ref.message}:
at {filename} line {line_num} column {col_num}:
{Colors.FAINT}{line_num :>4} |{line.rstrip()}\n {Colors.FAINT}|{" "*(col_num-1)}^{Colors.CLEAR}\n""")
stream.write("\n") stream.write("\n")