Split out an `IrDataSerializer` class
In preparation for reworking `ir_data` move json serialazition to it's
own class. For now this is simply a wrapper. All `to_json` call sites
are updated.
Part of #118.
diff --git a/compiler/back_end/cpp/emboss_codegen_cpp.py b/compiler/back_end/cpp/emboss_codegen_cpp.py
index 0a70f41..6da9f7d 100644
--- a/compiler/back_end/cpp/emboss_codegen_cpp.py
+++ b/compiler/back_end/cpp/emboss_codegen_cpp.py
@@ -27,6 +27,7 @@
from compiler.back_end.cpp import header_generator
from compiler.util import error
from compiler.util import ir_data
+from compiler.util import ir_data_utils
def _parse_command_line(argv):
@@ -82,9 +83,9 @@
def main(flags):
if flags.input_file:
with open(flags.input_file) as f:
- ir = ir_data.EmbossIr.from_json(f.read())
+ ir = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr, f.read())
else:
- ir = ir_data.EmbossIr.from_json(sys.stdin.read())
+ ir = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr, sys.stdin.read())
config = header_generator.Config(include_enum_traits=flags.cc_enum_traits)
header, errors = generate_headers_and_log_errors(ir, flags.color_output, config)
if errors:
diff --git a/compiler/front_end/emboss_front_end.py b/compiler/front_end/emboss_front_end.py
index 6232a40..1e30ded 100644
--- a/compiler/front_end/emboss_front_end.py
+++ b/compiler/front_end/emboss_front_end.py
@@ -30,6 +30,7 @@
from compiler.front_end import glue
from compiler.front_end import module_ir
from compiler.util import error
+from compiler.util import ir_data_utils
def _parse_command_line(argv):
@@ -178,10 +179,10 @@
print(glue.format_production_set(
set(module_ir.PRODUCTIONS) - main_module_debug_info.used_productions))
if flags.output_ir_to_stdout:
- print(ir.to_json())
+ print(ir_data_utils.IrDataSerializer(ir).to_json())
if flags.output_file:
with open(flags.output_file, "w") as f:
- f.write(ir.to_json())
+ f.write(ir_data_utils.IrDataSerializer(ir).to_json())
return 0
diff --git a/compiler/front_end/glue.py b/compiler/front_end/glue.py
index a1b0706..7724da9 100644
--- a/compiler/front_end/glue.py
+++ b/compiler/front_end/glue.py
@@ -34,6 +34,7 @@
from compiler.front_end import write_inference
from compiler.util import error
from compiler.util import ir_data
+from compiler.util import ir_data_utils
from compiler.util import parser_types
from compiler.util import resources
@@ -111,7 +112,7 @@
def format_module_ir(self):
"""Renders self.ir in a human-readable format."""
- return self.ir.to_json(indent=2)
+ return ir_data_utils.IrDataSerializer(self.ir).to_json(indent=2)
def format_production_set(productions):
diff --git a/compiler/front_end/glue_test.py b/compiler/front_end/glue_test.py
index a2b61ad..10613d7 100644
--- a/compiler/front_end/glue_test.py
+++ b/compiler/front_end/glue_test.py
@@ -20,6 +20,7 @@
from compiler.front_end import glue
from compiler.util import error
from compiler.util import ir_data
+from compiler.util import ir_data_utils
from compiler.util import parser_types
from compiler.util import test_util
@@ -33,7 +34,7 @@
_ROOT_PACKAGE, _SPAN_SE_LOG_FILE_PATH).decode(encoding="UTF-8")
_SPAN_SE_LOG_FILE_READER = test_util.dict_file_reader(
{_SPAN_SE_LOG_FILE_PATH: _SPAN_SE_LOG_FILE_EMB})
-_SPAN_SE_LOG_FILE_IR = ir_data.Module.from_json(
+_SPAN_SE_LOG_FILE_IR = ir_data_utils.IrDataSerializer.from_json(ir_data.Module,
pkgutil.get_data(
_ROOT_PACKAGE,
_GOLDEN_PATH + "span_se_log_file_status.ir.txt"
@@ -155,7 +156,7 @@
self.assertEqual(_SPAN_SE_LOG_FILE_PARSE_TREE_TEXT.strip(),
debug_info.format_parse_tree().strip())
self.assertEqual(_SPAN_SE_LOG_FILE_IR, debug_info.ir)
- self.assertEqual(_SPAN_SE_LOG_FILE_IR.to_json(indent=2),
+ self.assertEqual(ir_data_utils.IrDataSerializer(_SPAN_SE_LOG_FILE_IR).to_json(indent=2),
debug_info.format_module_ir())
def test_parse_emboss_file(self):
diff --git a/compiler/front_end/module_ir_test.py b/compiler/front_end/module_ir_test.py
index 1f4233d..57d5f4c 100644
--- a/compiler/front_end/module_ir_test.py
+++ b/compiler/front_end/module_ir_test.py
@@ -24,6 +24,7 @@
from compiler.front_end import parser
from compiler.front_end import tokenizer
from compiler.util import ir_data
+from compiler.util import ir_data_utils
from compiler.util import test_util
_TESTDATA_PATH = "testdata.golden"
@@ -31,7 +32,7 @@
_TESTDATA_PATH, "span_se_log_file_status.emb").decode(encoding="UTF-8")
_MINIMAL_SAMPLE = parser.parse_module(
tokenizer.tokenize(_MINIMAL_SOURCE, "")[0]).parse_tree
-_MINIMAL_SAMPLE_IR = ir_data.Module.from_json(
+_MINIMAL_SAMPLE_IR = ir_data_utils.IrDataSerializer.from_json(ir_data.Module,
pkgutil.get_data(_TESTDATA_PATH, "span_se_log_file_status.ir.txt").decode(
encoding="UTF-8")
)
@@ -3978,7 +3979,7 @@
name, emb, ir_text = case.split("---")
name = name.strip()
try:
- ir = ir_data.Module.from_json(ir_text)
+ ir = ir_data_utils.IrDataSerializer.from_json(ir_data.Module, ir_text)
except Exception:
print(name)
raise
@@ -4152,10 +4153,11 @@
def test_case(self):
ir = module_ir.build_ir(test.parse_tree)
is_superset, error_message = test_util.proto_is_superset(ir, test.ir)
+
self.assertTrue(
is_superset,
- error_message + "\n" + ir.to_json(indent=2) + "\n" +
- test.ir.to_json(indent=2))
+ error_message + "\n" + ir_data_utils.IrDataSerializer(ir).to_json(indent=2) + "\n" +
+ ir_data_utils.IrDataSerializer(test.ir).to_json(indent=2))
return test_case
diff --git a/compiler/front_end/type_check_test.py b/compiler/front_end/type_check_test.py
index 6906738..d308fed 100644
--- a/compiler/front_end/type_check_test.py
+++ b/compiler/front_end/type_check_test.py
@@ -18,6 +18,7 @@
from compiler.front_end import glue
from compiler.front_end import type_check
from compiler.util import error
+from compiler.util import ir_data_utils
from compiler.util import test_util
@@ -44,7 +45,7 @@
" 0 [+1] UInt x\n"
" 1 [+true] UInt:8[] y\n")
self.assertEqual([], error.filter_errors(type_check.annotate_types(ir)),
- ir.to_json(indent=2))
+ ir_data_utils.IrDataSerializer(ir).to_json(indent=2))
expression = ir.module[0].type[0].structure.field[1].location.size
self.assertEqual(expression.type.WhichOneof("type"), "boolean")
diff --git a/compiler/util/BUILD b/compiler/util/BUILD
index bbc2ec0..5946dcb 100644
--- a/compiler/util/BUILD
+++ b/compiler/util/BUILD
@@ -25,6 +25,7 @@
name = "ir_data",
srcs = [
"ir_data.py",
+ "ir_data_utils.py",
],
)
diff --git a/compiler/util/ir_data_utils.py b/compiler/util/ir_data_utils.py
new file mode 100644
index 0000000..63b55b7
--- /dev/null
+++ b/compiler/util/ir_data_utils.py
@@ -0,0 +1,31 @@
+# Copyright 2024 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.
+
+from compiler.util import ir_data
+
+class IrDataSerializer:
+ """Provides methods for serializing IR data objects"""
+
+ def __init__(self, ir: ir_data.Message):
+ assert ir is not None
+ self.ir = ir
+
+ def to_json(self, *args, **kwargs):
+ """Converts the IR data class to a JSON string"""
+ return self.ir.to_json(*args, **kwargs)
+
+ @staticmethod
+ def from_json(data_cls: type[ir_data.Message], data):
+ """Constructs an IR data class from the given JSON string"""
+ return data_cls.from_json(data)
diff --git a/compiler/util/ir_util_test.py b/compiler/util/ir_util_test.py
index 1afed9c..b92ffb9 100644
--- a/compiler/util/ir_util_test.py
+++ b/compiler/util/ir_util_test.py
@@ -17,6 +17,7 @@
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
@@ -410,7 +411,7 @@
"bob")
def test_find_object(self):
- ir = ir_data.EmbossIr.from_json(
+ ir = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr,
"""{
"module": [
{
@@ -564,7 +565,7 @@
object_path=["Foo", "Bar"]))))
def test_get_base_type(self):
- array_type_ir = ir_data.Type.from_json(
+ array_type_ir = ir_data_utils.IrDataSerializer.from_json(ir_data.Type,
"""{
"array_type": {
"element_count": { "constant": { "value": "20" } },
@@ -590,7 +591,7 @@
self.assertEqual(base_type_ir, ir_util.get_base_type(base_type_ir))
def test_size_of_type_in_bits(self):
- ir = ir_data.EmbossIr.from_json(
+ ir = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr,
"""{
"module": [{
"type": [{
@@ -638,7 +639,7 @@
}]
}""")
- fixed_size_type = ir_data.Type.from_json(
+ fixed_size_type = ir_data_utils.IrDataSerializer.from_json(ir_data.Type,
"""{
"atomic_type": {
"reference": {
@@ -648,7 +649,7 @@
}""")
self.assertEqual(8, ir_util.fixed_size_of_type_in_bits(fixed_size_type, ir))
- explicit_size_type = ir_data.Type.from_json(
+ explicit_size_type = ir_data_utils.IrDataSerializer.from_json(ir_data.Type,
"""{
"atomic_type": {
"reference": {
@@ -665,7 +666,7 @@
self.assertEqual(32,
ir_util.fixed_size_of_type_in_bits(explicit_size_type, ir))
- fixed_size_array = ir_data.Type.from_json(
+ fixed_size_array = ir_data_utils.IrDataSerializer.from_json(ir_data.Type,
"""{
"array_type": {
"base_type": {
@@ -686,7 +687,7 @@
self.assertEqual(40,
ir_util.fixed_size_of_type_in_bits(fixed_size_array, ir))
- fixed_size_2d_array = ir_data.Type.from_json(
+ fixed_size_2d_array = ir_data_utils.IrDataSerializer.from_json(ir_data.Type,
"""{
"array_type": {
"base_type": {
@@ -720,7 +721,7 @@
self.assertEqual(
80, ir_util.fixed_size_of_type_in_bits(fixed_size_2d_array, ir))
- automatic_size_array = ir_data.Type.from_json(
+ automatic_size_array = ir_data_utils.IrDataSerializer.from_json(ir_data.Type,
"""{
"array_type": {
"base_type": {
@@ -749,7 +750,7 @@
self.assertIsNone(
ir_util.fixed_size_of_type_in_bits(automatic_size_array, ir))
- variable_size_type = ir_data.Type.from_json(
+ variable_size_type = ir_data_utils.IrDataSerializer.from_json(ir_data.Type,
"""{
"atomic_type": {
"reference": {
@@ -760,7 +761,7 @@
self.assertIsNone(
ir_util.fixed_size_of_type_in_bits(variable_size_type, ir))
- no_size_type = ir_data.Type.from_json(
+ no_size_type = ir_data_utils.IrDataSerializer.from_json(ir_data.Type,
"""{
"atomic_type": {
"reference": {
diff --git a/compiler/util/traverse_ir_test.py b/compiler/util/traverse_ir_test.py
index 64da8f6..ff54d63 100644
--- a/compiler/util/traverse_ir_test.py
+++ b/compiler/util/traverse_ir_test.py
@@ -19,9 +19,10 @@
import unittest
from compiler.util import ir_data
+from compiler.util import ir_data_utils
from compiler.util import traverse_ir
-_EXAMPLE_IR = ir_data.EmbossIr.from_json("""{
+_EXAMPLE_IR = ir_data_utils.IrDataSerializer.from_json(ir_data.EmbossIr, """{
"module": [
{
"type": [