def test_hashable_form_of_reference(self): self.assertEqual( ("t.emb", "Foo", "Bar"), ir_util.hashable_form_of_reference( ir_pb2.Reference(canonical_name=ir_pb2.CanonicalName( module_file="t.emb", object_path=["Foo", "Bar"])))) self.assertEqual( ("t.emb", "Foo", "Bar"), ir_util.hashable_form_of_reference( ir_pb2.NameDefinition(canonical_name=ir_pb2.CanonicalName( module_file="t.emb", object_path=["Foo", "Bar"]))))
def _types_are_compatible(a, b): """Returns true if a and b have compatible types.""" if a.type.WhichOneof("type") != b.type.WhichOneof("type"): return False elif a.type.WhichOneof("type") == "enumeration": return (ir_util.hashable_form_of_reference( a.type.enumeration.name) == ir_util.hashable_form_of_reference( b.type.enumeration.name)) elif a.type.WhichOneof("type") in ("integer", "boolean"): # All integers are compatible with integers; booleans are compatible with # booleans return True else: assert False, "_types_are_compatible works with enums, integers, booleans."
def _find_dependency_ordering_for_fields_in_structure(structure, type_definition, dependencies): """Populates structure.fields_in_dependency_order.""" # For fields which appear before their dependencies in the original source # text, this algorithm moves them to immediately after their dependencies. # # This is one of many possible schemes for constructing a dependency ordering; # it has the advantage that all of the generated fields (e.g., $size_in_bytes) # stay at the end of the ordering, which makes testing easier. order = [] added = set() for parameter in type_definition.runtime_parameter: added.add(ir_util.hashable_form_of_reference(parameter.name)) needed = list(range(len(structure.field))) while True: for i in range(len(needed)): field_number = needed[i] field = ir_util.hashable_form_of_reference( structure.field[field_number].name) assert field in dependencies, "dependencies = {}".format( dependencies) if all(dependency in added for dependency in dependencies[field]): order.append(field_number) added.add(field) del needed[i] break else: break # If a non-local-field dependency were in dependencies[field], then not all # fields would be added to the dependency ordering. This shouldn't happen. assert len(order) == len( structure.field), ("order: {}\nlen(structure.field: {})".format( order, len(structure.field))) del structure.fields_in_dependency_order[:] structure.fields_in_dependency_order.extend(order)
def _add_reference_to_dependencies(reference, dependencies, name, source_file_name, errors): if reference.canonical_name.object_path[0] in { "$is_statically_sized", "$static_size_in_bits", "$next" }: # This error is a bit opaque, but given that the compiler used to crash on # this case -- for a couple of years -- and no one complained, it seems # safe to assume that this is a rare error. errors.append([ error.error( source_file_name, reference.source_location, "Keyword `" + reference.canonical_name.object_path[0] + "` may not be used in this context."), ]) return dependencies[name] |= {ir_util.hashable_form_of_reference(reference)}
def _add_name_to_dependencies(proto, dependencies): name = ir_util.hashable_form_of_reference(proto.name) dependencies.setdefault(name, set()) return {"name": name}
def _add_field_reference_to_dependencies(reference, dependencies, name): dependencies[name] |= { ir_util.hashable_form_of_reference(reference.path[0]) }