Coverage for src / renaissance / integrations / clang / clang_adapter.py: 87%
31 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 clang import cindex
3from renaissance.integrations.tree_sitter.lst import LST, LSTNode
4from renaissance.utils.ast_utils import detect_placeholder
7class ClangAdapter:
8 def __init__(self, clang_path: str | None = None, args: list | None = None):
9 if clang_path and cindex.Config.library_path is None:
10 cindex.Config.set_library_path(clang_path)
11 self.args = args or ["-std=c++17"]
13 def parse(self, file_path: str) -> LST:
14 index = cindex.Index.create()
15 translation_unit = index.parse(file_path, args=self.args)
16 return LST(self._convert_node(translation_unit.cursor))
18 def load_from_text(self, text: str, file_name: str):
19 index = cindex.Index.create()
20 translation_unit = index.parse(file_name, unsaved_files=[(file_name, text)], args=[])
21 return LST(self._convert_node(translation_unit.cursor))
23 def to_lst(self, source_code: str) -> LST:
24 # source_code= replace_dollar(source_code)
25 return self.load_from_text(source_code, "no_src.cpp")
27 def _convert_node(self, cursor: cindex.Cursor, parent: LSTNode | None = None) -> LSTNode:
28 try:
29 kind = cursor.kind.name
30 except Exception as e:
31 print(e.__cause__)
32 kind = "invalid kind"
33 signature = cursor.spelling or cursor.displayname or kind
35 is_ph, coerced_type, ph_name = detect_placeholder(signature, kind)
37 node = LSTNode(
38 node_type=coerced_type if is_ph else kind,
39 properties={
40 "spelling": cursor.spelling,
41 "type": str(cursor.type.spelling),
42 "location": str(cursor.location),
43 "is_definition": cursor.is_definition(),
44 "name": ph_name,
45 **(
46 {
47 "placeholder": True,
48 "placeholder_name": ph_name,
49 "original_node_type": cursor.kind.name,
50 }
51 if is_ph
52 else {}
53 ),
54 },
55 signature=signature,
56 offset=cursor.extent.start.offset,
57 parent=parent,
58 )
60 for child in cursor.get_children():
61 child_node = self._convert_node(child, parent=node)
62 node.add_child(child_node)
63 return node