lib/poset: implement serialization compatible with nith
authorAlexis Laferrière <alexis.laf@xymus.net>
Thu, 8 Sep 2016 17:30:37 +0000 (13:30 -0400)
committerAlexis Laferrière <alexis.laf@xymus.net>
Fri, 14 Oct 2016 19:18:31 +0000 (15:18 -0400)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

lib/poset.nit

index 1c2a349..98205ac 100644 (file)
@@ -17,6 +17,8 @@
 # Pre order sets and partial order set (ie hierarchies)
 module poset
 
+import serialization
+
 # Pre-order set graph.
 # This class models an incremental pre-order graph where new nodes and edges can be added (but not removed).
 # Pre-order graph has two characteristics:
@@ -75,6 +77,7 @@ class POSet[E]
        super Collection[E]
        super Comparator
        super Cloneable
+       super Serializable
 
        redef type COMPARED: E is fixed
 
@@ -484,6 +487,23 @@ class POSet[E]
                end
                return res
        end
+
+       redef fun core_serialize_to(serializer)
+       do
+               # Optimize written data because this structure has duplicated data
+               # For example, serializing the class hierarchy of a simple program where E is String
+               # result is before: 200k, after: 56k.
+               serializer.serialize_attribute("elements", elements)
+       end
+
+       redef init from_deserializer(deserializer)
+       do
+               deserializer.notify_of_creation self
+               var elements = deserializer.deserialize_attribute("elements")
+               if elements isa HashMap[E, POSetElement[E]] then
+                       self.elements = elements
+               end
+       end
 end
 
 # View of an object in a poset
@@ -501,6 +521,8 @@ end
 # t.in_some_relation.greaters
 # ~~~
 class POSetElement[E]
+       super Serializable
+
        # The poset self belong to
        var poset: POSet[E]
 
@@ -616,6 +638,94 @@ class POSetElement[E]
                        end
                end
                return min
+       end
 
+       redef fun core_serialize_to(serializer)
+       do
+               serializer.serialize_attribute("poset", poset)
+               serializer.serialize_attribute("element", element)
+               serializer.serialize_attribute("tos", tos)
+               serializer.serialize_attribute("froms", froms)
+               serializer.serialize_attribute("dtos", dtos)
+               serializer.serialize_attribute("dfroms", dfroms)
+               serializer.serialize_attribute("count", count)
+
+               # Don't serialize `froms`, `dtos` and `tos` as they duplicate information.
+               # TODO serialize them if a flag for extra info is set on `serializer`.
+       end
+
+       redef init from_deserializer(v)
+       do
+               # Code generated by the serialization_phase from the compiler frontend,
+               # copied here for compatibility with nith.
+
+               super
+               v.notify_of_creation self
+
+               var poset = v.deserialize_attribute("poset", "POSet[nullable Object]")
+               if v.deserialize_attribute_missing then
+                       v.errors.add new Error("Deserialization Error: attribute `{class_name}::poset` missing from JSON object")
+               else if not poset isa POSet[E] then
+                       v.errors.add new AttributeTypeError(self, "poset", poset, "POSet[nullable Object]")
+                       if v.keep_going == false then return
+               else
+                       self.poset = poset
+               end
+
+               var element = v.deserialize_attribute("element", "nullable Object")
+               if v.deserialize_attribute_missing then
+                       v.errors.add new Error("Deserialization Error: attribute `{class_name}::element` missing from JSON object")
+               else if not element isa E then
+                       v.errors.add new AttributeTypeError(self, "element", element, "nullable Object")
+                       if v.keep_going == false then return
+               else
+                       self.element = element
+               end
+
+               var tos = v.deserialize_attribute("tos", "HashSet[nullable Object]")
+               if v.deserialize_attribute_missing then
+               else if not tos isa HashSet[E] then
+                       v.errors.add new AttributeTypeError(self, "tos", tos, "HashSet[nullable Object]")
+                       if v.keep_going == false then return
+               else
+                       self.tos = tos
+               end
+
+               var froms = v.deserialize_attribute("froms", "HashSet[nullable Object]")
+               if v.deserialize_attribute_missing then
+               else if not froms isa HashSet[E] then
+                       v.errors.add new AttributeTypeError(self, "froms", froms, "HashSet[nullable Object]")
+                       if v.keep_going == false then return
+               else
+                       self.froms = froms
+               end
+
+               var dtos = v.deserialize_attribute("dtos", "HashSet[nullable Object]")
+               if v.deserialize_attribute_missing then
+               else if not dtos isa HashSet[E] then
+                       v.errors.add new AttributeTypeError(self, "dtos", dtos, "HashSet[nullable Object]")
+                       if v.keep_going == false then return
+               else
+                       self.dtos = dtos
+               end
+
+               var dfroms = v.deserialize_attribute("dfroms", "HashSet[nullable Object]")
+               if v.deserialize_attribute_missing then
+               else if not dfroms isa HashSet[E] then
+                       v.errors.add new AttributeTypeError(self, "dfroms", dfroms, "HashSet[nullable Object]")
+                       if v.keep_going == false then return
+               else
+                       self.dfroms = dfroms
+               end
+
+               var count = v.deserialize_attribute("count", "Int")
+               if v.deserialize_attribute_missing then
+                       v.errors.add new Error("Deserialization Error: attribute `{class_name}::count` missing from JSON object")
+               else if not count isa Int then
+                       v.errors.add new AttributeTypeError(self, "count", count, "Int")
+                       if v.keep_going == false then return
+               else
+                       self.count = count
+               end
        end
 end