# Copyright 2019 Google LLC # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # https://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Tests for util.ir_util.""" import unittest from compiler.util import expression_parser from compiler.util import ir_data from compiler.util import ir_data_utils from compiler.util import ir_util def _parse_expression(text): return expression_parser.parse(text) class IrUtilTest(unittest.TestCase): """Tests for the miscellaneous utility functions in ir_util.py.""" def test_is_constant_integer(self): self.assertTrue(ir_util.is_constant(_parse_expression("6"))) expression = _parse_expression("12") # The type information should be ignored for constants like this one. ir_data_utils.builder(expression).type.integer.CopyFrom(ir_data.IntegerType()) self.assertTrue(ir_util.is_constant(expression)) def test_is_constant_boolean(self): self.assertTrue(ir_util.is_constant(_parse_expression("true"))) expression = _parse_expression("true") # The type information should be ignored for constants like this one. ir_data_utils.builder(expression).type.boolean.CopyFrom(ir_data.BooleanType()) self.assertTrue(ir_util.is_constant(expression)) def test_is_constant_enum(self): self.assertTrue(ir_util.is_constant(ir_data.Expression( constant_reference=ir_data.Reference(), type=ir_data.ExpressionType(enumeration=ir_data.EnumType(value="12"))))) def test_is_constant_integer_type(self): self.assertFalse(ir_util.is_constant_type(ir_data.ExpressionType( integer=ir_data.IntegerType( modulus="10", modular_value="5", minimum_value="-5", maximum_value="15")))) self.assertTrue(ir_util.is_constant_type(ir_data.ExpressionType( integer=ir_data.IntegerType( modulus="infinity", modular_value="5", minimum_value="5", maximum_value="5")))) def test_is_constant_boolean_type(self): self.assertFalse(ir_util.is_constant_type(ir_data.ExpressionType( boolean=ir_data.BooleanType()))) self.assertTrue(ir_util.is_constant_type(ir_data.ExpressionType( boolean=ir_data.BooleanType(value=True)))) self.assertTrue(ir_util.is_constant_type(ir_data.ExpressionType( boolean=ir_data.BooleanType(value=False)))) def test_is_constant_enumeration_type(self): self.assertFalse(ir_util.is_constant_type(ir_data.ExpressionType( enumeration=ir_data.EnumType()))) self.assertTrue(ir_util.is_constant_type(ir_data.ExpressionType( enumeration=ir_data.EnumType(value="0")))) def test_is_constant_opaque_type(self): self.assertFalse(ir_util.is_constant_type(ir_data.ExpressionType( opaque=ir_data.OpaqueType()))) def test_constant_value_of_integer(self): self.assertEqual(6, ir_util.constant_value(_parse_expression("6"))) def test_constant_value_of_none(self): self.assertIsNone(ir_util.constant_value(ir_data.Expression())) def test_constant_value_of_addition(self): self.assertEqual(6, ir_util.constant_value(_parse_expression("2+4"))) def test_constant_value_of_subtraction(self): self.assertEqual(-2, ir_util.constant_value(_parse_expression("2-4"))) def test_constant_value_of_multiplication(self): self.assertEqual(8, ir_util.constant_value(_parse_expression("2*4"))) def test_constant_value_of_equality(self): self.assertFalse(ir_util.constant_value(_parse_expression("2 == 4"))) def test_constant_value_of_inequality(self): self.assertTrue(ir_util.constant_value(_parse_expression("2 != 4"))) def test_constant_value_of_less(self): self.assertTrue(ir_util.constant_value(_parse_expression("2 < 4"))) def test_constant_value_of_less_or_equal(self): self.assertTrue(ir_util.constant_value(_parse_expression("2 <= 4"))) def test_constant_value_of_greater(self): self.assertFalse(ir_util.constant_value(_parse_expression("2 > 4"))) def test_constant_value_of_greater_or_equal(self): self.assertFalse(ir_util.constant_value(_parse_expression("2 >= 4"))) def test_constant_value_of_and(self): self.assertFalse(ir_util.constant_value(_parse_expression("true && false"))) self.assertTrue(ir_util.constant_value(_parse_expression("true && true"))) def test_constant_value_of_or(self): self.assertTrue(ir_util.constant_value(_parse_expression("true || false"))) self.assertFalse( ir_util.constant_value(_parse_expression("false || false"))) def test_constant_value_of_choice(self): self.assertEqual( 10, ir_util.constant_value(_parse_expression("false ? 20 : 10"))) self.assertEqual( 20, ir_util.constant_value(_parse_expression("true ? 20 : 10"))) def test_constant_value_of_choice_with_unknown_other_branch(self): self.assertEqual( 10, ir_util.constant_value(_parse_expression("false ? foo : 10"))) self.assertEqual( 20, ir_util.constant_value(_parse_expression("true ? 20 : foo"))) def test_constant_value_of_maximum(self): self.assertEqual(10, ir_util.constant_value(_parse_expression("$max(5, 10)"))) self.assertEqual(10, ir_util.constant_value(_parse_expression("$max(10)"))) self.assertEqual( 10, ir_util.constant_value(_parse_expression("$max(5, 9, 7, 10, 6, -100)"))) def test_constant_value_of_boolean(self): self.assertTrue(ir_util.constant_value(_parse_expression("true"))) self.assertFalse(ir_util.constant_value(_parse_expression("false"))) def test_constant_value_of_enum(self): self.assertEqual(12, ir_util.constant_value(ir_data.Expression( constant_reference=ir_data.Reference(), type=ir_data.ExpressionType(enumeration=ir_data.EnumType(value="12"))))) def test_constant_value_of_integer_reference(self): self.assertEqual(12, ir_util.constant_value(ir_data.Expression( constant_reference=ir_data.Reference(), type=ir_data.ExpressionType( integer=ir_data.IntegerType(modulus="infinity", modular_value="12"))))) def test_constant_value_of_boolean_reference(self): self.assertTrue(ir_util.constant_value(ir_data.Expression( constant_reference=ir_data.Reference(), type=ir_data.ExpressionType(boolean=ir_data.BooleanType(value=True))))) def test_constant_value_of_builtin_reference(self): self.assertEqual(12, ir_util.constant_value( ir_data.Expression( builtin_reference=ir_data.Reference( canonical_name=ir_data.CanonicalName(object_path=["$foo"]))), {"$foo": 12})) def test_constant_value_of_field_reference(self): self.assertIsNone(ir_util.constant_value(_parse_expression("foo"))) def test_constant_value_of_missing_builtin_reference(self): self.assertIsNone(ir_util.constant_value( _parse_expression("$static_size_in_bits"), {"$bar": 12})) def test_constant_value_of_present_builtin_reference(self): self.assertEqual(12, ir_util.constant_value( _parse_expression("$static_size_in_bits"), {"$static_size_in_bits": 12})) def test_constant_false_value_of_operator_and_with_missing_value(self): self.assertIs(False, ir_util.constant_value( _parse_expression("false && foo"), {"bar": 12})) self.assertIs(False, ir_util.constant_value( _parse_expression("foo && false"), {"bar": 12})) def test_constant_false_value_of_operator_and_known_value(self): self.assertTrue(ir_util.constant_value( _parse_expression("true && $is_statically_sized"), {"$is_statically_sized": True})) def test_constant_none_value_of_operator_and_with_missing_value(self): self.assertIsNone(ir_util.constant_value( _parse_expression("true && foo"), {"bar": 12})) self.assertIsNone(ir_util.constant_value( _parse_expression("foo && true"), {"bar": 12})) def test_constant_false_value_of_operator_or_with_missing_value(self): self.assertTrue(ir_util.constant_value( _parse_expression("true || foo"), {"bar": 12})) self.assertTrue(ir_util.constant_value( _parse_expression("foo || true"), {"bar": 12})) def test_constant_none_value_of_operator_or_with_missing_value(self): self.assertIsNone(ir_util.constant_value( _parse_expression("foo || false"), {"bar": 12})) self.assertIsNone(ir_util.constant_value( _parse_expression("false || foo"), {"bar": 12})) def test_constant_value_of_operator_plus_with_missing_value(self): self.assertIsNone(ir_util.constant_value( _parse_expression("12 + foo"), {"bar": 12})) def test_is_array(self): self.assertTrue( ir_util.is_array(ir_data.Type(array_type=ir_data.ArrayType()))) self.assertFalse( ir_util.is_array(ir_data.Type(atomic_type=ir_data.AtomicType()))) def test_get_attribute(self): type_def = ir_data.TypeDefinition(attribute=[ ir_data.Attribute( value=ir_data.AttributeValue(expression=ir_data.Expression()), name=ir_data.Word(text="phil")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word(text="bob"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("true")), name=ir_data.Word(text="bob")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word(text="bob2")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("true")), name=ir_data.Word(text="bob2"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word(text="bob3"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word()), ]) self.assertEqual( ir_data.AttributeValue(expression=_parse_expression("true")), ir_util.get_attribute(type_def.attribute, "bob")) self.assertEqual( ir_data.AttributeValue(expression=_parse_expression("false")), ir_util.get_attribute(type_def.attribute, "bob2")) self.assertEqual(None, ir_util.get_attribute(type_def.attribute, "Bob")) self.assertEqual(None, ir_util.get_attribute(type_def.attribute, "bob3")) def test_get_boolean_attribute(self): type_def = ir_data.TypeDefinition(attribute=[ ir_data.Attribute( value=ir_data.AttributeValue(expression=ir_data.Expression()), name=ir_data.Word(text="phil")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word(text="bob"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("true")), name=ir_data.Word(text="bob")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word(text="bob2")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("true")), name=ir_data.Word(text="bob2"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word(text="bob3"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word()), ]) self.assertTrue(ir_util.get_boolean_attribute(type_def.attribute, "bob")) self.assertTrue(ir_util.get_boolean_attribute(type_def.attribute, "bob", default_value=False)) self.assertFalse(ir_util.get_boolean_attribute(type_def.attribute, "bob2")) self.assertFalse(ir_util.get_boolean_attribute(type_def.attribute, "bob2", default_value=True)) self.assertIsNone(ir_util.get_boolean_attribute(type_def.attribute, "Bob")) self.assertTrue(ir_util.get_boolean_attribute(type_def.attribute, "Bob", default_value=True)) self.assertIsNone(ir_util.get_boolean_attribute(type_def.attribute, "bob3")) def test_get_integer_attribute(self): type_def = ir_data.TypeDefinition(attribute=[ ir_data.Attribute( value=ir_data.AttributeValue( expression=ir_data.Expression( type=ir_data.ExpressionType(integer=ir_data.IntegerType()))), name=ir_data.Word(text="phil")), ir_data.Attribute( value=ir_data.AttributeValue( expression=ir_data.Expression( constant=ir_data.NumericConstant(value="20"), type=ir_data.ExpressionType(integer=ir_data.IntegerType( modular_value="20", modulus="infinity")))), name=ir_data.Word(text="bob"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue( expression=ir_data.Expression( constant=ir_data.NumericConstant(value="10"), type=ir_data.ExpressionType(integer=ir_data.IntegerType( modular_value="10", modulus="infinity")))), name=ir_data.Word(text="bob")), ir_data.Attribute( value=ir_data.AttributeValue( expression=ir_data.Expression( constant=ir_data.NumericConstant(value="5"), type=ir_data.ExpressionType(integer=ir_data.IntegerType( modular_value="5", modulus="infinity")))), name=ir_data.Word(text="bob2")), ir_data.Attribute( value=ir_data.AttributeValue( expression=ir_data.Expression( constant=ir_data.NumericConstant(value="0"), type=ir_data.ExpressionType(integer=ir_data.IntegerType( modular_value="0", modulus="infinity")))), name=ir_data.Word(text="bob2"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue( expression=ir_data.Expression( constant=ir_data.NumericConstant(value="30"), type=ir_data.ExpressionType(integer=ir_data.IntegerType( modular_value="30", modulus="infinity")))), name=ir_data.Word(text="bob3"), is_default=True), ir_data.Attribute( value=ir_data.AttributeValue( expression=ir_data.Expression( function=ir_data.Function( function=ir_data.FunctionMapping.ADDITION, args=[ ir_data.Expression( constant=ir_data.NumericConstant(value="100"), type=ir_data.ExpressionType( integer=ir_data.IntegerType( modular_value="100", modulus="infinity"))), ir_data.Expression( constant=ir_data.NumericConstant(value="100"), type=ir_data.ExpressionType( integer=ir_data.IntegerType( modular_value="100", modulus="infinity"))) ]), type=ir_data.ExpressionType(integer=ir_data.IntegerType( modular_value="200", modulus="infinity")))), name=ir_data.Word(text="bob4")), ir_data.Attribute( value=ir_data.AttributeValue( expression=ir_data.Expression( constant=ir_data.NumericConstant(value="40"), type=ir_data.ExpressionType(integer=ir_data.IntegerType( modular_value="40", modulus="infinity")))), name=ir_data.Word()), ]) self.assertEqual(10, ir_util.get_integer_attribute(type_def.attribute, "bob")) self.assertEqual(5, ir_util.get_integer_attribute(type_def.attribute, "bob2")) self.assertIsNone(ir_util.get_integer_attribute(type_def.attribute, "Bob")) self.assertEqual(10, ir_util.get_integer_attribute(type_def.attribute, "Bob", default_value=10)) self.assertIsNone(ir_util.get_integer_attribute(type_def.attribute, "bob3")) self.assertEqual(200, ir_util.get_integer_attribute(type_def.attribute, "bob4")) def test_get_duplicate_attribute(self): type_def = ir_data.TypeDefinition(attribute=[ ir_data.Attribute( value=ir_data.AttributeValue(expression=ir_data.Expression()), name=ir_data.Word(text="phil")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("true")), name=ir_data.Word(text="bob")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word(text="bob")), ir_data.Attribute( value=ir_data.AttributeValue(expression=_parse_expression("false")), name=ir_data.Word()), ]) self.assertRaises(AssertionError, ir_util.get_attribute, type_def.attribute, "bob") def test_find_object(self): ir = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr, """{ "module": [ { "type": [ { "structure": { "field": [ { "name": { "name": { "text": "field" }, "canonical_name": { "module_file": "test.emb", "object_path": [ "Foo", "field" ] } } } ] }, "name": { "name": { "text": "Foo" }, "canonical_name": { "module_file": "test.emb", "object_path": [ "Foo" ] } }, "runtime_parameter": [ { "name": { "name": { "text": "parameter" }, "canonical_name": { "module_file": "test.emb", "object_path": [ "Foo", "parameter" ] } } } ] }, { "enumeration": { "value": [ { "name": { "name": { "text": "QUX" }, "canonical_name": { "module_file": "test.emb", "object_path": [ "Bar", "QUX" ] } } } ] }, "name": { "name": { "text": "Bar" }, "canonical_name": { "module_file": "test.emb", "object_path": [ "Bar" ] } } } ], "source_file_name": "test.emb" }, { "type": [ { "external": {}, "name": { "name": { "text": "UInt" }, "canonical_name": { "module_file": "", "object_path": [ "UInt" ] } } } ], "source_file_name": "" } ] }""") # Test that find_object works with any of its four "name" types. canonical_name_of_foo = ir_data.CanonicalName(module_file="test.emb", object_path=["Foo"]) self.assertEqual(ir.module[0].type[0], ir_util.find_object( ir_data.Reference(canonical_name=canonical_name_of_foo), ir)) self.assertEqual(ir.module[0].type[0], ir_util.find_object( ir_data.NameDefinition(canonical_name=canonical_name_of_foo), ir)) self.assertEqual(ir.module[0].type[0], ir_util.find_object(canonical_name_of_foo, ir)) self.assertEqual(ir.module[0].type[0], ir_util.find_object(("test.emb", "Foo"), ir)) # Test that find_object works with objects other than structs. self.assertEqual(ir.module[0].type[1], ir_util.find_object(("test.emb", "Bar"), ir)) self.assertEqual(ir.module[1].type[0], ir_util.find_object(("", "UInt"), ir)) self.assertEqual(ir.module[0].type[0].structure.field[0], ir_util.find_object(("test.emb", "Foo", "field"), ir)) self.assertEqual(ir.module[0].type[0].runtime_parameter[0], ir_util.find_object(("test.emb", "Foo", "parameter"), ir)) self.assertEqual(ir.module[0].type[1].enumeration.value[0], ir_util.find_object(("test.emb", "Bar", "QUX"), ir)) self.assertEqual(ir.module[0], ir_util.find_object(("test.emb",), ir)) self.assertEqual(ir.module[1], ir_util.find_object(("",), ir)) # Test searching for non-present objects. self.assertIsNone(ir_util.find_object_or_none(("not_test.emb",), ir)) self.assertIsNone(ir_util.find_object_or_none(("test.emb", "NotFoo"), ir)) self.assertIsNone( ir_util.find_object_or_none(("test.emb", "Foo", "not_field"), ir)) self.assertIsNone( ir_util.find_object_or_none(("test.emb", "Foo", "field", "no_subfield"), ir)) self.assertIsNone( ir_util.find_object_or_none(("test.emb", "Bar", "NOT_QUX"), ir)) self.assertIsNone( ir_util.find_object_or_none(("test.emb", "Bar", "QUX", "no_subenum"), ir)) # Test that find_parent_object works with any of its four "name" types. self.assertEqual(ir.module[0], ir_util.find_parent_object( ir_data.Reference(canonical_name=canonical_name_of_foo), ir)) self.assertEqual(ir.module[0], ir_util.find_parent_object( ir_data.NameDefinition(canonical_name=canonical_name_of_foo), ir)) self.assertEqual(ir.module[0], ir_util.find_parent_object(canonical_name_of_foo, ir)) self.assertEqual(ir.module[0], ir_util.find_parent_object(("test.emb", "Foo"), ir)) # Test that find_parent_object works with objects other than structs. self.assertEqual(ir.module[0], ir_util.find_parent_object(("test.emb", "Bar"), ir)) self.assertEqual(ir.module[1], ir_util.find_parent_object(("", "UInt"), ir)) self.assertEqual(ir.module[0].type[0], ir_util.find_parent_object(("test.emb", "Foo", "field"), ir)) self.assertEqual(ir.module[0].type[1], ir_util.find_parent_object(("test.emb", "Bar", "QUX"), ir)) def test_hashable_form_of_reference(self): self.assertEqual( ("t.emb", "Foo", "Bar"), ir_util.hashable_form_of_reference(ir_data.Reference( canonical_name=ir_data.CanonicalName(module_file="t.emb", object_path=["Foo", "Bar"])))) self.assertEqual( ("t.emb", "Foo", "Bar"), ir_util.hashable_form_of_reference(ir_data.NameDefinition( canonical_name=ir_data.CanonicalName(module_file="t.emb", object_path=["Foo", "Bar"])))) def test_get_base_type(self): array_type_ir = ir_data_utils.IrDataSerializer.from_json(ir_data.Type, """{ "array_type": { "element_count": { "constant": { "value": "20" } }, "base_type": { "array_type": { "element_count": { "constant": { "value": "10" } }, "base_type": { "atomic_type": { "reference": { }, "source_location": { "start": { "line": 5 } } } }, "source_location": { "start": { "line": 4 } } } }, "source_location": { "start": { "line": 3 } } } }""") base_type_ir = array_type_ir.array_type.base_type.array_type.base_type self.assertEqual(base_type_ir, ir_util.get_base_type(array_type_ir)) self.assertEqual(base_type_ir, ir_util.get_base_type( array_type_ir.array_type.base_type)) self.assertEqual(base_type_ir, ir_util.get_base_type(base_type_ir)) def test_size_of_type_in_bits(self): ir = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr, """{ "module": [{ "type": [{ "name": { "name": { "text": "Baz" }, "canonical_name": { "module_file": "s.emb", "object_path": ["Baz"] } } }], "source_file_name": "s.emb" }, { "type": [{ "name": { "name": { "text": "UInt" }, "canonical_name": { "module_file": "", "object_path": ["UInt"] } } }, { "name": { "name": { "text": "Byte" }, "canonical_name": { "module_file": "", "object_path": ["Byte"] } }, "attribute": [{ "name": { "text": "fixed_size_in_bits" }, "value": { "expression": { "constant": { "value": "8" }, "type": { "integer": { "modular_value": "8", "modulus": "infinity" } } } } }] }], "source_file_name": "" }] }""") fixed_size_type = ir_data_utils.IrDataSerializer.from_json(ir_data.Type, """{ "atomic_type": { "reference": { "canonical_name": { "module_file": "", "object_path": ["Byte"] } } } }""") self.assertEqual(8, ir_util.fixed_size_of_type_in_bits(fixed_size_type, ir)) explicit_size_type = ir_data_utils.IrDataSerializer.from_json(ir_data.Type, """{ "atomic_type": { "reference": { "canonical_name": { "module_file": "", "object_path": ["UInt"] } } }, "size_in_bits": { "constant": { "value": "32" }, "type": { "integer": { "modular_value": "32", "modulus": "infinity" } } } }""") self.assertEqual(32, ir_util.fixed_size_of_type_in_bits(explicit_size_type, ir)) fixed_size_array = ir_data_utils.IrDataSerializer.from_json(ir_data.Type, """{ "array_type": { "base_type": { "atomic_type": { "reference": { "canonical_name": { "module_file": "", "object_path": ["Byte"] } } } }, "element_count": { "constant": { "value": "5" }, "type": { "integer": { "modular_value": "5", "modulus": "infinity" } } } } }""") self.assertEqual(40, ir_util.fixed_size_of_type_in_bits(fixed_size_array, ir)) fixed_size_2d_array = ir_data_utils.IrDataSerializer.from_json(ir_data.Type, """{ "array_type": { "base_type": { "array_type": { "base_type": { "atomic_type": { "reference": { "canonical_name": { "module_file": "", "object_path": ["Byte"] } } } }, "element_count": { "constant": { "value": "5" }, "type": { "integer": { "modular_value": "5", "modulus": "infinity" } } } } }, "element_count": { "constant": { "value": "2" }, "type": { "integer": { "modular_value": "2", "modulus": "infinity" } } } } }""") self.assertEqual( 80, ir_util.fixed_size_of_type_in_bits(fixed_size_2d_array, ir)) automatic_size_array = ir_data_utils.IrDataSerializer.from_json(ir_data.Type, """{ "array_type": { "base_type": { "array_type": { "base_type": { "atomic_type": { "reference": { "canonical_name": { "module_file": "", "object_path": ["Byte"] } } } }, "element_count": { "constant": { "value": "5" }, "type": { "integer": { "modular_value": "5", "modulus": "infinity" } } } } }, "automatic": { } } }""") self.assertIsNone( ir_util.fixed_size_of_type_in_bits(automatic_size_array, ir)) variable_size_type = ir_data_utils.IrDataSerializer.from_json(ir_data.Type, """{ "atomic_type": { "reference": { "canonical_name": { "module_file": "", "object_path": ["UInt"] } } } }""") self.assertIsNone( ir_util.fixed_size_of_type_in_bits(variable_size_type, ir)) no_size_type = ir_data_utils.IrDataSerializer.from_json(ir_data.Type, """{ "atomic_type": { "reference": { "canonical_name": { "module_file": "s.emb", "object_path": ["Baz"] } } } }""") self.assertIsNone(ir_util.fixed_size_of_type_in_bits(no_size_type, ir)) def test_field_is_virtual(self): self.assertTrue(ir_util.field_is_virtual(ir_data.Field())) def test_field_is_not_virtual(self): self.assertFalse(ir_util.field_is_virtual( ir_data.Field(location=ir_data.FieldLocation()))) def test_field_is_read_only(self): self.assertTrue(ir_util.field_is_read_only(ir_data.Field( write_method=ir_data.WriteMethod(read_only=True)))) def test_field_is_not_read_only(self): self.assertFalse(ir_util.field_is_read_only( ir_data.Field(location=ir_data.FieldLocation()))) self.assertFalse(ir_util.field_is_read_only(ir_data.Field( write_method=ir_data.WriteMethod()))) if __name__ == "__main__": unittest.main()