Merge: example: add 24 game task of Rosetta code
[nit.git] / src / frontend / serialization_phase.nit
index ac128c6..8d576ba 100644 (file)
@@ -101,7 +101,6 @@ private class SerializationPhasePreModel
                                end
                        end
 
-               generate_serialization_method(nclassdef)
                        # Check for useless double declarations
                        if serialize and up_serialize then
                                toolcontext.warning(node.location, "useless-serialize",
@@ -113,13 +112,40 @@ private class SerializationPhasePreModel
                end
        end
 
-               generate_deserialization_init(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
+
+               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)
@@ -140,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
 
@@ -150,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
@@ -161,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
 
@@ -172,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
@@ -317,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