def test_aliasing_monitor_dict_merge(self): def merge_value(v0, v1, name): if v0 == v1: return v0 raise datatypes.AliasingDictConflictError(name) d1 = datatypes.AliasingMonitorDict() d1["alias1"] = "1" d1.add_alias("alias1", "alias2", merge_value) d2 = datatypes.AliasingMonitorDict() d2["alias3"] = "1" d2.add_alias("alias3", "alias4", merge_value) d1.merge_from(d2, merge_value) self.assertEqual(d1["alias1"], "1") self.assertEqual(d1["alias2"], "1") self.assertEqual(d1["alias3"], "1") self.assertEqual(d1["alias4"], "1") self.assertEqual(d1.same_name("alias3", "alias4"), True) d4 = datatypes.AliasingMonitorDict() d4["alias2"] = 3 with self.assertRaises(datatypes.AliasingDictConflictError): d1.merge_from(d4, merge_value) d3 = datatypes.AliasingMonitorDict() d3.add_alias("alias2", "alias5", merge_value) d3["alias5"] = 3 with self.assertRaises(datatypes.AliasingDictConflictError): d1.merge_from(d3, merge_value)
def test_add_alias_for_aliasing_monitor_dict(self): def merge_value(v0, v1, name): if v0 == v1: return v0 raise datatypes.AliasingDictConflictError(name) d = datatypes.AliasingMonitorDict() d["alias1"] = "1" d["alias2"] = "1" self.assertEqual(len(d), 2) # Merge with same values d.add_alias("alias1", "alias2", merge_value) self.assertEqual(len(d), 1) self.assertEqual(d["alias1"], "1") self.assertEqual(d["alias2"], "1") # Merge with different values d["alias3"] = "2" with self.assertRaises(datatypes.AliasingDictConflictError): d.add_alias("alias1", "alias3", merge_value) # Neither of names has value d.add_alias("alias5", "alias6", merge_value) # The first name is in dict d.add_alias("alias3", "alias4", merge_value) # The second name is in dict d.add_alias("alias5", "alias3", merge_value) self.assertEqual(d["alias3"], "2") self.assertEqual(d["alias4"], "2") self.assertEqual(d["alias5"], "2") self.assertEqual(d["alias6"], "2")
def type_param_check(self): """Throw exception for invalid type parameters.""" # It will cause infinite recursion if `formal_type_parameters` is # `LazyFormalTypeParameters` if not isinstance(self._formal_type_parameters, abstract_utils.LazyFormalTypeParameters): tparams = datatypes.AliasingMonitorDict() abstract_utils.parse_formal_type_parameters(self, None, tparams)
def init_mixin(self, metaclass): """Mix-in equivalent of __init__.""" if metaclass is None: self.cls = self._get_inherited_metaclass() else: # TODO(rechen): Check that the metaclass is a (non-strict) subclass of the # metaclasses of the base classes. self.cls = metaclass self._instance_cache = {} self._init_abstract_methods() self._all_formal_type_parameters = datatypes.AliasingMonitorDict() self._all_formal_type_parameters_loaded = False
def init_mixin(self, metaclass): """Mix-in equivalent of __init__.""" if metaclass is None: metaclass = self._get_inherited_metaclass() if metaclass: self.cls = metaclass # Key-value store of metadata for overlays to use. self.metadata = {} self._instance_cache = {} self._init_abstract_methods() self._init_protocol_attributes() self._init_overrides_bool() self._all_formal_type_parameters = datatypes.AliasingMonitorDict() self._all_formal_type_parameters_loaded = False # Call these methods in addition to __init__ when constructing instances. self.additional_init_methods = [] if self.is_test_class(): self.additional_init_methods.append("setUp")
def _load_instance_type_parameters(self): if self._instance_type_parameters_loaded: return all_formal_type_parameters = datatypes.AliasingMonitorDict() abstract_utils.parse_formal_type_parameters( self.cls, None, all_formal_type_parameters, self._container) self._instance_type_parameters.uf = all_formal_type_parameters.uf for name, param in all_formal_type_parameters.items(): if param is None: value = self.ctx.program.NewVariable() log.info("Initializing type param %s: %r", name, value) self._instance_type_parameters[name] = value else: self._instance_type_parameters[name] = param.instantiate( self.ctx.root_node, self._container or self) # We purposely set this flag at the very end so that accidentally accessing # instance_type_parameters during loading will trigger an obvious crash due # to infinite recursion, rather than silently returning an incomplete dict. self._instance_type_parameters_loaded = True
def __init__(self, name, ctx): """Initialize a SimpleValue. Args: name: Name of this value. For debugging and error reporting. ctx: The abstract context. """ super().__init__(name, ctx) self._cls = None # lazily loaded 'cls' attribute self.members = datatypes.MonitorDict() # Lazily loaded to handle recursive types. # See Instance._load_instance_type_parameters(). self._instance_type_parameters = datatypes.AliasingMonitorDict() # This attribute depends on self.cls, which isn't yet set to its true value. self._maybe_missing_members = None # The latter caches the result of get_type_key. This is a recursive function # that has the potential to generate too many calls for large definitions. self._cached_type_key = ( (self.members.changestamp, self._instance_type_parameters.changestamp), None)