X-Git-Url: http://nitlanguage.org diff --git a/src/model/mmodule.nit b/src/model/mmodule.nit index e3fda2d..923923a 100644 --- a/src/model/mmodule.nit +++ b/src/model/mmodule.nit @@ -17,26 +17,27 @@ # modules and module hierarchies in the metamodel module mmodule -import poset import location -import model_base +import mproject private import more_collections # The container class of a Nit object-oriented model. # A model knows modules, classes and properties and can retrieve them. redef class Model # All known modules - var mmodules: Array[MModule] = new Array[MModule] + var mmodules = new Array[MModule] - # Module nesting hierarchy. + # placebo for old module nesting hierarchy. # where mainmodule < mainmodule::nestedmodule - var mmodule_nesting_hierarchy: POSet[MModule] = new POSet[MModule] + # + # TODO REMOVE, rely on mgroup instead + var mmodule_nesting_hierarchy = new POSet[MModule] # Full module importation hierarchy including private or nested links. - var mmodule_importation_hierarchy: POSet[MModule] = new POSet[MModule] + var mmodule_importation_hierarchy = new POSet[MModule] # Collections of modules grouped by their short names - private var mmodules_by_name: MultiHashMap[String, MModule] = new MultiHashMap[String, MModule] + private var mmodules_by_name = new MultiHashMap[String, MModule] # Return all module named `name` # If such a module does not exist, null is returned (instead of an empty array) @@ -52,17 +53,30 @@ redef class Model end end +redef class MGroup + # The loaded modules of this group + var mmodules = new Array[MModule] + + # The default module of a group (if any, and if loaded) + # + # The default module of a group is the one that has the same name. + # Return `null` if the group has no default module or if the default + # module is not loaded. + var default_mmodule: nullable MModule = null +end + # A Nit module is usually associated with a Nit source file. -# Modules can be nested (see `direct_owner`, `public_owner`, and `in_nesting`) class MModule + super MConcern + # The model considered - var model: Model + redef var model: Model - # The direct nesting module, return null if self is not nested (ie. is a top-level module) - var direct_owner: nullable MModule + # The group of module in the project if any + var mgroup: nullable MGroup # The short name of the module - var name: String + redef var name: String # The origin of the definition var location: Location @@ -70,27 +84,29 @@ class MModule # Alias for `name` redef fun to_s do return self.name + # placebo for old module nesting hierarchy # The view of the module in the `model.mmodule_nesting_hierarchy` + # + # TODO REMOVE, rely on mgroup instead var in_nesting: POSetElement[MModule] # The view of the module in the `model.mmodule_importation_hierarchy` var in_importation: POSetElement[MModule] # The canonical name of the module - # Example: `"owner::name"` + # Example: `"project::name"` fun full_name: String do - var owner = self.public_owner - if owner == null then + var mgroup = self.mgroup + if mgroup == null or mgroup.mproject.name == self.name then return self.name else - return "{owner.full_name}::{self.name}" + return "{mgroup.mproject.name}::{self.name}" end end # Create a new empty module and register it to a model - # `direct_owner` is the direct owner (null if top-level module) - init(model: Model, direct_owner: nullable MModule, name: String, location: Location) + init(model: Model, mgroup: nullable MGroup, name: String, location: Location) do self.model = model self.name = name @@ -98,9 +114,27 @@ class MModule model.mmodules_by_name.add_one(name, self) model.mmodules.add(self) self.in_nesting = model.mmodule_nesting_hierarchy.add_node(self) - self.direct_owner = direct_owner - if direct_owner != null then - model.mmodule_nesting_hierarchy.add_edge(direct_owner, self) + self.mgroup = mgroup + if mgroup != null then + mgroup.mmodules.add(self) + if mgroup.name == name then + assert mgroup.default_mmodule == null + mgroup.default_mmodule = self + end + # placebo for old module nesting hierarchy + var direct_owner = mgroup.default_mmodule + if direct_owner == self then + # The module is the new owner of its own group, thus adopt the other modules + for m in mgroup.mmodules do + if m == self then continue + model.mmodule_nesting_hierarchy.add_edge(self, m) + end + # The potential owner is the default_mmodule of the parent group + if mgroup.parent != null then direct_owner = mgroup.parent.default_mmodule + end + if direct_owner != self and direct_owner != null then + model.mmodule_nesting_hierarchy.add_edge(direct_owner, self) + end end self.in_importation = model.mmodule_importation_hierarchy.add_node(self) end @@ -116,9 +150,9 @@ class MModule end end - private var intrude_mmodules: HashSet[MModule] = new HashSet[MModule] - private var public_mmodules: HashSet[MModule] = new HashSet[MModule] - private var private_mmodules: HashSet[MModule] = new HashSet[MModule] + private var intrude_mmodules = new HashSet[MModule] + private var public_mmodules = new HashSet[MModule] + private var private_mmodules = new HashSet[MModule] # Return the visibility level of an imported module `m` fun visibility_for(m: MModule): MVisibility @@ -153,20 +187,6 @@ class MModule end end - # The first module in the nesting hierarchy to export self as public - # This function is used to determine the canonical name of modules, classes and properties. - # REQUIRE: the visibility of all nesting modules is already set. - fun public_owner: nullable MModule - do - var res = self.direct_owner - var last = res - while last != null do - if last.visibility_for(self) >= public_visibility then res = last - last = last.direct_owner - end - return res - end - # Return true if a class or a property introduced in `intro_mmodule` with a visibility of `visibility` is visible in self. fun is_visible(intro_mmodule: MModule, visibility: MVisibility): Bool do @@ -183,4 +203,11 @@ class MModule abort end end + + # Is `self` created for internal purpose? + # Fictive modules are instantiated internally but they should not be + # exposed to the final user. + var is_fictive: Bool = false is writable + + redef fun parent_concern do return mgroup end