diff options
Diffstat (limited to 'debuginfo-tests/dexter/dex/dextIR/ProgramState.py')
-rw-r--r-- | debuginfo-tests/dexter/dex/dextIR/ProgramState.py | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/debuginfo-tests/dexter/dex/dextIR/ProgramState.py b/debuginfo-tests/dexter/dex/dextIR/ProgramState.py new file mode 100644 index 00000000000..4f05189aed8 --- /dev/null +++ b/debuginfo-tests/dexter/dex/dextIR/ProgramState.py @@ -0,0 +1,117 @@ +# 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 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 (self.path != 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 |