X-Git-Url: http://nitlanguage.org diff --git a/src/nitserial.nit b/src/nitserial.nit index 0b60a1b..2b347f1 100644 --- a/src/nitserial.nit +++ b/src/nitserial.nit @@ -25,42 +25,11 @@ # generate and include its own serialization support module. module nitserial -import frontend -import rapid_type_analysis -import model_utils import template +import gen_nit -# A Nit module -# -# TODO add more features and move to lib -class NitModule - super Template - - var header: nullable Writable = null - - # The module's name - var name: Writable - - # Imports from this module - var imports = new Array[Writable] - - # Main content of this module - var content = new Array[Writable] - - redef fun rendering - do - var header = header - if header != null then add header - - var name = name - add "module {name}\n\n" - - for i in imports do add "import {i}\n" - add "\n" - - for l in content do add "{l}\n" - end -end +import frontend +import rapid_type_analysis redef class ToolContext # Where do we put a single result? @@ -70,7 +39,7 @@ redef class ToolContext var opt_dir: OptionString = new OptionString("Output directory", "--dir") # Depth of the visit and generation - var opt_depth = new OptionEnum(["module", "group", "project"], + var opt_depth = new OptionEnum(["module", "group", "package"], "Depth of the visit and generation", 0, "-d", "--depth") redef init @@ -88,25 +57,24 @@ redef class MModule end redef class MType - # Is this type fully visible from `mmodule`? - fun is_visible_from(mmodule: MModule): Bool is abstract + # List classes composing this type + private fun related_mclasses(mmodule: MModule): Array[MClass] is abstract end redef class MClassType - redef fun is_visible_from(mmodule) do - return mmodule.is_visible(mclass.intro_mmodule, public_visibility) - end + redef fun related_mclasses(mmodule) do return [mclass] end -redef class MNullableType - redef fun is_visible_from(mmodule) do return mtype.is_visible_from(mmodule) +redef class MProxyType + redef fun related_mclasses(mmodule) do return undecorate.related_mclasses(mmodule) end redef class MGenericType - redef fun is_visible_from(mmodule) + redef fun related_mclasses(mmodule) do - for arg_mtype in arguments do if not arg_mtype.is_visible_from(mmodule) then return false - return super + var mods = super + for arg_mtype in arguments do mods.add_all(arg_mtype.related_mclasses(mmodule)) + return mods end end @@ -153,7 +121,7 @@ for mmodule in mmodules do else if module_path.has_suffix(".nit") then module_name = module_path.basename(".nit") else - module_name = module_path.basename("") + module_name = module_path.basename module_path += ".nit" end @@ -161,14 +129,14 @@ for mmodule in mmodules do var importations = null var mgroup = mmodule.mgroup if toolcontext.opt_depth.value == 1 and mgroup != null then - modelbuilder.visit_group mgroup + modelbuilder.scan_group mgroup target_modules = mgroup.mmodules else if toolcontext.opt_depth.value == 2 then - # project + # package target_modules = new Array[MModule] importations = new Array[MModule] if mgroup != null then - for g in mgroup.mproject.mgroups do + for g in mgroup.mpackage.mgroups do target_modules.add_all g.mmodules end @@ -189,6 +157,8 @@ for mmodule in mmodules do if importations == null then importations = target_modules var nit_module = new NitModule(module_name) + nit_module.annotations.add """generated""" + nit_module.annotations.add """no_warning("property-conflict")""" nit_module.header = """ # This file is generated by nitserial # Do not modify, but you can redef @@ -218,9 +188,25 @@ redef class Deserializer # and which are visible. if mtype isa MGenericType and mtype.is_subtype(m, null, serializable_type) and - mtype.is_visible_from(mmodule) and + mtype.mclass.kind == concrete_kind and not compiled_types.has(mtype) then + # Intrude import the modules declaring private classes + var related_mclasses = mtype.related_mclasses(mmodule) + for mclass in related_mclasses do + if not mmodule.is_visible(mclass.intro_mmodule, mclass.visibility) then + var intro_mmodule = mclass.intro_mmodule + var intro_mgroup = intro_mmodule.mgroup + + var to_import = intro_mmodule.full_name + if intro_mgroup == null or intro_mgroup.default_mmodule == intro_mmodule then + to_import = intro_mmodule.name + end + + nit_module.imports.add "intrude import {to_import}" + end + end + compiled_types.add mtype nit_module.content.add """ if name == \"{{{mtype}}}\" then return new {{{mtype}}}.from_deserializer(self)"""