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

1import io 

2from collections.abc import Sequence 

3from io import StringIO 

4from pathlib import Path 

5from typing import Protocol, Self, runtime_checkable 

6 

7from termcolor import colored 

8 

9 

10@runtime_checkable 

11class Displayable(Protocol): 

12 ast_type: str 

13 children: list[Self] 

14 is_implicit: bool 

15 show_props: bool 

16 

17 

18class ASTShower: 

19 focus: str = "NO-FOCUS-DEFINED" 

20 

21 @staticmethod 

22 def show_node(node, include_properties: bool = False) -> None: 

23 print("\n" + ASTShower.get_node(node, include_properties)) 

24 

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) 

29 

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 "" 

37 

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)) 

42 

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)