Coverage for src / renaissance / integrations / clang / clang_compilation_database.py: 47%
19 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 collections.abc import Iterator
2from pathlib import Path
4from clang.cindex import CompilationDatabase as ClangCompilationDatabase
6from renaissance.syntax_tree import ASTFactory, ASTNode
9class CompilationDatabase:
10 @staticmethod
11 def walk(typ: type[ASTNode], path: Path) -> Iterator[tuple[ASTFactory, ASTNode]]:
12 """Load the Clang compilation database and yield factory and AST node type tuples.
14 Args:
15 typ (type[ASTNode]): The type of AST node to be used.
16 path (Path): The path to the directory containing the compilation database.
18 Yields:
19 Iterator[tuple[ASTFactory, ASTNode]]: An iterator of tuples, each containing
20 an AST factory and an AST node type.
22 Be careful to not use the Iterable is a list as it will load ALL the AST nodes in memory.
24 """
25 db = ClangCompilationDatabase.fromDirectory(str(path))
27 def factory_and_atu(command):
28 return CompilationDatabase.__create_processor(typ, command)
30 yield from map(factory_and_atu, db.getAllCompileCommands())
32 @staticmethod
33 def __create_processor(typ: type[ASTNode], compile_command) -> tuple[ASTFactory, ASTNode]:
34 extra_args = list(compile_command.arguments)
35 skip = ["-o", "-c"]
36 filtered_args = [
37 arg
38 for idx, arg in enumerate(extra_args)
39 if arg != compile_command.filename and arg not in skip and (idx == 0 or extra_args[idx - 1] not in skip)
40 ]
41 factory = ASTFactory(typ, extra_args=filtered_args, working_dir=Path(compile_command.directory))
42 atu = factory.create(Path(compile_command.filename)) # The first argument is the file path
43 return factory, atu