Rename REAMDE to README.md
[nit.git] / src / nitserial.nit
index 4953156..0b60a1b 100644 (file)
@@ -18,7 +18,7 @@
 #
 # Executing on the module `game_logic` will create the module `game_logic_serial`
 # in the local directory. Mixing the generated module to the main module with
-# `nitg game_logic.nit -m game_logic_serial` will create a program supporting
+# `nitc game_logic.nit -m game_logic_serial` will create a program supporting
 # deserialization of all generic types visible from the main module.
 #
 # Because the generation is limited to the visible types, a module author might want
@@ -36,16 +36,16 @@ import template
 class NitModule
        super Template
 
-       var header: nullable Streamable = null
+       var header: nullable Writable = null
 
        # The module's name
-       var name: Streamable
+       var name: Writable
 
        # Imports from this module
-       var imports = new Array[Streamable]
+       var imports = new Array[Writable]
 
        # Main content of this module
-       var content = new Array[Streamable]
+       var content = new Array[Writable]
 
        redef fun rendering
        do
@@ -69,16 +69,20 @@ redef class ToolContext
        # Where do we put the result?
        var opt_dir: OptionString = new OptionString("Output directory", "--dir")
 
+       # Depth of the visit and generation
+       var opt_depth = new OptionEnum(["module", "group", "project"],
+               "Depth of the visit and generation", 0, "-d", "--depth")
+
        redef init
        do
-               option_context.add_option(opt_output, opt_dir)
+               option_context.add_option(opt_output, opt_dir, opt_depth)
                super
        end
 end
 
 redef class MModule
        # Get the type of the class `Serializable`
-       fun serializable_type: MClassType is cached do
+       var serializable_type: MClassType is lazy do
                return self.get_primitive_class("Serializable").mclass_type
        end
 end
@@ -130,10 +134,8 @@ var modelbuilder = new ModelBuilder(model, toolcontext)
 var mmodules = modelbuilder.parse_full(arguments)
 modelbuilder.run_phases
 
-# Create a distinct support module per targetted modules
+# Create a distinct support module per target modules
 for mmodule in mmodules do
-       var rta = modelbuilder.do_rapid_type_analysis(mmodule)
-
        # Name of the support module
        var module_name
 
@@ -155,13 +157,47 @@ for mmodule in mmodules do
                module_path += ".nit"
        end
 
+       var target_modules = null
+       var importations = null
+       var mgroup = mmodule.mgroup
+       if toolcontext.opt_depth.value == 1 and mgroup != null then
+               modelbuilder.visit_group mgroup
+               target_modules = mgroup.mmodules
+       else if toolcontext.opt_depth.value == 2 then
+               # project
+               target_modules = new Array[MModule]
+               importations = new Array[MModule]
+               if mgroup != null then
+                       for g in mgroup.mproject.mgroups do
+                               target_modules.add_all g.mmodules
+                       end
+
+                       for g in mgroup.in_nesting.direct_smallers do
+                               var dm = g.default_mmodule
+                               if dm != null then
+                                       importations.add dm
+                               end
+                       end
+
+                       for m in mgroup.mmodules do
+                               importations.add m
+                       end
+               end
+       end
+
+       if target_modules == null then target_modules = [mmodule]
+       if importations == null then importations = target_modules
+
        var nit_module = new NitModule(module_name)
        nit_module.header = """
 # This file is generated by nitserial
 # Do not modify, but you can redef
 """
 
-       nit_module.imports.add mmodule.name
+       for importation in importations do
+               nit_module.imports.add importation.name
+       end
+
        nit_module.imports.add "serialization"
 
        nit_module.content.add """
@@ -170,15 +206,25 @@ redef class Deserializer
        do"""
 
        var serializable_type = mmodule.serializable_type
-       for mtype in rta.live_types do
-               # We are only interested in instanciated generics, subtypes of Serializable
-               # and which are visibles.
-               if mtype isa MGenericType and
-                  mtype.is_subtype(mmodule, null, serializable_type) and
-                  mtype.is_visible_from(mmodule) then
-
-                       nit_module.content.add """
+       var compiled_types = new Array[MType]
+       for m in target_modules do
+               nit_module.content.add """
+               # Module: {{{m.to_s}}}"""
+
+               var rta = modelbuilder.do_rapid_type_analysis(m)
+
+               for mtype in rta.live_types do
+                       # We are only interested in instanciated generics, subtypes of Serializable
+                       # and which are visible.
+                       if mtype isa MGenericType and
+                          mtype.is_subtype(m, null, serializable_type) and
+                          mtype.is_visible_from(mmodule) and
+                          not compiled_types.has(mtype) then
+
+                               compiled_types.add mtype
+                               nit_module.content.add """
                if name == \"{{{mtype}}}\" then return new {{{mtype}}}.from_deserializer(self)"""
+                       end
                end
        end