Coverage for src/renaissance/integrations/clang/clang_compilation_database.py: 47%
19 statements
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-15 10:34 +0000
« prev ^ index » next coverage.py v7.16.2, created at 2026-10-15 10:34 +0000
1# Copyright (C) 2024-2026 TNO
2#
3# Licensed under the terms specified in the LICENSE file in the root directory
4# of this repository, also available at:
5# https://github.com/TNO/Renaissance.Py/blob/main/LICENSE
7"""AI: Load a Clang compilation database and iterate its translation units as AST nodes."""
9from collections.abc import Iterator
10from pathlib import Path
12from clang.cindex import CompilationDatabase as ClangCompilationDatabase
14from renaissance.syntax_tree import ASTFactory, ASTNode
17class CompilationDatabase:
18 """AI: Load a Clang compilation database and iterate its translation units as AST nodes."""
20 @staticmethod
21 def walk(typ: type[ASTNode], path: Path) -> Iterator[tuple[ASTFactory, ASTNode]]:
22 """Load the Clang compilation database and yield factory and AST node type tuples.
24 Args:
25 typ (type[ASTNode]): The type of AST node to be used.
26 path (Path): The path to the directory containing the compilation database.
28 Yields:
29 Iterator[tuple[ASTFactory, ASTNode]]: An iterator of tuples, each containing
30 an AST factory and an AST node type.
32 Be careful to not use the Iterable is a list as it will load ALL the AST nodes in memory.
34 """
35 db = ClangCompilationDatabase.fromDirectory(str(path))
37 def factory_and_atu(command):
38 return CompilationDatabase.__create_processor(typ, command)
40 yield from map(factory_and_atu, db.getAllCompileCommands())
42 @staticmethod
43 def __create_processor(typ: type[ASTNode], compile_command) -> tuple[ASTFactory, ASTNode]:
44 extra_args = list(compile_command.arguments)
45 skip = ["-o", "-c"]
46 filtered_args = [
47 arg
48 for idx, arg in enumerate(extra_args)
49 if arg != compile_command.filename and arg not in skip and (idx == 0 or extra_args[idx - 1] not in skip)
50 ]
51 factory = ASTFactory(typ, extra_args=filtered_args, working_dir=Path(compile_command.directory))
52 atu = factory.create(Path(compile_command.filename)) # The first argument is the file path
53 return factory, atu