brintos

brintos / llvm-project-archived public Read only

0
0
Text · 2.9 KiB · 54c62a1 Raw
92 lines · python
1# DExTer : Debugging Experience Tester2# ~~~~~~   ~         ~~         ~   ~~3#4# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.5# See https://llvm.org/LICENSE.txt for license information.6# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception7"""Command for specifying a partial or complete state for the program to enter8during execution.9"""10 11from itertools import chain12 13from dex.command.CommandBase import CommandBase, StepExpectInfo14from dex.dextIR import ProgramState, SourceLocation, StackFrame, DextIR15 16 17def frame_from_dict(source: dict) -> StackFrame:18    if "location" in source:19        assert isinstance(source["location"], dict)20        source["location"] = SourceLocation(**source["location"])21    return StackFrame(**source)22 23 24def state_from_dict(source: dict) -> ProgramState:25    if "frames" in source:26        assert isinstance(source["frames"], list)27        source["frames"] = list(map(frame_from_dict, source["frames"]))28    return ProgramState(**source)29 30 31class DexExpectProgramState(CommandBase):32    """Expect to see a given program `state` a certain numer of `times`.33 34    DexExpectProgramState(state [,**times])35 36    See Commands.md for more info.37    """38 39    def __init__(self, *args, **kwargs):40        if len(args) != 1:41            raise TypeError("expected exactly one unnamed arg")42 43        self.program_state_text = str(args[0])44 45        self.expected_program_state = state_from_dict(args[0])46 47        self.times = kwargs.pop("times", -1)48        if kwargs:49            raise TypeError("unexpected named args: {}".format(", ".join(kwargs)))50 51        # Step indices at which the expected program state was encountered.52        self.encounters = []53 54        super(DexExpectProgramState, self).__init__()55 56    @staticmethod57    def get_name():58        return __class__.__name__59 60    def get_watches(self):61        frame_expects = set()62        for idx, frame in enumerate(self.expected_program_state.frames):63            path = (64                frame.location.path65                if frame.location and frame.location.path66                else self.path67            )68            line_range = (69                range(frame.location.lineno, frame.location.lineno + 1)70                if frame.location and frame.location.lineno71                else None72            )73            for watch in frame.watches:74                frame_expects.add(75                    StepExpectInfo(76                        expression=watch,77                        path=path,78                        frame_idx=idx,79                        line_range=line_range,80                    )81                )82        return frame_expects83 84    def eval(self, step_collection: DextIR) -> bool:85        for step in step_collection.steps:86            if self.expected_program_state.match(step.program_state):87                self.encounters.append(step.step_index)88 89        return (90            self.times < 0 < len(self.encounters) or len(self.encounters) == self.times91        )92