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
64
65
66
67
68
69
70
|
#!/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)]
|