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
« 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
6class TreeSitterAdapter:
7 def __init__(self, grammar_module):
8 language = Language(grammar_module.language())
9 self.language = language
10 self.parser = Parser(language)
12 def parse_code(self, source_code: str):
13 return self.parser.parse(bytes(source_code, "utf8"))
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))
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)
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
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