diff options
Diffstat (limited to 'Tools/c-analyzer/c_analyzer/symbols/info.py')
-rw-r--r-- | Tools/c-analyzer/c_analyzer/symbols/info.py | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/Tools/c-analyzer/c_analyzer/symbols/info.py b/Tools/c-analyzer/c_analyzer/symbols/info.py new file mode 100644 index 0000000000..96a251abb7 --- /dev/null +++ b/Tools/c-analyzer/c_analyzer/symbols/info.py @@ -0,0 +1,51 @@ +from collections import namedtuple + +from c_analyzer.common.info import ID +from c_analyzer.common.util import classonly, _NTBase + + +class Symbol(_NTBase, namedtuple('Symbol', 'id kind external')): + """Info for a single compilation symbol.""" + + __slots__ = () + + class KIND: + VARIABLE = 'variable' + FUNCTION = 'function' + OTHER = 'other' + + @classonly + def from_name(cls, name, filename=None, kind=KIND.VARIABLE, external=None): + """Return a new symbol based on the given name.""" + id = ID(filename, None, name) + return cls(id, kind, external) + + def __new__(cls, id, kind=KIND.VARIABLE, external=None): + self = super().__new__( + cls, + id=ID.from_raw(id), + kind=str(kind) if kind else None, + external=bool(external) if external is not None else None, + ) + return self + + def __hash__(self): + return hash(self.id) + + def __getattr__(self, name): + return getattr(self.id, name) + + def validate(self): + """Fail if the object is invalid (i.e. init with bad data).""" + if not self.id: + raise TypeError('missing id') + else: + self.id.validate() + + if not self.kind: + raise TypeError('missing kind') + elif self.kind not in vars(self.KIND).values(): + raise ValueError(f'unsupported kind {self.kind}') + + if self.external is None: + raise TypeError('missing external') |