Coverage for src/pystencilssfg/ir/analysis.py: 88%

41 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-04-04 07:16 +0000

1from __future__ import annotations 

2 

3from ..lang import HeaderFile, includes 

4from .syntax import ( 

5 SfgSourceFile, 

6 SfgNamespaceElement, 

7 SfgClassBodyElement, 

8 SfgNamespaceBlock, 

9 SfgEntityDecl, 

10 SfgEntityDef, 

11 SfgClassBody, 

12 SfgVisibilityBlock, 

13) 

14 

15 

16def collect_includes(file: SfgSourceFile) -> set[HeaderFile]: 

17 from .call_tree import SfgCallTreeNode 

18 from .entities import ( 

19 SfgCodeEntity, 

20 SfgKernelHandle, 

21 SfgFunction, 

22 SfgMethod, 

23 SfgClassMember, 

24 SfgConstructor, 

25 SfgMemberVariable, 

26 ) 

27 

28 def visit_decl(entity: SfgCodeEntity | SfgClassMember) -> set[HeaderFile]: 

29 match entity: 

30 case ( 

31 SfgKernelHandle(_, parameters) 

32 | SfgFunction(_, _, parameters) 

33 | SfgMethod(_, _, parameters) 

34 | SfgConstructor(_, parameters, _, _) 

35 ): 

36 incls: set[HeaderFile] = set().union(*(includes(p) for p in parameters)) 

37 if isinstance(entity, (SfgFunction, SfgMethod)): 

38 incls |= includes(entity.return_type) 

39 return incls 

40 

41 case SfgMemberVariable(): 

42 return includes(entity) 

43 

44 case _: 

45 assert False, "unexpected entity" 

46 

47 def walk_syntax( 

48 obj: ( 

49 SfgNamespaceElement 

50 | SfgClassBodyElement 

51 | SfgVisibilityBlock 

52 | SfgCallTreeNode 

53 ), 

54 ) -> set[HeaderFile]: 

55 match obj: 

56 case str(): 

57 return set() 

58 

59 case SfgCallTreeNode(): 

60 return obj.required_includes.union( 

61 *(walk_syntax(child) for child in obj.children), 

62 ) 

63 

64 case SfgEntityDecl(entity): 

65 return visit_decl(entity) 

66 

67 case SfgEntityDef(entity): 

68 match entity: 

69 case SfgKernelHandle(kernel, _): 

70 return ( 

71 set(HeaderFile.parse(h) for h in kernel.required_headers) 

72 | {HeaderFile.parse("<cstdint>")} 

73 | visit_decl(entity) 

74 ) 

75 

76 case SfgFunction(_, tree, _) | SfgMethod(_, tree, _): 

77 return walk_syntax(tree) | visit_decl(entity) 

78 

79 case SfgConstructor(): 

80 return visit_decl(entity) 

81 

82 case SfgMemberVariable(): 

83 return includes(entity) 

84 

85 case _: 

86 assert False, "unexpected entity" 

87 

88 case SfgNamespaceBlock(_, elements) | SfgVisibilityBlock(_, elements): 

89 return set().union(*(walk_syntax(elem) for elem in elements)) # type: ignore 

90 

91 case SfgClassBody(_, vblocks): 

92 return set().union(*(walk_syntax(vb) for vb in vblocks)) 

93 

94 case _: 

95 assert False, "unexpected syntax element" 

96 

97 return set().union(*(walk_syntax(elem) for elem in file.elements))