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

1from collections.abc import Iterator 

2from pathlib import Path 

3 

4from clang.cindex import CompilationDatabase as ClangCompilationDatabase 

5 

6from renaissance.syntax_tree import ASTFactory, ASTNode 

7 

8 

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. 

13 

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. 

17 

18 Yields: 

19 Iterator[tuple[ASTFactory, ASTNode]]: An iterator of tuples, each containing 

20 an AST factory and an AST node type. 

21 

22 Be careful to not use the Iterable is a list as it will load ALL the AST nodes in memory. 

23 

24 """ 

25 db = ClangCompilationDatabase.fromDirectory(str(path)) 

26 

27 def factory_and_atu(command): 

28 return CompilationDatabase.__create_processor(typ, command) 

29 

30 yield from map(factory_and_atu, db.getAllCompileCommands()) 

31 

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