From cc23996266846890fea708a7eb5dcff66d44c8b6 Mon Sep 17 00:00:00 2001 From: Eli Schwartz Date: Wed, 1 Mar 2023 23:28:43 -0500 Subject: mparser: Add partial AST to exceptions Surprisingly enough we need to do this twice. In some cases (failing-meson/72 triggers this) we can error out after parsing the codeblock, but without getting the expected eof. We need to catch both exceptions as either one can interrupt the built codeblock object. Co-authored-by: Xavier Claessens --- mesonbuild/mparser.py | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/mesonbuild/mparser.py b/mesonbuild/mparser.py index dbb6a454e..fb0ec9535 100644 --- a/mesonbuild/mparser.py +++ b/mesonbuild/mparser.py @@ -41,6 +41,9 @@ def decode_match(match: T.Match[str]) -> str: return codecs.decode(match.group(0).encode(), 'unicode_escape') class ParseException(MesonException): + + ast: T.Optional[CodeBlockNode] = None + def __init__(self, text: str, line: str, lineno: int, colno: int) -> None: # Format as error message, followed by the line with the error, followed by a caret to show the error column. super().__init__(mlog.code_line(text, line, colno)) @@ -548,7 +551,11 @@ class Parser: def parse(self) -> CodeBlockNode: block = self.codeblock() - self.expect('eof') + try: + self.expect('eof') + except ParseException as e: + e.ast = block + raise return block def statement(self) -> BaseNode: @@ -838,9 +845,13 @@ class Parser: def codeblock(self) -> CodeBlockNode: block = CodeBlockNode(self.current) cond = True - while cond: - curline = self.line() - if not isinstance(curline, EmptyNode): - block.lines.append(curline) - cond = self.accept('eol') + try: + while cond: + curline = self.line() + if not isinstance(curline, EmptyNode): + block.lines.append(curline) + cond = self.accept('eol') + except ParseException as e: + e.ast = block + raise return block -- cgit v1.2.3