Coverage for src / renaissance / syntax_tree / ast_shower.py: 95%
39 statements
« prev ^ index » next coverage.py v7.13.4, created at 2026-09-09 14:04 +0000
« prev ^ index » next coverage.py v7.13.4, created at 2026-09-09 14:04 +0000
1import io
2from collections.abc import Sequence
3from io import StringIO
4from pathlib import Path
5from typing import Protocol, Self, runtime_checkable
7from termcolor import colored
10@runtime_checkable
11class Displayable(Protocol):
12 ast_type: str
13 children: list[Self]
14 is_implicit: bool
15 show_props: bool
18class ASTShower:
19 focus: str = "NO-FOCUS-DEFINED"
21 @staticmethod
22 def show_node(node, include_properties: bool = False) -> None:
23 print("\n" + ASTShower.get_node(node, include_properties))
25 @staticmethod
26 def show_nodes(ast_nodes: Sequence, include_properties: bool = False) -> None:
27 for ast_node in ast_nodes:
28 ASTShower.show_node(ast_node, include_properties)
30 @staticmethod
31 def get_node(ast_node: Displayable, include_properties: bool = False) -> str:
32 if isinstance(ast_node, Displayable):
33 buffer = io.StringIO()
34 ASTShower._process_node(buffer, "", ast_node, include_properties)
35 return buffer.getvalue()
36 return ""
38 @staticmethod
39 def store_node(filename: str, ast_node: Displayable, include_properties: bool = False) -> None:
40 with Path(filename).open("w") as f:
41 f.write(ASTShower.get_node(ast_node, include_properties))
43 @staticmethod
44 def _process_node(output: StringIO, indent: str, node: Displayable, include_properties: bool) -> None:
45 if node.is_implicit:
46 node.indent = indent
47 node.show_props = include_properties
48 raw = str(node)
49 raw = raw.replace(ASTShower.focus, colored(ASTShower.focus, "red", attrs=["bold"]))
50 output.write(raw)
51 if node.children:
52 for child in node.children:
53 ASTShower._process_node(output, indent + " ", child, include_properties)