blob: 07cf4dc4a98012ff0af8fa1a779cdc0fc8d12bcf [file] [log] [blame]
# 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()