Coverage for src / renaissance / integrations / tree_sitter / adapter.py: 100%

24 statements  

« prev     ^ index     » next       coverage.py v7.13.4, created at 2026-09-09 14:04 +0000

1from renaissance.integrations.tree_sitter.lst import LST, LSTNode 

2from renaissance.utils.ast_utils import detect_placeholder, replace_dollar 

3from tree_sitter import Language, Parser 

4 

5 

6class TreeSitterAdapter: 

7 def __init__(self, grammar_module): 

8 language = Language(grammar_module.language()) 

9 self.language = language 

10 self.parser = Parser(language) 

11 

12 def parse_code(self, source_code: str): 

13 return self.parser.parse(bytes(source_code, "utf8")) 

14 

15 def to_lst(self, source_code: str, tree) -> LST: 

16 root_node = tree.root_node 

17 source_code = replace_dollar(source_code) 

18 return LST(self._convert_node(root_node, source_code, None)) 

19 

20 def _convert_node(self, node, source_code: str, parent, root=None) -> LSTNode: 

21 signature = source_code[node.start_byte : node.end_byte] 

22 is_ph, coerced_type, ph_name = detect_placeholder(signature, node.type) 

23 

24 lst_node = LSTNode( 

25 node_type=coerced_type if is_ph else node.type, 

26 properties={ 

27 "start_point": node.start_point, 

28 "end_point": node.end_point, 

29 "source_code": source_code, 

30 "name": ph_name, 

31 "is_named": node.is_named, 

32 **( 

33 { 

34 "placeholder": True, 

35 "placeholder_name": ph_name, 

36 "original_node_type": node.type, 

37 } 

38 if is_ph 

39 else {} 

40 ), 

41 }, 

42 signature=signature, 

43 offset=node.start_byte, 

44 children=[], 

45 parent=parent, 

46 root=root, 

47 ) 

48 if not root: 

49 root = lst_node 

50 

51 for child in node.children: 

52 lst_child = self._convert_node(child, source_code, lst_node, root) 

53 lst_node.add_child(lst_child) 

54 return lst_node