from collections import defaultdict
class Body(dict):
def __init__(self, body):
self['BlockIdKind'] = body['BlockId']['Kind']
if 'Variable' in body['BlockId']:
self['BlockName'] = body['BlockId']['Variable']['Name'][0].split("$")[-1]
loc = body['Location']
self['LineRange'] = (loc[0]['Line'], loc[1]['Line'])
self['Filename'] = loc[0]['CacheString']
self['Edges'] = body.get('PEdge', [])
self['Points'] = {i: p['Location']['Line'] for i, p in enumerate(body['PPoint'], 1)}
self['Index'] = body['Index']
self['Variables'] = {x['Variable']['Name'][0].split(
"$")[-1]: x['Type'] for x in body['DefineVariable']}
self['Line2Points'] = defaultdict(list)
for point, line in self['Points'].items():
self['Line2Points'][line].append(point)
self['SrcPoint2Edges'] = defaultdict(list)
for edge in self['Edges']:
src, dst = edge['Index']
self['SrcPoint2Edges'][src].append(edge)
self['Line2Edges'] = defaultdict(list)
for (src, edges) in self['SrcPoint2Edges'].items():
line = self['Points'][src]
self['Line2Edges'][line].extend(edges)
def edges_from_line(self, line):
return self['Line2Edges'][line]
def edge_from_line(self, line):
edges = self.edges_from_line(line)
assert(len(edges) == 1)
return edges[0]
def edges_from_point(self, point):
return self['SrcPoint2Edges'][point]
def edge_from_point(self, point):
edges = self.edges_from_point(point)
assert(len(edges) == 1)
return edges[0]
def assignment_point(self, varname):
for edge in self['Edges']:
if edge['Kind'] != 'Assign':
continue
dst = edge['Exp'][0]
if dst['Kind'] != 'Var':
continue
if dst['Variable']['Name'][0] == varname:
return edge['Index'][0]
raise Exception("assignment to variable %s not found" % varname)
def assignment_line(self, varname):
return self['Points'][self.assignment_point(varname)]