summaryrefslogtreecommitdiffstats
path: root/debuginfo-tests/dexter/dex/dextIR/ProgramState.py
diff options
context:
space:
mode:
Diffstat (limited to 'debuginfo-tests/dexter/dex/dextIR/ProgramState.py')
-rw-r--r--debuginfo-tests/dexter/dex/dextIR/ProgramState.py117
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
OpenPOWER on IntegriCloud