
from claripy import Annotation


class StackLocationAnnotation(Annotation):
    def __init__(self, offset):
        super(StackLocationAnnotation, self).__init__()

        self.offset = offset

    @property
    def eliminatable(self):
        return False

    @property
    def relocatable(self):
        return False

    def __hash__(self):
        return hash(('stack_location', self.offset))

    def __eq__(self, other):
        if not isinstance(other, StackLocationAnnotation):
            return False

        return self.offset == other.offset


class VariableSourceAnnotation(Annotation):
    def __init__(self, block_addr, stmt_idx, ins_addr):
        super(VariableSourceAnnotation, self).__init__()

        self.block_addr = block_addr
        self.stmt_idx = stmt_idx
        self.ins_addr = ins_addr

    @property
    def eliminatable(self):
        return False

    @property
    def relocatable(self):
        return False

    def __hash__(self):
        return hash((self.block_addr, self.stmt_idx, self.ins_addr))

    def __eq__(self, other):
        if not isinstance(other, VariableSourceAnnotation):
            return False

        return self.block_addr == other.block_addr and \
               self.stmt_idx == other.stmt_idx and \
               self.ins_addr == other.ins_addr

    @staticmethod
    def from_state(state):
        return VariableSourceAnnotation(state.scratch.bbl_addr, state.scratch.stmt_idx, state.scratch.ins_addr)
