Coverage for lobster/tools/cpp/implementation_builder.py: 100%
28 statements
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-06 09:51 +0000
« prev ^ index » next coverage.py v7.10.2, created at 2025-08-06 09:51 +0000
1from os.path import abspath
2from typing import Dict, Match
3from lobster.file_tag_generator import FileTagGenerator
4from lobster.items import Implementation, Tracing_Tag
5from lobster.location import File_Reference
8class ImplementationBuilder:
9 """
10 A specialized file tag generator for C/C++ files.
11 It generates Tracing_Tag and File_Reference objects based on the file name and line
12 number.
13 """
15 MIN_NUM_GROUPS = 4
16 REASON_GROUP_NUM = MIN_NUM_GROUPS + 1
17 REFERENCE_GROUP_NUM = MIN_NUM_GROUPS + 1
19 def __init__(self) -> None:
20 self._generator = FileTagGenerator()
22 def from_match_if_new(
23 self,
24 db: Dict[str, Implementation],
25 match: Match,
26 ) -> Implementation:
27 """
28 Builds and insert a new Implementation object into the database if it does not
29 already exist.
30 Otherwise, it returns the existing Implementation object.
31 """
32 impl = self.from_match(match)
33 return db.setdefault(impl.tag.key(), impl)
35 def from_match(self, match: Match) -> Implementation:
36 """
37 Generate an Implementation object from a regex match object.
38 """
39 filename, line_nr, kind, function_name, *_ = match.groups()
40 try:
41 line_nr = int(line_nr)
42 except ValueError as exc:
43 raise ValueError(f"Invalid line number '{line_nr}' "
44 f"in regex group '{match.group(2)}'!") from exc
46 return Implementation(
47 tag = self._get_tag(filename, function_name, line_nr),
48 location = self._get_location(filename, line_nr),
49 language = "C/C++",
50 kind = kind,
51 name = function_name,
52 )
54 def _get_tag(self, file: str, function_name: str, line_nr: int) -> Tracing_Tag:
55 """
56 Generate a unique tag for the given file.
57 """
58 file_tag = self._generator.get_tag(file)
59 function_uid = f"{file_tag}:{function_name}:{line_nr}"
60 return Tracing_Tag("cpp", function_uid)
62 @staticmethod
63 def _get_location(file: str, line_nr: int) -> File_Reference:
64 """
65 Generate a location object for the file using its absolute path.
66 """
67 return File_Reference(abspath(file), line_nr)