From 638b5f1dc2c2a463a605a1fbb8080294ba2019e3 Mon Sep 17 00:00:00 2001 From: Jan Tojnar Date: Sat, 18 Nov 2023 20:06:33 +0100 Subject: [PATCH] decompiler: Allow appending to end without newline This will be useful for nested `lookup`s, which are parsed top to bottom but Blueprint prints them in more human-readable bottom to top orientation. --- blueprintcompiler/decompiler.py | 33 +++++++++++++++++++++++---------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/blueprintcompiler/decompiler.py b/blueprintcompiler/decompiler.py index 2663a09..d2f3176 100644 --- a/blueprintcompiler/decompiler.py +++ b/blueprintcompiler/decompiler.py @@ -42,6 +42,18 @@ _NAMESPACES = [ ] +@dataclass +class TextFragment: + text: str + newline_after: bool = True + indent: bool = True + + +@dataclass +class BlockInfo: + terminator: T.Optional[TextFragment] = None + + class LineType(Enum): NONE = 1 STMT = 2 @@ -54,7 +66,7 @@ class DecompileCtx: self._result: str = "" self.gir = GirContext() self._indent: int = 0 - self._blocks_need_end: T.List[str] = [] + self._blocks: T.List[BlockInfo] = [] self._last_line_type: LineType = LineType.NONE self.template_class: T.Optional[str] = None @@ -86,16 +98,17 @@ class DecompileCtx: return None def start_block(self) -> None: - self._blocks_need_end.append("") + self._blocks.append(BlockInfo()) def end_block(self) -> None: - if close := self._blocks_need_end.pop(): - self.print(close) + block = self._blocks.pop() + if terminator := block.terminator: + self.print(terminator.text, terminator.newline_after, terminator.indent) - def end_block_with(self, text: str) -> None: - self._blocks_need_end[-1] = text + def end_block_with(self, text: str, newline_after: bool = True, indent: bool = True) -> None: + self._blocks[-1].terminator = TextFragment(text, newline_after, indent) - def print(self, line: str, newline: bool = True) -> None: + def print(self, line: str, newline: bool = True, indent: bool = True) -> None: if line == "}" or line == "]": self._indent -= 1 @@ -117,13 +130,13 @@ class DecompileCtx: self._result += "\n" self._last_line_type = line_type - self._result += (" " * self._indent) + line + self._result += (" " * self._indent * indent) + line if newline: self._result += "\n" if line.endswith("{") or line.endswith("["): - if len(self._blocks_need_end): - self._blocks_need_end[-1] = _CLOSING[line[-1]] + if len(self._blocks): + self._blocks[-1].terminator = TextFragment(_CLOSING[line[-1]]) self._indent += 1 def print_attribute(self, name: str, value: str, type: GirType) -> None: