dataflow-analysis/clang_interop/types.py

174 lines
5.3 KiB
Python
Raw Normal View History

import os
from dataclasses import dataclass, field
from typing import List, Literal, Dict, Set
@dataclass
class ClTranslationUnit:
dependencies: Dict[int, Set[int]]
publications: Dict[int, Set[int]]
nodes: Dict[int, 'ClNode']
publishers: Dict[int, 'ClPublisher']
subscriptions: Dict[int, 'ClSubscription']
timers: Dict[int, 'ClTimer']
fields: Dict[int, 'ClField']
methods: Dict[int, 'ClMethod']
accesses: List['ClMemberRef']
@dataclass
class ClContext:
translation_units: Dict[str, 'ClTranslationUnit'] = field(default_factory=dict)
@dataclass
class ClSourceRange:
start_file: str
start_line: int | None
start_col: int | None
end_file: str
end_line: int | None
end_col: int | None
def __init__(self, json_obj):
begin = json_obj["begin"].split(":")
end = json_obj["end"].split(":")
self.start_file = os.path.realpath(begin[0])
self.start_line = int(begin[1]) if len(begin) > 1 else None
self.start_col = int(begin[2].split(" ")[0]) if len(begin) > 2 else None
self.end_file = os.path.realpath(end[0])
self.end_line = int(end[1]) if len(end) > 1 else None
self.end_col = int(end[2].split(" ")[0]) if len(end) > 2 else None
def __hash__(self):
return hash((self.start_file, self.start_line, self.start_col,
self.end_file, self.end_line, self.end_col))
@dataclass
class ClNode:
id: int
qualified_name: str
source_range: 'ClSourceRange'
field_ids: List[int] | None
method_ids: List[int] | None
ros_name: str | None
ros_namespace: str | None
def __init__(self, json_obj):
self.id = json_obj['id']
self.qualified_name = json_obj['id']
self.source_range = ClSourceRange(json_obj['source_range'])
self.field_ids = list(map(lambda obj: obj['id'], json_obj['fields'])) if 'fields' in json_obj else None
self.method_ids = list(map(lambda obj: obj['id'], json_obj['methods'])) if 'methods' in json_obj else None
self.ros_name = json_obj['ros_name'] if 'ros_name' in json_obj else None
self.ros_namespace = json_obj['ros_namespace'] if 'ros_namespace' in json_obj else None
def __hash__(self):
return hash(self.id)
@dataclass
class ClMethod:
id: int
qualified_name: str
source_range: 'ClSourceRange'
return_type: str | None
parameter_types: List[str] | None
def __init__(self, json_obj):
self.id = json_obj['id']
self.qualified_name = json_obj['qualified_name']
self.source_range = ClSourceRange(json_obj['source_range'])
self.return_type = json_obj['signature']['return_type'] if 'signature' in json_obj else None
self.parameter_types = json_obj['signature']['parameter_types'] if 'signature' in json_obj else None
def __hash__(self):
return hash(self.id)
@dataclass
class ClField:
id: int
qualified_name: str
source_range: 'ClSourceRange'
def __init__(self, json_obj):
self.id = json_obj['id']
self.qualified_name = json_obj['qualified_name']
self.source_range = ClSourceRange(json_obj['source_range'])
def __hash__(self):
return hash(self.id)
@dataclass
class ClMemberRef:
type: Literal["read", "write", "call", "arg", "pub"] | None
member_chain: List[int]
method_id: int | None
node_id: int | None
source_range: 'ClSourceRange'
def __init__(self, json_obj):
access_type = json_obj['context']['access_type']
if access_type == 'none':
access_type = None
self.type = access_type
self.member_chain = list(map(lambda obj: obj['id'], json_obj['member'][::-1]))
self.method_id = json_obj['context']['method']['id'] if 'method' in json_obj['context'] else None
self.node_id = json_obj['context']['node']['id'] if 'node' in json_obj['context'] else None
self.source_range = ClSourceRange(json_obj['context']['statement']['source_range'])
def __hash__(self):
return self.source_range.__hash__()
@dataclass
class ClSubscription:
topic: str | None
callback_id: int | None
source_range: 'ClSourceRange'
def __init__(self, json_obj):
self.topic = json_obj['topic'] if 'topic' in json_obj else None
self.callback_id = json_obj['callback']['id'] if 'callback' in json_obj else None
self.source_range = ClSourceRange(json_obj['source_range'])
def __hash__(self):
return self.source_range.__hash__()
@dataclass
class ClPublisher:
topic: str | None
member_id: int | None
source_range: 'ClSourceRange'
def update(self, t2: 'ClTimer'):
return self
def __init__(self, json_obj):
self.topic = json_obj['topic'] if 'topic' in json_obj else None
self.member_id = json_obj['member']['id'] if 'member' in json_obj else None
self.source_range = ClSourceRange(json_obj['source_range'])
def __hash__(self):
return self.source_range.__hash__()
@dataclass
class ClTimer:
callback_id: int | None
source_range: 'ClSourceRange'
def __init__(self, json_obj):
self.callback_id = json_obj['callback']['id'] if 'callback' in json_obj else None
self.source_range = ClSourceRange(json_obj['source_range'])
def __hash__(self):
return self.source_range.__hash__()