sixgill.py (2503B)
1 #!/usr/bin/env python 2 # This Source Code Form is subject to the terms of the Mozilla Public 3 # License, v. 2.0. If a copy of the MPL was not distributed with this 4 # file, You can obtain one at http://mozilla.org/MPL/2.0/. 5 6 from collections import defaultdict 7 8 # Simplified version of the body info. 9 10 11 class Body(dict): 12 def __init__(self, body): 13 self["BlockIdKind"] = body["BlockId"]["Kind"] 14 if "Variable" in body["BlockId"]: 15 self["BlockName"] = body["BlockId"]["Variable"]["Name"][0].split("$")[-1] 16 loc = body["Location"] 17 self["LineRange"] = (loc[0]["Line"], loc[1]["Line"]) 18 self["Filename"] = loc[0]["CacheString"] 19 self["Edges"] = body.get("PEdge", []) 20 self["Points"] = { 21 i: p["Location"]["Line"] for i, p in enumerate(body["PPoint"], 1) 22 } 23 self["Index"] = body["Index"] 24 self["Variables"] = { 25 x["Variable"]["Name"][0].split("$")[-1]: x["Type"] 26 for x in body["DefineVariable"] 27 } 28 29 # Indexes 30 self["Line2Points"] = defaultdict(list) 31 for point, line in self["Points"].items(): 32 self["Line2Points"][line].append(point) 33 self["SrcPoint2Edges"] = defaultdict(list) 34 for edge in self["Edges"]: 35 src, dst = edge["Index"] 36 self["SrcPoint2Edges"][src].append(edge) 37 self["Line2Edges"] = defaultdict(list) 38 for src, edges in self["SrcPoint2Edges"].items(): 39 line = self["Points"][src] 40 self["Line2Edges"][line].extend(edges) 41 42 def edges_from_line(self, line): 43 return self["Line2Edges"][line] 44 45 def edge_from_line(self, line): 46 edges = self.edges_from_line(line) 47 assert len(edges) == 1 48 return edges[0] 49 50 def edges_from_point(self, point): 51 return self["SrcPoint2Edges"][point] 52 53 def edge_from_point(self, point): 54 edges = self.edges_from_point(point) 55 assert len(edges) == 1 56 return edges[0] 57 58 def assignment_point(self, varname): 59 for edge in self["Edges"]: 60 if edge["Kind"] != "Assign": 61 continue 62 dst = edge["Exp"][0] 63 if dst["Kind"] != "Var": 64 continue 65 if dst["Variable"]["Name"][0] == varname: 66 return edge["Index"][0] 67 raise Exception("assignment to variable %s not found" % varname) 68 69 def assignment_line(self, varname): 70 return self["Points"][self.assignment_point(varname)]