<commit_before>import functools
import itertools

from ..backend_object import BackendObject
from ..annotation import Annotation

def normalize_types_two_args(f):
    @functools.wraps(f)
    def normalizer(self, region, o):
        """
        Convert any object to an object that we can process.
        """
        if isinstance(o, Base):
            raise ClaripyValueError("BoolResult can't handle AST objects directly")

        if not isinstance(o, StridedInterval):
            raise ClaripyVSAOperationError('Unsupported operand type %s' % type(o))

        return f(self, region, o)

    return normalizer

def normalize_types_one_arg(f):
    @functools.wraps(f)
    def normalizer(self, o):
        """
        Convert any object to an object that we can process.
        """
        if isinstance(o, Base):
            raise ClaripyValueError("BoolResult can't handle AST objects directly")

        return f(self, o)

    return normalizer

vs_id_ctr = itertools.count()


class RegionAnnotation(Annotation):
    """
    Use RegionAnnotation to annotate ASTs. Normally, an AST annotated by RegionAnnotations is treated as a ValueSet.

    Note that Annotation objects are immutable. Do not change properties of an Annotation object without creating a new
    one.
    """

    def __init__(self, region_id, region_base_addr, offset):
        self.region_id = region_id
        self.region_base_addr = region_base_addr
        self.offset = offset

        # Do necessary conversion here
        if isinstance(self.region_base_addr, Base):
            self.region_base_addr = self.region_base_addr._model_vsa
        if isinstance(self.offset, Base):
            self.offset = self.offset._model_vsa

    @property
    def eliminatable(self):
        """
        A Region annotation is not eliminatable in simplifications.

        :return: False
        :rtype: bool
        """

        return False

    @property
    def relocatable(self):
        """
        A Region annotation annotations are relocatable in simplifications.

        :return: True
        :rtype: bool
        """

        return True

    #
    # Public methods
    #

    def relocate(self, src, dst):
        """
        Override Annotation.relocate().

        :param src: The old AST
        :param dst: The new AST, as the result of a simplification
        :return: The new annotation that should be applied on the new AST
        """

        return self

    #
    # Overriding base methods
    #

    def __hash__(self):
        return hash((self.region_id, self.region_base_addr, hash(self.offset)))


class ValueSet(BackendObject):
    """
    ValueSet is a mapping between memory regions and corresponding offsets.
    """

    def __init__(self, name=None, region=None, region_base_addr=None, bits=None, val=None):
        """
        Constructor.

        :param str name: Name of this ValueSet object. Only for debugging purposes.
        :param str region: Region ID.
        :param int region_base_addr: Base address of the region.
        :param int bits: Size of the ValueSet.
        :param val: an initial offset
        """

        self._name = 'VS_%d' % vs_id_ctr.next() if name is None else name
        if bits is None:
            raise ClaripyVSAError('bits must be specified when creating a ValueSet.')<commit_msg>RegionAnnotation is not relocatable<commit_after>import functools
import itertools

from ..backend_object import BackendObject
from ..annotation import Annotation

def normalize_types_two_args(f):
    @functools.wraps(f)
    def normalizer(self, region, o):
        """
        Convert any object to an object that we can process.
        """
        if isinstance(o, Base):
            raise ClaripyValueError("BoolResult can't handle AST objects directly")

        if not isinstance(o, StridedInterval):
            raise ClaripyVSAOperationError('Unsupported operand type %s' % type(o))

        return f(self, region, o)

    return normalizer

def normalize_types_one_arg(f):
    @functools.wraps(f)
    def normalizer(self, o):
        """
        Convert any object to an object that we can process.
        """
        if isinstance(o, Base):
            raise ClaripyValueError("BoolResult can't handle AST objects directly")

        return f(self, o)

    return normalizer

vs_id_ctr = itertools.count()


class RegionAnnotation(Annotation):
    """
    Use RegionAnnotation to annotate ASTs. Normally, an AST annotated by RegionAnnotations is treated as a ValueSet.

    Note that Annotation objects are immutable. Do not change properties of an Annotation object without creating a new
    one.
    """

    def __init__(self, region_id, region_base_addr, offset):
        self.region_id = region_id
        self.region_base_addr = region_base_addr
        self.offset = offset

        # Do necessary conversion here
        if isinstance(self.region_base_addr, Base):
            self.region_base_addr = self.region_base_addr._model_vsa
        if isinstance(self.offset, Base):
            self.offset = self.offset._model_vsa

    @property
    def eliminatable(self):
        """
        A Region annotation is not eliminatable in simplifications.

        :return: False
        :rtype: bool
        """

        return False

    @property
    def relocatable(self):
        """
        A Region annotation is not relocatable in simplifications.

        :return: False
        :rtype: bool
        """

        return False

    #
    # Public methods
    #

    def relocate(self, src, dst):
        """
        Override Annotation.relocate().

        :param src: The old AST
        :param dst: The new AST, as the result of a simplification
        :return: The new annotation that should be applied on the new AST
        """

        raise ClaripyVSAError('RegionAnnotation is not relocatable')

    #
    # Overriding base methods
    #

    def __hash__(self):
        return hash((self.region_id, self.region_base_addr, hash(self.offset)))

    def __repr__(self):
        return "<RegionAnnotation %s:%#08x>" % (self.region_id, self.offset)

class ValueSet(BackendObject):
    """
    ValueSet is a mapping between memory regions and corresponding offsets.
    """

    def __init__(self, name=None, region=None, region_base_addr=None, bits=None, val=None):
        """
        Constructor.

        :param str name: Name of this ValueSet object. Only for debugging purposes.
        :param str region: Region ID.
        :param int region_base_addr: Base address of the region.
        :param int bits: Size of the ValueSet.
        :param val: an initial offset
        """

        self._name = 'VS_%d' % vs_id_ctr.next() if name is None else name
        if bits is None:
            raise ClaripyVSAError('bits must be specified when creating a ValueSet.')
{'fraction_non_alphanumeric': 0.07987688699985343, 'fraction_numerical': 0.0002931261908251502, 'mean_word_length': 2.4551898734177215, 'pattern_counts': {'":': 0, '<': 4, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3674753', 'n_tokens_mistral': 1937, 'n_tokens_neox': 1855, 'n_words': 632}