# 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?
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
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, mclass.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
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
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
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
# 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)"""