# SPDX-License-Identifier: Apache-2.0
#
# This file is part of the M2-ISA-R project: https://github.com/tum-ei-eda/M2-ISA-R
#
# Copyright (C) 2024
# Chair of Electrical Design Automation
# Technical University of Munich
from dataclasses import dataclass, field
from enum import Enum, auto
[docs]
class LineInfoPlacement(Enum):
@dataclass
[docs]
class CodeInfoBase:
"""Base class for tracking code info."""
[docs]
id: int = field(default=None, kw_only=True)
"""Automatically calculated unique ID for tracking purposes in consumer programs."""
"""A global database of all created CodeInfo objects."""
[docs]
def __post_init__(self):
if self.id is None:
self.id = CodeInfoBase.__id_counter
CodeInfoBase.__id_counter += 1
CodeInfoBase.database[self.id] = self
[docs]
def line_eq(self, other):
if isinstance(other, self.__class__) or isinstance(self, other.__class__):
return self.file_path == other.file_path and \
self.start_line_no == other.start_line_no #and \
#self.stop_line_no == other.stop_line_no
raise NotImplementedError
[docs]
def __hash__(self) -> int:
return hash(self.id)
[docs]
def line_hash(self):
return hash((self.file_path, self.start_line_no, self.stop_line_no))
@dataclass(eq=False)
[docs]
class LineInfo(CodeInfoBase):
[docs]
placement: LineInfoPlacement = field(default=LineInfoPlacement.AFTER, kw_only=True)
@dataclass(eq=False)
[docs]
class FunctionInfo(CodeInfoBase):
@dataclass(eq=False)
[docs]
class BranchInfo(LineInfo):
[docs]
branch_id: int = field(default=None, kw_only=True)
@dataclass(eq=False)
[docs]
class BranchEntryInfo(BranchInfo):
[docs]
placement: LineInfoPlacement = field(default=LineInfoPlacement.BEFORE, init=False)
[docs]
def __post_init__(self):
super().__post_init__()
if self.branch_id is None:
self.branch_id = self.id
[docs]
class InfoFactory:
def __init__(self, cls_to_use):
[docs]
self.cls_to_use = cls_to_use
[docs]
self.tracker: "dict[tuple[str, int, int], CodeInfoBase]" = {}
[docs]
def make(self, file_path, start_chr, stop_chr, start_line_no, stop_line_no, *args, **kwargs):
ret = self.tracker.get((file_path, start_chr, stop_chr))
if ret is None:
ret = self.cls_to_use(file_path, start_chr, stop_chr, start_line_no, stop_line_no, *args, **kwargs)
self.tracker[((file_path, start_chr, stop_chr))] = ret
return ret
[docs]
LineInfoFactory = InfoFactory(LineInfo)
[docs]
FunctionInfoFactory = InfoFactory(FunctionInfo)
[docs]
BranchEntryInfoFactory = InfoFactory(BranchEntryInfo)