File: ProgramState.py

package info (click to toggle)
swiftlang 6.0.3-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,519,992 kB
  • sloc: cpp: 9,107,863; ansic: 2,040,022; asm: 1,135,751; python: 296,500; objc: 82,456; f90: 60,502; lisp: 34,951; pascal: 19,946; sh: 18,133; perl: 7,482; ml: 4,937; javascript: 4,117; makefile: 3,840; awk: 3,535; xml: 914; fortran: 619; cs: 573; ruby: 573
file content (130 lines) | stat: -rw-r--r-- 4,008 bytes parent folder | download | duplicates (12)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# DExTer : Debugging Experience Tester
# ~~~~~~   ~         ~~         ~   ~~
#
# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
# See https://llvm.org/LICENSE.txt for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""Set of data classes for representing the complete debug program state at a
fixed point in execution.
"""

import os

from collections import OrderedDict
from pathlib import PurePath
from typing import List


class SourceLocation:
    def __init__(self, path: str = None, lineno: int = None, column: int = None):
        if path:
            path = os.path.normcase(path)
        self.path = path
        self.lineno = lineno
        self.column = column

    def __str__(self):
        return "{}({}:{})".format(self.path, self.lineno, self.column)

    def match(self, other) -> bool:
        """Returns true iff all the properties that appear in `self` have the
        same value in `other`, but not necessarily vice versa.
        """
        if not other or not isinstance(other, SourceLocation):
            return False

        if self.path and (
            other.path is None or (PurePath(self.path) != PurePath(other.path))
        ):
            return False

        if self.lineno and (self.lineno != other.lineno):
            return False

        if self.column and (self.column != other.column):
            return False

        return True


class StackFrame:
    def __init__(
        self,
        function: str = None,
        is_inlined: bool = None,
        location: SourceLocation = None,
        watches: OrderedDict = None,
    ):
        if watches is None:
            watches = {}

        self.function = function
        self.is_inlined = is_inlined
        self.location = location
        self.watches = watches

    def __str__(self):
        return "{}{}: {} | {}".format(
            self.function,
            " (inlined)" if self.is_inlined else "",
            self.location,
            {k: str(self.watches[k]) for k in self.watches},
        )

    def match(self, other) -> bool:
        """Returns true iff all the properties that appear in `self` have the
        same value in `other`, but not necessarily vice versa.
        """
        if not other or not isinstance(other, StackFrame):
            return False

        if self.location and not self.location.match(other.location):
            return False

        if self.watches:
            for name in iter(self.watches):
                try:
                    if isinstance(self.watches[name], dict):
                        for attr in iter(self.watches[name]):
                            if (
                                getattr(other.watches[name], attr, None)
                                != self.watches[name][attr]
                            ):
                                return False
                    else:
                        if other.watches[name].value != self.watches[name]:
                            return False
                except KeyError:
                    return False

        return True


class ProgramState:
    def __init__(self, frames: List[StackFrame] = None):
        self.frames = frames

    def __str__(self):
        return "\n".join(
            map(
                lambda enum: "Frame {}: {}".format(enum[0], enum[1]),
                enumerate(self.frames),
            )
        )

    def match(self, other) -> bool:
        """Returns true iff all the properties that appear in `self` have the
        same value in `other`, but not necessarily vice versa.
        """
        if not other or not isinstance(other, ProgramState):
            return False

        if self.frames:
            for idx, frame in enumerate(self.frames):
                try:
                    if not frame.match(other.frames[idx]):
                        return False
                except (IndexError, KeyError):
                    return False

        return True