X-Git-Url: http://nitlanguage.org diff --git a/src/frontend/serialization_phase.nit b/src/frontend/serialization_phase.nit index 3e144ef..8d576ba 100644 --- a/src/frontend/serialization_phase.nit +++ b/src/frontend/serialization_phase.nit @@ -85,14 +85,67 @@ private class SerializationPhasePreModel "Warning: duplicated annotation `{text}`.") end - # Add `super Serializable` - var sc = toolcontext.parse_superclass("Serializable") - sc.location = nat.location - nclassdef.n_propdefs.add sc + # Check the `serialize` state of the parent + if not node isa AModuledecl then + var up_serialize = false + var up: nullable ANode = node + loop + up = up.parent + if up == null then + break + else if up.is_serialize then + up_serialize = true + break + else if up.is_noserialize then + break + end + end + + # Check for useless double declarations + if serialize and up_serialize then + toolcontext.warning(node.location, "useless-serialize", + "Warning: superfluous use of `{text}`.") + else if noserialize and not up_serialize then + toolcontext.warning(node.location, "useless-noserialize", + "Warning: superfluous use of `{text}`.") + end + end + end - generate_serialization_method(nclassdef) + redef fun process_nclassdef(nclassdef) + do + if not nclassdef isa AStdClassdef then return + + # Is there a declaration on the classdef or the module? + var serialize = nclassdef.is_serialize - generate_deserialization_init(nclassdef) + if not serialize and not nclassdef.is_noserialize then + # Is the module marked serialize? + serialize = nclassdef.parent.as(AModule).is_serialize + end + + var per_attribute = false + if not serialize then + # Is there an attribute marked serialize? + for npropdef in nclassdef.n_propdefs do + if npropdef.is_serialize then + serialize = true + per_attribute = true + break + end + end + end + + if serialize then + # Add `super Serializable` + var sc = toolcontext.parse_superclass("Serializable") + sc.location = nclassdef.location + nclassdef.n_propdefs.add sc + + # Add services + generate_serialization_method(nclassdef, per_attribute) + generate_deserialization_init(nclassdef, per_attribute) + end end redef fun process_nmodule(nmodule) @@ -113,7 +166,7 @@ private class SerializationPhasePreModel end end - fun generate_serialization_method(nclassdef: AClassdef) + fun generate_serialization_method(nclassdef: AClassdef, per_attribute: Bool) do var npropdefs = nclassdef.n_propdefs @@ -123,6 +176,11 @@ private class SerializationPhasePreModel code.add " super" for attribute in npropdefs do if attribute isa AAttrPropdef then + + # Is `attribute` to be skipped? + if (per_attribute and not attribute.is_serialize) or + attribute.is_noserialize then continue + var name = attribute.name code.add " v.serialize_attribute(\"{name}\", {name})" end @@ -134,7 +192,7 @@ private class SerializationPhasePreModel end # Add a constructor to the automated nclassdef - fun generate_deserialization_init(nclassdef: AStdClassdef) + fun generate_deserialization_init(nclassdef: AClassdef, per_attribute: Bool) do var npropdefs = nclassdef.n_propdefs @@ -145,6 +203,11 @@ private class SerializationPhasePreModel code.add " v.notify_of_creation self" for attribute in npropdefs do if attribute isa AAttrPropdef then + + # Is `attribute` to be skipped? + if (per_attribute and not attribute.is_serialize) or + attribute.is_noserialize then continue + var n_type = attribute.n_type var type_name if n_type == null then @@ -290,6 +353,8 @@ redef class AModule end private var inits_to_retype = new Array[AMethPropdef] + + redef fun is_serialize do return n_moduledecl != null and n_moduledecl.is_serialize end redef class AStdClassdef