Coverage for src/renaissance/integrations/tree_sitter/adapter.py: 100%
24 statements
« prev ^ index » next coverage.py v7.16.1, created at 2026-10-02 13:12 +0000
« prev ^ index » next coverage.py v7.16.1, created at 2026-10-02 13:12 +0000
1"""AI: Adapter that parses source code with tree-sitter into the internal LST representation."""
3from renaissance.integrations.tree_sitter.lst import LST, LSTNode
4from renaissance.utils.ast_utils import detect_placeholder, replace_dollar
5from tree_sitter import Language, Parser
8class TreeSitterAdapter:
9 """AI: Adapter that parses source code with tree-sitter into the internal LST representation."""
11 def __init__(self, grammar_module):
12 """AI: Configure a tree-sitter parser for the given language grammar."""
13 language = Language(grammar_module.language())
14 self.language = language
15 self.parser = Parser(language)
17 def parse_code(self, source_code: str):
18 """AI: Parse source_code with tree-sitter and return the resulting parse tree."""
19 return self.parser.parse(bytes(source_code, "utf8"))
21 def to_lst(self, source_code: str, tree) -> LST:
22 """AI: Convert a tree-sitter parse tree of source_code into an LST."""
23 root_node = tree.root_node
24 source_code = replace_dollar(source_code)
25 return LST(self._convert_node(root_node, source_code, None))
27 def _convert_node(self, node, source_code: str, parent, root=None) -> LSTNode:
28 signature = source_code[node.start_byte : node.end_byte]
29 is_ph, coerced_type, ph_name = detect_placeholder(signature, node.type)
31 lst_node = LSTNode(
32 node_type=coerced_type if is_ph else node.type,
33 properties={
34 "start_point": node.start_point,
35 "end_point": node.end_point,
36 "source_code": source_code,
37 "name": ph_name,
38 "is_named": node.is_named,
39 **(
40 {
41 "placeholder": True,
42 "placeholder_name": ph_name,
43 "original_node_type": node.type,
44 }
45 if is_ph
46 else {}
47 ),
48 },
49 signature=signature,
50 offset=node.start_byte,
51 children=[],
52 parent=parent,
53 root=root,
54 )
55 if not root:
56 root = lst_node
58 for child in node.children:
59 lst_child = self._convert_node(child, source_code, lst_node, root)
60 lst_node.add_child(lst_child)
61 return lst_node