1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
|
#!/usr/bin/env python
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
from collections import defaultdict
# Simplified version of the body info.
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'] }
# Indexes
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)]
|