summaryrefslogtreecommitdiffstats
path: root/js/src/devtools/rootAnalysis/t/sixgill.py
blob: 0b8c2c7073dbc5a3e70688610c68a44a89f11964 (plain)
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)]